Merge 5.10.192 into android12-5.10-lts

Changes in 5.10.192
	mmc: sdhci-f-sdh30: Replace with sdhci_pltfm
	macsec: Fix traffic counters/statistics
	macsec: use DEV_STATS_INC()
	net/mlx5: Refactor init clock function
	net/mlx5: Move all internal timer metadata into a dedicated struct
	net/mlx5: Skip clock update work when device is in error state
	drm/radeon: Fix integer overflow in radeon_cs_parser_init
	ALSA: emu10k1: roll up loops in DSP setup code for Audigy
	ASoC: Intel: sof_sdw: add quirk for MTL RVP
	ASoC: Intel: sof_sdw: add quirk for LNL RVP
	PCI: tegra194: Fix possible array out of bounds access
	ARM: dts: imx6dl: prtrvt, prtvt7, prti6q, prtwd2: fix USB related warnings
	ASoC: Intel: sof_sdw: Add support for Rex soundwire
	iopoll: Call cpu_relax() in busy loops
	quota: Properly disable quotas when add_dquot_ref() fails
	quota: fix warning in dqgrab()
	dma-remap: use kvmalloc_array/kvfree for larger dma memory remap
	drm/amdgpu: install stub fence into potential unused fence pointers
	HID: add quirk for 03f0:464a HP Elite Presenter Mouse
	RDMA/mlx5: Return the firmware result upon destroying QP/RQ
	ovl: check type and offset of struct vfsmount in ovl_entry
	udf: Fix uninitialized array access for some pathnames
	fs: jfs: Fix UBSAN: array-index-out-of-bounds in dbAllocDmapLev
	MIPS: dec: prom: Address -Warray-bounds warning
	FS: JFS: Fix null-ptr-deref Read in txBegin
	FS: JFS: Check for read-only mounted filesystem in txBegin
	media: v4l2-mem2mem: add lock to protect parameter num_rdy
	usb: gadget: u_serial: Avoid spinlock recursion in __gs_console_push
	media: platform: mediatek: vpu: fix NULL ptr dereference
	usb: chipidea: imx: don't request QoS for imx8ulp
	usb: chipidea: imx: add missing USB PHY DPDM wakeup setting
	gfs2: Fix possible data races in gfs2_show_options()
	pcmcia: rsrc_nonstatic: Fix memory leak in nonstatic_release_resource_db()
	Bluetooth: L2CAP: Fix use-after-free
	Bluetooth: btusb: Add MT7922 bluetooth ID for the Asus Ally
	drm/amdgpu: Fix potential fence use-after-free v2
	ALSA: hda/realtek: Add quirks for Unis H3C Desktop B760 & Q760
	ALSA: hda: fix a possible null-pointer dereference due to data race in snd_hdac_regmap_sync()
	powerpc/kasan: Disable KCOV in KASAN code
	ring-buffer: Do not swap cpu_buffer during resize process
	IMA: allow/fix UML builds
	iio: add addac subdirectory
	dt-bindings: iio: add AD74413R
	iio: adc: stx104: Utilize iomap interface
	iio: adc: stx104: Implement and utilize register structures
	iio: addac: stx104: Fix race condition for stx104_write_raw()
	iio: addac: stx104: Fix race condition when converting analog-to-digital
	bus: mhi: Add MHI PCI support for WWAN modems
	bus: mhi: Add MMIO region length to controller structure
	bus: mhi: Move host MHI code to "host" directory
	bus: mhi: host: Range check CHDBOFF and ERDBOFF
	irqchip/mips-gic: Get rid of the reliance on irq_cpu_online()
	irqchip/mips-gic: Use raw spinlock for gic_lock
	usb: gadget: udc: core: Introduce check_config to verify USB configuration
	usb: cdns3: allocate TX FIFO size according to composite EP number
	usb: cdns3: fix NCM gadget RX speed 20x slow than expection at iMX8QM
	USB: dwc3: qcom: fix NULL-deref on suspend
	mmc: bcm2835: fix deferred probing
	mmc: sunxi: fix deferred probing
	mmc: core: add devm_mmc_alloc_host
	mmc: meson-gx: use devm_mmc_alloc_host
	mmc: meson-gx: fix deferred probing
	tracing/probes: Have process_fetch_insn() take a void * instead of pt_regs
	tracing/probes: Fix to update dynamic data counter if fetcharg uses it
	virtio-mmio: Use to_virtio_mmio_device() to simply code
	virtio-mmio: don't break lifecycle of vm_dev
	i2c: bcm-iproc: Fix bcm_iproc_i2c_isr deadlock issue
	fbdev: mmp: fix value check in mmphw_probe()
	powerpc/rtas_flash: allow user copy to flash block cache objects
	tty: n_gsm: fix the UAF caused by race condition in gsm_cleanup_mux
	tty: serial: fsl_lpuart: Clear the error flags by writing 1 for lpuart32 platforms
	btrfs: fix BUG_ON condition in btrfs_cancel_balance
	i2c: designware: Handle invalid SMBus block data response length value
	net: xfrm: Fix xfrm_address_filter OOB read
	net: af_key: fix sadb_x_filter validation
	net: xfrm: Amend XFRMA_SEC_CTX nla_policy structure
	xfrm: fix slab-use-after-free in decode_session6
	ip6_vti: fix slab-use-after-free in decode_session6
	ip_vti: fix potential slab-use-after-free in decode_session6
	xfrm: add NULL check in xfrm_update_ae_params
	xfrm: add forgotten nla_policy for XFRMA_MTIMER_THRESH
	selftests: mirror_gre_changes: Tighten up the TTL test match
	drm/panel: simple: Fix AUO G121EAN01 panel timings according to the docs
	ipvs: fix racy memcpy in proc_do_sync_threshold
	netfilter: nft_dynset: disallow object maps
	net: phy: broadcom: stub c45 read/write for 54810
	team: Fix incorrect deletion of ETH_P_8021AD protocol vid from slaves
	i40e: fix misleading debug logs
	net: dsa: mv88e6xxx: Wait for EEPROM done before HW reset
	sock: Fix misuse of sk_under_memory_pressure()
	net: do not allow gso_size to be set to GSO_BY_FRAGS
	bus: ti-sysc: Flush posted write on enable before reset
	arm64: dts: rockchip: fix supplies on rk3399-rock-pi-4
	arm64: dts: rockchip: use USB host by default on rk3399-rock-pi-4
	arm64: dts: rockchip: add ES8316 codec for ROCK Pi 4
	arm64: dts: rockchip: add SPDIF node for ROCK Pi 4
	arm64: dts: rockchip: fix regulator name on rk3399-rock-4
	arm64: dts: rockchip: sort nodes/properties on rk3399-rock-4
	arm64: dts: rockchip: Disable HS400 for eMMC on ROCK Pi 4
	ASoC: rt5665: add missed regulator_bulk_disable
	ASoC: meson: axg-tdm-formatter: fix channel slot allocation
	ALSA: hda/realtek - Remodified 3k pull low procedure
	serial: 8250: Fix oops for port->pm on uart_change_pm()
	ALSA: usb-audio: Add support for Mythware XA001AU capture and playback interfaces.
	cifs: Release folio lock on fscache read hit.
	mmc: wbsd: fix double mmc_free_host() in wbsd_init()
	mmc: block: Fix in_flight[issue_type] value error
	netfilter: set default timeout to 3 secs for sctp shutdown send and recv state
	af_unix: Fix null-ptr-deref in unix_stream_sendpage().
	virtio-net: set queues after driver_ok
	net: fix the RTO timer retransmitting skb every 1ms if linear option is enabled
	mmc: f-sdh30: fix order of function calls in sdhci_f_sdh30_remove
	x86/cpu: Fix __x86_return_thunk symbol type
	x86/cpu: Fix up srso_safe_ret() and __x86_return_thunk()
	x86/alternative: Make custom return thunk unconditional
	objtool: Add frame-pointer-specific function ignore
	x86/ibt: Add ANNOTATE_NOENDBR
	x86/cpu: Clean up SRSO return thunk mess
	x86/cpu: Rename original retbleed methods
	x86/cpu: Rename srso_(.*)_alias to srso_alias_\1
	x86/cpu: Cleanup the untrain mess
	x86/srso: Explain the untraining sequences a bit more
	x86/static_call: Fix __static_call_fixup()
	x86/retpoline: Don't clobber RFLAGS during srso_safe_ret()
	x86/CPU/AMD: Fix the DIV(0) initial fix attempt
	x86/srso: Disable the mitigation on unaffected configurations
	x86/retpoline,kprobes: Fix position of thunk sections with CONFIG_LTO_CLANG
	objtool/x86: Fixup frame-pointer vs rethunk
	x86/srso: Correct the mitigation status when SMT is disabled
	Linux 5.10.192

Change-Id: Id6dcc6748bce39baa640b8f0c3764d1d95643016
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
Greg Kroah-Hartman 2023-08-28 16:31:53 +00:00
commit b23fd871be
125 changed files with 1789 additions and 643 deletions

View File

@ -124,8 +124,8 @@ sequence.
To ensure the safety of this mitigation, the kernel must ensure that the
safe return sequence is itself free from attacker interference. In Zen3
and Zen4, this is accomplished by creating a BTB alias between the
untraining function srso_untrain_ret_alias() and the safe return
function srso_safe_ret_alias() which results in evicting a potentially
untraining function srso_alias_untrain_ret() and the safe return
function srso_alias_safe_ret() which results in evicting a potentially
poisoned BTB entry and using that safe one for all function returns.
In older Zen1 and Zen2, this is accomplished using a reinterpretation

View File

@ -0,0 +1,158 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/addac/adi,ad74413r.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Analog Devices AD74412R/AD74413R device
maintainers:
- Cosmin Tanislav <cosmin.tanislav@analog.com>
description: |
The AD74412R and AD74413R are quad-channel software configurable input/output
solutions for building and process control applications. They contain
functionality for analog output, analog input, digital input, resistance
temperature detector, and thermocouple measurements integrated
into a single chip solution with an SPI interface.
The devices feature a 16-bit ADC and four configurable 13-bit DACs to provide
four configurable input/output channels and a suite of diagnostic functions.
The AD74413R differentiates itself from the AD74412R by being HART-compatible.
https://www.analog.com/en/products/ad74412r.html
https://www.analog.com/en/products/ad74413r.html
properties:
compatible:
enum:
- adi,ad74412r
- adi,ad74413r
reg:
maxItems: 1
'#address-cells':
const: 1
'#size-cells':
const: 0
spi-max-frequency:
maximum: 1000000
spi-cpol: true
interrupts:
maxItems: 1
refin-supply: true
shunt-resistor-micro-ohms:
description:
Shunt (sense) resistor value in micro-Ohms.
default: 100000000
required:
- compatible
- reg
- spi-max-frequency
- spi-cpol
- refin-supply
additionalProperties: false
patternProperties:
"^channel@[0-3]$":
type: object
description: Represents the external channels which are connected to the device.
properties:
reg:
description: |
The channel number. It can have up to 4 channels numbered from 0 to 3.
minimum: 0
maximum: 3
adi,ch-func:
$ref: /schemas/types.yaml#/definitions/uint32
description: |
Channel function.
HART functions are not supported on AD74412R.
0 - CH_FUNC_HIGH_IMPEDANCE
1 - CH_FUNC_VOLTAGE_OUTPUT
2 - CH_FUNC_CURRENT_OUTPUT
3 - CH_FUNC_VOLTAGE_INPUT
4 - CH_FUNC_CURRENT_INPUT_EXT_POWER
5 - CH_FUNC_CURRENT_INPUT_LOOP_POWER
6 - CH_FUNC_RESISTANCE_INPUT
7 - CH_FUNC_DIGITAL_INPUT_LOGIC
8 - CH_FUNC_DIGITAL_INPUT_LOOP_POWER
9 - CH_FUNC_CURRENT_INPUT_EXT_POWER_HART
10 - CH_FUNC_CURRENT_INPUT_LOOP_POWER_HART
minimum: 0
maximum: 10
default: 0
adi,gpo-comparator:
type: boolean
description: |
Whether to configure GPO as a comparator or not.
When not configured as a comparator, the GPO will be treated as an
output-only GPIO.
required:
- reg
examples:
- |
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/iio/addac/adi,ad74413r.h>
spi {
#address-cells = <1>;
#size-cells = <0>;
cs-gpios = <&gpio 17 GPIO_ACTIVE_LOW>;
status = "okay";
ad74413r@0 {
compatible = "adi,ad74413r";
reg = <0>;
spi-max-frequency = <1000000>;
spi-cpol;
#address-cells = <1>;
#size-cells = <0>;
interrupt-parent = <&gpio>;
interrupts = <26 IRQ_TYPE_EDGE_FALLING>;
refin-supply = <&ad74413r_refin>;
channel@0 {
reg = <0>;
adi,ch-func = <CH_FUNC_VOLTAGE_OUTPUT>;
};
channel@1 {
reg = <1>;
adi,ch-func = <CH_FUNC_CURRENT_OUTPUT>;
};
channel@2 {
reg = <2>;
adi,ch-func = <CH_FUNC_DIGITAL_INPUT_LOGIC>;
adi,gpo-comparator;
};
channel@3 {
reg = <3>;
adi,ch-func = <CH_FUNC_CURRENT_INPUT_EXT_POWER>;
};
};
};
...

View File

@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0
VERSION = 5
PATCHLEVEL = 10
SUBLEVEL = 191
SUBLEVEL = 192
EXTRAVERSION =
NAME = Dare mighty things

View File

@ -126,6 +126,10 @@ &usbh1 {
status = "disabled";
};
&usbotg {
disable-over-current;
};
&vpu {
status = "disabled";
};

View File

@ -69,6 +69,7 @@ &usbh1 {
vbus-supply = <&reg_usb_h1_vbus>;
phy_type = "utmi";
dr_mode = "host";
disable-over-current;
status = "okay";
};
@ -78,10 +79,18 @@ &usbotg {
pinctrl-0 = <&pinctrl_usbotg>;
phy_type = "utmi";
dr_mode = "host";
disable-over-current;
over-current-active-low;
status = "okay";
};
&usbphynop1 {
status = "disabled";
};
&usbphynop2 {
status = "disabled";
};
&usdhc1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_usdhc1>;

View File

@ -31,6 +31,40 @@ sdio_pwrseq: sdio-pwrseq {
reset-gpios = <&gpio0 RK_PB2 GPIO_ACTIVE_LOW>;
};
sound {
compatible = "audio-graph-card";
label = "Analog";
dais = <&i2s0_p0>;
};
sound-dit {
compatible = "audio-graph-card";
label = "SPDIF";
dais = <&spdif_p0>;
};
spdif-dit {
compatible = "linux,spdif-dit";
#sound-dai-cells = <0>;
port {
dit_p0_0: endpoint {
remote-endpoint = <&spdif_p0_0>;
};
};
};
vbus_typec: vbus-typec-regulator {
compatible = "regulator-fixed";
enable-active-high;
gpio = <&gpio1 RK_PA3 GPIO_ACTIVE_HIGH>;
pinctrl-names = "default";
pinctrl-0 = <&vcc5v0_typec_en>;
regulator-name = "vbus_typec";
regulator-always-on;
vin-supply = <&vcc5v0_sys>;
};
vcc12v_dcin: dc-12v {
compatible = "regulator-fixed";
regulator-name = "vcc12v_dcin";
@ -40,23 +74,13 @@ vcc12v_dcin: dc-12v {
regulator-max-microvolt = <12000000>;
};
vcc5v0_sys: vcc-sys {
vcc3v3_lan: vcc3v3-lan-regulator {
compatible = "regulator-fixed";
regulator-name = "vcc5v0_sys";
regulator-name = "vcc3v3_lan";
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
vin-supply = <&vcc12v_dcin>;
};
vcc_0v9: vcc-0v9 {
compatible = "regulator-fixed";
regulator-name = "vcc_0v9";
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <900000>;
regulator-max-microvolt = <900000>;
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
vin-supply = <&vcc3v3_sys>;
};
@ -93,28 +117,24 @@ vcc5v0_host: vcc5v0-host-regulator {
vin-supply = <&vcc5v0_sys>;
};
vcc5v0_typec: vcc5v0-typec-regulator {
vcc5v0_sys: vcc-sys {
compatible = "regulator-fixed";
enable-active-high;
gpio = <&gpio1 RK_PA3 GPIO_ACTIVE_HIGH>;
pinctrl-names = "default";
pinctrl-0 = <&vcc5v0_typec_en>;
regulator-name = "vcc5v0_typec";
regulator-always-on;
vin-supply = <&vcc5v0_sys>;
};
vcc_lan: vcc3v3-phy-regulator {
compatible = "regulator-fixed";
regulator-name = "vcc_lan";
regulator-name = "vcc5v0_sys";
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
vin-supply = <&vcc12v_dcin>;
};
regulator-state-mem {
regulator-off-in-suspend;
};
vcc_0v9: vcc-0v9 {
compatible = "regulator-fixed";
regulator-name = "vcc_0v9";
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <900000>;
regulator-max-microvolt = <900000>;
vin-supply = <&vcc3v3_sys>;
};
vdd_log: vdd-log {
@ -161,7 +181,7 @@ &gmac {
assigned-clocks = <&cru SCLK_RMII_SRC>;
assigned-clock-parents = <&clkin_gmac>;
clock_in_out = "input";
phy-supply = <&vcc_lan>;
phy-supply = <&vcc3v3_lan>;
phy-mode = "rgmii";
pinctrl-names = "default";
pinctrl-0 = <&rgmii_pins>;
@ -266,8 +286,8 @@ regulator-state-mem {
};
};
vcc1v8_codec: LDO_REG1 {
regulator-name = "vcc1v8_codec";
vcca1v8_codec: LDO_REG1 {
regulator-name = "vcca1v8_codec";
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <1800000>;
@ -277,8 +297,8 @@ regulator-state-mem {
};
};
vcc1v8_hdmi: LDO_REG2 {
regulator-name = "vcc1v8_hdmi";
vcca1v8_hdmi: LDO_REG2 {
regulator-name = "vcca1v8_hdmi";
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <1800000>;
@ -335,8 +355,8 @@ regulator-state-mem {
};
};
vcc0v9_hdmi: LDO_REG7 {
regulator-name = "vcc0v9_hdmi";
vcca0v9_hdmi: LDO_REG7 {
regulator-name = "vcca0v9_hdmi";
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <900000>;
@ -362,8 +382,6 @@ vcc_cam: SWITCH_REG1 {
regulator-name = "vcc_cam";
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-state-mem {
regulator-off-in-suspend;
};
@ -373,8 +391,6 @@ vcc_mipi: SWITCH_REG2 {
regulator-name = "vcc_mipi";
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-state-mem {
regulator-off-in-suspend;
};
@ -425,6 +441,20 @@ &i2c1 {
i2c-scl-rising-time-ns = <300>;
i2c-scl-falling-time-ns = <15>;
status = "okay";
es8316: codec@11 {
compatible = "everest,es8316";
reg = <0x11>;
clocks = <&cru SCLK_I2S_8CH_OUT>;
clock-names = "mclk";
#sound-dai-cells = <0>;
port {
es8316_p0_0: endpoint {
remote-endpoint = <&i2s0_p0_0>;
};
};
};
};
&i2c3 {
@ -443,6 +473,14 @@ &i2s0 {
rockchip,playback-channels = <8>;
rockchip,capture-channels = <8>;
status = "okay";
i2s0_p0: port {
i2s0_p0_0: endpoint {
dai-format = "i2s";
mclk-fs = <256>;
remote-endpoint = <&es8316_p0_0>;
};
};
};
&i2s1 {
@ -455,21 +493,10 @@ &i2s2 {
};
&io_domains {
status = "okay";
audio-supply = <&vcca1v8_codec>;
bt656-supply = <&vcc_3v0>;
audio-supply = <&vcc1v8_codec>;
sdmmc-supply = <&vcc_sdio>;
gpio1830-supply = <&vcc_3v0>;
};
&pmu_io_domains {
status = "okay";
pmu1830-supply = <&vcc_3v0>;
};
&pcie_phy {
sdmmc-supply = <&vcc_sdio>;
status = "okay";
};
@ -485,6 +512,10 @@ &pcie0 {
status = "okay";
};
&pcie_phy {
status = "okay";
};
&pinctrl {
bt {
bt_enable_h: bt-enable-h {
@ -506,6 +537,20 @@ pcie_pwr_en: pcie-pwr-en {
};
};
pmic {
pmic_int_l: pmic-int-l {
rockchip,pins = <1 RK_PC5 RK_FUNC_GPIO &pcfg_pull_up>;
};
vsel1_pin: vsel1-pin {
rockchip,pins = <1 RK_PC1 RK_FUNC_GPIO &pcfg_pull_down>;
};
vsel2_pin: vsel2-pin {
rockchip,pins = <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_down>;
};
};
sdio0 {
sdio0_bus4: sdio0-bus4 {
rockchip,pins = <2 RK_PC4 1 &pcfg_pull_up_20ma>,
@ -523,20 +568,6 @@ sdio0_clk: sdio0-clk {
};
};
pmic {
pmic_int_l: pmic-int-l {
rockchip,pins = <1 RK_PC5 RK_FUNC_GPIO &pcfg_pull_up>;
};
vsel1_pin: vsel1-pin {
rockchip,pins = <1 RK_PC1 RK_FUNC_GPIO &pcfg_pull_down>;
};
vsel2_pin: vsel2-pin {
rockchip,pins = <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_down>;
};
};
usb-typec {
vcc5v0_typec_en: vcc5v0-typec-en {
rockchip,pins = <1 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>;
@ -560,6 +591,11 @@ wifi_host_wake_l: wifi-host-wake-l {
};
};
&pmu_io_domains {
pmu1830-supply = <&vcc_3v0>;
status = "okay";
};
&pwm2 {
status = "okay";
};
@ -570,6 +606,14 @@ &saradc {
vref-supply = <&vcc_1v8>;
};
&sdhci {
max-frequency = <150000000>;
bus-width = <8>;
mmc-hs200-1_8v;
non-removable;
status = "okay";
};
&sdio0 {
#address-cells = <1>;
#size-cells = <0>;
@ -597,12 +641,13 @@ &sdmmc {
status = "okay";
};
&sdhci {
bus-width = <8>;
mmc-hs400-1_8v;
mmc-hs400-enhanced-strobe;
non-removable;
status = "okay";
&spdif {
spdif_p0: port {
spdif_p0_0: endpoint {
remote-endpoint = <&dit_p0_0>;
};
};
};
&tcphy0 {
@ -677,15 +722,15 @@ &usbdrd3_0 {
status = "okay";
};
&usbdrd_dwc3_0 {
status = "okay";
dr_mode = "otg";
};
&usbdrd3_1 {
status = "okay";
};
&usbdrd_dwc3_0 {
status = "okay";
dr_mode = "host";
};
&usbdrd_dwc3_1 {
status = "okay";
dr_mode = "host";

View File

@ -70,7 +70,7 @@ static inline bool prom_is_rex(u32 magic)
*/
typedef struct {
int pagesize;
unsigned char bitmap[0];
unsigned char bitmap[];
} memmap;

View File

@ -710,9 +710,9 @@ static int __init rtas_flash_init(void)
if (!rtas_validate_flash_data.buf)
return -ENOMEM;
flash_block_cache = kmem_cache_create("rtas_flash_cache",
RTAS_BLK_SIZE, RTAS_BLK_SIZE, 0,
NULL);
flash_block_cache = kmem_cache_create_usercopy("rtas_flash_cache",
RTAS_BLK_SIZE, RTAS_BLK_SIZE,
0, 0, RTAS_BLK_SIZE, NULL);
if (!flash_block_cache) {
printk(KERN_ERR "%s: failed to create block cache\n",
__func__);

View File

@ -1,6 +1,7 @@
# SPDX-License-Identifier: GPL-2.0
KASAN_SANITIZE := n
KCOV_INSTRUMENT := n
obj-$(CONFIG_PPC32) += kasan_init_32.o
obj-$(CONFIG_PPC_8xx) += 8xx.o

View File

@ -78,6 +78,7 @@ static inline void arch_exit_to_user_mode_prepare(struct pt_regs *regs,
static __always_inline void arch_exit_to_user_mode(void)
{
mds_user_clear_cpu_buffers();
amd_clear_divider();
}
#define arch_exit_to_user_mode arch_exit_to_user_mode

View File

@ -156,9 +156,9 @@
.endm
#ifdef CONFIG_CPU_UNRET_ENTRY
#define CALL_ZEN_UNTRAIN_RET "call zen_untrain_ret"
#define CALL_UNTRAIN_RET "call entry_untrain_ret"
#else
#define CALL_ZEN_UNTRAIN_RET ""
#define CALL_UNTRAIN_RET ""
#endif
/*
@ -166,7 +166,7 @@
* return thunk isn't mapped into the userspace tables (then again, AMD
* typically has NO_MELTDOWN).
*
* While zen_untrain_ret() doesn't clobber anything but requires stack,
* While retbleed_untrain_ret() doesn't clobber anything but requires stack,
* entry_ibpb() will clobber AX, CX, DX.
*
* As such, this must be placed after every *SWITCH_TO_KERNEL_CR3 at a point
@ -177,14 +177,9 @@
defined(CONFIG_CPU_SRSO)
ANNOTATE_UNRET_END
ALTERNATIVE_2 "", \
CALL_ZEN_UNTRAIN_RET, X86_FEATURE_UNRET, \
CALL_UNTRAIN_RET, X86_FEATURE_UNRET, \
"call entry_ibpb", X86_FEATURE_ENTRY_IBPB
#endif
#ifdef CONFIG_CPU_SRSO
ALTERNATIVE_2 "", "call srso_untrain_ret", X86_FEATURE_SRSO, \
"call srso_untrain_ret_alias", X86_FEATURE_SRSO_ALIAS
#endif
.endm
#else /* __ASSEMBLY__ */
@ -195,10 +190,21 @@
_ASM_PTR " 999b\n\t" \
".popsection\n\t"
#ifdef CONFIG_RETHUNK
extern void __x86_return_thunk(void);
extern void zen_untrain_ret(void);
#else
static inline void __x86_return_thunk(void) {}
#endif
extern void retbleed_return_thunk(void);
extern void srso_return_thunk(void);
extern void srso_alias_return_thunk(void);
extern void retbleed_untrain_ret(void);
extern void srso_untrain_ret(void);
extern void srso_untrain_ret_alias(void);
extern void srso_alias_untrain_ret(void);
extern void entry_untrain_ret(void);
extern void entry_ibpb(void);
#ifdef CONFIG_RETPOLINE

View File

@ -1332,3 +1332,4 @@ void noinstr amd_clear_divider(void)
asm volatile(ALTERNATIVE("", "div %2\n\t", X86_BUG_DIV0)
:: "a" (0), "d" (0), "r" (1));
}
EXPORT_SYMBOL_GPL(amd_clear_divider);

View File

@ -61,6 +61,8 @@ EXPORT_SYMBOL_GPL(x86_pred_cmd);
static DEFINE_MUTEX(spec_ctrl_mutex);
void (*x86_return_thunk)(void) __ro_after_init = &__x86_return_thunk;
/* Update SPEC_CTRL MSR and its cached copy unconditionally */
static void update_spec_ctrl(u64 val)
{
@ -155,8 +157,13 @@ void __init cpu_select_mitigations(void)
l1tf_select_mitigation();
md_clear_select_mitigation();
srbds_select_mitigation();
gds_select_mitigation();
/*
* srso_select_mitigation() depends and must run after
* retbleed_select_mitigation().
*/
srso_select_mitigation();
gds_select_mitigation();
}
/*
@ -976,6 +983,9 @@ static void __init retbleed_select_mitigation(void)
setup_force_cpu_cap(X86_FEATURE_RETHUNK);
setup_force_cpu_cap(X86_FEATURE_UNRET);
if (IS_ENABLED(CONFIG_RETHUNK))
x86_return_thunk = retbleed_return_thunk;
if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD &&
boot_cpu_data.x86_vendor != X86_VENDOR_HYGON)
pr_err(RETBLEED_UNTRAIN_MSG);
@ -2318,9 +2328,10 @@ static void __init srso_select_mitigation(void)
* Zen1/2 with SMT off aren't vulnerable after the right
* IBPB microcode has been applied.
*/
if ((boot_cpu_data.x86 < 0x19) &&
(!cpu_smt_possible() || (cpu_smt_control == CPU_SMT_DISABLED)))
if (boot_cpu_data.x86 < 0x19 && !cpu_smt_possible()) {
setup_force_cpu_cap(X86_FEATURE_SRSO_NO);
return;
}
}
if (retbleed_mitigation == RETBLEED_MITIGATION_IBPB) {
@ -2349,11 +2360,15 @@ static void __init srso_select_mitigation(void)
* like ftrace, static_call, etc.
*/
setup_force_cpu_cap(X86_FEATURE_RETHUNK);
setup_force_cpu_cap(X86_FEATURE_UNRET);
if (boot_cpu_data.x86 == 0x19)
if (boot_cpu_data.x86 == 0x19) {
setup_force_cpu_cap(X86_FEATURE_SRSO_ALIAS);
else
x86_return_thunk = srso_alias_return_thunk;
} else {
setup_force_cpu_cap(X86_FEATURE_SRSO);
x86_return_thunk = srso_return_thunk;
}
srso_mitigation = SRSO_MITIGATION_SAFE_RET;
} else {
pr_err("WARNING: kernel not compiled with CPU_SRSO.\n");
@ -2602,6 +2617,9 @@ static ssize_t gds_show_state(char *buf)
static ssize_t srso_show_state(char *buf)
{
if (boot_cpu_has(X86_FEATURE_SRSO_NO))
return sysfs_emit(buf, "Mitigation: SMT disabled\n");
return sysfs_emit(buf, "%s%s\n",
srso_strings[srso_mitigation],
(cpu_has_ibpb_brtype_microcode() ? "" : ", no microcode"));

View File

@ -123,6 +123,19 @@ EXPORT_SYMBOL_GPL(arch_static_call_transform);
*/
bool __static_call_fixup(void *tramp, u8 op, void *dest)
{
unsigned long addr = (unsigned long)tramp;
/*
* Not all .return_sites are a static_call trampoline (most are not).
* Check if the 3 bytes after the return are still kernel text, if not,
* then this definitely is not a trampoline and we need not worry
* further.
*
* This avoids the memcmp() below tripping over pagefaults etc..
*/
if (((addr >> PAGE_SHIFT) != ((addr + 7) >> PAGE_SHIFT)) &&
!kernel_text_address(addr + 7))
return false;
if (memcmp(tramp+5, tramp_ud, 3)) {
/* Not a trampoline site, not our problem. */
return false;

View File

@ -198,8 +198,6 @@ DEFINE_IDTENTRY(exc_divide_error)
{
do_error_trap(regs, 0, "divide error", X86_TRAP_DE, SIGFPE,
FPE_INTDIV, error_get_trap_addr(regs));
amd_clear_divider();
}
DEFINE_IDTENTRY(exc_overflow)

View File

@ -134,18 +134,18 @@ SECTIONS
KPROBES_TEXT
ALIGN_ENTRY_TEXT_BEGIN
#ifdef CONFIG_CPU_SRSO
*(.text.__x86.rethunk_untrain)
*(.text..__x86.rethunk_untrain)
#endif
ENTRY_TEXT
#ifdef CONFIG_CPU_SRSO
/*
* See the comment above srso_untrain_ret_alias()'s
* See the comment above srso_alias_untrain_ret()'s
* definition.
*/
. = srso_untrain_ret_alias | (1 << 2) | (1 << 8) | (1 << 14) | (1 << 20);
*(.text.__x86.rethunk_safe)
. = srso_alias_untrain_ret | (1 << 2) | (1 << 8) | (1 << 14) | (1 << 20);
*(.text..__x86.rethunk_safe)
#endif
ALIGN_ENTRY_TEXT_END
SOFTIRQENTRY_TEXT
@ -155,8 +155,8 @@ SECTIONS
#ifdef CONFIG_RETPOLINE
__indirect_thunk_start = .;
*(.text.__x86.indirect_thunk)
*(.text.__x86.return_thunk)
*(.text..__x86.indirect_thunk)
*(.text..__x86.return_thunk)
__indirect_thunk_end = .;
#endif
} :text =0xcccc
@ -518,7 +518,7 @@ INIT_PER_CPU(irq_stack_backing_store);
#endif
#ifdef CONFIG_RETHUNK
. = ASSERT((__ret & 0x3f) == 0, "__ret not cacheline-aligned");
. = ASSERT((retbleed_return_thunk & 0x3f) == 0, "retbleed_return_thunk not cacheline-aligned");
. = ASSERT((srso_safe_ret & 0x3f) == 0, "srso_safe_ret not cacheline-aligned");
#endif
@ -533,8 +533,8 @@ INIT_PER_CPU(irq_stack_backing_store);
* Instead do: (A | B) - (A & B) in order to compute the XOR
* of the two function addresses:
*/
. = ASSERT(((ABSOLUTE(srso_untrain_ret_alias) | srso_safe_ret_alias) -
(ABSOLUTE(srso_untrain_ret_alias) & srso_safe_ret_alias)) == ((1 << 2) | (1 << 8) | (1 << 14) | (1 << 20)),
. = ASSERT(((ABSOLUTE(srso_alias_untrain_ret) | srso_alias_safe_ret) -
(ABSOLUTE(srso_alias_untrain_ret) & srso_alias_safe_ret)) == ((1 << 2) | (1 << 8) | (1 << 14) | (1 << 20)),
"SRSO function pair won't alias");
#endif

View File

@ -3376,6 +3376,7 @@ static void svm_flush_tlb_gva(struct kvm_vcpu *vcpu, gva_t gva)
static void svm_prepare_guest_switch(struct kvm_vcpu *vcpu)
{
amd_clear_divider();
}
static inline void sync_cr8_to_lapic(struct kvm_vcpu *vcpu)

View File

@ -11,7 +11,7 @@
#include <asm/frame.h>
#include <asm/nops.h>
.section .text.__x86.indirect_thunk
.section .text..__x86.indirect_thunk
.macro RETPOLINE reg
ANNOTATE_INTRA_FUNCTION_CALL
@ -75,74 +75,105 @@ SYM_CODE_END(__x86_indirect_thunk_array)
#ifdef CONFIG_RETHUNK
/*
* srso_untrain_ret_alias() and srso_safe_ret_alias() are placed at
* srso_alias_untrain_ret() and srso_alias_safe_ret() are placed at
* special addresses:
*
* - srso_untrain_ret_alias() is 2M aligned
* - srso_safe_ret_alias() is also in the same 2M page but bits 2, 8, 14
* - srso_alias_untrain_ret() is 2M aligned
* - srso_alias_safe_ret() is also in the same 2M page but bits 2, 8, 14
* and 20 in its virtual address are set (while those bits in the
* srso_untrain_ret_alias() function are cleared).
* srso_alias_untrain_ret() function are cleared).
*
* This guarantees that those two addresses will alias in the branch
* target buffer of Zen3/4 generations, leading to any potential
* poisoned entries at that BTB slot to get evicted.
*
* As a result, srso_safe_ret_alias() becomes a safe return.
* As a result, srso_alias_safe_ret() becomes a safe return.
*/
#ifdef CONFIG_CPU_SRSO
.section .text.__x86.rethunk_untrain
.section .text..__x86.rethunk_untrain
SYM_START(srso_untrain_ret_alias, SYM_L_GLOBAL, SYM_A_NONE)
SYM_START(srso_alias_untrain_ret, SYM_L_GLOBAL, SYM_A_NONE)
UNWIND_HINT_FUNC
ASM_NOP2
lfence
jmp __x86_return_thunk
SYM_FUNC_END(srso_untrain_ret_alias)
__EXPORT_THUNK(srso_untrain_ret_alias)
jmp srso_alias_return_thunk
SYM_FUNC_END(srso_alias_untrain_ret)
__EXPORT_THUNK(srso_alias_untrain_ret)
.section .text.__x86.rethunk_safe
#endif
/* Needs a definition for the __x86_return_thunk alternative below. */
SYM_START(srso_safe_ret_alias, SYM_L_GLOBAL, SYM_A_NONE)
#ifdef CONFIG_CPU_SRSO
add $8, %_ASM_SP
UNWIND_HINT_FUNC
#endif
.section .text..__x86.rethunk_safe
#else
/* dummy definition for alternatives */
SYM_START(srso_alias_untrain_ret, SYM_L_GLOBAL, SYM_A_NONE)
ANNOTATE_UNRET_SAFE
ret
int3
SYM_FUNC_END(srso_safe_ret_alias)
SYM_FUNC_END(srso_alias_untrain_ret)
#endif
.section .text.__x86.return_thunk
SYM_START(srso_alias_safe_ret, SYM_L_GLOBAL, SYM_A_NONE)
lea 8(%_ASM_SP), %_ASM_SP
UNWIND_HINT_FUNC
ANNOTATE_UNRET_SAFE
ret
int3
SYM_FUNC_END(srso_alias_safe_ret)
.section .text..__x86.return_thunk
SYM_CODE_START(srso_alias_return_thunk)
UNWIND_HINT_FUNC
ANNOTATE_NOENDBR
call srso_alias_safe_ret
ud2
SYM_CODE_END(srso_alias_return_thunk)
/*
* Some generic notes on the untraining sequences:
*
* They are interchangeable when it comes to flushing potentially wrong
* RET predictions from the BTB.
*
* The SRSO Zen1/2 (MOVABS) untraining sequence is longer than the
* Retbleed sequence because the return sequence done there
* (srso_safe_ret()) is longer and the return sequence must fully nest
* (end before) the untraining sequence. Therefore, the untraining
* sequence must fully overlap the return sequence.
*
* Regarding alignment - the instructions which need to be untrained,
* must all start at a cacheline boundary for Zen1/2 generations. That
* is, instruction sequences starting at srso_safe_ret() and
* the respective instruction sequences at retbleed_return_thunk()
* must start at a cacheline boundary.
*/
/*
* Safety details here pertain to the AMD Zen{1,2} microarchitecture:
* 1) The RET at __x86_return_thunk must be on a 64 byte boundary, for
* 1) The RET at retbleed_return_thunk must be on a 64 byte boundary, for
* alignment within the BTB.
* 2) The instruction at zen_untrain_ret must contain, and not
* 2) The instruction at retbleed_untrain_ret must contain, and not
* end with, the 0xc3 byte of the RET.
* 3) STIBP must be enabled, or SMT disabled, to prevent the sibling thread
* from re-poisioning the BTB prediction.
*/
.align 64
.skip 64 - (__ret - zen_untrain_ret), 0xcc
SYM_FUNC_START_NOALIGN(zen_untrain_ret);
.skip 64 - (retbleed_return_thunk - retbleed_untrain_ret), 0xcc
SYM_FUNC_START_NOALIGN(retbleed_untrain_ret);
/*
* As executed from zen_untrain_ret, this is:
* As executed from retbleed_untrain_ret, this is:
*
* TEST $0xcc, %bl
* LFENCE
* JMP __x86_return_thunk
* JMP retbleed_return_thunk
*
* Executing the TEST instruction has a side effect of evicting any BTB
* prediction (potentially attacker controlled) attached to the RET, as
* __x86_return_thunk + 1 isn't an instruction boundary at the moment.
* retbleed_return_thunk + 1 isn't an instruction boundary at the moment.
*/
.byte 0xf6
/*
* As executed from __x86_return_thunk, this is a plain RET.
* As executed from retbleed_return_thunk, this is a plain RET.
*
* As part of the TEST above, RET is the ModRM byte, and INT3 the imm8.
*
@ -154,13 +185,13 @@ SYM_FUNC_START_NOALIGN(zen_untrain_ret);
* With SMT enabled and STIBP active, a sibling thread cannot poison
* RET's prediction to a type of its choice, but can evict the
* prediction due to competitive sharing. If the prediction is
* evicted, __x86_return_thunk will suffer Straight Line Speculation
* evicted, retbleed_return_thunk will suffer Straight Line Speculation
* which will be contained safely by the INT3.
*/
SYM_INNER_LABEL(__ret, SYM_L_GLOBAL)
SYM_INNER_LABEL(retbleed_return_thunk, SYM_L_GLOBAL)
ret
int3
SYM_CODE_END(__ret)
SYM_CODE_END(retbleed_return_thunk)
/*
* Ensure the TEST decoding / BTB invalidation is complete.
@ -171,16 +202,16 @@ SYM_CODE_END(__ret)
* Jump back and execute the RET in the middle of the TEST instruction.
* INT3 is for SLS protection.
*/
jmp __ret
jmp retbleed_return_thunk
int3
SYM_FUNC_END(zen_untrain_ret)
__EXPORT_THUNK(zen_untrain_ret)
SYM_FUNC_END(retbleed_untrain_ret)
__EXPORT_THUNK(retbleed_untrain_ret)
/*
* SRSO untraining sequence for Zen1/2, similar to zen_untrain_ret()
* SRSO untraining sequence for Zen1/2, similar to retbleed_untrain_ret()
* above. On kernel entry, srso_untrain_ret() is executed which is a
*
* movabs $0xccccccc308c48348,%rax
* movabs $0xccccc30824648d48,%rax
*
* and when the return thunk executes the inner label srso_safe_ret()
* later, it is a stack manipulation and a RET which is mispredicted and
@ -191,22 +222,44 @@ __EXPORT_THUNK(zen_untrain_ret)
SYM_START(srso_untrain_ret, SYM_L_GLOBAL, SYM_A_NONE)
.byte 0x48, 0xb8
/*
* This forces the function return instruction to speculate into a trap
* (UD2 in srso_return_thunk() below). This RET will then mispredict
* and execution will continue at the return site read from the top of
* the stack.
*/
SYM_INNER_LABEL(srso_safe_ret, SYM_L_GLOBAL)
add $8, %_ASM_SP
lea 8(%_ASM_SP), %_ASM_SP
ret
int3
int3
int3
/* end of movabs */
lfence
call srso_safe_ret
int3
ud2
SYM_CODE_END(srso_safe_ret)
SYM_FUNC_END(srso_untrain_ret)
__EXPORT_THUNK(srso_untrain_ret)
SYM_FUNC_START(__x86_return_thunk)
ALTERNATIVE_2 "jmp __ret", "call srso_safe_ret", X86_FEATURE_SRSO, \
"call srso_safe_ret_alias", X86_FEATURE_SRSO_ALIAS
SYM_CODE_START(srso_return_thunk)
UNWIND_HINT_FUNC
ANNOTATE_NOENDBR
call srso_safe_ret
ud2
SYM_CODE_END(srso_return_thunk)
SYM_FUNC_START(entry_untrain_ret)
ALTERNATIVE_2 "jmp retbleed_untrain_ret", \
"jmp srso_untrain_ret", X86_FEATURE_SRSO, \
"jmp srso_alias_untrain_ret", X86_FEATURE_SRSO_ALIAS
SYM_FUNC_END(entry_untrain_ret)
__EXPORT_THUNK(entry_untrain_ret)
SYM_CODE_START(__x86_return_thunk)
UNWIND_HINT_FUNC
ANNOTATE_NOENDBR
ANNOTATE_UNRET_SAFE
ret
int3
SYM_CODE_END(__x86_return_thunk)
EXPORT_SYMBOL(__x86_return_thunk)

View File

@ -432,6 +432,9 @@ static const struct usb_device_id blacklist_table[] = {
{ USB_DEVICE(0x0489, 0xe0d9), .driver_info = BTUSB_MEDIATEK |
BTUSB_WIDEBAND_SPEECH |
BTUSB_VALID_LE_STATES },
{ USB_DEVICE(0x0489, 0xe0f5), .driver_info = BTUSB_MEDIATEK |
BTUSB_WIDEBAND_SPEECH |
BTUSB_VALID_LE_STATES },
{ USB_DEVICE(0x13d3, 0x3568), .driver_info = BTUSB_MEDIATEK |
BTUSB_WIDEBAND_SPEECH |
BTUSB_VALID_LE_STATES },

View File

@ -38,4 +38,4 @@ obj-$(CONFIG_VEXPRESS_CONFIG) += vexpress-config.o
obj-$(CONFIG_DA8XX_MSTPRI) += da8xx-mstpri.o
# MHI
obj-$(CONFIG_MHI_BUS) += mhi/
obj-y += mhi/

View File

@ -2,21 +2,7 @@
#
# MHI bus
#
# Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
# Copyright (c) 2021, Linaro Ltd.
#
config MHI_BUS
tristate "Modem Host Interface (MHI) bus"
help
Bus driver for MHI protocol. Modem Host Interface (MHI) is a
communication protocol used by the host processors to control
and communicate with modem devices over a high speed peripheral
bus or shared memory.
config MHI_BUS_DEBUG
bool "Debugfs support for the MHI bus"
depends on MHI_BUS && DEBUG_FS
help
Enable debugfs support for use with the MHI transport. Allows
reading and/or modifying some values within the MHI controller
for debug and test purposes.
source "drivers/bus/mhi/host/Kconfig"

View File

@ -1,2 +1,2 @@
# core layer
obj-y += core/
# Host MHI stack
obj-y += host/

View File

@ -0,0 +1,31 @@
# SPDX-License-Identifier: GPL-2.0
#
# MHI bus
#
# Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
#
config MHI_BUS
tristate "Modem Host Interface (MHI) bus"
help
Bus driver for MHI protocol. Modem Host Interface (MHI) is a
communication protocol used by the host processors to control
and communicate with modem devices over a high speed peripheral
bus or shared memory.
config MHI_BUS_DEBUG
bool "Debugfs support for the MHI bus"
depends on MHI_BUS && DEBUG_FS
help
Enable debugfs support for use with the MHI transport. Allows
reading and/or modifying some values within the MHI controller
for debug and test purposes.
config MHI_BUS_PCI_GENERIC
tristate "MHI PCI controller driver"
depends on MHI_BUS
depends on PCI
help
This driver provides MHI PCI controller driver for devices such as
Qualcomm SDX55 based PCIe modems.

View File

@ -1,4 +1,6 @@
obj-$(CONFIG_MHI_BUS) += mhi.o
mhi-y := init.o main.o pm.o boot.o
mhi-$(CONFIG_MHI_BUS_DEBUG) += debugfs.o
obj-$(CONFIG_MHI_BUS_PCI_GENERIC) += mhi_pci_generic.o
mhi_pci_generic-y += pci_generic.o

View File

@ -498,6 +498,12 @@ int mhi_init_mmio(struct mhi_controller *mhi_cntrl)
return -EIO;
}
if (val >= mhi_cntrl->reg_len - (8 * MHI_DEV_WAKE_DB)) {
dev_err(dev, "CHDB offset: 0x%x is out of range: 0x%zx\n",
val, mhi_cntrl->reg_len - (8 * MHI_DEV_WAKE_DB));
return -ERANGE;
}
/* Setup wake db */
mhi_cntrl->wake_db = base + val + (8 * MHI_DEV_WAKE_DB);
mhi_write_reg(mhi_cntrl, mhi_cntrl->wake_db, 4, 0);
@ -517,6 +523,12 @@ int mhi_init_mmio(struct mhi_controller *mhi_cntrl)
return -EIO;
}
if (val >= mhi_cntrl->reg_len - (8 * mhi_cntrl->total_ev_rings)) {
dev_err(dev, "ERDB offset: 0x%x is out of range: 0x%zx\n",
val, mhi_cntrl->reg_len - (8 * mhi_cntrl->total_ev_rings));
return -ERANGE;
}
/* Setup event db address for each ev_ring */
mhi_event = mhi_cntrl->mhi_event;
for (i = 0; i < mhi_cntrl->total_ev_rings; i++, val += 8, mhi_event++) {

View File

@ -0,0 +1,345 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* MHI PCI driver - MHI over PCI controller driver
*
* This module is a generic driver for registering MHI-over-PCI devices,
* such as PCIe QCOM modems.
*
* Copyright (C) 2020 Linaro Ltd <loic.poulain@linaro.org>
*/
#include <linux/device.h>
#include <linux/mhi.h>
#include <linux/module.h>
#include <linux/pci.h>
#define MHI_PCI_DEFAULT_BAR_NUM 0
/**
* struct mhi_pci_dev_info - MHI PCI device specific information
* @config: MHI controller configuration
* @name: name of the PCI module
* @fw: firmware path (if any)
* @edl: emergency download mode firmware path (if any)
* @bar_num: PCI base address register to use for MHI MMIO register space
* @dma_data_width: DMA transfer word size (32 or 64 bits)
*/
struct mhi_pci_dev_info {
const struct mhi_controller_config *config;
const char *name;
const char *fw;
const char *edl;
unsigned int bar_num;
unsigned int dma_data_width;
};
#define MHI_CHANNEL_CONFIG_UL(ch_num, ch_name, el_count, ev_ring) \
{ \
.num = ch_num, \
.name = ch_name, \
.num_elements = el_count, \
.event_ring = ev_ring, \
.dir = DMA_TO_DEVICE, \
.ee_mask = BIT(MHI_EE_AMSS), \
.pollcfg = 0, \
.doorbell = MHI_DB_BRST_DISABLE, \
.lpm_notify = false, \
.offload_channel = false, \
.doorbell_mode_switch = false, \
} \
#define MHI_CHANNEL_CONFIG_DL(ch_num, ch_name, el_count, ev_ring) \
{ \
.num = ch_num, \
.name = ch_name, \
.num_elements = el_count, \
.event_ring = ev_ring, \
.dir = DMA_FROM_DEVICE, \
.ee_mask = BIT(MHI_EE_AMSS), \
.pollcfg = 0, \
.doorbell = MHI_DB_BRST_DISABLE, \
.lpm_notify = false, \
.offload_channel = false, \
.doorbell_mode_switch = false, \
}
#define MHI_EVENT_CONFIG_CTRL(ev_ring) \
{ \
.num_elements = 64, \
.irq_moderation_ms = 0, \
.irq = (ev_ring) + 1, \
.priority = 1, \
.mode = MHI_DB_BRST_DISABLE, \
.data_type = MHI_ER_CTRL, \
.hardware_event = false, \
.client_managed = false, \
.offload_channel = false, \
}
#define MHI_EVENT_CONFIG_DATA(ev_ring) \
{ \
.num_elements = 128, \
.irq_moderation_ms = 5, \
.irq = (ev_ring) + 1, \
.priority = 1, \
.mode = MHI_DB_BRST_DISABLE, \
.data_type = MHI_ER_DATA, \
.hardware_event = false, \
.client_managed = false, \
.offload_channel = false, \
}
#define MHI_EVENT_CONFIG_HW_DATA(ev_ring, ch_num) \
{ \
.num_elements = 128, \
.irq_moderation_ms = 5, \
.irq = (ev_ring) + 1, \
.priority = 1, \
.mode = MHI_DB_BRST_DISABLE, \
.data_type = MHI_ER_DATA, \
.hardware_event = true, \
.client_managed = false, \
.offload_channel = false, \
.channel = ch_num, \
}
static const struct mhi_channel_config modem_qcom_v1_mhi_channels[] = {
MHI_CHANNEL_CONFIG_UL(12, "MBIM", 4, 0),
MHI_CHANNEL_CONFIG_DL(13, "MBIM", 4, 0),
MHI_CHANNEL_CONFIG_UL(14, "QMI", 4, 0),
MHI_CHANNEL_CONFIG_DL(15, "QMI", 4, 0),
MHI_CHANNEL_CONFIG_UL(20, "IPCR", 8, 0),
MHI_CHANNEL_CONFIG_DL(21, "IPCR", 8, 0),
MHI_CHANNEL_CONFIG_UL(100, "IP_HW0", 128, 1),
MHI_CHANNEL_CONFIG_DL(101, "IP_HW0", 128, 2),
};
static const struct mhi_event_config modem_qcom_v1_mhi_events[] = {
/* first ring is control+data ring */
MHI_EVENT_CONFIG_CTRL(0),
/* Hardware channels request dedicated hardware event rings */
MHI_EVENT_CONFIG_HW_DATA(1, 100),
MHI_EVENT_CONFIG_HW_DATA(2, 101)
};
static const struct mhi_controller_config modem_qcom_v1_mhiv_config = {
.max_channels = 128,
.timeout_ms = 5000,
.num_channels = ARRAY_SIZE(modem_qcom_v1_mhi_channels),
.ch_cfg = modem_qcom_v1_mhi_channels,
.num_events = ARRAY_SIZE(modem_qcom_v1_mhi_events),
.event_cfg = modem_qcom_v1_mhi_events,
};
static const struct mhi_pci_dev_info mhi_qcom_sdx55_info = {
.name = "qcom-sdx55m",
.fw = "qcom/sdx55m/sbl1.mbn",
.edl = "qcom/sdx55m/edl.mbn",
.config = &modem_qcom_v1_mhiv_config,
.bar_num = MHI_PCI_DEFAULT_BAR_NUM,
.dma_data_width = 32
};
static const struct pci_device_id mhi_pci_id_table[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_QCOM, 0x0306),
.driver_data = (kernel_ulong_t) &mhi_qcom_sdx55_info },
{ }
};
MODULE_DEVICE_TABLE(pci, mhi_pci_id_table);
static int mhi_pci_read_reg(struct mhi_controller *mhi_cntrl,
void __iomem *addr, u32 *out)
{
*out = readl(addr);
return 0;
}
static void mhi_pci_write_reg(struct mhi_controller *mhi_cntrl,
void __iomem *addr, u32 val)
{
writel(val, addr);
}
static void mhi_pci_status_cb(struct mhi_controller *mhi_cntrl,
enum mhi_callback cb)
{
/* Nothing to do for now */
}
static int mhi_pci_claim(struct mhi_controller *mhi_cntrl,
unsigned int bar_num, u64 dma_mask)
{
struct pci_dev *pdev = to_pci_dev(mhi_cntrl->cntrl_dev);
int err;
err = pci_assign_resource(pdev, bar_num);
if (err)
return err;
err = pcim_enable_device(pdev);
if (err) {
dev_err(&pdev->dev, "failed to enable pci device: %d\n", err);
return err;
}
err = pcim_iomap_regions(pdev, 1 << bar_num, pci_name(pdev));
if (err) {
dev_err(&pdev->dev, "failed to map pci region: %d\n", err);
return err;
}
mhi_cntrl->regs = pcim_iomap_table(pdev)[bar_num];
err = pci_set_dma_mask(pdev, dma_mask);
if (err) {
dev_err(&pdev->dev, "Cannot set proper DMA mask\n");
return err;
}
err = pci_set_consistent_dma_mask(pdev, dma_mask);
if (err) {
dev_err(&pdev->dev, "set consistent dma mask failed\n");
return err;
}
pci_set_master(pdev);
return 0;
}
static int mhi_pci_get_irqs(struct mhi_controller *mhi_cntrl,
const struct mhi_controller_config *mhi_cntrl_config)
{
struct pci_dev *pdev = to_pci_dev(mhi_cntrl->cntrl_dev);
int nr_vectors, i;
int *irq;
/*
* Alloc one MSI vector for BHI + one vector per event ring, ideally...
* No explicit pci_free_irq_vectors required, done by pcim_release.
*/
mhi_cntrl->nr_irqs = 1 + mhi_cntrl_config->num_events;
nr_vectors = pci_alloc_irq_vectors(pdev, 1, mhi_cntrl->nr_irqs, PCI_IRQ_MSI);
if (nr_vectors < 0) {
dev_err(&pdev->dev, "Error allocating MSI vectors %d\n",
nr_vectors);
return nr_vectors;
}
if (nr_vectors < mhi_cntrl->nr_irqs) {
dev_warn(&pdev->dev, "Not enough MSI vectors (%d/%d), use shared MSI\n",
nr_vectors, mhi_cntrl_config->num_events);
}
irq = devm_kcalloc(&pdev->dev, mhi_cntrl->nr_irqs, sizeof(int), GFP_KERNEL);
if (!irq)
return -ENOMEM;
for (i = 0; i < mhi_cntrl->nr_irqs; i++) {
int vector = i >= nr_vectors ? (nr_vectors - 1) : i;
irq[i] = pci_irq_vector(pdev, vector);
}
mhi_cntrl->irq = irq;
return 0;
}
static int mhi_pci_runtime_get(struct mhi_controller *mhi_cntrl)
{
/* no PM for now */
return 0;
}
static void mhi_pci_runtime_put(struct mhi_controller *mhi_cntrl)
{
/* no PM for now */
}
static int mhi_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
const struct mhi_pci_dev_info *info = (struct mhi_pci_dev_info *) id->driver_data;
const struct mhi_controller_config *mhi_cntrl_config;
struct mhi_controller *mhi_cntrl;
int err;
dev_dbg(&pdev->dev, "MHI PCI device found: %s\n", info->name);
mhi_cntrl = mhi_alloc_controller();
if (!mhi_cntrl)
return -ENOMEM;
mhi_cntrl_config = info->config;
mhi_cntrl->cntrl_dev = &pdev->dev;
mhi_cntrl->iova_start = 0;
mhi_cntrl->iova_stop = DMA_BIT_MASK(info->dma_data_width);
mhi_cntrl->fw_image = info->fw;
mhi_cntrl->edl_image = info->edl;
mhi_cntrl->read_reg = mhi_pci_read_reg;
mhi_cntrl->write_reg = mhi_pci_write_reg;
mhi_cntrl->status_cb = mhi_pci_status_cb;
mhi_cntrl->runtime_get = mhi_pci_runtime_get;
mhi_cntrl->runtime_put = mhi_pci_runtime_put;
err = mhi_pci_claim(mhi_cntrl, info->bar_num, DMA_BIT_MASK(info->dma_data_width));
if (err)
goto err_release;
err = mhi_pci_get_irqs(mhi_cntrl, mhi_cntrl_config);
if (err)
goto err_release;
pci_set_drvdata(pdev, mhi_cntrl);
err = mhi_register_controller(mhi_cntrl, mhi_cntrl_config);
if (err)
goto err_release;
/* MHI bus does not power up the controller by default */
err = mhi_prepare_for_power_up(mhi_cntrl);
if (err) {
dev_err(&pdev->dev, "failed to prepare MHI controller\n");
goto err_unregister;
}
err = mhi_sync_power_up(mhi_cntrl);
if (err) {
dev_err(&pdev->dev, "failed to power up MHI controller\n");
goto err_unprepare;
}
return 0;
err_unprepare:
mhi_unprepare_after_power_down(mhi_cntrl);
err_unregister:
mhi_unregister_controller(mhi_cntrl);
err_release:
mhi_free_controller(mhi_cntrl);
return err;
}
static void mhi_pci_remove(struct pci_dev *pdev)
{
struct mhi_controller *mhi_cntrl = pci_get_drvdata(pdev);
mhi_power_down(mhi_cntrl, true);
mhi_unprepare_after_power_down(mhi_cntrl);
mhi_unregister_controller(mhi_cntrl);
mhi_free_controller(mhi_cntrl);
}
static struct pci_driver mhi_pci_driver = {
.name = "mhi-pci-generic",
.id_table = mhi_pci_id_table,
.probe = mhi_pci_probe,
.remove = mhi_pci_remove
};
module_pci_driver(mhi_pci_driver);
MODULE_AUTHOR("Loic Poulain <loic.poulain@linaro.org>");
MODULE_DESCRIPTION("Modem Host Interface (MHI) PCI controller driver");
MODULE_LICENSE("GPL");

View File

@ -2078,6 +2078,8 @@ static int sysc_reset(struct sysc *ddata)
sysc_val = sysc_read_sysconfig(ddata);
sysc_val |= sysc_mask;
sysc_write(ddata, sysc_offset, sysc_val);
/* Flush posted write */
sysc_val = sysc_read_sysconfig(ddata);
}
if (ddata->cfg.srst_udelay)

View File

@ -1517,15 +1517,15 @@ static int amdgpu_cs_wait_all_fences(struct amdgpu_device *adev,
continue;
r = dma_fence_wait_timeout(fence, true, timeout);
if (r > 0 && fence->error)
r = fence->error;
dma_fence_put(fence);
if (r < 0)
return r;
if (r == 0)
break;
if (fence->error)
return fence->error;
}
memset(wait, 0, sizeof(*wait));

View File

@ -2155,6 +2155,7 @@ struct amdgpu_bo_va *amdgpu_vm_bo_add(struct amdgpu_device *adev,
amdgpu_vm_bo_base_init(&bo_va->base, vm, bo);
bo_va->ref_count = 1;
bo_va->last_pt_update = dma_fence_get_stub();
INIT_LIST_HEAD(&bo_va->valids);
INIT_LIST_HEAD(&bo_va->invalids);
@ -2867,7 +2868,8 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm,
vm->update_funcs = &amdgpu_vm_cpu_funcs;
else
vm->update_funcs = &amdgpu_vm_sdma_funcs;
vm->last_update = NULL;
vm->last_update = dma_fence_get_stub();
vm->last_unlocked = dma_fence_get_stub();
mutex_init(&vm->eviction_lock);
@ -3042,7 +3044,7 @@ int amdgpu_vm_make_compute(struct amdgpu_device *adev, struct amdgpu_vm *vm,
vm->update_funcs = &amdgpu_vm_sdma_funcs;
}
dma_fence_put(vm->last_update);
vm->last_update = NULL;
vm->last_update = dma_fence_get_stub();
vm->is_compute_context = true;
if (vm->pasid) {

View File

@ -1010,21 +1010,21 @@ static const struct panel_desc auo_g104sn02 = {
},
};
static const struct drm_display_mode auo_g121ean01_mode = {
.clock = 66700,
.hdisplay = 1280,
.hsync_start = 1280 + 58,
.hsync_end = 1280 + 58 + 8,
.htotal = 1280 + 58 + 8 + 70,
.vdisplay = 800,
.vsync_start = 800 + 6,
.vsync_end = 800 + 6 + 4,
.vtotal = 800 + 6 + 4 + 10,
static const struct display_timing auo_g121ean01_timing = {
.pixelclock = { 60000000, 74400000, 90000000 },
.hactive = { 1280, 1280, 1280 },
.hfront_porch = { 20, 50, 100 },
.hback_porch = { 20, 50, 100 },
.hsync_len = { 30, 100, 200 },
.vactive = { 800, 800, 800 },
.vfront_porch = { 2, 10, 25 },
.vback_porch = { 2, 10, 25 },
.vsync_len = { 4, 18, 50 },
};
static const struct panel_desc auo_g121ean01 = {
.modes = &auo_g121ean01_mode,
.num_modes = 1,
.timings = &auo_g121ean01_timing,
.num_timings = 1,
.bpc = 8,
.size = {
.width = 261,

View File

@ -271,7 +271,8 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data)
{
struct drm_radeon_cs *cs = data;
uint64_t *chunk_array_ptr;
unsigned size, i;
u64 size;
unsigned i;
u32 ring = RADEON_CS_RING_GFX;
s32 priority = 0;

View File

@ -582,6 +582,7 @@
#define USB_DEVICE_ID_UGCI_FIGHTING 0x0030
#define USB_VENDOR_ID_HP 0x03f0
#define USB_PRODUCT_ID_HP_ELITE_PRESENTER_MOUSE_464A 0x464a
#define USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0A4A 0x0a4a
#define USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0B4A 0x0b4a
#define USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE 0x134a

View File

@ -96,6 +96,7 @@ static const struct hid_device_id hid_quirks[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD_A096), HID_QUIRK_NO_INIT_REPORTS },
{ HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD_A293), HID_QUIRK_ALWAYS_POLL },
{ HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0A4A), HID_QUIRK_ALWAYS_POLL },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_ELITE_PRESENTER_MOUSE_464A), HID_QUIRK_MULTI_INPUT },
{ HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0B4A), HID_QUIRK_ALWAYS_POLL },
{ HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE), HID_QUIRK_ALWAYS_POLL },
{ HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE_094A), HID_QUIRK_ALWAYS_POLL },

View File

@ -242,13 +242,14 @@ static inline u32 iproc_i2c_rd_reg(struct bcm_iproc_i2c_dev *iproc_i2c,
u32 offset)
{
u32 val;
unsigned long flags;
if (iproc_i2c->idm_base) {
spin_lock(&iproc_i2c->idm_lock);
spin_lock_irqsave(&iproc_i2c->idm_lock, flags);
writel(iproc_i2c->ape_addr_mask,
iproc_i2c->idm_base + IDM_CTRL_DIRECT_OFFSET);
val = readl(iproc_i2c->base + offset);
spin_unlock(&iproc_i2c->idm_lock);
spin_unlock_irqrestore(&iproc_i2c->idm_lock, flags);
} else {
val = readl(iproc_i2c->base + offset);
}
@ -259,12 +260,14 @@ static inline u32 iproc_i2c_rd_reg(struct bcm_iproc_i2c_dev *iproc_i2c,
static inline void iproc_i2c_wr_reg(struct bcm_iproc_i2c_dev *iproc_i2c,
u32 offset, u32 val)
{
unsigned long flags;
if (iproc_i2c->idm_base) {
spin_lock(&iproc_i2c->idm_lock);
spin_lock_irqsave(&iproc_i2c->idm_lock, flags);
writel(iproc_i2c->ape_addr_mask,
iproc_i2c->idm_base + IDM_CTRL_DIRECT_OFFSET);
writel(val, iproc_i2c->base + offset);
spin_unlock(&iproc_i2c->idm_lock);
spin_unlock_irqrestore(&iproc_i2c->idm_lock, flags);
} else {
writel(val, iproc_i2c->base + offset);
}

View File

@ -432,8 +432,19 @@ i2c_dw_read(struct dw_i2c_dev *dev)
regmap_read(dev->map, DW_IC_DATA_CMD, &tmp);
/* Ensure length byte is a valid value */
if (flags & I2C_M_RECV_LEN &&
tmp <= I2C_SMBUS_BLOCK_MAX && tmp > 0) {
if (flags & I2C_M_RECV_LEN) {
/*
* if IC_EMPTYFIFO_HOLD_MASTER_EN is set, which cannot be
* detected from the registers, the controller can be
* disabled if the STOP bit is set. But it is only set
* after receiving block data response length in
* I2C_FUNC_SMBUS_BLOCK_DATA case. That needs to read
* another byte with STOP bit set when the block data
* response length is invalid to complete the transaction.
*/
if (!tmp || tmp > I2C_SMBUS_BLOCK_MAX)
tmp = 1;
len = i2c_dw_recv_len(dev, tmp);
}
*buf++ = tmp;

View File

@ -70,6 +70,7 @@ config IIO_TRIGGERED_EVENT
source "drivers/iio/accel/Kconfig"
source "drivers/iio/adc/Kconfig"
source "drivers/iio/addac/Kconfig"
source "drivers/iio/afe/Kconfig"
source "drivers/iio/amplifiers/Kconfig"
source "drivers/iio/chemical/Kconfig"

View File

@ -15,6 +15,7 @@ obj-$(CONFIG_IIO_TRIGGERED_EVENT) += industrialio-triggered-event.o
obj-y += accel/
obj-y += adc/
obj-y += addac/
obj-y += afe/
obj-y += amplifiers/
obj-y += buffer/

View File

@ -15,7 +15,9 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/mutex.h>
#include <linux/spinlock.h>
#include <linux/types.h>
#define STX104_OUT_CHAN(chan) { \
.type = IIO_VOLTAGE, \
@ -44,14 +46,38 @@ static unsigned int num_stx104;
module_param_hw_array(base, uint, ioport, &num_stx104, 0);
MODULE_PARM_DESC(base, "Apex Embedded Systems STX104 base addresses");
/**
* struct stx104_reg - device register structure
* @ssr_ad: Software Strobe Register and ADC Data
* @achan: ADC Channel
* @dio: Digital I/O
* @dac: DAC Channels
* @cir_asr: Clear Interrupts and ADC Status
* @acr: ADC Control
* @pccr_fsh: Pacer Clock Control and FIFO Status MSB
* @acfg: ADC Configuration
*/
struct stx104_reg {
u16 ssr_ad;
u8 achan;
u8 dio;
u16 dac[2];
u8 cir_asr;
u8 acr;
u8 pccr_fsh;
u8 acfg;
};
/**
* struct stx104_iio - IIO device private data structure
* @lock: synchronization lock to prevent I/O race conditions
* @chan_out_states: channels' output states
* @base: base port address of the IIO device
* @reg: I/O address offset for the device registers
*/
struct stx104_iio {
struct mutex lock;
unsigned int chan_out_states[STX104_NUM_OUT_CHAN];
unsigned int base;
struct stx104_reg __iomem *reg;
};
/**
@ -64,7 +90,7 @@ struct stx104_iio {
struct stx104_gpio {
struct gpio_chip chip;
spinlock_t lock;
unsigned int base;
u8 __iomem *base;
unsigned int out_state;
};
@ -72,6 +98,7 @@ static int stx104_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan, int *val, int *val2, long mask)
{
struct stx104_iio *const priv = iio_priv(indio_dev);
struct stx104_reg __iomem *const reg = priv->reg;
unsigned int adc_config;
int adbu;
int gain;
@ -79,7 +106,7 @@ static int stx104_read_raw(struct iio_dev *indio_dev,
switch (mask) {
case IIO_CHAN_INFO_HARDWAREGAIN:
/* get gain configuration */
adc_config = inb(priv->base + 11);
adc_config = ioread8(&reg->acfg);
gain = adc_config & 0x3;
*val = 1 << gain;
@ -90,25 +117,31 @@ static int stx104_read_raw(struct iio_dev *indio_dev,
return IIO_VAL_INT;
}
mutex_lock(&priv->lock);
/* select ADC channel */
outb(chan->channel | (chan->channel << 4), priv->base + 2);
iowrite8(chan->channel | (chan->channel << 4), &reg->achan);
/* trigger ADC sample capture and wait for completion */
outb(0, priv->base);
while (inb(priv->base + 8) & BIT(7));
/* trigger ADC sample capture by writing to the 8-bit
* Software Strobe Register and wait for completion
*/
iowrite8(0, &reg->ssr_ad);
while (ioread8(&reg->cir_asr) & BIT(7));
*val = inw(priv->base);
*val = ioread16(&reg->ssr_ad);
mutex_unlock(&priv->lock);
return IIO_VAL_INT;
case IIO_CHAN_INFO_OFFSET:
/* get ADC bipolar/unipolar configuration */
adc_config = inb(priv->base + 11);
adc_config = ioread8(&reg->acfg);
adbu = !(adc_config & BIT(2));
*val = -32768 * adbu;
return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE:
/* get ADC bipolar/unipolar and gain configuration */
adc_config = inb(priv->base + 11);
adc_config = ioread8(&reg->acfg);
adbu = !(adc_config & BIT(2));
gain = adc_config & 0x3;
@ -130,16 +163,16 @@ static int stx104_write_raw(struct iio_dev *indio_dev,
/* Only four gain states (x1, x2, x4, x8) */
switch (val) {
case 1:
outb(0, priv->base + 11);
iowrite8(0, &priv->reg->acfg);
break;
case 2:
outb(1, priv->base + 11);
iowrite8(1, &priv->reg->acfg);
break;
case 4:
outb(2, priv->base + 11);
iowrite8(2, &priv->reg->acfg);
break;
case 8:
outb(3, priv->base + 11);
iowrite8(3, &priv->reg->acfg);
break;
default:
return -EINVAL;
@ -152,9 +185,12 @@ static int stx104_write_raw(struct iio_dev *indio_dev,
if ((unsigned int)val > 65535)
return -EINVAL;
priv->chan_out_states[chan->channel] = val;
outw(val, priv->base + 4 + 2 * chan->channel);
mutex_lock(&priv->lock);
priv->chan_out_states[chan->channel] = val;
iowrite16(val, &priv->reg->dac[chan->channel]);
mutex_unlock(&priv->lock);
return 0;
}
return -EINVAL;
@ -222,7 +258,7 @@ static int stx104_gpio_get(struct gpio_chip *chip, unsigned int offset)
if (offset >= 4)
return -EINVAL;
return !!(inb(stx104gpio->base) & BIT(offset));
return !!(ioread8(stx104gpio->base) & BIT(offset));
}
static int stx104_gpio_get_multiple(struct gpio_chip *chip, unsigned long *mask,
@ -230,7 +266,7 @@ static int stx104_gpio_get_multiple(struct gpio_chip *chip, unsigned long *mask,
{
struct stx104_gpio *const stx104gpio = gpiochip_get_data(chip);
*bits = inb(stx104gpio->base);
*bits = ioread8(stx104gpio->base);
return 0;
}
@ -252,7 +288,7 @@ static void stx104_gpio_set(struct gpio_chip *chip, unsigned int offset,
else
stx104gpio->out_state &= ~mask;
outb(stx104gpio->out_state, stx104gpio->base);
iowrite8(stx104gpio->out_state, stx104gpio->base);
spin_unlock_irqrestore(&stx104gpio->lock, flags);
}
@ -279,7 +315,7 @@ static void stx104_gpio_set_multiple(struct gpio_chip *chip,
stx104gpio->out_state &= ~*mask;
stx104gpio->out_state |= *mask & *bits;
outb(stx104gpio->out_state, stx104gpio->base);
iowrite8(stx104gpio->out_state, stx104gpio->base);
spin_unlock_irqrestore(&stx104gpio->lock, flags);
}
@ -306,11 +342,16 @@ static int stx104_probe(struct device *dev, unsigned int id)
return -EBUSY;
}
priv = iio_priv(indio_dev);
priv->reg = devm_ioport_map(dev, base[id], STX104_EXTENT);
if (!priv->reg)
return -ENOMEM;
indio_dev->info = &stx104_info;
indio_dev->modes = INDIO_DIRECT_MODE;
/* determine if differential inputs */
if (inb(base[id] + 8) & BIT(5)) {
if (ioread8(&priv->reg->cir_asr) & BIT(5)) {
indio_dev->num_channels = ARRAY_SIZE(stx104_channels_diff);
indio_dev->channels = stx104_channels_diff;
} else {
@ -320,18 +361,17 @@ static int stx104_probe(struct device *dev, unsigned int id)
indio_dev->name = dev_name(dev);
priv = iio_priv(indio_dev);
priv->base = base[id];
mutex_init(&priv->lock);
/* configure device for software trigger operation */
outb(0, base[id] + 9);
iowrite8(0, &priv->reg->acr);
/* initialize gain setting to x1 */
outb(0, base[id] + 11);
iowrite8(0, &priv->reg->acfg);
/* initialize DAC output to 0V */
outw(0, base[id] + 4);
outw(0, base[id] + 6);
iowrite16(0, &priv->reg->dac[0]);
iowrite16(0, &priv->reg->dac[1]);
stx104gpio->chip.label = dev_name(dev);
stx104gpio->chip.parent = dev;
@ -346,7 +386,7 @@ static int stx104_probe(struct device *dev, unsigned int id)
stx104gpio->chip.get_multiple = stx104_gpio_get_multiple;
stx104gpio->chip.set = stx104_gpio_set;
stx104gpio->chip.set_multiple = stx104_gpio_set_multiple;
stx104gpio->base = base[id] + 3;
stx104gpio->base = &priv->reg->dio;
stx104gpio->out_state = 0x0;
spin_lock_init(&stx104gpio->lock);

View File

@ -0,0 +1,8 @@
#
# ADC DAC drivers
#
# When adding new entries keep the list in alphabetical order
menu "Analog to digital and digital to analog converters"
endmenu

View File

@ -0,0 +1,6 @@
# SPDX-License-Identifier: GPL-2.0
#
# Makefile for industrial I/O ADDAC drivers
#
# When adding new entries keep the list in alphabetical order

View File

@ -297,8 +297,7 @@ int mlx5_core_destroy_qp(struct mlx5_ib_dev *dev, struct mlx5_core_qp *qp)
MLX5_SET(destroy_qp_in, in, opcode, MLX5_CMD_OP_DESTROY_QP);
MLX5_SET(destroy_qp_in, in, qpn, qp->qpn);
MLX5_SET(destroy_qp_in, in, uid, qp->uid);
mlx5_cmd_exec_in(dev->mdev, destroy_qp, in);
return 0;
return mlx5_cmd_exec_in(dev->mdev, destroy_qp, in);
}
int mlx5_core_set_delay_drop(struct mlx5_ib_dev *dev,
@ -542,14 +541,14 @@ int mlx5_core_xrcd_dealloc(struct mlx5_ib_dev *dev, u32 xrcdn)
return mlx5_cmd_exec_in(dev->mdev, dealloc_xrcd, in);
}
static void destroy_rq_tracked(struct mlx5_ib_dev *dev, u32 rqn, u16 uid)
static int destroy_rq_tracked(struct mlx5_ib_dev *dev, u32 rqn, u16 uid)
{
u32 in[MLX5_ST_SZ_DW(destroy_rq_in)] = {};
MLX5_SET(destroy_rq_in, in, opcode, MLX5_CMD_OP_DESTROY_RQ);
MLX5_SET(destroy_rq_in, in, rqn, rqn);
MLX5_SET(destroy_rq_in, in, uid, uid);
mlx5_cmd_exec_in(dev->mdev, destroy_rq, in);
return mlx5_cmd_exec_in(dev->mdev, destroy_rq, in);
}
int mlx5_core_create_rq_tracked(struct mlx5_ib_dev *dev, u32 *in, int inlen,
@ -580,8 +579,7 @@ int mlx5_core_destroy_rq_tracked(struct mlx5_ib_dev *dev,
struct mlx5_core_qp *rq)
{
destroy_resource_common(dev, rq);
destroy_rq_tracked(dev, rq->qpn, rq->uid);
return 0;
return destroy_rq_tracked(dev, rq->qpn, rq->uid);
}
static void destroy_sq_tracked(struct mlx5_ib_dev *dev, u32 sqn, u16 uid)

View File

@ -48,7 +48,7 @@ void __iomem *mips_gic_base;
static DEFINE_PER_CPU_READ_MOSTLY(unsigned long[GIC_MAX_LONGS], pcpu_masks);
static DEFINE_SPINLOCK(gic_lock);
static DEFINE_RAW_SPINLOCK(gic_lock);
static struct irq_domain *gic_irq_domain;
static int gic_shared_intrs;
static unsigned int gic_cpu_pin;
@ -209,7 +209,7 @@ static int gic_set_type(struct irq_data *d, unsigned int type)
irq = GIC_HWIRQ_TO_SHARED(d->hwirq);
spin_lock_irqsave(&gic_lock, flags);
raw_spin_lock_irqsave(&gic_lock, flags);
switch (type & IRQ_TYPE_SENSE_MASK) {
case IRQ_TYPE_EDGE_FALLING:
pol = GIC_POL_FALLING_EDGE;
@ -249,7 +249,7 @@ static int gic_set_type(struct irq_data *d, unsigned int type)
else
irq_set_chip_handler_name_locked(d, &gic_level_irq_controller,
handle_level_irq, NULL);
spin_unlock_irqrestore(&gic_lock, flags);
raw_spin_unlock_irqrestore(&gic_lock, flags);
return 0;
}
@ -267,7 +267,7 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *cpumask,
return -EINVAL;
/* Assumption : cpumask refers to a single CPU */
spin_lock_irqsave(&gic_lock, flags);
raw_spin_lock_irqsave(&gic_lock, flags);
/* Re-route this IRQ */
write_gic_map_vp(irq, BIT(mips_cm_vp_id(cpu)));
@ -278,7 +278,7 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *cpumask,
set_bit(irq, per_cpu_ptr(pcpu_masks, cpu));
irq_data_update_effective_affinity(d, cpumask_of(cpu));
spin_unlock_irqrestore(&gic_lock, flags);
raw_spin_unlock_irqrestore(&gic_lock, flags);
return IRQ_SET_MASK_OK;
}
@ -356,12 +356,12 @@ static void gic_mask_local_irq_all_vpes(struct irq_data *d)
cd = irq_data_get_irq_chip_data(d);
cd->mask = false;
spin_lock_irqsave(&gic_lock, flags);
raw_spin_lock_irqsave(&gic_lock, flags);
for_each_online_cpu(cpu) {
write_gic_vl_other(mips_cm_vp_id(cpu));
write_gic_vo_rmask(BIT(intr));
}
spin_unlock_irqrestore(&gic_lock, flags);
raw_spin_unlock_irqrestore(&gic_lock, flags);
}
static void gic_unmask_local_irq_all_vpes(struct irq_data *d)
@ -374,32 +374,43 @@ static void gic_unmask_local_irq_all_vpes(struct irq_data *d)
cd = irq_data_get_irq_chip_data(d);
cd->mask = true;
spin_lock_irqsave(&gic_lock, flags);
raw_spin_lock_irqsave(&gic_lock, flags);
for_each_online_cpu(cpu) {
write_gic_vl_other(mips_cm_vp_id(cpu));
write_gic_vo_smask(BIT(intr));
}
spin_unlock_irqrestore(&gic_lock, flags);
raw_spin_unlock_irqrestore(&gic_lock, flags);
}
static void gic_all_vpes_irq_cpu_online(struct irq_data *d)
static void gic_all_vpes_irq_cpu_online(void)
{
struct gic_all_vpes_chip_data *cd;
unsigned int intr;
static const unsigned int local_intrs[] = {
GIC_LOCAL_INT_TIMER,
GIC_LOCAL_INT_PERFCTR,
GIC_LOCAL_INT_FDC,
};
unsigned long flags;
int i;
intr = GIC_HWIRQ_TO_LOCAL(d->hwirq);
cd = irq_data_get_irq_chip_data(d);
raw_spin_lock_irqsave(&gic_lock, flags);
write_gic_vl_map(mips_gic_vx_map_reg(intr), cd->map);
if (cd->mask)
write_gic_vl_smask(BIT(intr));
for (i = 0; i < ARRAY_SIZE(local_intrs); i++) {
unsigned int intr = local_intrs[i];
struct gic_all_vpes_chip_data *cd;
cd = &gic_all_vpes_chip_data[intr];
write_gic_vl_map(mips_gic_vx_map_reg(intr), cd->map);
if (cd->mask)
write_gic_vl_smask(BIT(intr));
}
raw_spin_unlock_irqrestore(&gic_lock, flags);
}
static struct irq_chip gic_all_vpes_local_irq_controller = {
.name = "MIPS GIC Local",
.irq_mask = gic_mask_local_irq_all_vpes,
.irq_unmask = gic_unmask_local_irq_all_vpes,
.irq_cpu_online = gic_all_vpes_irq_cpu_online,
};
static void __gic_irq_dispatch(void)
@ -423,11 +434,11 @@ static int gic_shared_irq_domain_map(struct irq_domain *d, unsigned int virq,
data = irq_get_irq_data(virq);
spin_lock_irqsave(&gic_lock, flags);
raw_spin_lock_irqsave(&gic_lock, flags);
write_gic_map_pin(intr, GIC_MAP_PIN_MAP_TO_PIN | gic_cpu_pin);
write_gic_map_vp(intr, BIT(mips_cm_vp_id(cpu)));
irq_data_update_effective_affinity(data, cpumask_of(cpu));
spin_unlock_irqrestore(&gic_lock, flags);
raw_spin_unlock_irqrestore(&gic_lock, flags);
return 0;
}
@ -480,6 +491,10 @@ static int gic_irq_domain_map(struct irq_domain *d, unsigned int virq,
intr = GIC_HWIRQ_TO_LOCAL(hwirq);
map = GIC_MAP_PIN_MAP_TO_PIN | gic_cpu_pin;
/*
* If adding support for more per-cpu interrupts, keep the the
* array in gic_all_vpes_irq_cpu_online() in sync.
*/
switch (intr) {
case GIC_LOCAL_INT_TIMER:
/* CONFIG_MIPS_CMP workaround (see __gic_init) */
@ -518,12 +533,12 @@ static int gic_irq_domain_map(struct irq_domain *d, unsigned int virq,
if (!gic_local_irq_is_routable(intr))
return -EPERM;
spin_lock_irqsave(&gic_lock, flags);
raw_spin_lock_irqsave(&gic_lock, flags);
for_each_online_cpu(cpu) {
write_gic_vl_other(mips_cm_vp_id(cpu));
write_gic_vo_map(mips_gic_vx_map_reg(intr), map);
}
spin_unlock_irqrestore(&gic_lock, flags);
raw_spin_unlock_irqrestore(&gic_lock, flags);
return 0;
}
@ -710,8 +725,8 @@ static int gic_cpu_startup(unsigned int cpu)
/* Clear all local IRQ masks (ie. disable all local interrupts) */
write_gic_vl_rmask(~0);
/* Invoke irq_cpu_online callbacks to enable desired interrupts */
irq_cpu_online();
/* Enable desired interrupts */
gic_all_vpes_irq_cpu_online();
return 0;
}

View File

@ -539,15 +539,17 @@ static int load_requested_vpu(struct mtk_vpu *vpu,
int vpu_load_firmware(struct platform_device *pdev)
{
struct mtk_vpu *vpu;
struct device *dev = &pdev->dev;
struct device *dev;
struct vpu_run *run;
int ret;
if (!pdev) {
dev_err(dev, "VPU platform device is invalid\n");
pr_err("VPU platform device is invalid\n");
return -EINVAL;
}
dev = &pdev->dev;
vpu = platform_get_drvdata(pdev);
run = &vpu->run;

View File

@ -1991,14 +1991,14 @@ static void mmc_blk_mq_poll_completion(struct mmc_queue *mq,
mmc_blk_urgent_bkops(mq, mqrq);
}
static void mmc_blk_mq_dec_in_flight(struct mmc_queue *mq, struct request *req)
static void mmc_blk_mq_dec_in_flight(struct mmc_queue *mq, enum mmc_issue_type issue_type)
{
unsigned long flags;
bool put_card;
spin_lock_irqsave(&mq->lock, flags);
mq->in_flight[mmc_issue_type(mq, req)] -= 1;
mq->in_flight[issue_type] -= 1;
put_card = (mmc_tot_in_flight(mq) == 0);
@ -2010,6 +2010,7 @@ static void mmc_blk_mq_dec_in_flight(struct mmc_queue *mq, struct request *req)
static void mmc_blk_mq_post_req(struct mmc_queue *mq, struct request *req)
{
enum mmc_issue_type issue_type = mmc_issue_type(mq, req);
struct mmc_queue_req *mqrq = req_to_mmc_queue_req(req);
struct mmc_request *mrq = &mqrq->brq.mrq;
struct mmc_host *host = mq->card->host;
@ -2025,7 +2026,7 @@ static void mmc_blk_mq_post_req(struct mmc_queue *mq, struct request *req)
else if (likely(!blk_should_fake_timeout(req->q)))
blk_mq_complete_request(req);
mmc_blk_mq_dec_in_flight(mq, req);
mmc_blk_mq_dec_in_flight(mq, issue_type);
}
void mmc_blk_mq_recovery(struct mmc_queue *mq)

View File

@ -514,6 +514,32 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev)
EXPORT_SYMBOL(mmc_alloc_host);
static void devm_mmc_host_release(struct device *dev, void *res)
{
mmc_free_host(*(struct mmc_host **)res);
}
struct mmc_host *devm_mmc_alloc_host(struct device *dev, int extra)
{
struct mmc_host **dr, *host;
dr = devres_alloc(devm_mmc_host_release, sizeof(*dr), GFP_KERNEL);
if (!dr)
return ERR_PTR(-ENOMEM);
host = mmc_alloc_host(extra, dev);
if (IS_ERR(host)) {
devres_free(dr);
return host;
}
*dr = host;
devres_add(dev, dr);
return host;
}
EXPORT_SYMBOL(devm_mmc_alloc_host);
static int mmc_validate_host_caps(struct mmc_host *host)
{
if (host->caps & MMC_CAP_SDIO_IRQ && !host->ops->enable_sdio_irq) {

View File

@ -1413,8 +1413,8 @@ static int bcm2835_probe(struct platform_device *pdev)
host->max_clk = clk_get_rate(clk);
host->irq = platform_get_irq(pdev, 0);
if (host->irq <= 0) {
ret = -EINVAL;
if (host->irq < 0) {
ret = host->irq;
goto err;
}

View File

@ -1122,7 +1122,7 @@ static int meson_mmc_probe(struct platform_device *pdev)
struct mmc_host *mmc;
int ret;
mmc = mmc_alloc_host(sizeof(struct meson_host), &pdev->dev);
mmc = devm_mmc_alloc_host(&pdev->dev, sizeof(struct meson_host));
if (!mmc)
return -ENOMEM;
host = mmc_priv(mmc);
@ -1138,46 +1138,33 @@ static int meson_mmc_probe(struct platform_device *pdev)
host->vqmmc_enabled = false;
ret = mmc_regulator_get_supply(mmc);
if (ret)
goto free_host;
return ret;
ret = mmc_of_parse(mmc);
if (ret) {
if (ret != -EPROBE_DEFER)
dev_warn(&pdev->dev, "error parsing DT: %d\n", ret);
goto free_host;
}
if (ret)
return dev_err_probe(&pdev->dev, ret, "error parsing DT\n");
host->data = (struct meson_mmc_data *)
of_device_get_match_data(&pdev->dev);
if (!host->data) {
ret = -EINVAL;
goto free_host;
}
if (!host->data)
return -EINVAL;
ret = device_reset_optional(&pdev->dev);
if (ret) {
dev_err_probe(&pdev->dev, ret, "device reset failed\n");
goto free_host;
}
if (ret)
return dev_err_probe(&pdev->dev, ret, "device reset failed\n");
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
host->regs = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(host->regs)) {
ret = PTR_ERR(host->regs);
goto free_host;
}
if (IS_ERR(host->regs))
return PTR_ERR(host->regs);
host->irq = platform_get_irq(pdev, 0);
if (host->irq <= 0) {
ret = -EINVAL;
goto free_host;
}
if (host->irq < 0)
return host->irq;
host->pinctrl = devm_pinctrl_get(&pdev->dev);
if (IS_ERR(host->pinctrl)) {
ret = PTR_ERR(host->pinctrl);
goto free_host;
}
if (IS_ERR(host->pinctrl))
return PTR_ERR(host->pinctrl);
host->pins_clk_gate = pinctrl_lookup_state(host->pinctrl,
"clk-gate");
@ -1188,14 +1175,12 @@ static int meson_mmc_probe(struct platform_device *pdev)
}
host->core_clk = devm_clk_get(&pdev->dev, "core");
if (IS_ERR(host->core_clk)) {
ret = PTR_ERR(host->core_clk);
goto free_host;
}
if (IS_ERR(host->core_clk))
return PTR_ERR(host->core_clk);
ret = clk_prepare_enable(host->core_clk);
if (ret)
goto free_host;
return ret;
ret = meson_mmc_clk_init(host);
if (ret)
@ -1290,8 +1275,6 @@ static int meson_mmc_probe(struct platform_device *pdev)
clk_disable_unprepare(host->mmc_clk);
err_core_clk:
clk_disable_unprepare(host->core_clk);
free_host:
mmc_free_host(mmc);
return ret;
}
@ -1315,7 +1298,6 @@ static int meson_mmc_remove(struct platform_device *pdev)
clk_disable_unprepare(host->mmc_clk);
clk_disable_unprepare(host->core_clk);
mmc_free_host(host->mmc);
return 0;
}

View File

@ -26,9 +26,16 @@ struct f_sdhost_priv {
bool enable_cmd_dat_delay;
};
static void *sdhci_f_sdhost_priv(struct sdhci_host *host)
{
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
return sdhci_pltfm_priv(pltfm_host);
}
static void sdhci_f_sdh30_soft_voltage_switch(struct sdhci_host *host)
{
struct f_sdhost_priv *priv = sdhci_priv(host);
struct f_sdhost_priv *priv = sdhci_f_sdhost_priv(host);
u32 ctrl = 0;
usleep_range(2500, 3000);
@ -61,7 +68,7 @@ static unsigned int sdhci_f_sdh30_get_min_clock(struct sdhci_host *host)
static void sdhci_f_sdh30_reset(struct sdhci_host *host, u8 mask)
{
struct f_sdhost_priv *priv = sdhci_priv(host);
struct f_sdhost_priv *priv = sdhci_f_sdhost_priv(host);
u32 ctl;
if (sdhci_readw(host, SDHCI_CLOCK_CONTROL) == 0)
@ -85,30 +92,32 @@ static const struct sdhci_ops sdhci_f_sdh30_ops = {
.set_uhs_signaling = sdhci_set_uhs_signaling,
};
static const struct sdhci_pltfm_data sdhci_f_sdh30_pltfm_data = {
.ops = &sdhci_f_sdh30_ops,
.quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC
| SDHCI_QUIRK_INVERTED_WRITE_PROTECT,
.quirks2 = SDHCI_QUIRK2_SUPPORT_SINGLE
| SDHCI_QUIRK2_TUNING_WORK_AROUND,
};
static int sdhci_f_sdh30_probe(struct platform_device *pdev)
{
struct sdhci_host *host;
struct device *dev = &pdev->dev;
int irq, ctrl = 0, ret = 0;
int ctrl = 0, ret = 0;
struct f_sdhost_priv *priv;
struct sdhci_pltfm_host *pltfm_host;
u32 reg = 0;
irq = platform_get_irq(pdev, 0);
if (irq < 0)
return irq;
host = sdhci_alloc_host(dev, sizeof(struct f_sdhost_priv));
host = sdhci_pltfm_init(pdev, &sdhci_f_sdh30_pltfm_data,
sizeof(struct f_sdhost_priv));
if (IS_ERR(host))
return PTR_ERR(host);
priv = sdhci_priv(host);
pltfm_host = sdhci_priv(host);
priv = sdhci_pltfm_priv(pltfm_host);
priv->dev = dev;
host->quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC |
SDHCI_QUIRK_INVERTED_WRITE_PROTECT;
host->quirks2 = SDHCI_QUIRK2_SUPPORT_SINGLE |
SDHCI_QUIRK2_TUNING_WORK_AROUND;
priv->enable_cmd_dat_delay = device_property_read_bool(dev,
"fujitsu,cmd-dat-delay-select");
@ -116,18 +125,6 @@ static int sdhci_f_sdh30_probe(struct platform_device *pdev)
if (ret)
goto err;
platform_set_drvdata(pdev, host);
host->hw_name = "f_sdh30";
host->ops = &sdhci_f_sdh30_ops;
host->irq = irq;
host->ioaddr = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(host->ioaddr)) {
ret = PTR_ERR(host->ioaddr);
goto err;
}
if (dev_of_node(dev)) {
sdhci_get_of_property(pdev);
@ -182,23 +179,22 @@ static int sdhci_f_sdh30_probe(struct platform_device *pdev)
err_clk:
clk_disable_unprepare(priv->clk_iface);
err:
sdhci_free_host(host);
sdhci_pltfm_free(pdev);
return ret;
}
static int sdhci_f_sdh30_remove(struct platform_device *pdev)
{
struct sdhci_host *host = platform_get_drvdata(pdev);
struct f_sdhost_priv *priv = sdhci_priv(host);
struct f_sdhost_priv *priv = sdhci_f_sdhost_priv(host);
struct clk *clk_iface = priv->clk_iface;
struct clk *clk = priv->clk;
sdhci_remove_host(host, readl(host->ioaddr + SDHCI_INT_STATUS) ==
0xffffffff);
sdhci_pltfm_unregister(pdev);
clk_disable_unprepare(priv->clk_iface);
clk_disable_unprepare(priv->clk);
sdhci_free_host(host);
platform_set_drvdata(pdev, NULL);
clk_disable_unprepare(clk_iface);
clk_disable_unprepare(clk);
return 0;
}

View File

@ -1317,8 +1317,8 @@ static int sunxi_mmc_resource_request(struct sunxi_mmc_host *host,
return ret;
host->irq = platform_get_irq(pdev, 0);
if (host->irq <= 0) {
ret = -EINVAL;
if (host->irq < 0) {
ret = host->irq;
goto error_disable_mmc;
}

View File

@ -1710,8 +1710,6 @@ static int wbsd_init(struct device *dev, int base, int irq, int dma,
wbsd_release_resources(host);
wbsd_free_mmc(dev);
mmc_free_host(mmc);
return ret;
}

View File

@ -2310,6 +2310,14 @@ static void mv88e6xxx_hardware_reset(struct mv88e6xxx_chip *chip)
/* If there is a GPIO connected to the reset pin, toggle it */
if (gpiod) {
/* If the switch has just been reset and not yet completed
* loading EEPROM, the reset may interrupt the I2C transaction
* mid-byte, causing the first EEPROM read after the reset
* from the wrong location resulting in the switch booting
* to wrong mode and inoperable.
*/
mv88e6xxx_g1_wait_eeprom_done(chip);
gpiod_set_value_cansleep(gpiod, 1);
usleep_range(10000, 20000);
gpiod_set_value_cansleep(gpiod, 0);

View File

@ -210,11 +210,11 @@ static i40e_status i40e_read_nvm_word_srctl(struct i40e_hw *hw, u16 offset,
* @hw: pointer to the HW structure.
* @module_pointer: module pointer location in words from the NVM beginning
* @offset: offset in words from module start
* @words: number of words to write
* @data: buffer with words to write to the Shadow RAM
* @words: number of words to read
* @data: buffer with words to read to the Shadow RAM
* @last_command: tells the AdminQ that this is the last command
*
* Writes a 16 bit words buffer to the Shadow RAM using the admin command.
* Reads a 16 bit words buffer to the Shadow RAM using the admin command.
**/
static i40e_status i40e_read_nvm_aq(struct i40e_hw *hw,
u8 module_pointer, u32 offset,
@ -234,18 +234,18 @@ static i40e_status i40e_read_nvm_aq(struct i40e_hw *hw,
*/
if ((offset + words) > hw->nvm.sr_size)
i40e_debug(hw, I40E_DEBUG_NVM,
"NVM write error: offset %d beyond Shadow RAM limit %d\n",
"NVM read error: offset %d beyond Shadow RAM limit %d\n",
(offset + words), hw->nvm.sr_size);
else if (words > I40E_SR_SECTOR_SIZE_IN_WORDS)
/* We can write only up to 4KB (one sector), in one AQ write */
/* We can read only up to 4KB (one sector), in one AQ write */
i40e_debug(hw, I40E_DEBUG_NVM,
"NVM write fail error: tried to write %d words, limit is %d.\n",
"NVM read fail error: tried to read %d words, limit is %d.\n",
words, I40E_SR_SECTOR_SIZE_IN_WORDS);
else if (((offset + (words - 1)) / I40E_SR_SECTOR_SIZE_IN_WORDS)
!= (offset / I40E_SR_SECTOR_SIZE_IN_WORDS))
/* A single write cannot spread over two sectors */
/* A single read cannot spread over two sectors */
i40e_debug(hw, I40E_DEBUG_NVM,
"NVM write error: cannot spread over two sectors in a single write offset=%d words=%d\n",
"NVM read error: cannot spread over two sectors in a single read offset=%d words=%d\n",
offset, words);
else
ret_code = i40e_aq_read_nvm(hw, module_pointer,

View File

@ -89,7 +89,8 @@ static u64 mlx5_read_internal_timer(struct mlx5_core_dev *dev,
static u64 read_internal_timer(const struct cyclecounter *cc)
{
struct mlx5_clock *clock = container_of(cc, struct mlx5_clock, cycles);
struct mlx5_timer *timer = container_of(cc, struct mlx5_timer, cycles);
struct mlx5_clock *clock = container_of(timer, struct mlx5_clock, timer);
struct mlx5_core_dev *mdev = container_of(clock, struct mlx5_core_dev,
clock);
@ -100,6 +101,7 @@ static void mlx5_update_clock_info_page(struct mlx5_core_dev *mdev)
{
struct mlx5_ib_clock_info *clock_info = mdev->clock_info;
struct mlx5_clock *clock = &mdev->clock;
struct mlx5_timer *timer;
u32 sign;
if (!clock_info)
@ -109,10 +111,11 @@ static void mlx5_update_clock_info_page(struct mlx5_core_dev *mdev)
smp_store_mb(clock_info->sign,
sign | MLX5_IB_CLOCK_INFO_KERNEL_UPDATING);
clock_info->cycles = clock->tc.cycle_last;
clock_info->mult = clock->cycles.mult;
clock_info->nsec = clock->tc.nsec;
clock_info->frac = clock->tc.frac;
timer = &clock->timer;
clock_info->cycles = timer->tc.cycle_last;
clock_info->mult = timer->cycles.mult;
clock_info->nsec = timer->tc.nsec;
clock_info->frac = timer->tc.frac;
smp_store_release(&clock_info->sign,
sign + MLX5_IB_CLOCK_INFO_KERNEL_UPDATING * 2);
@ -151,28 +154,37 @@ static void mlx5_timestamp_overflow(struct work_struct *work)
{
struct delayed_work *dwork = to_delayed_work(work);
struct mlx5_core_dev *mdev;
struct mlx5_timer *timer;
struct mlx5_clock *clock;
unsigned long flags;
clock = container_of(dwork, struct mlx5_clock, overflow_work);
timer = container_of(dwork, struct mlx5_timer, overflow_work);
clock = container_of(timer, struct mlx5_clock, timer);
mdev = container_of(clock, struct mlx5_core_dev, clock);
if (mdev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR)
goto out;
write_seqlock_irqsave(&clock->lock, flags);
timecounter_read(&clock->tc);
timecounter_read(&timer->tc);
mlx5_update_clock_info_page(mdev);
write_sequnlock_irqrestore(&clock->lock, flags);
schedule_delayed_work(&clock->overflow_work, clock->overflow_period);
out:
schedule_delayed_work(&timer->overflow_work, timer->overflow_period);
}
static int mlx5_ptp_settime(struct ptp_clock_info *ptp, const struct timespec64 *ts)
{
struct mlx5_clock *clock = container_of(ptp, struct mlx5_clock, ptp_info);
struct mlx5_timer *timer = &clock->timer;
u64 ns = timespec64_to_ns(ts);
struct mlx5_core_dev *mdev;
unsigned long flags;
mdev = container_of(clock, struct mlx5_core_dev, clock);
write_seqlock_irqsave(&clock->lock, flags);
timecounter_init(&clock->tc, &clock->cycles, ns);
timecounter_init(&timer->tc, &timer->cycles, ns);
mlx5_update_clock_info_page(mdev);
write_sequnlock_irqrestore(&clock->lock, flags);
@ -183,6 +195,7 @@ static int mlx5_ptp_gettimex(struct ptp_clock_info *ptp, struct timespec64 *ts,
struct ptp_system_timestamp *sts)
{
struct mlx5_clock *clock = container_of(ptp, struct mlx5_clock, ptp_info);
struct mlx5_timer *timer = &clock->timer;
struct mlx5_core_dev *mdev;
unsigned long flags;
u64 cycles, ns;
@ -190,7 +203,7 @@ static int mlx5_ptp_gettimex(struct ptp_clock_info *ptp, struct timespec64 *ts,
mdev = container_of(clock, struct mlx5_core_dev, clock);
write_seqlock_irqsave(&clock->lock, flags);
cycles = mlx5_read_internal_timer(mdev, sts);
ns = timecounter_cyc2time(&clock->tc, cycles);
ns = timecounter_cyc2time(&timer->tc, cycles);
write_sequnlock_irqrestore(&clock->lock, flags);
*ts = ns_to_timespec64(ns);
@ -201,12 +214,13 @@ static int mlx5_ptp_gettimex(struct ptp_clock_info *ptp, struct timespec64 *ts,
static int mlx5_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
{
struct mlx5_clock *clock = container_of(ptp, struct mlx5_clock, ptp_info);
struct mlx5_timer *timer = &clock->timer;
struct mlx5_core_dev *mdev;
unsigned long flags;
mdev = container_of(clock, struct mlx5_core_dev, clock);
write_seqlock_irqsave(&clock->lock, flags);
timecounter_adjtime(&clock->tc, delta);
timecounter_adjtime(&timer->tc, delta);
mlx5_update_clock_info_page(mdev);
write_sequnlock_irqrestore(&clock->lock, flags);
@ -216,27 +230,27 @@ static int mlx5_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
static int mlx5_ptp_adjfreq(struct ptp_clock_info *ptp, s32 delta)
{
struct mlx5_clock *clock = container_of(ptp, struct mlx5_clock, ptp_info);
struct mlx5_timer *timer = &clock->timer;
struct mlx5_core_dev *mdev;
unsigned long flags;
int neg_adj = 0;
u32 diff;
u64 adj;
if (delta < 0) {
neg_adj = 1;
delta = -delta;
}
adj = clock->nominal_c_mult;
adj = timer->nominal_c_mult;
adj *= delta;
diff = div_u64(adj, 1000000000ULL);
mdev = container_of(clock, struct mlx5_core_dev, clock);
write_seqlock_irqsave(&clock->lock, flags);
timecounter_read(&clock->tc);
clock->cycles.mult = neg_adj ? clock->nominal_c_mult - diff :
clock->nominal_c_mult + diff;
timecounter_read(&timer->tc);
timer->cycles.mult = neg_adj ? timer->nominal_c_mult - diff :
timer->nominal_c_mult + diff;
mlx5_update_clock_info_page(mdev);
write_sequnlock_irqrestore(&clock->lock, flags);
@ -313,6 +327,7 @@ static int mlx5_perout_configure(struct ptp_clock_info *ptp,
container_of(ptp, struct mlx5_clock, ptp_info);
struct mlx5_core_dev *mdev =
container_of(clock, struct mlx5_core_dev, clock);
struct mlx5_timer *timer = &clock->timer;
u32 in[MLX5_ST_SZ_DW(mtpps_reg)] = {0};
u64 nsec_now, nsec_delta, time_stamp = 0;
u64 cycles_now, cycles_delta;
@ -355,10 +370,10 @@ static int mlx5_perout_configure(struct ptp_clock_info *ptp,
ns = timespec64_to_ns(&ts);
cycles_now = mlx5_read_internal_timer(mdev, NULL);
write_seqlock_irqsave(&clock->lock, flags);
nsec_now = timecounter_cyc2time(&clock->tc, cycles_now);
nsec_now = timecounter_cyc2time(&timer->tc, cycles_now);
nsec_delta = ns - nsec_now;
cycles_delta = div64_u64(nsec_delta << clock->cycles.shift,
clock->cycles.mult);
cycles_delta = div64_u64(nsec_delta << timer->cycles.shift,
timer->cycles.mult);
write_sequnlock_irqrestore(&clock->lock, flags);
time_stamp = cycles_now + cycles_delta;
field_select = MLX5_MTPPS_FS_PIN_MODE |
@ -541,6 +556,7 @@ static int mlx5_pps_event(struct notifier_block *nb,
unsigned long type, void *data)
{
struct mlx5_clock *clock = mlx5_nb_cof(nb, struct mlx5_clock, pps_nb);
struct mlx5_timer *timer = &clock->timer;
struct ptp_clock_event ptp_event;
u64 cycles_now, cycles_delta;
u64 nsec_now, nsec_delta, ns;
@ -575,10 +591,10 @@ static int mlx5_pps_event(struct notifier_block *nb,
ts.tv_nsec = 0;
ns = timespec64_to_ns(&ts);
write_seqlock_irqsave(&clock->lock, flags);
nsec_now = timecounter_cyc2time(&clock->tc, cycles_now);
nsec_now = timecounter_cyc2time(&timer->tc, cycles_now);
nsec_delta = ns - nsec_now;
cycles_delta = div64_u64(nsec_delta << clock->cycles.shift,
clock->cycles.mult);
cycles_delta = div64_u64(nsec_delta << timer->cycles.shift,
timer->cycles.mult);
clock->pps_info.start[pin] = cycles_now + cycles_delta;
write_sequnlock_irqrestore(&clock->lock, flags);
schedule_work(&clock->pps_info.out_work);
@ -591,29 +607,32 @@ static int mlx5_pps_event(struct notifier_block *nb,
return NOTIFY_OK;
}
void mlx5_init_clock(struct mlx5_core_dev *mdev)
static void mlx5_timecounter_init(struct mlx5_core_dev *mdev)
{
struct mlx5_clock *clock = &mdev->clock;
u64 overflow_cycles;
u64 ns;
u64 frac = 0;
struct mlx5_timer *timer = &clock->timer;
u32 dev_freq;
dev_freq = MLX5_CAP_GEN(mdev, device_frequency_khz);
if (!dev_freq) {
mlx5_core_warn(mdev, "invalid device_frequency_khz, aborting HW clock init\n");
return;
}
seqlock_init(&clock->lock);
clock->cycles.read = read_internal_timer;
clock->cycles.shift = MLX5_CYCLES_SHIFT;
clock->cycles.mult = clocksource_khz2mult(dev_freq,
clock->cycles.shift);
clock->nominal_c_mult = clock->cycles.mult;
clock->cycles.mask = CLOCKSOURCE_MASK(41);
timer->cycles.read = read_internal_timer;
timer->cycles.shift = MLX5_CYCLES_SHIFT;
timer->cycles.mult = clocksource_khz2mult(dev_freq,
timer->cycles.shift);
timer->nominal_c_mult = timer->cycles.mult;
timer->cycles.mask = CLOCKSOURCE_MASK(41);
timecounter_init(&clock->tc, &clock->cycles,
timecounter_init(&timer->tc, &timer->cycles,
ktime_to_ns(ktime_get_real()));
}
static void mlx5_init_overflow_period(struct mlx5_clock *clock)
{
struct mlx5_core_dev *mdev = container_of(clock, struct mlx5_core_dev, clock);
struct mlx5_ib_clock_info *clock_info = mdev->clock_info;
struct mlx5_timer *timer = &clock->timer;
u64 overflow_cycles;
u64 frac = 0;
u64 ns;
/* Calculate period in seconds to call the overflow watchdog - to make
* sure counter is checked at least twice every wrap around.
@ -622,32 +641,63 @@ void mlx5_init_clock(struct mlx5_core_dev *mdev)
* multiplied by clock multiplier where the result doesn't exceed
* 64bits.
*/
overflow_cycles = div64_u64(~0ULL >> 1, clock->cycles.mult);
overflow_cycles = min(overflow_cycles, div_u64(clock->cycles.mask, 3));
overflow_cycles = div64_u64(~0ULL >> 1, timer->cycles.mult);
overflow_cycles = min(overflow_cycles, div_u64(timer->cycles.mask, 3));
ns = cyclecounter_cyc2ns(&clock->cycles, overflow_cycles,
ns = cyclecounter_cyc2ns(&timer->cycles, overflow_cycles,
frac, &frac);
do_div(ns, NSEC_PER_SEC / HZ);
clock->overflow_period = ns;
timer->overflow_period = ns;
mdev->clock_info =
(struct mlx5_ib_clock_info *)get_zeroed_page(GFP_KERNEL);
if (mdev->clock_info) {
mdev->clock_info->nsec = clock->tc.nsec;
mdev->clock_info->cycles = clock->tc.cycle_last;
mdev->clock_info->mask = clock->cycles.mask;
mdev->clock_info->mult = clock->nominal_c_mult;
mdev->clock_info->shift = clock->cycles.shift;
mdev->clock_info->frac = clock->tc.frac;
mdev->clock_info->overflow_period = clock->overflow_period;
INIT_DELAYED_WORK(&timer->overflow_work, mlx5_timestamp_overflow);
if (timer->overflow_period)
schedule_delayed_work(&timer->overflow_work, 0);
else
mlx5_core_warn(mdev,
"invalid overflow period, overflow_work is not scheduled\n");
if (clock_info)
clock_info->overflow_period = timer->overflow_period;
}
static void mlx5_init_clock_info(struct mlx5_core_dev *mdev)
{
struct mlx5_clock *clock = &mdev->clock;
struct mlx5_ib_clock_info *info;
struct mlx5_timer *timer;
mdev->clock_info = (struct mlx5_ib_clock_info *)get_zeroed_page(GFP_KERNEL);
if (!mdev->clock_info) {
mlx5_core_warn(mdev, "Failed to allocate IB clock info page\n");
return;
}
info = mdev->clock_info;
timer = &clock->timer;
info->nsec = timer->tc.nsec;
info->cycles = timer->tc.cycle_last;
info->mask = timer->cycles.mask;
info->mult = timer->nominal_c_mult;
info->shift = timer->cycles.shift;
info->frac = timer->tc.frac;
}
void mlx5_init_clock(struct mlx5_core_dev *mdev)
{
struct mlx5_clock *clock = &mdev->clock;
if (!MLX5_CAP_GEN(mdev, device_frequency_khz)) {
mlx5_core_warn(mdev, "invalid device_frequency_khz, aborting HW clock init\n");
return;
}
seqlock_init(&clock->lock);
mlx5_timecounter_init(mdev);
mlx5_init_clock_info(mdev);
mlx5_init_overflow_period(clock);
INIT_WORK(&clock->pps_info.out_work, mlx5_pps_out);
INIT_DELAYED_WORK(&clock->overflow_work, mlx5_timestamp_overflow);
if (clock->overflow_period)
schedule_delayed_work(&clock->overflow_work, 0);
else
mlx5_core_warn(mdev, "invalid overflow period, overflow_work is not scheduled\n");
/* Configure the PHC */
clock->ptp_info = mlx5_ptp_clock_info;
@ -684,7 +734,7 @@ void mlx5_cleanup_clock(struct mlx5_core_dev *mdev)
}
cancel_work_sync(&clock->pps_info.out_work);
cancel_delayed_work_sync(&clock->overflow_work);
cancel_delayed_work_sync(&clock->timer.overflow_work);
if (mdev->clock_info) {
free_page((unsigned long)mdev->clock_info);

View File

@ -45,12 +45,13 @@ static inline int mlx5_clock_get_ptp_index(struct mlx5_core_dev *mdev)
static inline ktime_t mlx5_timecounter_cyc2time(struct mlx5_clock *clock,
u64 timestamp)
{
struct mlx5_timer *timer = &clock->timer;
unsigned int seq;
u64 nsec;
do {
seq = read_seqbegin(&clock->lock);
nsec = timecounter_cyc2time(&clock->tc, timestamp);
nsec = timecounter_cyc2time(&timer->tc, timestamp);
} while (read_seqretry(&clock->lock, seq));
return ns_to_ktime(nsec);

View File

@ -159,6 +159,19 @@ static struct macsec_rx_sa *macsec_rxsa_get(struct macsec_rx_sa __rcu *ptr)
return sa;
}
static struct macsec_rx_sa *macsec_active_rxsa_get(struct macsec_rx_sc *rx_sc)
{
struct macsec_rx_sa *sa = NULL;
int an;
for (an = 0; an < MACSEC_NUM_AN; an++) {
sa = macsec_rxsa_get(rx_sc->sa[an]);
if (sa)
break;
}
return sa;
}
static void free_rx_sc_rcu(struct rcu_head *head)
{
struct macsec_rx_sc *rx_sc = container_of(head, struct macsec_rx_sc, rcu_head);
@ -497,18 +510,28 @@ static void macsec_encrypt_finish(struct sk_buff *skb, struct net_device *dev)
skb->protocol = eth_hdr(skb)->h_proto;
}
static unsigned int macsec_msdu_len(struct sk_buff *skb)
{
struct macsec_dev *macsec = macsec_priv(skb->dev);
struct macsec_secy *secy = &macsec->secy;
bool sci_present = macsec_skb_cb(skb)->has_sci;
return skb->len - macsec_hdr_len(sci_present) - secy->icv_len;
}
static void macsec_count_tx(struct sk_buff *skb, struct macsec_tx_sc *tx_sc,
struct macsec_tx_sa *tx_sa)
{
unsigned int msdu_len = macsec_msdu_len(skb);
struct pcpu_tx_sc_stats *txsc_stats = this_cpu_ptr(tx_sc->stats);
u64_stats_update_begin(&txsc_stats->syncp);
if (tx_sc->encrypt) {
txsc_stats->stats.OutOctetsEncrypted += skb->len;
txsc_stats->stats.OutOctetsEncrypted += msdu_len;
txsc_stats->stats.OutPktsEncrypted++;
this_cpu_inc(tx_sa->stats->OutPktsEncrypted);
} else {
txsc_stats->stats.OutOctetsProtected += skb->len;
txsc_stats->stats.OutOctetsProtected += msdu_len;
txsc_stats->stats.OutPktsProtected++;
this_cpu_inc(tx_sa->stats->OutPktsProtected);
}
@ -538,9 +561,10 @@ static void macsec_encrypt_done(struct crypto_async_request *base, int err)
aead_request_free(macsec_skb_cb(skb)->req);
rcu_read_lock_bh();
macsec_encrypt_finish(skb, dev);
macsec_count_tx(skb, &macsec->secy.tx_sc, macsec_skb_cb(skb)->tx_sa);
len = skb->len;
/* packet is encrypted/protected so tx_bytes must be calculated */
len = macsec_msdu_len(skb) + 2 * ETH_ALEN;
macsec_encrypt_finish(skb, dev);
ret = dev_queue_xmit(skb);
count_tx(dev, ret, len);
rcu_read_unlock_bh();
@ -699,6 +723,7 @@ static struct sk_buff *macsec_encrypt(struct sk_buff *skb,
macsec_skb_cb(skb)->req = req;
macsec_skb_cb(skb)->tx_sa = tx_sa;
macsec_skb_cb(skb)->has_sci = sci_present;
aead_request_set_callback(req, 0, macsec_encrypt_done, skb);
dev_hold(skb->dev);
@ -740,15 +765,17 @@ static bool macsec_post_decrypt(struct sk_buff *skb, struct macsec_secy *secy, u
u64_stats_update_begin(&rxsc_stats->syncp);
rxsc_stats->stats.InPktsLate++;
u64_stats_update_end(&rxsc_stats->syncp);
DEV_STATS_INC(secy->netdev, rx_dropped);
return false;
}
if (secy->validate_frames != MACSEC_VALIDATE_DISABLED) {
unsigned int msdu_len = macsec_msdu_len(skb);
u64_stats_update_begin(&rxsc_stats->syncp);
if (hdr->tci_an & MACSEC_TCI_E)
rxsc_stats->stats.InOctetsDecrypted += skb->len;
rxsc_stats->stats.InOctetsDecrypted += msdu_len;
else
rxsc_stats->stats.InOctetsValidated += skb->len;
rxsc_stats->stats.InOctetsValidated += msdu_len;
u64_stats_update_end(&rxsc_stats->syncp);
}
@ -761,6 +788,8 @@ static bool macsec_post_decrypt(struct sk_buff *skb, struct macsec_secy *secy, u
u64_stats_update_begin(&rxsc_stats->syncp);
rxsc_stats->stats.InPktsNotValid++;
u64_stats_update_end(&rxsc_stats->syncp);
this_cpu_inc(rx_sa->stats->InPktsNotValid);
DEV_STATS_INC(secy->netdev, rx_errors);
return false;
}
@ -853,9 +882,9 @@ static void macsec_decrypt_done(struct crypto_async_request *base, int err)
macsec_finalize_skb(skb, macsec->secy.icv_len,
macsec_extra_len(macsec_skb_cb(skb)->has_sci));
len = skb->len;
macsec_reset_skb(skb, macsec->secy.netdev);
len = skb->len;
if (gro_cells_receive(&macsec->gro_cells, skb) == NET_RX_SUCCESS)
count_rx(dev, len);
@ -1046,6 +1075,7 @@ static enum rx_handler_result handle_not_macsec(struct sk_buff *skb)
u64_stats_update_begin(&secy_stats->syncp);
secy_stats->stats.InPktsNoTag++;
u64_stats_update_end(&secy_stats->syncp);
DEV_STATS_INC(macsec->secy.netdev, rx_dropped);
continue;
}
@ -1155,6 +1185,7 @@ static rx_handler_result_t macsec_handle_frame(struct sk_buff **pskb)
u64_stats_update_begin(&secy_stats->syncp);
secy_stats->stats.InPktsBadTag++;
u64_stats_update_end(&secy_stats->syncp);
DEV_STATS_INC(secy->netdev, rx_errors);
goto drop_nosa;
}
@ -1165,11 +1196,15 @@ static rx_handler_result_t macsec_handle_frame(struct sk_buff **pskb)
/* If validateFrames is Strict or the C bit in the
* SecTAG is set, discard
*/
struct macsec_rx_sa *active_rx_sa = macsec_active_rxsa_get(rx_sc);
if (hdr->tci_an & MACSEC_TCI_C ||
secy->validate_frames == MACSEC_VALIDATE_STRICT) {
u64_stats_update_begin(&rxsc_stats->syncp);
rxsc_stats->stats.InPktsNotUsingSA++;
u64_stats_update_end(&rxsc_stats->syncp);
DEV_STATS_INC(secy->netdev, rx_errors);
if (active_rx_sa)
this_cpu_inc(active_rx_sa->stats->InPktsNotUsingSA);
goto drop_nosa;
}
@ -1179,6 +1214,8 @@ static rx_handler_result_t macsec_handle_frame(struct sk_buff **pskb)
u64_stats_update_begin(&rxsc_stats->syncp);
rxsc_stats->stats.InPktsUnusedSA++;
u64_stats_update_end(&rxsc_stats->syncp);
if (active_rx_sa)
this_cpu_inc(active_rx_sa->stats->InPktsUnusedSA);
goto deliver;
}
@ -1199,6 +1236,7 @@ static rx_handler_result_t macsec_handle_frame(struct sk_buff **pskb)
u64_stats_update_begin(&rxsc_stats->syncp);
rxsc_stats->stats.InPktsLate++;
u64_stats_update_end(&rxsc_stats->syncp);
DEV_STATS_INC(macsec->secy.netdev, rx_dropped);
goto drop;
}
}
@ -1227,6 +1265,7 @@ static rx_handler_result_t macsec_handle_frame(struct sk_buff **pskb)
deliver:
macsec_finalize_skb(skb, secy->icv_len,
macsec_extra_len(macsec_skb_cb(skb)->has_sci));
len = skb->len;
macsec_reset_skb(skb, secy->netdev);
if (rx_sa)
@ -1234,12 +1273,11 @@ static rx_handler_result_t macsec_handle_frame(struct sk_buff **pskb)
macsec_rxsc_put(rx_sc);
skb_orphan(skb);
len = skb->len;
ret = gro_cells_receive(&macsec->gro_cells, skb);
if (ret == NET_RX_SUCCESS)
count_rx(dev, len);
else
macsec->secy.netdev->stats.rx_dropped++;
DEV_STATS_INC(macsec->secy.netdev, rx_dropped);
rcu_read_unlock();
@ -1276,6 +1314,7 @@ static rx_handler_result_t macsec_handle_frame(struct sk_buff **pskb)
u64_stats_update_begin(&secy_stats->syncp);
secy_stats->stats.InPktsNoSCI++;
u64_stats_update_end(&secy_stats->syncp);
DEV_STATS_INC(macsec->secy.netdev, rx_errors);
continue;
}
@ -1294,7 +1333,7 @@ static rx_handler_result_t macsec_handle_frame(struct sk_buff **pskb)
secy_stats->stats.InPktsUnknownSCI++;
u64_stats_update_end(&secy_stats->syncp);
} else {
macsec->secy.netdev->stats.rx_dropped++;
DEV_STATS_INC(macsec->secy.netdev, rx_dropped);
}
}
@ -3403,21 +3442,21 @@ static netdev_tx_t macsec_start_xmit(struct sk_buff *skb,
if (!secy->operational) {
kfree_skb(skb);
dev->stats.tx_dropped++;
DEV_STATS_INC(dev, tx_dropped);
return NETDEV_TX_OK;
}
len = skb->len;
skb = macsec_encrypt(skb, dev);
if (IS_ERR(skb)) {
if (PTR_ERR(skb) != -EINPROGRESS)
dev->stats.tx_dropped++;
DEV_STATS_INC(dev, tx_dropped);
return NETDEV_TX_OK;
}
macsec_count_tx(skb, &macsec->secy.tx_sc, macsec_skb_cb(skb)->tx_sa);
macsec_encrypt_finish(skb, dev);
len = skb->len;
ret = dev_queue_xmit(skb);
count_tx(dev, ret, len);
return ret;
@ -3646,8 +3685,9 @@ static void macsec_get_stats64(struct net_device *dev,
dev_fetch_sw_netstats(s, dev->tstats);
s->rx_dropped = dev->stats.rx_dropped;
s->tx_dropped = dev->stats.tx_dropped;
s->rx_dropped = atomic_long_read(&dev->stats.__rx_dropped);
s->tx_dropped = atomic_long_read(&dev->stats.__tx_dropped);
s->rx_errors = atomic_long_read(&dev->stats.__rx_errors);
}
static int macsec_get_iflink(const struct net_device *dev)

View File

@ -404,6 +404,17 @@ static int bcm54xx_resume(struct phy_device *phydev)
return bcm54xx_config_init(phydev);
}
static int bcm54810_read_mmd(struct phy_device *phydev, int devnum, u16 regnum)
{
return -EOPNOTSUPP;
}
static int bcm54810_write_mmd(struct phy_device *phydev, int devnum, u16 regnum,
u16 val)
{
return -EOPNOTSUPP;
}
static int bcm54811_config_init(struct phy_device *phydev)
{
int err, reg;
@ -841,6 +852,8 @@ static struct phy_driver broadcom_drivers[] = {
.phy_id_mask = 0xfffffff0,
.name = "Broadcom BCM54810",
/* PHY_GBIT_FEATURES */
.read_mmd = bcm54810_read_mmd,
.write_mmd = bcm54810_write_mmd,
.config_init = bcm54xx_config_init,
.config_aneg = bcm5481_config_aneg,
.ack_interrupt = bcm_phy_ack_intr,

View File

@ -2195,7 +2195,9 @@ static void team_setup(struct net_device *dev)
dev->hw_features = TEAM_VLAN_FEATURES |
NETIF_F_HW_VLAN_CTAG_RX |
NETIF_F_HW_VLAN_CTAG_FILTER;
NETIF_F_HW_VLAN_CTAG_FILTER |
NETIF_F_HW_VLAN_STAG_RX |
NETIF_F_HW_VLAN_STAG_FILTER;
dev->hw_features |= NETIF_F_GSO_ENCAP_ALL | NETIF_F_GSO_UDP_L4;
dev->features |= dev->hw_features;

View File

@ -3223,8 +3223,6 @@ static int virtnet_probe(struct virtio_device *vdev)
}
}
_virtnet_set_queues(vi, vi->curr_queue_pairs);
/* serialize netdev register + virtio_device_ready() with ndo_open() */
rtnl_lock();
@ -3237,6 +3235,8 @@ static int virtnet_probe(struct virtio_device *vdev)
virtio_device_ready(vdev);
_virtnet_set_queues(vi, vi->curr_queue_pairs);
rtnl_unlock();
err = virtnet_cpu_notif_add(vi);

View File

@ -239,6 +239,7 @@
#define EP_STATE_ENABLED 1
static const unsigned int pcie_gen_freq[] = {
GEN1_CORE_CLK_FREQ, /* PCI_EXP_LNKSTA_CLS == 0; undefined */
GEN1_CORE_CLK_FREQ,
GEN2_CORE_CLK_FREQ,
GEN3_CORE_CLK_FREQ,
@ -470,7 +471,11 @@ static irqreturn_t tegra_pcie_ep_irq_thread(int irq, void *arg)
speed = dw_pcie_readw_dbi(pci, pcie->pcie_cap_base + PCI_EXP_LNKSTA) &
PCI_EXP_LNKSTA_CLS;
clk_set_rate(pcie->core_clk, pcie_gen_freq[speed - 1]);
if (speed >= ARRAY_SIZE(pcie_gen_freq))
speed = 0;
clk_set_rate(pcie->core_clk, pcie_gen_freq[speed]);
/* If EP doesn't advertise L1SS, just return */
val = dw_pcie_readl_dbi(pci, pcie->cfg_link_cap_l1sub);
@ -973,7 +978,11 @@ static int tegra_pcie_dw_host_init(struct pcie_port *pp)
speed = dw_pcie_readw_dbi(pci, pcie->pcie_cap_base + PCI_EXP_LNKSTA) &
PCI_EXP_LNKSTA_CLS;
clk_set_rate(pcie->core_clk, pcie_gen_freq[speed - 1]);
if (speed >= ARRAY_SIZE(pcie_gen_freq))
speed = 0;
clk_set_rate(pcie->core_clk, pcie_gen_freq[speed]);
tegra_pcie_enable_interrupts(pp);

View File

@ -1053,6 +1053,8 @@ static void nonstatic_release_resource_db(struct pcmcia_socket *s)
q = p->next;
kfree(p);
}
kfree(data);
}

View File

@ -2159,12 +2159,13 @@ static void gsm_error(struct gsm_mux *gsm,
static void gsm_cleanup_mux(struct gsm_mux *gsm, bool disc)
{
int i;
struct gsm_dlci *dlci = gsm->dlci[0];
struct gsm_dlci *dlci;
struct gsm_msg *txq, *ntxq;
gsm->dead = true;
mutex_lock(&gsm->mutex);
dlci = gsm->dlci[0];
if (dlci) {
if (disc && dlci->state != DLCI_CLOSED) {
gsm_dlci_begin_close(dlci);

View File

@ -3233,6 +3233,7 @@ void serial8250_init_port(struct uart_8250_port *up)
struct uart_port *port = &up->port;
spin_lock_init(&port->lock);
port->pm = NULL;
port->ops = &serial8250_pops;
port->has_sysrq = IS_ENABLED(CONFIG_SERIAL_8250_CONSOLE);

View File

@ -1062,8 +1062,8 @@ static void lpuart_copy_rx_to_tty(struct lpuart_port *sport)
unsigned long sr = lpuart32_read(&sport->port, UARTSTAT);
if (sr & (UARTSTAT_PE | UARTSTAT_FE)) {
/* Read DR to clear the error flags */
lpuart32_read(&sport->port, UARTDATA);
/* Clear the error flags */
lpuart32_write(&sport->port, sr, UARTSTAT);
if (sr & UARTSTAT_PE)
sport->port.icount.parity++;

View File

@ -2041,7 +2041,7 @@ int cdns3_ep_config(struct cdns3_endpoint *priv_ep, bool enable)
u8 mult = 0;
int ret;
buffering = CDNS3_EP_BUF_SIZE - 1;
buffering = priv_dev->ep_buf_size - 1;
cdns3_configure_dmult(priv_dev, priv_ep);
@ -2060,7 +2060,7 @@ int cdns3_ep_config(struct cdns3_endpoint *priv_ep, bool enable)
break;
default:
ep_cfg = EP_CFG_EPTYPE(USB_ENDPOINT_XFER_ISOC);
mult = CDNS3_EP_ISO_HS_MULT - 1;
mult = priv_dev->ep_iso_burst - 1;
buffering = mult + 1;
}
@ -2076,14 +2076,14 @@ int cdns3_ep_config(struct cdns3_endpoint *priv_ep, bool enable)
mult = 0;
max_packet_size = 1024;
if (priv_ep->type == USB_ENDPOINT_XFER_ISOC) {
maxburst = CDNS3_EP_ISO_SS_BURST - 1;
maxburst = priv_dev->ep_iso_burst - 1;
buffering = (mult + 1) *
(maxburst + 1);
if (priv_ep->interval > 1)
buffering++;
} else {
maxburst = CDNS3_EP_BUF_SIZE - 1;
maxburst = priv_dev->ep_buf_size - 1;
}
break;
default:
@ -2098,6 +2098,23 @@ int cdns3_ep_config(struct cdns3_endpoint *priv_ep, bool enable)
else
priv_ep->trb_burst_size = 16;
/*
* In versions preceding DEV_VER_V2, for example, iMX8QM, there exit the bugs
* in the DMA. These bugs occur when the trb_burst_size exceeds 16 and the
* address is not aligned to 128 Bytes (which is a product of the 64-bit AXI
* and AXI maximum burst length of 16 or 0xF+1, dma_axi_ctrl0[3:0]). This
* results in data corruption when it crosses the 4K border. The corruption
* specifically occurs from the position (4K - (address & 0x7F)) to 4K.
*
* So force trb_burst_size to 16 at such platform.
*/
if (priv_dev->dev_ver < DEV_VER_V2)
priv_ep->trb_burst_size = 16;
mult = min_t(u8, mult, EP_CFG_MULT_MAX);
buffering = min_t(u8, buffering, EP_CFG_BUFFERING_MAX);
maxburst = min_t(u8, maxburst, EP_CFG_MAXBURST_MAX);
/* onchip buffer is only allocated before configuration */
if (!priv_dev->hw_configured_flag) {
ret = cdns3_ep_onchip_buffer_reserve(priv_dev, buffering + 1,
@ -2971,6 +2988,40 @@ static int cdns3_gadget_udc_stop(struct usb_gadget *gadget)
return 0;
}
/**
* cdns3_gadget_check_config - ensure cdns3 can support the USB configuration
* @gadget: pointer to the USB gadget
*
* Used to record the maximum number of endpoints being used in a USB composite
* device. (across all configurations) This is to be used in the calculation
* of the TXFIFO sizes when resizing internal memory for individual endpoints.
* It will help ensured that the resizing logic reserves enough space for at
* least one max packet.
*/
static int cdns3_gadget_check_config(struct usb_gadget *gadget)
{
struct cdns3_device *priv_dev = gadget_to_cdns3_device(gadget);
struct usb_ep *ep;
int n_in = 0;
int total;
list_for_each_entry(ep, &gadget->ep_list, ep_list) {
if (ep->claimed && (ep->address & USB_DIR_IN))
n_in++;
}
/* 2KB are reserved for EP0, 1KB for out*/
total = 2 + n_in + 1;
if (total > priv_dev->onchip_buffers)
return -ENOMEM;
priv_dev->ep_buf_size = priv_dev->ep_iso_burst =
(priv_dev->onchip_buffers - 2) / (n_in + 1);
return 0;
}
static const struct usb_gadget_ops cdns3_gadget_ops = {
.get_frame = cdns3_gadget_get_frame,
.wakeup = cdns3_gadget_wakeup,
@ -2979,6 +3030,7 @@ static const struct usb_gadget_ops cdns3_gadget_ops = {
.udc_start = cdns3_gadget_udc_start,
.udc_stop = cdns3_gadget_udc_stop,
.match_ep = cdns3_gadget_match_ep,
.check_config = cdns3_gadget_check_config,
};
static void cdns3_free_all_eps(struct cdns3_device *priv_dev)

View File

@ -561,15 +561,18 @@ struct cdns3_usb_regs {
/* Max burst size (used only in SS mode). */
#define EP_CFG_MAXBURST_MASK GENMASK(11, 8)
#define EP_CFG_MAXBURST(p) (((p) << 8) & EP_CFG_MAXBURST_MASK)
#define EP_CFG_MAXBURST_MAX 15
/* ISO max burst. */
#define EP_CFG_MULT_MASK GENMASK(15, 14)
#define EP_CFG_MULT(p) (((p) << 14) & EP_CFG_MULT_MASK)
#define EP_CFG_MULT_MAX 2
/* ISO max burst. */
#define EP_CFG_MAXPKTSIZE_MASK GENMASK(26, 16)
#define EP_CFG_MAXPKTSIZE(p) (((p) << 16) & EP_CFG_MAXPKTSIZE_MASK)
/* Max number of buffered packets. */
#define EP_CFG_BUFFERING_MASK GENMASK(31, 27)
#define EP_CFG_BUFFERING(p) (((p) << 27) & EP_CFG_BUFFERING_MASK)
#define EP_CFG_BUFFERING_MAX 15
/* EP_CMD - bitmasks */
/* Endpoint reset. */
@ -1093,9 +1096,6 @@ struct cdns3_trb {
#define CDNS3_ENDPOINTS_MAX_COUNT 32
#define CDNS3_EP_ZLP_BUF_SIZE 1024
#define CDNS3_EP_BUF_SIZE 4 /* KB */
#define CDNS3_EP_ISO_HS_MULT 3
#define CDNS3_EP_ISO_SS_BURST 3
#define CDNS3_MAX_NUM_DESCMISS_BUF 32
#define CDNS3_DESCMIS_BUF_SIZE 2048 /* Bytes */
#define CDNS3_WA2_NUM_BUFFERS 128
@ -1330,6 +1330,9 @@ struct cdns3_device {
/*in KB */
u16 onchip_buffers;
u16 onchip_used_size;
u16 ep_buf_size;
u16 ep_iso_burst;
};
void cdns3_set_register_bit(void __iomem *ptr, u32 mask);

View File

@ -70,6 +70,10 @@ static const struct ci_hdrc_imx_platform_flag imx7ulp_usb_data = {
CI_HDRC_PMQOS,
};
static const struct ci_hdrc_imx_platform_flag imx8ulp_usb_data = {
.flags = CI_HDRC_SUPPORTS_RUNTIME_PM,
};
static const struct of_device_id ci_hdrc_imx_dt_ids[] = {
{ .compatible = "fsl,imx23-usb", .data = &imx23_usb_data},
{ .compatible = "fsl,imx28-usb", .data = &imx28_usb_data},
@ -80,6 +84,7 @@ static const struct of_device_id ci_hdrc_imx_dt_ids[] = {
{ .compatible = "fsl,imx6ul-usb", .data = &imx6ul_usb_data},
{ .compatible = "fsl,imx7d-usb", .data = &imx7d_usb_data},
{ .compatible = "fsl,imx7ulp-usb", .data = &imx7ulp_usb_data},
{ .compatible = "fsl,imx8ulp-usb", .data = &imx8ulp_usb_data},
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, ci_hdrc_imx_dt_ids);

View File

@ -135,7 +135,7 @@
#define TXVREFTUNE0_MASK (0xf << 20)
#define MX6_USB_OTG_WAKEUP_BITS (MX6_BM_WAKEUP_ENABLE | MX6_BM_VBUS_WAKEUP | \
MX6_BM_ID_WAKEUP)
MX6_BM_ID_WAKEUP | MX6SX_BM_DPDM_WAKEUP_EN)
struct usbmisc_ops {
/* It's called once when probe a usb device */

View File

@ -306,7 +306,16 @@ static void dwc3_qcom_interconnect_exit(struct dwc3_qcom *qcom)
/* Only usable in contexts where the role can not change. */
static bool dwc3_qcom_is_host(struct dwc3_qcom *qcom)
{
struct dwc3 *dwc = platform_get_drvdata(qcom->dwc3);
struct dwc3 *dwc;
/*
* FIXME: Fix this layering violation.
*/
dwc = platform_get_drvdata(qcom->dwc3);
/* Core driver may not have probed yet. */
if (!dwc)
return false;
return dwc->xhci;
}

View File

@ -915,8 +915,11 @@ static void __gs_console_push(struct gs_console *cons)
}
req->length = size;
spin_unlock_irq(&cons->lock);
if (usb_ep_queue(ep, req, GFP_ATOMIC))
req->length = 0;
spin_lock_irq(&cons->lock);
}
static void gs_console_work(struct work_struct *work)

View File

@ -518,7 +518,9 @@ static int mmphw_probe(struct platform_device *pdev)
ret = -ENOENT;
goto failed;
}
clk_prepare_enable(ctrl->clk);
ret = clk_prepare_enable(ctrl->clk);
if (ret)
goto failed;
/* init global regs */
ctrl_set_default(ctrl);

View File

@ -571,11 +571,9 @@ static void virtio_mmio_release_dev(struct device *_d)
{
struct virtio_device *vdev =
container_of(_d, struct virtio_device, dev);
struct virtio_mmio_device *vm_dev =
container_of(vdev, struct virtio_mmio_device, vdev);
struct platform_device *pdev = vm_dev->pdev;
struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vdev);
devm_kfree(&pdev->dev, vm_dev);
kfree(vm_dev);
}
/* Platform device */
@ -586,7 +584,7 @@ static int virtio_mmio_probe(struct platform_device *pdev)
unsigned long magic;
int rc;
vm_dev = devm_kzalloc(&pdev->dev, sizeof(*vm_dev), GFP_KERNEL);
vm_dev = kzalloc(sizeof(*vm_dev), GFP_KERNEL);
if (!vm_dev)
return -ENOMEM;

View File

@ -4459,8 +4459,7 @@ int btrfs_cancel_balance(struct btrfs_fs_info *fs_info)
}
}
BUG_ON(fs_info->balance_ctl ||
test_bit(BTRFS_FS_BALANCE_RUNNING, &fs_info->flags));
ASSERT(!test_bit(BTRFS_FS_BALANCE_RUNNING, &fs_info->flags));
atomic_dec(&fs_info->balance_cancel_req);
mutex_unlock(&fs_info->balance_mutex);
return 0;

View File

@ -4580,9 +4580,9 @@ static int cifs_readpage_worker(struct file *file, struct page *page,
io_error:
kunmap(page);
unlock_page(page);
read_complete:
unlock_page(page);
return rc;
}

View File

@ -1017,7 +1017,14 @@ static int gfs2_show_options(struct seq_file *s, struct dentry *root)
{
struct gfs2_sbd *sdp = root->d_sb->s_fs_info;
struct gfs2_args *args = &sdp->sd_args;
int val;
unsigned int logd_secs, statfs_slow, statfs_quantum, quota_quantum;
spin_lock(&sdp->sd_tune.gt_spin);
logd_secs = sdp->sd_tune.gt_logd_secs;
quota_quantum = sdp->sd_tune.gt_quota_quantum;
statfs_quantum = sdp->sd_tune.gt_statfs_quantum;
statfs_slow = sdp->sd_tune.gt_statfs_slow;
spin_unlock(&sdp->sd_tune.gt_spin);
if (is_ancestor(root, sdp->sd_master_dir))
seq_puts(s, ",meta");
@ -1072,17 +1079,14 @@ static int gfs2_show_options(struct seq_file *s, struct dentry *root)
}
if (args->ar_discard)
seq_puts(s, ",discard");
val = sdp->sd_tune.gt_logd_secs;
if (val != 30)
seq_printf(s, ",commit=%d", val);
val = sdp->sd_tune.gt_statfs_quantum;
if (val != 30)
seq_printf(s, ",statfs_quantum=%d", val);
else if (sdp->sd_tune.gt_statfs_slow)
if (logd_secs != 30)
seq_printf(s, ",commit=%d", logd_secs);
if (statfs_quantum != 30)
seq_printf(s, ",statfs_quantum=%d", statfs_quantum);
else if (statfs_slow)
seq_puts(s, ",statfs_quantum=0");
val = sdp->sd_tune.gt_quota_quantum;
if (val != 60)
seq_printf(s, ",quota_quantum=%d", val);
if (quota_quantum != 60)
seq_printf(s, ",quota_quantum=%d", quota_quantum);
if (args->ar_statfs_percent)
seq_printf(s, ",statfs_percent=%d", args->ar_statfs_percent);
if (args->ar_errors != GFS2_ERRORS_DEFAULT) {

View File

@ -2027,6 +2027,9 @@ dbAllocDmapLev(struct bmap * bmp,
if (dbFindLeaf((dmtree_t *) & dp->tree, l2nb, &leafidx))
return -ENOSPC;
if (leafidx < 0)
return -EIO;
/* determine the block number within the file system corresponding
* to the leaf at which free space was found.
*/

View File

@ -354,6 +354,11 @@ tid_t txBegin(struct super_block *sb, int flag)
jfs_info("txBegin: flag = 0x%x", flag);
log = JFS_SBI(sb)->log;
if (!log) {
jfs_error(sb, "read-only filesystem\n");
return 0;
}
TXN_LOCK();
INCREMENT(TxStat.txBegin);

View File

@ -798,6 +798,11 @@ static int jfs_link(struct dentry *old_dentry,
if (rc)
goto out;
if (isReadOnly(ip)) {
jfs_error(ip->i_sb, "read-only filesystem\n");
return -EROFS;
}
tid = txBegin(ip->i_sb, 0);
mutex_lock_nested(&JFS_IP(dir)->commit_mutex, COMMIT_MUTEX_PARENT);

View File

@ -31,6 +31,7 @@ struct ovl_sb {
};
struct ovl_layer {
/* ovl_free_fs() relies on @mnt being the first member! */
struct vfsmount *mnt;
/* Trap in ovl inode cache */
struct inode *trap;
@ -41,6 +42,14 @@ struct ovl_layer {
int fsid;
};
/*
* ovl_free_fs() relies on @mnt being the first member when unmounting
* the private mounts created for each layer. Let's check both the
* offset and type.
*/
static_assert(offsetof(struct ovl_layer, mnt) == 0);
static_assert(__same_type(typeof_member(struct ovl_layer, mnt), struct vfsmount *));
struct ovl_path {
const struct ovl_layer *layer;
struct dentry *dentry;

View File

@ -557,7 +557,7 @@ static void invalidate_dquots(struct super_block *sb, int type)
continue;
/* Wait for dquot users */
if (atomic_read(&dquot->dq_count)) {
dqgrab(dquot);
atomic_inc(&dquot->dq_count);
spin_unlock(&dq_list_lock);
/*
* Once dqput() wakes us up, we know it's time to free
@ -2415,7 +2415,8 @@ int dquot_load_quota_sb(struct super_block *sb, int type, int format_id,
error = add_dquot_ref(sb, type);
if (error)
dquot_disable(sb, type, flags);
dquot_disable(sb, type,
DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED);
return error;
out_fmt:

View File

@ -247,7 +247,7 @@ static int udf_name_from_CS0(struct super_block *sb,
}
if (translate) {
if (str_o_len <= 2 && str_o[0] == '.' &&
if (str_o_len > 0 && str_o_len <= 2 && str_o[0] == '.' &&
(str_o_len == 1 || str_o[1] == '.'))
needsCRC = 1;
if (needsCRC) {

View File

@ -0,0 +1,21 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _DT_BINDINGS_ADI_AD74413R_H
#define _DT_BINDINGS_ADI_AD74413R_H
#define CH_FUNC_HIGH_IMPEDANCE 0x0
#define CH_FUNC_VOLTAGE_OUTPUT 0x1
#define CH_FUNC_CURRENT_OUTPUT 0x2
#define CH_FUNC_VOLTAGE_INPUT 0x3
#define CH_FUNC_CURRENT_INPUT_EXT_POWER 0x4
#define CH_FUNC_CURRENT_INPUT_LOOP_POWER 0x5
#define CH_FUNC_RESISTANCE_INPUT 0x6
#define CH_FUNC_DIGITAL_INPUT_LOGIC 0x7
#define CH_FUNC_DIGITAL_INPUT_LOOP_POWER 0x8
#define CH_FUNC_CURRENT_INPUT_EXT_POWER_HART 0x9
#define CH_FUNC_CURRENT_INPUT_LOOP_POWER_HART 0xA
#define CH_FUNC_MIN CH_FUNC_HIGH_IMPEDANCE
#define CH_FUNC_MAX CH_FUNC_CURRENT_INPUT_LOOP_POWER_HART
#endif /* _DT_BINDINGS_ADI_AD74413R_H */

View File

@ -53,6 +53,7 @@
} \
if (__sleep_us) \
usleep_range((__sleep_us >> 2) + 1, __sleep_us); \
cpu_relax(); \
} \
(cond) ? 0 : -ETIMEDOUT; \
})
@ -95,6 +96,7 @@
} \
if (__delay_us) \
udelay(__delay_us); \
cpu_relax(); \
} \
(cond) ? 0 : -ETIMEDOUT; \
})

View File

@ -303,6 +303,7 @@ struct mhi_controller_config {
* @rddm_size: RAM dump size that host should allocate for debugging purpose
* @sbl_size: SBL image size downloaded through BHIe (optional)
* @seg_len: BHIe vector size (optional)
* @reg_len: Length of the MHI MMIO region (required)
* @fbc_image: Points to firmware image buffer
* @rddm_image: Points to RAM dump buffer
* @mhi_chan: Points to the channel configuration table
@ -383,6 +384,7 @@ struct mhi_controller {
size_t rddm_size;
size_t sbl_size;
size_t seg_len;
size_t reg_len;
struct image_info *fbc_image;
struct image_info *rddm_image;
struct mhi_chan *mhi_chan;

View File

@ -644,18 +644,22 @@ struct mlx5_pps {
u8 enabled;
};
struct mlx5_clock {
struct mlx5_nb pps_nb;
seqlock_t lock;
struct mlx5_timer {
struct cyclecounter cycles;
struct timecounter tc;
struct hwtstamp_config hwtstamp_config;
u32 nominal_c_mult;
unsigned long overflow_period;
struct delayed_work overflow_work;
};
struct mlx5_clock {
struct mlx5_nb pps_nb;
seqlock_t lock;
struct hwtstamp_config hwtstamp_config;
struct ptp_clock *ptp;
struct ptp_clock_info ptp_info;
struct mlx5_pps pps_info;
struct mlx5_timer timer;
};
struct mlx5_dm;

View File

@ -503,6 +503,7 @@ struct mmc_host {
struct device_node;
struct mmc_host *mmc_alloc_host(int extra, struct device *);
struct mmc_host *devm_mmc_alloc_host(struct device *dev, int extra);
int mmc_add_host(struct mmc_host *);
void mmc_remove_host(struct mmc_host *);
void mmc_free_host(struct mmc_host *);

View File

@ -71,6 +71,23 @@ struct unwind_hint {
static void __used __section(".discard.func_stack_frame_non_standard") \
*__func_stack_frame_non_standard_##func = func
/*
* STACK_FRAME_NON_STANDARD_FP() is a frame-pointer-specific function ignore
* for the case where a function is intentionally missing frame pointer setup,
* but otherwise needs objtool/ORC coverage when frame pointers are disabled.
*/
#ifdef CONFIG_FRAME_POINTER
#define STACK_FRAME_NON_STANDARD_FP(func) STACK_FRAME_NON_STANDARD(func)
#else
#define STACK_FRAME_NON_STANDARD_FP(func)
#endif
#define ANNOTATE_NOENDBR \
"986: \n\t" \
".pushsection .discard.noendbr\n\t" \
_ASM_PTR " 986b\n\t" \
".popsection\n\t"
#else /* __ASSEMBLY__ */
/*
@ -117,6 +134,13 @@ struct unwind_hint {
.popsection
.endm
.macro ANNOTATE_NOENDBR
.Lhere_\@:
.pushsection .discard.noendbr
.quad .Lhere_\@
.popsection
.endm
#endif /* __ASSEMBLY__ */
#else /* !CONFIG_STACK_VALIDATION */
@ -126,10 +150,14 @@ struct unwind_hint {
#define UNWIND_HINT(sp_reg, sp_offset, type, end) \
"\n\t"
#define STACK_FRAME_NON_STANDARD(func)
#define STACK_FRAME_NON_STANDARD_FP(func)
#define ANNOTATE_NOENDBR
#else
#define ANNOTATE_INTRA_FUNCTION_CALL
.macro UNWIND_HINT type:req sp_reg=0 sp_offset=0 end=0
.endm
.macro ANNOTATE_NOENDBR
.endm
#endif
#endif /* CONFIG_STACK_VALIDATION */

View File

@ -148,6 +148,10 @@ static inline int virtio_net_hdr_to_skb(struct sk_buff *skb,
if (gso_type & SKB_GSO_UDP)
nh_off -= thlen;
/* Kernel has a special handling for GSO_BY_FRAGS. */
if (gso_size == GSO_BY_FRAGS)
return -EINVAL;
/* Too small packets are not really GSO ones. */
if (skb->len - nh_off > gso_size) {
shinfo->gso_size = gso_size;

View File

@ -588,7 +588,14 @@ void v4l2_m2m_buf_queue(struct v4l2_m2m_ctx *m2m_ctx,
static inline
unsigned int v4l2_m2m_num_src_bufs_ready(struct v4l2_m2m_ctx *m2m_ctx)
{
return m2m_ctx->out_q_ctx.num_rdy;
unsigned int num_buf_rdy;
unsigned long flags;
spin_lock_irqsave(&m2m_ctx->out_q_ctx.rdy_spinlock, flags);
num_buf_rdy = m2m_ctx->out_q_ctx.num_rdy;
spin_unlock_irqrestore(&m2m_ctx->out_q_ctx.rdy_spinlock, flags);
return num_buf_rdy;
}
/**
@ -600,7 +607,14 @@ unsigned int v4l2_m2m_num_src_bufs_ready(struct v4l2_m2m_ctx *m2m_ctx)
static inline
unsigned int v4l2_m2m_num_dst_bufs_ready(struct v4l2_m2m_ctx *m2m_ctx)
{
return m2m_ctx->cap_q_ctx.num_rdy;
unsigned int num_buf_rdy;
unsigned long flags;
spin_lock_irqsave(&m2m_ctx->cap_q_ctx.rdy_spinlock, flags);
num_buf_rdy = m2m_ctx->cap_q_ctx.num_rdy;
spin_unlock_irqrestore(&m2m_ctx->cap_q_ctx.rdy_spinlock, flags);
return num_buf_rdy;
}
/**

View File

@ -1361,6 +1361,12 @@ static inline bool sk_has_memory_pressure(const struct sock *sk)
return sk->sk_prot->memory_pressure != NULL;
}
static inline bool sk_under_global_memory_pressure(const struct sock *sk)
{
return sk->sk_prot->memory_pressure &&
!!*sk->sk_prot->memory_pressure;
}
static inline bool sk_under_memory_pressure(const struct sock *sk)
{
if (!sk->sk_prot->memory_pressure)

View File

@ -43,13 +43,13 @@ void *dma_common_contiguous_remap(struct page *page, size_t size,
void *vaddr;
int i;
pages = kmalloc_array(count, sizeof(struct page *), GFP_KERNEL);
pages = kvmalloc_array(count, sizeof(struct page *), GFP_KERNEL);
if (!pages)
return NULL;
for (i = 0; i < count; i++)
pages[i] = nth_page(page, i);
vaddr = vmap(pages, count, VM_DMA_COHERENT, prot);
kfree(pages);
kvfree(pages);
return vaddr;
}

View File

@ -541,6 +541,7 @@ struct trace_buffer {
unsigned flags;
int cpus;
atomic_t record_disabled;
atomic_t resizing;
cpumask_var_t cpumask;
struct lock_class_key *reader_lock_key;
@ -2041,7 +2042,7 @@ int ring_buffer_resize(struct trace_buffer *buffer, unsigned long size,
/* prevent another thread from changing buffer sizes */
mutex_lock(&buffer->mutex);
atomic_inc(&buffer->resizing);
if (cpu_id == RING_BUFFER_ALL_CPUS) {
/*
@ -2184,6 +2185,7 @@ int ring_buffer_resize(struct trace_buffer *buffer, unsigned long size,
atomic_dec(&buffer->record_disabled);
}
atomic_dec(&buffer->resizing);
mutex_unlock(&buffer->mutex);
return 0;
@ -2204,6 +2206,7 @@ int ring_buffer_resize(struct trace_buffer *buffer, unsigned long size,
}
}
out_err_unlock:
atomic_dec(&buffer->resizing);
mutex_unlock(&buffer->mutex);
return err;
}
@ -5253,6 +5256,15 @@ int ring_buffer_swap_cpu(struct trace_buffer *buffer_a,
if (local_read(&cpu_buffer_b->committing))
goto out_dec;
/*
* When resize is in progress, we cannot swap it because
* it will mess the state of the cpu buffer.
*/
if (atomic_read(&buffer_a->resizing))
goto out_dec;
if (atomic_read(&buffer_b->resizing))
goto out_dec;
buffer_a->buffers[cpu] = cpu_buffer_b;
buffer_b->buffers[cpu] = cpu_buffer_a;

View File

@ -1883,9 +1883,10 @@ update_max_tr_single(struct trace_array *tr, struct task_struct *tsk, int cpu)
* place on this CPU. We fail to record, but we reset
* the max trace buffer (no one writes directly to it)
* and flag that it failed.
* Another reason is resize is in progress.
*/
trace_array_printk_buf(tr->max_buffer.buffer, _THIS_IP_,
"Failed to swap buffers due to commit in progress\n");
"Failed to swap buffers due to commit or resize in progress\n");
}
WARN_ON_ONCE(ret && ret != -EAGAIN && ret != -EBUSY);

View File

@ -1332,9 +1332,10 @@ probe_mem_read(void *dest, void *src, size_t size)
/* Note that we don't verify it, since the code does not come from user space */
static int
process_fetch_insn(struct fetch_insn *code, struct pt_regs *regs, void *dest,
process_fetch_insn(struct fetch_insn *code, void *rec, void *dest,
void *base)
{
struct pt_regs *regs = rec;
unsigned long val;
retry:

View File

@ -54,7 +54,7 @@ fetch_apply_bitfield(struct fetch_insn *code, void *buf)
* If dest is NULL, don't store result and return required dynamic data size.
*/
static int
process_fetch_insn(struct fetch_insn *code, struct pt_regs *regs,
process_fetch_insn(struct fetch_insn *code, void *rec,
void *dest, void *base);
static nokprobe_inline int fetch_store_strlen(unsigned long addr);
static nokprobe_inline int
@ -190,7 +190,7 @@ __get_data_size(struct trace_probe *tp, struct pt_regs *regs)
/* Store the value of each argument */
static nokprobe_inline void
store_trace_args(void *data, struct trace_probe *tp, struct pt_regs *regs,
store_trace_args(void *data, struct trace_probe *tp, void *rec,
int header_size, int maxlen)
{
struct probe_arg *arg;
@ -205,12 +205,14 @@ store_trace_args(void *data, struct trace_probe *tp, struct pt_regs *regs,
/* Point the dynamic data area if needed */
if (unlikely(arg->dynamic))
*dl = make_data_loc(maxlen, dyndata - base);
ret = process_fetch_insn(arg->code, regs, dl, base);
if (unlikely(ret < 0 && arg->dynamic)) {
*dl = make_data_loc(0, dyndata - base);
} else {
dyndata += ret;
maxlen -= ret;
ret = process_fetch_insn(arg->code, rec, dl, base);
if (arg->dynamic) {
if (unlikely(ret < 0)) {
*dl = make_data_loc(0, dyndata - base);
} else {
dyndata += ret;
maxlen -= ret;
}
}
}
}

View File

@ -217,9 +217,10 @@ static unsigned long translate_user_vaddr(unsigned long file_offset)
/* Note that we don't verify it, since the code does not come from user space */
static int
process_fetch_insn(struct fetch_insn *code, struct pt_regs *regs, void *dest,
process_fetch_insn(struct fetch_insn *code, void *rec, void *dest,
void *base)
{
struct pt_regs *regs = rec;
unsigned long val;
/* 1st stage: get value from context */

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