ASoC: Updates for v6.6

Here's an initial batch of updates for ASoC for this release cycle.
 We've got a bunch of new drivers in here, a bit of core work from
 Morimoto-san and quite a lot of janitorial work.  There's several
 updates that pull in changes from other subsystems in order to build
 on them:
 
  - An adaptor to allow use of IIO DACs and ADCs in ASoC which pulls in
    some IIO changes.
  - Create a library function for intlog10() and use it in the NAU8825
    driver.
  - Include the ASoC tests, including the topology tests, in the default
    KUnit full test coverage.  This also involves enabling UML builds of
    ALSA since that's the default KUnit test environment which pulls in
    the addition of some stubs to the driver.
  - More factoring out from Morimoto-san.
  - Convert a lot of drivers to use the more modern maple tree register
    cache.
  - Support for AMD machines with MAX98388 and NAU8821, Cirrus Logic
    CS35L36, Intel AVS machines with ES8336 and RT5663 and NXP i.MX93.
 -----BEGIN PGP SIGNATURE-----
 
 iQEzBAABCgAdFiEEreZoqmdXGLWf4p/qJNaLcl1Uh9AFAmS/t9MACgkQJNaLcl1U
 h9Dg4wf+Njvy5zphgUJlSJ7vNj7GtzgldnWwfQrb+19BOtv5HHIYg4e/Yr4eWdgc
 rg5DGIGvr8sxYQ44TCA59sXdTuakkNF/ejDoj8AwNsr/J3sD6S+FTkV8qLFcgQ3r
 +0ElZ26I2kd6gfvDlwHfa5rJVPCa7vrg3o6EHccqRX9CSyPJRlwRqRRj+w8ftZtV
 rZ7Gapz3E4A3mBo7VIO/kEgI1uSmaShM8d4HoVmxJEKJ6lbyX8SIXMBzZVq5z/iX
 DcnRaMPAMhgzytmdDJ7SjJuxL0EOd6p8Lnk0jILvO6U30Z7aTunzMuK/o0GHqFkm
 eHveoHIU4gbt3YqDFgPosPlxi4OCgw==
 =KJZq
 -----END PGP SIGNATURE-----

Merge tag 'asoc-v6.6-early' of https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-next

ASoC: Updates for v6.6

Here's an initial batch of updates for ASoC for this release cycle.
We've got a bunch of new drivers in here, a bit of core work from
Morimoto-san and quite a lot of janitorial work.  There's several
updates that pull in changes from other subsystems in order to build
on them:

 - An adaptor to allow use of IIO DACs and ADCs in ASoC which pulls in
   some IIO changes.
 - Create a library function for intlog10() and use it in the NAU8825
   driver.
 - Include the ASoC tests, including the topology tests, in the default
   KUnit full test coverage.  This also involves enabling UML builds of
   ALSA since that's the default KUnit test environment which pulls in
   the addition of some stubs to the driver.
 - More factoring out from Morimoto-san.
 - Convert a lot of drivers to use the more modern maple tree register
   cache.
 - Support for AMD machines with MAX98388 and NAU8821, Cirrus Logic
   CS35L36, Intel AVS machines with ES8336 and RT5663 and NXP i.MX93.
This commit is contained in:
Takashi Iwai 2023-07-25 14:06:08 +02:00
commit a32e0834df
544 changed files with 9493 additions and 4050 deletions

View file

@ -241,6 +241,7 @@ Jisheng Zhang <jszhang@kernel.org> <Jisheng.Zhang@synaptics.com>
Johan Hovold <johan@kernel.org> <jhovold@gmail.com>
Johan Hovold <johan@kernel.org> <johan@hovoldconsulting.com>
John Crispin <john@phrozen.org> <blogic@openwrt.org>
John Fastabend <john.fastabend@gmail.com> <john.r.fastabend@intel.com>
John Keeping <john@keeping.me.uk> <john@metanate.com>
John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
John Stultz <johnstul@us.ibm.com>
@ -454,6 +455,8 @@ Sebastian Reichel <sre@kernel.org> <sre@debian.org>
Sedat Dilek <sedat.dilek@gmail.com> <sedat.dilek@credativ.de>
Seth Forshee <sforshee@kernel.org> <seth.forshee@canonical.com>
Shannon Nelson <shannon.nelson@amd.com> <snelson@pensando.io>
Shannon Nelson <shannon.nelson@amd.com> <shannon.nelson@intel.com>
Shannon Nelson <shannon.nelson@amd.com> <shannon.nelson@oracle.com>
Shiraz Hashim <shiraz.linux.kernel@gmail.com> <shiraz.hashim@st.com>
Shuah Khan <shuah@kernel.org> <shuahkhan@gmail.com>
Shuah Khan <shuah@kernel.org> <shuah.khan@hp.com>

View file

@ -162,8 +162,11 @@ Base 2 log and power Functions
.. kernel-doc:: include/linux/log2.h
:internal:
Integer power Functions
-----------------------
Integer log and power Functions
-------------------------------
.. kernel-doc:: include/linux/int_log.h
:export:
.. kernel-doc:: lib/math/int_pow.c
:export:

View file

@ -105,7 +105,7 @@ properties:
G coefficient for temperature equation.
Default for series 5 = 60000
Default for series 6 = 57400
multipleOf: 1000
multipleOf: 100
minimum: 1000
$ref: /schemas/types.yaml#/definitions/uint32
@ -114,7 +114,7 @@ properties:
H coefficient for temperature equation.
Default for series 5 = 200000
Default for series 6 = 249400
multipleOf: 1000
multipleOf: 100
minimum: 1000
$ref: /schemas/types.yaml#/definitions/uint32
@ -131,7 +131,7 @@ properties:
J coefficient for temperature equation.
Default for series 5 = -100
Default for series 6 = 0
multipleOf: 1000
multipleOf: 100
maximum: 0
$ref: /schemas/types.yaml#/definitions/int32

View file

@ -1,19 +0,0 @@
* Universal Asynchronous Receiver/Transmitter (UART)
- compatible: "cavium,octeon-3860-uart"
Compatibility with all cn3XXX, cn5XXX and cn6XXX SOCs.
- reg: The base address of the UART register bank.
- interrupts: A single interrupt specifier.
- current-speed: Optional, the current bit rate in bits per second.
Example:
uart1: serial@1180000000c00 {
compatible = "cavium,octeon-3860-uart","ns16550";
reg = <0x11800 0x00000c00 0x0 0x400>;
current-speed = <115200>;
interrupts = <0 35>;
};

View file

@ -1,28 +0,0 @@
* NXP LPC1850 UART
Required properties:
- compatible : "nxp,lpc1850-uart", "ns16550a".
- reg : offset and length of the register set for the device.
- interrupts : should contain uart interrupt.
- clocks : phandle to the input clocks.
- clock-names : required elements: "uartclk", "reg".
Optional properties:
- dmas : Two or more DMA channel specifiers following the
convention outlined in bindings/dma/dma.txt
- dma-names : Names for the dma channels, if present. There must
be at least one channel named "tx" for transmit
and named "rx" for receive.
Since it's also possible to also use the of_serial.c driver all
parameters from 8250.txt also apply but are optional.
Example:
uart0: serial@40081000 {
compatible = "nxp,lpc1850-uart", "ns16550a";
reg = <0x40081000 0x1000>;
reg-shift = <2>;
interrupts = <24>;
clocks = <&ccu2 CLK_APB0_UART0>, <&ccu1 CLK_CPU_UART0>;
clock-names = "uartclk", "reg";
};

View file

@ -39,22 +39,4 @@ required:
additionalProperties: false
examples:
- |
sound {
compatible = "audio-graph-card2";
links = <&cpu_port>;
};
cpu {
compatible = "cpu-driver";
cpu_port: port { cpu_ep: endpoint { remote-endpoint = <&codec_ep>; }; };
};
codec {
compatible = "codec-driver";
port { codec_ep: endpoint { remote-endpoint = <&cpu_ep>; }; };
};
...

View file

@ -0,0 +1,64 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/sound/audio-iio-aux.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Audio IIO auxiliary
maintainers:
- Herve Codina <herve.codina@bootlin.com>
description:
Auxiliary device based on Industrial I/O device channels
allOf:
- $ref: dai-common.yaml#
properties:
compatible:
const: audio-iio-aux
io-channels:
description:
Industrial I/O device channels used
io-channel-names:
description:
Industrial I/O channel names related to io-channels.
These names are used to provides sound controls, widgets and routes names.
snd-control-invert-range:
$ref: /schemas/types.yaml#/definitions/uint32-array
description: |
A list of 0/1 flags defining whether or not the related channel is
inverted
items:
enum: [0, 1]
default: 0
description: |
Invert the sound control value compared to the IIO channel raw value.
- 1: The related sound control value is inverted meaning that the
minimum sound control value correspond to the maximum IIO channel
raw value and the maximum sound control value correspond to the
minimum IIO channel raw value.
- 0: The related sound control value is not inverted meaning that the
minimum (resp maximum) sound control value correspond to the
minimum (resp maximum) IIO channel raw value.
required:
- compatible
- io-channels
- io-channel-names
unevaluatedProperties: false
examples:
- |
iio-aux {
compatible = "audio-iio-aux";
io-channels = <&iio 0>, <&iio 1>, <&iio 2>, <&iio 3>;
io-channel-names = "CH0", "CH1", "CH2", "CH3";
/* Invert CH1 and CH2 */
snd-control-invert-range = <0 1 1 0>;
};

View file

@ -25,6 +25,7 @@ properties:
- fsl,imx8mm-rpmsg-audio
- fsl,imx8mp-rpmsg-audio
- fsl,imx8ulp-rpmsg-audio
- fsl,imx93-rpmsg-audio
model:
$ref: /schemas/types.yaml#/definitions/string

View file

@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
title: Google SC7180-Trogdor ASoC sound card driver
maintainers:
- Rohit kumar <rohitkr@codeaurora.org>
- Rohit kumar <quic_rohkumar@quicinc.com>
- Cheng-Yi Chiang <cychiang@chromium.org>
description:

View file

@ -25,6 +25,12 @@ properties:
reset-names:
const: audiosys
memory-region:
maxItems: 1
description: |
Shared memory region for AFE memif. A "shared-dma-pool".
See ../reserved-memory/reserved-memory.yaml for details.
mediatek,topckgen:
$ref: /schemas/types.yaml#/definitions/phandle
description: The phandle of the mediatek topckgen controller
@ -176,6 +182,7 @@ examples:
interrupts = <GIC_SPI 822 IRQ_TYPE_LEVEL_HIGH 0>;
resets = <&watchdog 14>;
reset-names = "audiosys";
memory-region = <&snd_dma_mem_reserved>;
mediatek,topckgen = <&topckgen>;
mediatek,infracfg = <&infracfg_ao>;
power-domains = <&spm 13>; //MT8188_POWER_DOMAIN_AUDIO

View file

@ -1,55 +0,0 @@
Nuvoton NAU88L21 audio codec
This device supports I2C only.
Required properties:
- compatible : Must be "nuvoton,nau8821"
- reg : the I2C address of the device. This is either 0x1B (CSB=0) or 0x54 (CSB=1).
Optional properties:
- nuvoton,jkdet-enable: Enable jack detection via JKDET pin.
- nuvoton,jkdet-pull-enable: Enable JKDET pin pull. If set - pin pull enabled,
otherwise pin in high impedance state.
- nuvoton,jkdet-pull-up: Pull-up JKDET pin. If set then JKDET pin is pull up, otherwise pull down.
- nuvoton,jkdet-polarity: JKDET pin polarity. 0 - active high, 1 - active low.
- nuvoton,vref-impedance: VREF Impedance selection
0 - Open
1 - 25 kOhm
2 - 125 kOhm
3 - 2.5 kOhm
- nuvoton,micbias-voltage: Micbias voltage level.
0 - VDDA
1 - VDDA
2 - VDDA * 1.1
3 - VDDA * 1.2
4 - VDDA * 1.3
5 - VDDA * 1.4
6 - VDDA * 1.53
7 - VDDA * 1.53
- nuvoton,jack-insert-debounce: number from 0 to 7 that sets debounce time to 2^(n+2) ms
- nuvoton,jack-eject-debounce: number from 0 to 7 that sets debounce time to 2^(n+2) ms
- nuvoton,dmic-clk-threshold: the ADC threshold of DMIC clock.
- nuvoton,key_enable: Headset button detection switch.
Example:
headset: nau8821@1b {
compatible = "nuvoton,nau8821";
reg = <0x1b>;
interrupt-parent = <&gpio>;
interrupts = <23 IRQ_TYPE_LEVEL_LOW>;
nuvoton,jkdet-enable;
nuvoton,jkdet-pull-enable;
nuvoton,jkdet-pull-up;
nuvoton,jkdet-polarity = <GPIO_ACTIVE_LOW>;
nuvoton,vref-impedance = <2>;
nuvoton,micbias-voltage = <6>;
nuvoton,jack-insert-debounce = <7>;
nuvoton,jack-eject-debounce = <7>;
nuvoton,dmic-clk-threshold = 3072000;
};

View file

@ -0,0 +1,125 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/sound/nuvoton,nau8821.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: NAU88L21 audio codec
maintainers:
- Seven Lee <wtli@nuvoton.com>
allOf:
- $ref: dai-common.yaml#
properties:
compatible:
const: nuvoton,nau8821
reg:
maxItems: 1
interrupts:
maxItems: 1
nuvoton,jkdet-enable:
description: Enable jack detection via JKDET pin.
type: boolean
nuvoton,jkdet-pull-enable:
description: Enable JKDET pin pull. If set - pin pull enabled,
otherwise pin in high impedance state.
type: boolean
nuvoton,jkdet-pull-up:
description: Pull-up JKDET pin. If set then JKDET pin is pull up,
otherwise pull down.
type: boolean
nuvoton,key-enable:
description: handles key press detection.
type: boolean
nuvoton,jkdet-polarity:
description: JKDET pin polarity.
$ref: /schemas/types.yaml#/definitions/uint32
enum:
- 0 # active high
- 1 # active low
default: 1
nuvoton,micbias-voltage:
description: MICBIAS output level select.
$ref: /schemas/types.yaml#/definitions/uint32
enum:
- 0 # VDDA
- 1 # VDDA * 1
- 2 # VDDA * 1.1
- 3 # VDDA * 1.2
- 4 # VDDA * 1.3
- 5 # VDDA * 1.4
- 6 # VDDA * 1.53
- 7 # VDDA * 1.53
default: 6
nuvoton,vref-impedance:
description: VMID Tie-off impedance select.
$ref: /schemas/types.yaml#/definitions/uint32
enum:
- 0 # open
- 1 # 25KOhms
- 2 # 125KOhms
- 3 # 2.5KOhms
default: 2
nuvoton,jack-insert-debounce:
description: number from 0 to 7 that sets debounce time to 2^(n+2)ms.
$ref: /schemas/types.yaml#/definitions/uint32
maximum: 7
default: 7
nuvoton,jack-eject-debounce:
description: number from 0 to 7 that sets debounce time to 2^(n+2)ms.
$ref: /schemas/types.yaml#/definitions/uint32
maximum: 7
default: 0
nuvoton,dmic-clk-threshold:
description: DMIC clock speed expected value. Unit is Hz.
$ref: /schemas/types.yaml#/definitions/uint32
default: 3072000
'#sound-dai-cells':
const: 0
required:
- compatible
- reg
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/irq.h>
i2c {
#address-cells = <1>;
#size-cells = <0>;
codec@1b {
compatible = "nuvoton,nau8821";
reg = <0x1b>;
interrupt-parent = <&gpio>;
interrupts = <23 IRQ_TYPE_LEVEL_LOW>;
nuvoton,jkdet-enable;
nuvoton,jkdet-pull-enable;
nuvoton,jkdet-pull-up;
nuvoton,key-enable;
nuvoton,jkdet-polarity = <GPIO_ACTIVE_LOW>;
nuvoton,micbias-voltage = <6>;
nuvoton,vref-impedance = <2>;
nuvoton,jack-insert-debounce = <7>;
nuvoton,jack-eject-debounce = <0>;
nuvoton,dmic-clk-threshold = <3072000>;
#sound-dai-cells = <0>;
};
};

View file

@ -21,6 +21,15 @@ properties:
reg:
maxItems: 1
"#sound-dai-cells":
const: 0
clocks:
maxItems: 1
clock-names:
const: mclk
nuvoton,spk-btl:
description:
If set, configure the two loudspeaker outputs as a Bridge Tied Load output
@ -31,6 +40,9 @@ required:
- compatible
- reg
allOf:
- $ref: dai-common.yaml#
additionalProperties: false
examples:

View file

@ -8,7 +8,7 @@ title: Qualcomm Technologies Inc. LPASS CPU dai driver
maintainers:
- Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
- Rohit kumar <rohitkr@codeaurora.org>
- Rohit kumar <quic_rohkumar@quicinc.com>
description: |
Qualcomm Technologies Inc. SOC Low-Power Audio SubSystem (LPASS) that consist

View file

@ -1,101 +0,0 @@
msm8916 analog audio CODEC
Bindings for codec Analog IP which is integrated in pmic pm8916,
## Bindings for codec core on pmic:
Required properties
- compatible = "qcom,pm8916-wcd-analog-codec";
- reg: represents the slave base address provided to the peripheral.
- interrupts: List of interrupts in given SPMI peripheral.
- interrupt-names: Names specified to above list of interrupts in same
order. List of supported interrupt names are:
"cdc_spk_cnp_int" - Speaker click and pop interrupt.
"cdc_spk_clip_int" - Speaker clip interrupt.
"cdc_spk_ocp_int" - Speaker over current protect interrupt.
"mbhc_ins_rem_det1" - jack insert removal detect interrupt 1.
"mbhc_but_rel_det" - button release interrupt.
"mbhc_but_press_det" - button press event
"mbhc_ins_rem_det" - jack insert removal detect interrupt.
"mbhc_switch_int" - multi button headset interrupt.
"cdc_ear_ocp_int" - Earphone over current protect interrupt.
"cdc_hphr_ocp_int" - Headphone R over current protect interrupt.
"cdc_hphl_ocp_det" - Headphone L over current protect interrupt.
"cdc_ear_cnp_int" - earphone cnp interrupt.
"cdc_hphr_cnp_int" - hphr click and pop interrupt.
"cdc_hphl_cnp_int" - hphl click and pop interrupt.
- clocks: Handle to mclk.
- clock-names: should be "mclk"
- vdd-cdc-io-supply: phandle to VDD_CDC_IO regulator DT node.
- vdd-cdc-tx-rx-cx-supply: phandle to VDD_CDC_TX/RX/CX regulator DT node.
- vdd-micbias-supply: phandle of VDD_MICBIAS supply's regulator DT node.
Optional Properties:
- qcom,mbhc-vthreshold-low: Array of 5 threshold voltages in mV for 5 buttons
detection on headset when the mbhc is powered up
by internal current source, this is a low power.
- qcom,mbhc-vthreshold-high: Array of 5 thresold voltages in mV for 5 buttons
detection on headset when mbhc is powered up
from micbias.
- qcom,micbias-lvl: Voltage (mV) for Mic Bias
- qcom,hphl-jack-type-normally-open: boolean, present if hphl pin on jack is a
NO (Normally Open). If not specified, then
its assumed that hphl pin on jack is NC
(Normally Closed).
- qcom,gnd-jack-type-normally-open: boolean, present if gnd pin on jack is
NO (Normally Open). If not specified, then
its assumed that gnd pin on jack is NC
(Normally Closed).
- qcom,micbias1-ext-cap: boolean, present if micbias1 has external capacitor
connected.
- qcom,micbias2-ext-cap: boolean, present if micbias2 has external capacitor
connected.
Example:
spmi_bus {
...
audio-codec@f000{
compatible = "qcom,pm8916-wcd-analog-codec";
reg = <0xf000 0x200>;
reg-names = "pmic-codec-core";
clocks = <&gcc GCC_CODEC_DIGCODEC_CLK>;
clock-names = "mclk";
qcom,mbhc-vthreshold-low = <75 150 237 450 500>;
qcom,mbhc-vthreshold-high = <75 150 237 450 500>;
interrupt-parent = <&spmi_bus>;
interrupts = <0x1 0xf0 0x0 IRQ_TYPE_NONE>,
<0x1 0xf0 0x1 IRQ_TYPE_NONE>,
<0x1 0xf0 0x2 IRQ_TYPE_NONE>,
<0x1 0xf0 0x3 IRQ_TYPE_NONE>,
<0x1 0xf0 0x4 IRQ_TYPE_NONE>,
<0x1 0xf0 0x5 IRQ_TYPE_NONE>,
<0x1 0xf0 0x6 IRQ_TYPE_NONE>,
<0x1 0xf0 0x7 IRQ_TYPE_NONE>,
<0x1 0xf1 0x0 IRQ_TYPE_NONE>,
<0x1 0xf1 0x1 IRQ_TYPE_NONE>,
<0x1 0xf1 0x2 IRQ_TYPE_NONE>,
<0x1 0xf1 0x3 IRQ_TYPE_NONE>,
<0x1 0xf1 0x4 IRQ_TYPE_NONE>,
<0x1 0xf1 0x5 IRQ_TYPE_NONE>;
interrupt-names = "cdc_spk_cnp_int",
"cdc_spk_clip_int",
"cdc_spk_ocp_int",
"mbhc_ins_rem_det1",
"mbhc_but_rel_det",
"mbhc_but_press_det",
"mbhc_ins_rem_det",
"mbhc_switch_int",
"cdc_ear_ocp_int",
"cdc_hphr_ocp_int",
"cdc_hphl_ocp_det",
"cdc_ear_cnp_int",
"cdc_hphr_cnp_int",
"cdc_hphl_cnp_int";
vdd-cdc-io-supply = <&pm8916_l5>;
vdd-cdc-tx-rx-cx-supply = <&pm8916_l5>;
vdd-micbias-supply = <&pm8916_l13>;
#sound-dai-cells = <1>;
};
};

View file

@ -0,0 +1,153 @@
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/sound/qcom,pm8916-wcd-analog-codec.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm PM8916 WCD Analog Audio Codec
maintainers:
- Konrad Dybcio <konradybcio@kernel.org>
description:
The analog WCD audio codec found on Qualcomm PM8916 PMIC.
properties:
compatible:
const: qcom,pm8916-wcd-analog-codec
reg:
maxItems: 1
interrupts:
maxItems: 14
interrupt-names:
items:
- const: cdc_spk_cnp_int
- const: cdc_spk_clip_int
- const: cdc_spk_ocp_int
- const: mbhc_ins_rem_det1
- const: mbhc_but_rel_det
- const: mbhc_but_press_det
- const: mbhc_ins_rem_det
- const: mbhc_switch_int
- const: cdc_ear_ocp_int
- const: cdc_hphr_ocp_int
- const: cdc_hphl_ocp_det
- const: cdc_ear_cnp_int
- const: cdc_hphr_cnp_int
- const: cdc_hphl_cnp_int
vdd-cdc-io-supply:
description: 1.8V buck supply
vdd-cdc-tx-rx-cx-supply:
description: 1.8V SIDO buck supply
vdd-micbias-supply:
description: micbias supply
qcom,mbhc-vthreshold-low:
$ref: /schemas/types.yaml#/definitions/uint32-array
description:
Array of 5 threshold voltages in mV for 5-button detection on
headset when MBHC is powered by an internal current source.
minItems: 5
maxItems: 5
qcom,mbhc-vthreshold-high:
$ref: /schemas/types.yaml#/definitions/uint32-array
description:
Array of 5 threshold voltages in mV for 5-button detection on
headset when MBHC is powered from micbias.
minItems: 5
maxItems: 5
qcom,micbias-lvl:
$ref: /schemas/types.yaml#/definitions/uint32
description:
Voltage (mV) for Mic Bias
qcom,hphl-jack-type-normally-open:
type: boolean
description:
True if the HPHL pin on the jack is NO (Normally Open), false if it's
NC (Normally Closed).
qcom,gnd-jack-type-normally-open:
type: boolean
description:
True if the GND pin on the jack is NO (Normally Open), false if it's
NC (Normally Closed).
qcom,micbias1-ext-cap:
type: boolean
description:
True if micbias1 has an external capacitor.
qcom,micbias2-ext-cap:
type: boolean
description:
True if micbias2 has an external capacitor.
"#sound-dai-cells":
const: 1
required:
- compatible
- reg
additionalProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/spmi/spmi.h>
pmic@1 {
compatible = "qcom,pm8916", "qcom,spmi-pmic";
reg = <0x1 SPMI_USID>;
#address-cells = <1>;
#size-cells = <0>;
audio-codec@f000 {
compatible = "qcom,pm8916-wcd-analog-codec";
reg = <0xf000>;
qcom,mbhc-vthreshold-low = <75 150 237 450 500>;
qcom,mbhc-vthreshold-high = <75 150 237 450 500>;
interrupt-parent = <&spmi_bus>;
interrupts = <0x1 0xf0 0x0 IRQ_TYPE_NONE>,
<0x1 0xf0 0x1 IRQ_TYPE_NONE>,
<0x1 0xf0 0x2 IRQ_TYPE_NONE>,
<0x1 0xf0 0x3 IRQ_TYPE_NONE>,
<0x1 0xf0 0x4 IRQ_TYPE_NONE>,
<0x1 0xf0 0x5 IRQ_TYPE_NONE>,
<0x1 0xf0 0x6 IRQ_TYPE_NONE>,
<0x1 0xf0 0x7 IRQ_TYPE_NONE>,
<0x1 0xf1 0x0 IRQ_TYPE_NONE>,
<0x1 0xf1 0x1 IRQ_TYPE_NONE>,
<0x1 0xf1 0x2 IRQ_TYPE_NONE>,
<0x1 0xf1 0x3 IRQ_TYPE_NONE>,
<0x1 0xf1 0x4 IRQ_TYPE_NONE>,
<0x1 0xf1 0x5 IRQ_TYPE_NONE>;
interrupt-names = "cdc_spk_cnp_int",
"cdc_spk_clip_int",
"cdc_spk_ocp_int",
"mbhc_ins_rem_det1",
"mbhc_but_rel_det",
"mbhc_but_press_det",
"mbhc_ins_rem_det",
"mbhc_switch_int",
"cdc_ear_ocp_int",
"cdc_hphr_ocp_int",
"cdc_hphl_ocp_det",
"cdc_ear_cnp_int",
"cdc_hphr_cnp_int",
"cdc_hphl_cnp_int";
vdd-cdc-io-supply = <&pm8916_l5>;
vdd-cdc-tx-rx-cx-supply = <&pm8916_l5>;
vdd-micbias-supply = <&pm8916_l13>;
#sound-dai-cells = <1>;
};
};

View file

@ -148,6 +148,15 @@ definitions:
required:
- sound-dai
additional-devs:
type: object
description:
Additional devices used by the simple audio card.
patternProperties:
'^iio-aux(-.+)?$':
type: object
$ref: audio-iio-aux.yaml#
properties:
compatible:
contains:
@ -187,6 +196,8 @@ properties:
$ref: "#/definitions/mclk-fs"
simple-audio-card,aux-devs:
$ref: "#/definitions/aux-devs"
simple-audio-card,additional-devs:
$ref: "#/definitions/additional-devs"
simple-audio-card,convert-rate:
$ref: "#/definitions/convert-rate"
simple-audio-card,convert-channels:
@ -359,6 +370,48 @@ examples:
};
};
# --------------------
# route audio to/from a codec through an amplifier
# designed with a potentiometer driven by IIO:
# --------------------
- |
sound {
compatible = "simple-audio-card";
simple-audio-card,aux-devs = <&amp_in>, <&amp_out>;
simple-audio-card,routing =
"CODEC LEFTIN", "AMP_IN LEFT OUT",
"CODEC RIGHTIN", "AMP_IN RIGHT OUT",
"AMP_OUT LEFT IN", "CODEC LEFTOUT",
"AMP_OUT RIGHT IN", "CODEC RIGHTOUT";
simple-audio-card,additional-devs {
amp_out: iio-aux-out {
compatible = "audio-iio-aux";
io-channels = <&pot_out 0>, <&pot_out 1>;
io-channel-names = "LEFT", "RIGHT";
snd-control-invert-range = <1 1>;
sound-name-prefix = "AMP_OUT";
};
amp_in: iio_aux-in {
compatible = "audio-iio-aux";
io-channels = <&pot_in 0>, <&pot_in 1>;
io-channel-names = "LEFT", "RIGHT";
sound-name-prefix = "AMP_IN";
};
};
simple-audio-card,cpu {
sound-dai = <&cpu>;
};
simple-audio-card,codec {
sound-dai = <&codec>;
clocks = <&clocks>;
};
};
# --------------------
# Sampling Rate Conversion
# --------------------

View file

@ -0,0 +1,74 @@
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/sound/wlf,wm8904.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Wolfson WM8904/WM8912 audio codecs
maintainers:
- patches@opensource.cirrus.com
description: |
Pins on the device (for linking into audio routes):
IN1L, IN1R, IN2L, IN2R, IN3L, IN3R, HPOUTL, HPOUTR, LINEOUTL, LINEOUTR,
MICBIAS
properties:
compatible:
enum:
- wlf,wm8904
- wlf,wm8912
reg:
maxItems: 1
"#sound-dai-cells":
const: 0
clocks:
maxItems: 1
clock-names:
const: mclk
AVDD-supply: true
CPVDD-supply: true
DBVDD-supply: true
DCVDD-supply: true
MICVDD-supply: true
required:
- compatible
- reg
- clocks
- clock-names
- AVDD-supply
- CPVDD-supply
- DBVDD-supply
- DCVDD-supply
- MICVDD-supply
allOf:
- $ref: dai-common.yaml#
unevaluatedProperties: false
examples:
- |
i2c {
#address-cells = <1>;
#size-cells = <0>;
codec@1a {
compatible = "wlf,wm8904";
reg = <0x1a>;
clocks = <&pck0>;
clock-names = "mclk";
AVDD-supply = <&reg_1p8v>;
CPVDD-supply = <&reg_1p8v>;
DBVDD-supply = <&reg_1p8v>;
DCVDD-supply = <&reg_1p8v>;
MICVDD-supply = <&reg_1p8v>;
};
};

View file

@ -1,33 +0,0 @@
WM8904 audio CODEC
This device supports I2C only.
Required properties:
- compatible: "wlf,wm8904" or "wlf,wm8912"
- reg: the I2C address of the device.
- clock-names: "mclk"
- clocks: reference to
<Documentation/devicetree/bindings/clock/clock-bindings.txt>
Pins on the device (for linking into audio routes):
* IN1L
* IN1R
* IN2L
* IN2R
* IN3L
* IN3R
* HPOUTL
* HPOUTR
* LINEOUTL
* LINEOUTR
* MICBIAS
Examples:
codec: wm8904@1a {
compatible = "wlf,wm8904";
reg = <0x1a>;
clocks = <&pck0>;
clock-names = "mclk";
};

View file

@ -3,15 +3,6 @@
Digital TV Common functions
---------------------------
Math functions
~~~~~~~~~~~~~~
Provide some commonly-used math functions, usually required in order to
estimate signal strength and signal to noise measurements in dB.
.. kernel-doc:: include/media/dvb_math.h
DVB devices
~~~~~~~~~~~

View file

@ -1865,9 +1865,11 @@ M: Martin Povišer <povik+lin@cutebit.org>
L: asahi@lists.linux.dev
L: alsa-devel@alsa-project.org (moderated for non-subscribers)
S: Maintained
F: Documentation/devicetree/bindings/sound/adi,ssm3515.yaml
F: Documentation/devicetree/bindings/sound/apple,*
F: sound/soc/apple/*
F: sound/soc/codecs/cs42l83-i2c.c
F: sound/soc/codecs/ssm3515.c
ARM/APPLE MACHINE SUPPORT
M: Hector Martin <marcan@marcan.st>

View file

@ -2,7 +2,7 @@
VERSION = 6
PATCHLEVEL = 5
SUBLEVEL = 0
EXTRAVERSION = -rc2
EXTRAVERSION = -rc3
NAME = Hurr durr I'ma ninja sloth
# *DOCUMENTATION*
@ -555,11 +555,23 @@ LINUXINCLUDE := \
$(USERINCLUDE)
KBUILD_AFLAGS := -D__ASSEMBLY__ -fno-PIE
KBUILD_CFLAGS := -Wall -Wundef -Werror=strict-prototypes -Wno-trigraphs \
-fno-strict-aliasing -fno-common -fshort-wchar -fno-PIE \
-Werror=implicit-function-declaration -Werror=implicit-int \
-Werror=return-type -Wno-format-security -funsigned-char \
-std=gnu11
KBUILD_CFLAGS :=
KBUILD_CFLAGS += -std=gnu11
KBUILD_CFLAGS += -fshort-wchar
KBUILD_CFLAGS += -funsigned-char
KBUILD_CFLAGS += -fno-common
KBUILD_CFLAGS += -fno-PIE
KBUILD_CFLAGS += -fno-strict-aliasing
KBUILD_CFLAGS += -Wall
KBUILD_CFLAGS += -Wundef
KBUILD_CFLAGS += -Werror=implicit-function-declaration
KBUILD_CFLAGS += -Werror=implicit-int
KBUILD_CFLAGS += -Werror=return-type
KBUILD_CFLAGS += -Werror=strict-prototypes
KBUILD_CFLAGS += -Wno-format-security
KBUILD_CFLAGS += -Wno-trigraphs
KBUILD_CPPFLAGS := -D__KERNEL__
KBUILD_RUSTFLAGS := $(rust_common_flags) \
--target=$(objtree)/scripts/target.json \

View file

@ -727,6 +727,8 @@ struct kvm_vcpu_arch {
#define DBG_SS_ACTIVE_PENDING __vcpu_single_flag(sflags, BIT(5))
/* PMUSERENR for the guest EL0 is on physical CPU */
#define PMUSERENR_ON_CPU __vcpu_single_flag(sflags, BIT(6))
/* WFI instruction trapped */
#define IN_WFI __vcpu_single_flag(sflags, BIT(7))
/* Pointer to the vcpu's SVE FFR for sve_{save,load}_state() */

View file

@ -608,22 +608,26 @@ int kvm_pgtable_stage2_wrprotect(struct kvm_pgtable *pgt, u64 addr, u64 size);
kvm_pte_t kvm_pgtable_stage2_mkyoung(struct kvm_pgtable *pgt, u64 addr);
/**
* kvm_pgtable_stage2_mkold() - Clear the access flag in a page-table entry.
* kvm_pgtable_stage2_test_clear_young() - Test and optionally clear the access
* flag in a page-table entry.
* @pgt: Page-table structure initialised by kvm_pgtable_stage2_init*().
* @addr: Intermediate physical address to identify the page-table entry.
* @size: Size of the address range to visit.
* @mkold: True if the access flag should be cleared.
*
* The offset of @addr within a page is ignored.
*
* If there is a valid, leaf page-table entry used to translate @addr, then
* clear the access flag in that entry.
* Tests and conditionally clears the access flag for every valid, leaf
* page-table entry used to translate the range [@addr, @addr + @size).
*
* Note that it is the caller's responsibility to invalidate the TLB after
* calling this function to ensure that the updated permissions are visible
* to the CPUs.
*
* Return: The old page-table entry prior to clearing the flag, 0 on failure.
* Return: True if any of the visited PTEs had the access flag set.
*/
kvm_pte_t kvm_pgtable_stage2_mkold(struct kvm_pgtable *pgt, u64 addr);
bool kvm_pgtable_stage2_test_clear_young(struct kvm_pgtable *pgt, u64 addr,
u64 size, bool mkold);
/**
* kvm_pgtable_stage2_relax_perms() - Relax the permissions enforced by a
@ -645,18 +649,6 @@ kvm_pte_t kvm_pgtable_stage2_mkold(struct kvm_pgtable *pgt, u64 addr);
int kvm_pgtable_stage2_relax_perms(struct kvm_pgtable *pgt, u64 addr,
enum kvm_pgtable_prot prot);
/**
* kvm_pgtable_stage2_is_young() - Test whether a page-table entry has the
* access flag set.
* @pgt: Page-table structure initialised by kvm_pgtable_stage2_init*().
* @addr: Intermediate physical address to identify the page-table entry.
*
* The offset of @addr within a page is ignored.
*
* Return: True if the page-table entry has the access flag set, false otherwise.
*/
bool kvm_pgtable_stage2_is_young(struct kvm_pgtable *pgt, u64 addr);
/**
* kvm_pgtable_stage2_flush_range() - Clean and invalidate data cache to Point
* of Coherency for guest stage-2 address

View file

@ -78,6 +78,7 @@ extern u32 __boot_cpu_mode[2];
void __hyp_set_vectors(phys_addr_t phys_vector_base);
void __hyp_reset_vectors(void);
bool is_kvm_arm_initialised(void);
DECLARE_STATIC_KEY_FALSE(kvm_protected_mode_initialized);

View file

@ -847,6 +847,8 @@ void sve_sync_from_fpsimd_zeropad(struct task_struct *task)
int vec_set_vector_length(struct task_struct *task, enum vec_type type,
unsigned long vl, unsigned long flags)
{
bool free_sme = false;
if (flags & ~(unsigned long)(PR_SVE_VL_INHERIT |
PR_SVE_SET_VL_ONEXEC))
return -EINVAL;
@ -897,21 +899,36 @@ int vec_set_vector_length(struct task_struct *task, enum vec_type type,
task->thread.fp_type = FP_STATE_FPSIMD;
}
if (system_supports_sme() && type == ARM64_VEC_SME) {
task->thread.svcr &= ~(SVCR_SM_MASK |
SVCR_ZA_MASK);
clear_thread_flag(TIF_SME);
if (system_supports_sme()) {
if (type == ARM64_VEC_SME ||
!(task->thread.svcr & (SVCR_SM_MASK | SVCR_ZA_MASK))) {
/*
* We are changing the SME VL or weren't using
* SME anyway, discard the state and force a
* reallocation.
*/
task->thread.svcr &= ~(SVCR_SM_MASK |
SVCR_ZA_MASK);
clear_thread_flag(TIF_SME);
free_sme = true;
}
}
if (task == current)
put_cpu_fpsimd_context();
/*
* Force reallocation of task SVE and SME state to the correct
* size on next use:
* Free the changed states if they are not in use, SME will be
* reallocated to the correct size on next use and we just
* allocate SVE now in case it is needed for use in streaming
* mode.
*/
sve_free(task);
if (system_supports_sme() && type == ARM64_VEC_SME)
if (system_supports_sve()) {
sve_free(task);
sve_alloc(task, true);
}
if (free_sme)
sme_free(task);
task_set_vl(task, type, vl);

View file

@ -6,6 +6,10 @@
*
*/
int __kernel_clock_gettime(clockid_t clock, struct __kernel_timespec *ts);
int __kernel_gettimeofday(struct __kernel_old_timeval *tv, struct timezone *tz);
int __kernel_clock_getres(clockid_t clock_id, struct __kernel_timespec *res);
int __kernel_clock_gettime(clockid_t clock,
struct __kernel_timespec *ts)
{

View file

@ -827,8 +827,8 @@ static void timer_set_traps(struct kvm_vcpu *vcpu, struct timer_map *map)
assign_clear_set_bit(tpt, CNTHCTL_EL1PCEN << 10, set, clr);
assign_clear_set_bit(tpc, CNTHCTL_EL1PCTEN << 10, set, clr);
/* This only happens on VHE, so use the CNTKCTL_EL1 accessor */
sysreg_clear_set(cntkctl_el1, clr, set);
/* This only happens on VHE, so use the CNTHCTL_EL2 accessor. */
sysreg_clear_set(cnthctl_el2, clr, set);
}
void kvm_timer_vcpu_load(struct kvm_vcpu *vcpu)
@ -1563,7 +1563,7 @@ int kvm_timer_enable(struct kvm_vcpu *vcpu)
void kvm_timer_init_vhe(void)
{
if (cpus_have_final_cap(ARM64_HAS_ECV_CNTPOFF))
sysreg_clear_set(cntkctl_el1, 0, CNTHCTL_ECV);
sysreg_clear_set(cnthctl_el2, 0, CNTHCTL_ECV);
}
int kvm_arm_timer_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)

View file

@ -53,11 +53,16 @@ DECLARE_KVM_NVHE_PER_CPU(struct kvm_nvhe_init_params, kvm_init_params);
DECLARE_KVM_NVHE_PER_CPU(struct kvm_cpu_context, kvm_hyp_ctxt);
static bool vgic_present;
static bool vgic_present, kvm_arm_initialised;
static DEFINE_PER_CPU(unsigned char, kvm_arm_hardware_enabled);
DEFINE_STATIC_KEY_FALSE(userspace_irqchip_in_use);
bool is_kvm_arm_initialised(void)
{
return kvm_arm_initialised;
}
int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu)
{
return kvm_vcpu_exiting_guest_mode(vcpu) == IN_GUEST_MODE;
@ -713,13 +718,15 @@ void kvm_vcpu_wfi(struct kvm_vcpu *vcpu)
*/
preempt_disable();
kvm_vgic_vmcr_sync(vcpu);
vgic_v4_put(vcpu, true);
vcpu_set_flag(vcpu, IN_WFI);
vgic_v4_put(vcpu);
preempt_enable();
kvm_vcpu_halt(vcpu);
vcpu_clear_flag(vcpu, IN_WFIT);
preempt_disable();
vcpu_clear_flag(vcpu, IN_WFI);
vgic_v4_load(vcpu);
preempt_enable();
}
@ -787,7 +794,7 @@ static int check_vcpu_requests(struct kvm_vcpu *vcpu)
if (kvm_check_request(KVM_REQ_RELOAD_GICv4, vcpu)) {
/* The distributor enable bits were changed */
preempt_disable();
vgic_v4_put(vcpu, false);
vgic_v4_put(vcpu);
vgic_v4_load(vcpu);
preempt_enable();
}
@ -1867,8 +1874,17 @@ static void _kvm_arch_hardware_enable(void *discard)
int kvm_arch_hardware_enable(void)
{
int was_enabled = __this_cpu_read(kvm_arm_hardware_enabled);
int was_enabled;
/*
* Most calls to this function are made with migration
* disabled, but not with preemption disabled. The former is
* enough to ensure correctness, but most of the helpers
* expect the later and will throw a tantrum otherwise.
*/
preempt_disable();
was_enabled = __this_cpu_read(kvm_arm_hardware_enabled);
_kvm_arch_hardware_enable(NULL);
if (!was_enabled) {
@ -1876,6 +1892,8 @@ int kvm_arch_hardware_enable(void)
kvm_timer_cpu_up();
}
preempt_enable();
return 0;
}
@ -2482,6 +2500,8 @@ static __init int kvm_arm_init(void)
if (err)
goto out_subs;
kvm_arm_initialised = true;
return 0;
out_subs:

View file

@ -154,6 +154,12 @@ SYM_CODE_END(\label)
esb
stp x0, x1, [sp, #-16]!
662:
/*
* spectre vectors __bp_harden_hyp_vecs generate br instructions at runtime
* that jump at offset 8 at __kvm_hyp_vector.
* As hyp .text is guarded section, it needs bti j.
*/
bti j
b \target
check_preamble_length 661b, 662b
@ -165,6 +171,8 @@ check_preamble_length 661b, 662b
nop
stp x0, x1, [sp, #-16]!
662:
/* Check valid_vect */
bti j
b \target
check_preamble_length 661b, 662b

View file

@ -297,3 +297,13 @@ SYM_CODE_START(__kvm_hyp_host_forward_smc)
ret
SYM_CODE_END(__kvm_hyp_host_forward_smc)
/*
* kvm_host_psci_cpu_entry is called through br instruction, which requires
* bti j instruction as compilers (gcc and llvm) doesn't insert bti j for external
* functions, but bti c instead.
*/
SYM_CODE_START(kvm_host_psci_cpu_entry)
bti j
b __kvm_host_psci_cpu_entry
SYM_CODE_END(kvm_host_psci_cpu_entry)

View file

@ -200,7 +200,7 @@ static int psci_system_suspend(u64 func_id, struct kvm_cpu_context *host_ctxt)
__hyp_pa(init_params), 0);
}
asmlinkage void __noreturn kvm_host_psci_cpu_entry(bool is_cpu_on)
asmlinkage void __noreturn __kvm_host_psci_cpu_entry(bool is_cpu_on)
{
struct psci_boot_args *boot_args;
struct kvm_cpu_context *host_ctxt;

View file

@ -1195,25 +1195,54 @@ kvm_pte_t kvm_pgtable_stage2_mkyoung(struct kvm_pgtable *pgt, u64 addr)
return pte;
}
kvm_pte_t kvm_pgtable_stage2_mkold(struct kvm_pgtable *pgt, u64 addr)
struct stage2_age_data {
bool mkold;
bool young;
};
static int stage2_age_walker(const struct kvm_pgtable_visit_ctx *ctx,
enum kvm_pgtable_walk_flags visit)
{
kvm_pte_t pte = 0;
stage2_update_leaf_attrs(pgt, addr, 1, 0, KVM_PTE_LEAF_ATTR_LO_S2_AF,
&pte, NULL, 0);
kvm_pte_t new = ctx->old & ~KVM_PTE_LEAF_ATTR_LO_S2_AF;
struct stage2_age_data *data = ctx->arg;
if (!kvm_pte_valid(ctx->old) || new == ctx->old)
return 0;
data->young = true;
/*
* stage2_age_walker() is always called while holding the MMU lock for
* write, so this will always succeed. Nonetheless, this deliberately
* follows the race detection pattern of the other stage-2 walkers in
* case the locking mechanics of the MMU notifiers is ever changed.
*/
if (data->mkold && !stage2_try_set_pte(ctx, new))
return -EAGAIN;
/*
* "But where's the TLBI?!", you scream.
* "Over in the core code", I sigh.
*
* See the '->clear_flush_young()' callback on the KVM mmu notifier.
*/
return pte;
return 0;
}
bool kvm_pgtable_stage2_is_young(struct kvm_pgtable *pgt, u64 addr)
bool kvm_pgtable_stage2_test_clear_young(struct kvm_pgtable *pgt, u64 addr,
u64 size, bool mkold)
{
kvm_pte_t pte = 0;
stage2_update_leaf_attrs(pgt, addr, 1, 0, 0, &pte, NULL, 0);
return pte & KVM_PTE_LEAF_ATTR_LO_S2_AF;
struct stage2_age_data data = {
.mkold = mkold,
};
struct kvm_pgtable_walker walker = {
.cb = stage2_age_walker,
.arg = &data,
.flags = KVM_PGTABLE_WALK_LEAF,
};
WARN_ON(kvm_pgtable_walk(pgt, addr, size, &walker));
return data.young;
}
int kvm_pgtable_stage2_relax_perms(struct kvm_pgtable *pgt, u64 addr,

View file

@ -1756,27 +1756,25 @@ bool kvm_set_spte_gfn(struct kvm *kvm, struct kvm_gfn_range *range)
bool kvm_age_gfn(struct kvm *kvm, struct kvm_gfn_range *range)
{
u64 size = (range->end - range->start) << PAGE_SHIFT;
kvm_pte_t kpte;
pte_t pte;
if (!kvm->arch.mmu.pgt)
return false;
WARN_ON(size != PAGE_SIZE && size != PMD_SIZE && size != PUD_SIZE);
kpte = kvm_pgtable_stage2_mkold(kvm->arch.mmu.pgt,
range->start << PAGE_SHIFT);
pte = __pte(kpte);
return pte_valid(pte) && pte_young(pte);
return kvm_pgtable_stage2_test_clear_young(kvm->arch.mmu.pgt,
range->start << PAGE_SHIFT,
size, true);
}
bool kvm_test_age_gfn(struct kvm *kvm, struct kvm_gfn_range *range)
{
u64 size = (range->end - range->start) << PAGE_SHIFT;
if (!kvm->arch.mmu.pgt)
return false;
return kvm_pgtable_stage2_is_young(kvm->arch.mmu.pgt,
range->start << PAGE_SHIFT);
return kvm_pgtable_stage2_test_clear_young(kvm->arch.mmu.pgt,
range->start << PAGE_SHIFT,
size, false);
}
phys_addr_t kvm_mmu_get_httbr(void)

View file

@ -244,7 +244,7 @@ static int __init finalize_pkvm(void)
{
int ret;
if (!is_protected_kvm_enabled())
if (!is_protected_kvm_enabled() || !is_kvm_arm_initialised())
return 0;
/*

View file

@ -986,7 +986,6 @@ static bool access_pmu_evtyper(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
if (p->is_write) {
kvm_pmu_set_counter_event_type(vcpu, p->regval, idx);
__vcpu_sys_reg(vcpu, reg) = p->regval & ARMV8_PMU_EVTYPE_MASK;
kvm_vcpu_pmu_restore_guest(vcpu);
} else {
p->regval = __vcpu_sys_reg(vcpu, reg) & ARMV8_PMU_EVTYPE_MASK;
@ -1115,18 +1114,19 @@ static bool access_pmuserenr(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
{ SYS_DESC(SYS_DBGWCRn_EL1(n)), \
trap_wcr, reset_wcr, 0, 0, get_wcr, set_wcr }
#define PMU_SYS_REG(r) \
SYS_DESC(r), .reset = reset_pmu_reg, .visibility = pmu_visibility
#define PMU_SYS_REG(name) \
SYS_DESC(SYS_##name), .reset = reset_pmu_reg, \
.visibility = pmu_visibility
/* Macro to expand the PMEVCNTRn_EL0 register */
#define PMU_PMEVCNTR_EL0(n) \
{ PMU_SYS_REG(SYS_PMEVCNTRn_EL0(n)), \
{ PMU_SYS_REG(PMEVCNTRn_EL0(n)), \
.reset = reset_pmevcntr, .get_user = get_pmu_evcntr, \
.access = access_pmu_evcntr, .reg = (PMEVCNTR0_EL0 + n), }
/* Macro to expand the PMEVTYPERn_EL0 register */
#define PMU_PMEVTYPER_EL0(n) \
{ PMU_SYS_REG(SYS_PMEVTYPERn_EL0(n)), \
{ PMU_SYS_REG(PMEVTYPERn_EL0(n)), \
.reset = reset_pmevtyper, \
.access = access_pmu_evtyper, .reg = (PMEVTYPER0_EL0 + n), }
@ -2115,9 +2115,9 @@ static const struct sys_reg_desc sys_reg_descs[] = {
{ SYS_DESC(SYS_PMBSR_EL1), undef_access },
/* PMBIDR_EL1 is not trapped */
{ PMU_SYS_REG(SYS_PMINTENSET_EL1),
{ PMU_SYS_REG(PMINTENSET_EL1),
.access = access_pminten, .reg = PMINTENSET_EL1 },
{ PMU_SYS_REG(SYS_PMINTENCLR_EL1),
{ PMU_SYS_REG(PMINTENCLR_EL1),
.access = access_pminten, .reg = PMINTENSET_EL1 },
{ SYS_DESC(SYS_PMMIR_EL1), trap_raz_wi },
@ -2164,41 +2164,41 @@ static const struct sys_reg_desc sys_reg_descs[] = {
{ SYS_DESC(SYS_CTR_EL0), access_ctr },
{ SYS_DESC(SYS_SVCR), undef_access },
{ PMU_SYS_REG(SYS_PMCR_EL0), .access = access_pmcr,
{ PMU_SYS_REG(PMCR_EL0), .access = access_pmcr,
.reset = reset_pmcr, .reg = PMCR_EL0 },
{ PMU_SYS_REG(SYS_PMCNTENSET_EL0),
{ PMU_SYS_REG(PMCNTENSET_EL0),
.access = access_pmcnten, .reg = PMCNTENSET_EL0 },
{ PMU_SYS_REG(SYS_PMCNTENCLR_EL0),
{ PMU_SYS_REG(PMCNTENCLR_EL0),
.access = access_pmcnten, .reg = PMCNTENSET_EL0 },
{ PMU_SYS_REG(SYS_PMOVSCLR_EL0),
{ PMU_SYS_REG(PMOVSCLR_EL0),
.access = access_pmovs, .reg = PMOVSSET_EL0 },
/*
* PM_SWINC_EL0 is exposed to userspace as RAZ/WI, as it was
* previously (and pointlessly) advertised in the past...
*/
{ PMU_SYS_REG(SYS_PMSWINC_EL0),
{ PMU_SYS_REG(PMSWINC_EL0),
.get_user = get_raz_reg, .set_user = set_wi_reg,
.access = access_pmswinc, .reset = NULL },
{ PMU_SYS_REG(SYS_PMSELR_EL0),
{ PMU_SYS_REG(PMSELR_EL0),
.access = access_pmselr, .reset = reset_pmselr, .reg = PMSELR_EL0 },
{ PMU_SYS_REG(SYS_PMCEID0_EL0),
{ PMU_SYS_REG(PMCEID0_EL0),
.access = access_pmceid, .reset = NULL },
{ PMU_SYS_REG(SYS_PMCEID1_EL0),
{ PMU_SYS_REG(PMCEID1_EL0),
.access = access_pmceid, .reset = NULL },
{ PMU_SYS_REG(SYS_PMCCNTR_EL0),
{ PMU_SYS_REG(PMCCNTR_EL0),
.access = access_pmu_evcntr, .reset = reset_unknown,
.reg = PMCCNTR_EL0, .get_user = get_pmu_evcntr},
{ PMU_SYS_REG(SYS_PMXEVTYPER_EL0),
{ PMU_SYS_REG(PMXEVTYPER_EL0),
.access = access_pmu_evtyper, .reset = NULL },
{ PMU_SYS_REG(SYS_PMXEVCNTR_EL0),
{ PMU_SYS_REG(PMXEVCNTR_EL0),
.access = access_pmu_evcntr, .reset = NULL },
/*
* PMUSERENR_EL0 resets as unknown in 64bit mode while it resets as zero
* in 32bit mode. Here we choose to reset it as zero for consistency.
*/
{ PMU_SYS_REG(SYS_PMUSERENR_EL0), .access = access_pmuserenr,
{ PMU_SYS_REG(PMUSERENR_EL0), .access = access_pmuserenr,
.reset = reset_val, .reg = PMUSERENR_EL0, .val = 0 },
{ PMU_SYS_REG(SYS_PMOVSSET_EL0),
{ PMU_SYS_REG(PMOVSSET_EL0),
.access = access_pmovs, .reg = PMOVSSET_EL0 },
{ SYS_DESC(SYS_TPIDR_EL0), NULL, reset_unknown, TPIDR_EL0 },
@ -2354,7 +2354,7 @@ static const struct sys_reg_desc sys_reg_descs[] = {
* PMCCFILTR_EL0 resets as unknown in 64bit mode while it resets as zero
* in 32bit mode. Here we choose to reset it as zero for consistency.
*/
{ PMU_SYS_REG(SYS_PMCCFILTR_EL0), .access = access_pmu_evtyper,
{ PMU_SYS_REG(PMCCFILTR_EL0), .access = access_pmu_evtyper,
.reset = reset_val, .reg = PMCCFILTR_EL0, .val = 0 },
EL2_REG(VPIDR_EL2, access_rw, reset_unknown, 0),

View file

@ -749,7 +749,7 @@ void vgic_v3_put(struct kvm_vcpu *vcpu)
{
struct vgic_v3_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v3;
WARN_ON(vgic_v4_put(vcpu, false));
WARN_ON(vgic_v4_put(vcpu));
vgic_v3_vmcr_sync(vcpu);

View file

@ -336,14 +336,14 @@ void vgic_v4_teardown(struct kvm *kvm)
its_vm->vpes = NULL;
}
int vgic_v4_put(struct kvm_vcpu *vcpu, bool need_db)
int vgic_v4_put(struct kvm_vcpu *vcpu)
{
struct its_vpe *vpe = &vcpu->arch.vgic_cpu.vgic_v3.its_vpe;
if (!vgic_supports_direct_msis(vcpu->kvm) || !vpe->resident)
return 0;
return its_make_vpe_non_resident(vpe, need_db);
return its_make_vpe_non_resident(vpe, !!vcpu_get_flag(vcpu, IN_WFI));
}
int vgic_v4_load(struct kvm_vcpu *vcpu)
@ -354,6 +354,9 @@ int vgic_v4_load(struct kvm_vcpu *vcpu)
if (!vgic_supports_direct_msis(vcpu->kvm) || vpe->resident)
return 0;
if (vcpu_get_flag(vcpu, IN_WFI))
return 0;
/*
* Before making the VPE resident, make sure the redistributor
* corresponding to our current CPU expects us here. See the

View file

@ -24,6 +24,7 @@
#include <linux/bug.h>
#include <linux/mm.h>
#include <linux/mmzone.h>
#include <linux/kfence.h>
static void *trans_alloc(struct trans_pgd_info *info)
{
@ -41,7 +42,8 @@ static void _copy_pte(pte_t *dst_ptep, pte_t *src_ptep, unsigned long addr)
* the temporary mappings we use during restore.
*/
set_pte(dst_ptep, pte_mkwrite(pte));
} else if (debug_pagealloc_enabled() && !pte_none(pte)) {
} else if ((debug_pagealloc_enabled() ||
is_kfence_address((void *)addr)) && !pte_none(pte)) {
/*
* debug_pagealloc will removed the PTE_VALID bit if
* the page isn't in use by the resume kernel. It may have

View file

@ -322,7 +322,13 @@ static int build_prologue(struct jit_ctx *ctx, bool ebpf_from_cbpf)
*
*/
emit_bti(A64_BTI_C, ctx);
/* bpf function may be invoked by 3 instruction types:
* 1. bl, attached via freplace to bpf prog via short jump
* 2. br, attached via freplace to bpf prog via long jump
* 3. blr, working as a function pointer, used by emit_call.
* So BTI_JC should used here to support both br and blr.
*/
emit_bti(A64_BTI_JC, ctx);
emit(A64_MOV(1, A64_R(9), A64_LR), ctx);
emit(A64_NOP, ctx);

View file

@ -2017,7 +2017,7 @@ Field 0 SM
EndSysreg
SysregFields HFGxTR_EL2
Field 63 nAMIAIR2_EL1
Field 63 nAMAIR2_EL1
Field 62 nMAIR2_EL1
Field 61 nS2POR_EL1
Field 60 nPOR_EL1
@ -2032,9 +2032,9 @@ Field 52 nGCS_EL0
Res0 51
Field 50 nACCDATA_EL1
Field 49 ERXADDR_EL1
Field 48 EXRPFGCDN_EL1
Field 47 EXPFGCTL_EL1
Field 46 EXPFGF_EL1
Field 48 ERXPFGCDN_EL1
Field 47 ERXPFGCTL_EL1
Field 46 ERXPFGF_EL1
Field 45 ERXMISCn_EL1
Field 44 ERXSTATUS_EL1
Field 43 ERXCTLR_EL1
@ -2049,8 +2049,8 @@ Field 35 TPIDR_EL0
Field 34 TPIDRRO_EL0
Field 33 TPIDR_EL1
Field 32 TCR_EL1
Field 31 SCTXNUM_EL0
Field 30 SCTXNUM_EL1
Field 31 SCXTNUM_EL0
Field 30 SCXTNUM_EL1
Field 29 SCTLR_EL1
Field 28 REVIDR_EL1
Field 27 PAR_EL1

View file

@ -63,7 +63,7 @@ arch_get_unmapped_area (struct file *filp, unsigned long addr, unsigned long len
info.low_limit = addr;
info.high_limit = TASK_SIZE;
info.align_mask = align_mask;
info.align_offset = 0;
info.align_offset = pgoff << PAGE_SHIFT;
return vm_unmapped_area(&info);
}

View file

@ -27,12 +27,17 @@
#include <linux/elf-randomize.h>
/*
* Construct an artificial page offset for the mapping based on the physical
* Construct an artificial page offset for the mapping based on the virtual
* address of the kernel file mapping variable.
* If filp is zero the calculated pgoff value aliases the memory of the given
* address. This is useful for io_uring where the mapping shall alias a kernel
* address and a userspace adress where both the kernel and the userspace
* access the same memory region.
*/
#define GET_FILP_PGOFF(filp) \
(filp ? (((unsigned long) filp->f_mapping) >> 8) \
& ((SHM_COLOUR-1) >> PAGE_SHIFT) : 0UL)
#define GET_FILP_PGOFF(filp, addr) \
((filp ? (((unsigned long) filp->f_mapping) >> 8) \
& ((SHM_COLOUR-1) >> PAGE_SHIFT) : 0UL) \
+ (addr >> PAGE_SHIFT))
static unsigned long shared_align_offset(unsigned long filp_pgoff,
unsigned long pgoff)
@ -112,7 +117,7 @@ static unsigned long arch_get_unmapped_area_common(struct file *filp,
do_color_align = 0;
if (filp || (flags & MAP_SHARED))
do_color_align = 1;
filp_pgoff = GET_FILP_PGOFF(filp);
filp_pgoff = GET_FILP_PGOFF(filp, addr);
if (flags & MAP_FIXED) {
/* Even MAP_FIXED mappings must reside within TASK_SIZE */

3
arch/powerpc/crypto/.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
# SPDX-License-Identifier: GPL-2.0-only
aesp10-ppc.S
ghashp10-ppc.S

View file

@ -4,14 +4,13 @@
#ifdef __KERNEL__
#include <asm/asm-compat.h>
#include <asm/extable.h>
#ifdef CONFIG_BUG
#ifdef __ASSEMBLY__
#include <asm/asm-offsets.h>
#ifdef CONFIG_DEBUG_BUGVERBOSE
.macro __EMIT_BUG_ENTRY addr,file,line,flags
.macro EMIT_BUG_ENTRY addr,file,line,flags
.section __bug_table,"aw"
5001: .4byte \addr - .
.4byte 5002f - .
@ -23,7 +22,7 @@
.previous
.endm
#else
.macro __EMIT_BUG_ENTRY addr,file,line,flags
.macro EMIT_BUG_ENTRY addr,file,line,flags
.section __bug_table,"aw"
5001: .4byte \addr - .
.short \flags
@ -32,18 +31,6 @@
.endm
#endif /* verbose */
.macro EMIT_WARN_ENTRY addr,file,line,flags
EX_TABLE(\addr,\addr+4)
__EMIT_BUG_ENTRY \addr,\file,\line,\flags
.endm
.macro EMIT_BUG_ENTRY addr,file,line,flags
.if \flags & 1 /* BUGFLAG_WARNING */
.err /* Use EMIT_WARN_ENTRY for warnings */
.endif
__EMIT_BUG_ENTRY \addr,\file,\line,\flags
.endm
#else /* !__ASSEMBLY__ */
/* _EMIT_BUG_ENTRY expects args %0,%1,%2,%3 to be FILE, LINE, flags and
sizeof(struct bug_entry), respectively */
@ -73,16 +60,6 @@
"i" (sizeof(struct bug_entry)), \
##__VA_ARGS__)
#define WARN_ENTRY(insn, flags, label, ...) \
asm_volatile_goto( \
"1: " insn "\n" \
EX_TABLE(1b, %l[label]) \
_EMIT_BUG_ENTRY \
: : "i" (__FILE__), "i" (__LINE__), \
"i" (flags), \
"i" (sizeof(struct bug_entry)), \
##__VA_ARGS__ : : label)
/*
* BUG_ON() and WARN_ON() do their best to cooperate with compile-time
* optimisations. However depending on the complexity of the condition
@ -95,16 +72,7 @@
} while (0)
#define HAVE_ARCH_BUG
#define __WARN_FLAGS(flags) do { \
__label__ __label_warn_on; \
\
WARN_ENTRY("twi 31, 0, 0", BUGFLAG_WARNING | (flags), __label_warn_on); \
barrier_before_unreachable(); \
__builtin_unreachable(); \
\
__label_warn_on: \
break; \
} while (0)
#define __WARN_FLAGS(flags) BUG_ENTRY("twi 31, 0, 0", BUGFLAG_WARNING | (flags))
#ifdef CONFIG_PPC64
#define BUG_ON(x) do { \
@ -117,25 +85,15 @@ __label_warn_on: \
} while (0)
#define WARN_ON(x) ({ \
bool __ret_warn_on = false; \
do { \
if (__builtin_constant_p((x))) { \
if (!(x)) \
break; \
int __ret_warn_on = !!(x); \
if (__builtin_constant_p(__ret_warn_on)) { \
if (__ret_warn_on) \
__WARN(); \
__ret_warn_on = true; \
} else { \
__label__ __label_warn_on; \
\
WARN_ENTRY(PPC_TLNEI " %4, 0", \
BUGFLAG_WARNING | BUGFLAG_TAINT(TAINT_WARN), \
__label_warn_on, \
"r" ((__force long)(x))); \
break; \
__label_warn_on: \
__ret_warn_on = true; \
} \
} while (0); \
} else { \
BUG_ENTRY(PPC_TLNEI " %4, 0", \
BUGFLAG_WARNING | BUGFLAG_TAINT(TAINT_WARN), \
"r" (__ret_warn_on)); \
} \
unlikely(__ret_warn_on); \
})
@ -148,14 +106,13 @@ __label_warn_on: \
#ifdef __ASSEMBLY__
.macro EMIT_BUG_ENTRY addr,file,line,flags
.endm
.macro EMIT_WARN_ENTRY addr,file,line,flags
.endm
#else /* !__ASSEMBLY__ */
#define _EMIT_BUG_ENTRY
#define _EMIT_WARN_ENTRY
#endif
#endif /* CONFIG_BUG */
#define EMIT_WARN_ENTRY EMIT_BUG_ENTRY
#include <asm-generic/bug.h>
#ifndef __ASSEMBLY__

View file

@ -12,14 +12,8 @@
/*
* This is used to ensure we don't load something for the wrong architecture.
* 64le only supports ELFv2 64-bit binaries (64be supports v1 and v2).
*/
#if defined(CONFIG_PPC64) && defined(CONFIG_CPU_LITTLE_ENDIAN)
#define elf_check_arch(x) (((x)->e_machine == ELF_ARCH) && \
(((x)->e_flags & 0x3) == 0x2))
#else
#define elf_check_arch(x) ((x)->e_machine == ELF_ARCH)
#endif
#define compat_elf_check_arch(x) ((x)->e_machine == EM_PPC)
#define CORE_DUMP_USE_REGSET

View file

@ -183,13 +183,9 @@ static inline bool test_thread_local_flags(unsigned int flags)
#define clear_tsk_compat_task(tsk) do { } while (0)
#endif
#ifdef CONFIG_PPC64
#ifdef CONFIG_CPU_BIG_ENDIAN
#if defined(CONFIG_PPC64)
#define is_elf2_task() (test_thread_flag(TIF_ELF2ABI))
#else
#define is_elf2_task() (1)
#endif
#else
#define is_elf2_task() (0)
#endif

View file

@ -1508,13 +1508,8 @@ static void do_program_check(struct pt_regs *regs)
if (!(regs->msr & MSR_PR) && /* not user-mode */
report_bug(bugaddr, regs) == BUG_TRAP_TYPE_WARN) {
const struct exception_table_entry *entry;
entry = search_exception_tables(bugaddr);
if (entry) {
regs_set_return_ip(regs, extable_fixup(entry) + regs->nip - bugaddr);
return;
}
regs_add_return_ip(regs, 4);
return;
}
if (cpu_has_feature(CPU_FTR_DEXCR_NPHIE) && user_mode(regs)) {

View file

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

View file

@ -477,7 +477,7 @@ static int mpc512x_lpbfifo_probe(struct platform_device *pdev)
return ret;
}
static int mpc512x_lpbfifo_remove(struct platform_device *pdev)
static void mpc512x_lpbfifo_remove(struct platform_device *pdev)
{
unsigned long flags;
struct dma_device *dma_dev = lpbfifo.chan->device;
@ -494,8 +494,6 @@ static int mpc512x_lpbfifo_remove(struct platform_device *pdev)
free_irq(lpbfifo.irq, &pdev->dev);
irq_dispose_mapping(lpbfifo.irq);
dma_release_channel(lpbfifo.chan);
return 0;
}
static const struct of_device_id mpc512x_lpbfifo_match[] = {
@ -506,7 +504,7 @@ MODULE_DEVICE_TABLE(of, mpc512x_lpbfifo_match);
static struct platform_driver mpc512x_lpbfifo_driver = {
.probe = mpc512x_lpbfifo_probe,
.remove = mpc512x_lpbfifo_remove,
.remove_new = mpc512x_lpbfifo_remove,
.driver = {
.name = DRV_NAME,
.of_match_table = mpc512x_lpbfifo_match,

View file

@ -744,6 +744,12 @@ static int reconfig_close_windows(struct vas_caps *vcap, int excess_creds,
}
task_ref = &win->vas_win.task_ref;
/*
* VAS mmap (coproc_mmap()) and its fault handler
* (vas_mmap_fault()) are called after holding mmap lock.
* So hold mmap mutex after mmap_lock to avoid deadlock.
*/
mmap_write_lock(task_ref->mm);
mutex_lock(&task_ref->mmap_mutex);
vma = task_ref->vma;
/*
@ -752,7 +758,6 @@ static int reconfig_close_windows(struct vas_caps *vcap, int excess_creds,
*/
win->vas_win.status |= flag;
mmap_write_lock(task_ref->mm);
/*
* vma is set in the original mapping. But this mapping
* is done with mmap() after the window is opened with ioctl.
@ -762,8 +767,8 @@ static int reconfig_close_windows(struct vas_caps *vcap, int excess_creds,
if (vma)
zap_vma_pages(vma);
mmap_write_unlock(task_ref->mm);
mutex_unlock(&task_ref->mmap_mutex);
mmap_write_unlock(task_ref->mm);
/*
* Close VAS window in the hypervisor, but do not
* free vas_window struct since it may be reused

View file

@ -103,7 +103,7 @@ static inline void _free_kb_keybuf(struct key_blob *kb)
{
if (kb->key && kb->key != kb->keybuf
&& kb->keylen > sizeof(kb->keybuf)) {
kfree(kb->key);
kfree_sensitive(kb->key);
kb->key = NULL;
}
}

View file

@ -411,8 +411,12 @@ int kvm_s390_pv_deinit_cleanup_all(struct kvm *kvm, u16 *rc, u16 *rrc)
u16 _rc, _rrc;
int cc = 0;
/* Make sure the counter does not reach 0 before calling s390_uv_destroy_range */
atomic_inc(&kvm->mm->context.protected_count);
/*
* Nothing to do if the counter was already 0. Otherwise make sure
* the counter does not reach 0 before calling s390_uv_destroy_range.
*/
if (!atomic_inc_not_zero(&kvm->mm->context.protected_count))
return 0;
*rc = 1;
/* If the current VM is protected, destroy it */

View file

@ -421,6 +421,8 @@ static inline vm_fault_t do_exception(struct pt_regs *regs, int access)
vma_end_read(vma);
if (!(fault & VM_FAULT_RETRY)) {
count_vm_vma_lock_event(VMA_LOCK_SUCCESS);
if (likely(!(fault & VM_FAULT_ERROR)))
fault = 0;
goto out;
}
count_vm_vma_lock_event(VMA_LOCK_RETRY);

View file

@ -2853,6 +2853,7 @@ int s390_replace_asce(struct gmap *gmap)
page = alloc_pages(GFP_KERNEL_ACCOUNT, CRST_ALLOC_ORDER);
if (!page)
return -ENOMEM;
page->index = 0;
table = page_to_virt(page);
memcpy(table, gmap->table, 1UL << (CRST_ALLOC_ORDER + PAGE_SHIFT));

View file

@ -1144,8 +1144,7 @@ void __blk_flush_plug(struct blk_plug *plug, bool from_schedule)
{
if (!list_empty(&plug->cb_list))
flush_plug_callbacks(plug, from_schedule);
if (!rq_list_empty(plug->mq_list))
blk_mq_flush_plug_list(plug, from_schedule);
blk_mq_flush_plug_list(plug, from_schedule);
/*
* Unconditionally flush out cached requests, even if the unplug
* event came from schedule. Since we know hold references to the

View file

@ -2516,6 +2516,10 @@ static void calc_vtime_cost_builtin(struct bio *bio, struct ioc_gq *iocg,
u64 seek_pages = 0;
u64 cost = 0;
/* Can't calculate cost for empty bio */
if (!bio->bi_iter.bi_size)
goto out;
switch (bio_op(bio)) {
case REQ_OP_READ:
coef_seqio = ioc->params.lcoefs[LCOEF_RSEQIO];

View file

@ -2754,7 +2754,14 @@ void blk_mq_flush_plug_list(struct blk_plug *plug, bool from_schedule)
{
struct request *rq;
if (rq_list_empty(plug->mq_list))
/*
* We may have been called recursively midway through handling
* plug->mq_list via a schedule() in the driver's queue_rq() callback.
* To avoid mq_list changing under our feet, clear rq_count early and
* bail out specifically if rq_count is 0 rather than checking
* whether the mq_list is empty.
*/
if (plug->rq_count == 0)
return;
plug->rq_count = 0;

View file

@ -3980,6 +3980,15 @@ static inline void hl_debugfs_fini(void)
{
}
static inline int hl_debugfs_device_init(struct hl_device *hdev)
{
return 0;
}
static inline void hl_debugfs_device_fini(struct hl_device *hdev)
{
}
static inline void hl_debugfs_add_device(struct hl_device *hdev)
{
}

View file

@ -14,6 +14,7 @@
#include <linux/mm.h>
#include <linux/moduleparam.h>
#include <linux/mutex.h>
#include <linux/overflow.h>
#include <linux/pci.h>
#include <linux/scatterlist.h>
#include <linux/types.h>
@ -366,7 +367,7 @@ static int encode_passthrough(struct qaic_device *qdev, void *trans, struct wrap
if (in_trans->hdr.len % 8 != 0)
return -EINVAL;
if (msg_hdr_len + in_trans->hdr.len > QAIC_MANAGE_EXT_MSG_LENGTH)
if (size_add(msg_hdr_len, in_trans->hdr.len) > QAIC_MANAGE_EXT_MSG_LENGTH)
return -ENOSPC;
trans_wrapper = add_wrapper(wrappers,
@ -418,9 +419,12 @@ static int find_and_map_user_pages(struct qaic_device *qdev,
}
ret = get_user_pages_fast(xfer_start_addr, nr_pages, 0, page_list);
if (ret < 0 || ret != nr_pages) {
ret = -EFAULT;
if (ret < 0)
goto free_page_list;
if (ret != nr_pages) {
nr_pages = ret;
ret = -EFAULT;
goto put_pages;
}
sgt = kmalloc(sizeof(*sgt), GFP_KERNEL);
@ -557,11 +561,8 @@ static int encode_dma(struct qaic_device *qdev, void *trans, struct wrapper_list
msg = &wrapper->msg;
msg_hdr_len = le32_to_cpu(msg->hdr.len);
if (msg_hdr_len > (UINT_MAX - QAIC_MANAGE_EXT_MSG_LENGTH))
return -EINVAL;
/* There should be enough space to hold at least one ASP entry. */
if (msg_hdr_len + sizeof(*out_trans) + sizeof(struct wire_addr_size_pair) >
if (size_add(msg_hdr_len, sizeof(*out_trans) + sizeof(struct wire_addr_size_pair)) >
QAIC_MANAGE_EXT_MSG_LENGTH)
return -ENOMEM;
@ -634,7 +635,7 @@ static int encode_activate(struct qaic_device *qdev, void *trans, struct wrapper
msg = &wrapper->msg;
msg_hdr_len = le32_to_cpu(msg->hdr.len);
if (msg_hdr_len + sizeof(*out_trans) > QAIC_MANAGE_MAX_MSG_LENGTH)
if (size_add(msg_hdr_len, sizeof(*out_trans)) > QAIC_MANAGE_MAX_MSG_LENGTH)
return -ENOSPC;
if (!in_trans->queue_size)
@ -718,7 +719,7 @@ static int encode_status(struct qaic_device *qdev, void *trans, struct wrapper_l
msg = &wrapper->msg;
msg_hdr_len = le32_to_cpu(msg->hdr.len);
if (msg_hdr_len + in_trans->hdr.len > QAIC_MANAGE_MAX_MSG_LENGTH)
if (size_add(msg_hdr_len, in_trans->hdr.len) > QAIC_MANAGE_MAX_MSG_LENGTH)
return -ENOSPC;
trans_wrapper = add_wrapper(wrappers, sizeof(*trans_wrapper));
@ -748,7 +749,8 @@ static int encode_message(struct qaic_device *qdev, struct manage_msg *user_msg,
int ret;
int i;
if (!user_msg->count) {
if (!user_msg->count ||
user_msg->len < sizeof(*trans_hdr)) {
ret = -EINVAL;
goto out;
}
@ -765,12 +767,13 @@ static int encode_message(struct qaic_device *qdev, struct manage_msg *user_msg,
}
for (i = 0; i < user_msg->count; ++i) {
if (user_len >= user_msg->len) {
if (user_len > user_msg->len - sizeof(*trans_hdr)) {
ret = -EINVAL;
break;
}
trans_hdr = (struct qaic_manage_trans_hdr *)(user_msg->data + user_len);
if (user_len + trans_hdr->len > user_msg->len) {
if (trans_hdr->len < sizeof(trans_hdr) ||
size_add(user_len, trans_hdr->len) > user_msg->len) {
ret = -EINVAL;
break;
}
@ -953,15 +956,23 @@ static int decode_message(struct qaic_device *qdev, struct manage_msg *user_msg,
int ret;
int i;
if (msg_hdr_len > QAIC_MANAGE_MAX_MSG_LENGTH)
if (msg_hdr_len < sizeof(*trans_hdr) ||
msg_hdr_len > QAIC_MANAGE_MAX_MSG_LENGTH)
return -EINVAL;
user_msg->len = 0;
user_msg->count = le32_to_cpu(msg->hdr.count);
for (i = 0; i < user_msg->count; ++i) {
u32 hdr_len;
if (msg_len > msg_hdr_len - sizeof(*trans_hdr))
return -EINVAL;
trans_hdr = (struct wire_trans_hdr *)(msg->data + msg_len);
if (msg_len + le32_to_cpu(trans_hdr->len) > msg_hdr_len)
hdr_len = le32_to_cpu(trans_hdr->len);
if (hdr_len < sizeof(*trans_hdr) ||
size_add(msg_len, hdr_len) > msg_hdr_len)
return -EINVAL;
switch (le32_to_cpu(trans_hdr->type)) {

View file

@ -139,4 +139,6 @@ static struct pi_protocol aten = {
};
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Grant R. Guenther <grant@torque.net>");
MODULE_DESCRIPTION("ATEN EH-100 parallel port IDE adapter protocol driver");
module_pata_parport_driver(aten);

View file

@ -502,4 +502,6 @@ static struct pi_protocol bpck = {
};
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Grant R. Guenther <grant@torque.net>");
MODULE_DESCRIPTION("MicroSolutions BACKPACK parallel port IDE adapter protocol driver");
module_pata_parport_driver(bpck);

View file

@ -459,5 +459,6 @@ static struct pi_protocol bpck6 = {
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Micro Solutions Inc.");
MODULE_DESCRIPTION("BACKPACK Protocol module, compatible with PARIDE");
MODULE_DESCRIPTION("Micro Solutions BACKPACK parallel port IDE adapter "
"(version 6 drives) protocol driver");
module_pata_parport_driver(bpck6);

View file

@ -201,4 +201,6 @@ static struct pi_protocol comm = {
};
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Grant R. Guenther <grant@torque.net>");
MODULE_DESCRIPTION("DataStor Commuter parallel port IDE adapter protocol driver");
module_pata_parport_driver(comm);

View file

@ -230,4 +230,6 @@ static struct pi_protocol dstr = {
};
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Grant R. Guenther <grant@torque.net>");
MODULE_DESCRIPTION("DataStor EP2000 parallel port IDE adapter protocol driver");
module_pata_parport_driver(dstr);

View file

@ -358,5 +358,8 @@ static void __exit epat_exit(void)
}
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Grant R. Guenther <grant@torque.net>");
MODULE_DESCRIPTION("Shuttle Technologies EPAT parallel port IDE adapter "
"protocol driver");
module_init(epat_init)
module_exit(epat_exit)

View file

@ -306,4 +306,7 @@ static struct pi_protocol epia = {
};
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Grant R. Guenther <grant@torque.net>");
MODULE_DESCRIPTION("Shuttle Technologies EPIA parallel port IDE adapter "
"protocol driver");
module_pata_parport_driver(epia);

View file

@ -132,4 +132,7 @@ static struct pi_protocol fit2 = {
};
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Grant R. Guenther <grant@torque.net>");
MODULE_DESCRIPTION("Fidelity International Technology parallel port IDE adapter"
"(older models) protocol driver");
module_pata_parport_driver(fit2);

View file

@ -193,4 +193,7 @@ static struct pi_protocol fit3 = {
};
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Grant R. Guenther <grant@torque.net>");
MODULE_DESCRIPTION("Fidelity International Technology parallel port IDE adapter"
"(newer models) protocol driver");
module_pata_parport_driver(fit3);

View file

@ -259,4 +259,6 @@ static struct pi_protocol friq = {
};
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Grant R. Guenther <grant@torque.net>");
MODULE_DESCRIPTION("Freecom IQ parallel port IDE adapter protocol driver");
module_pata_parport_driver(friq);

View file

@ -293,4 +293,6 @@ static struct pi_protocol frpw = {
};
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Grant R. Guenther <grant@torque.net>");
MODULE_DESCRIPTION("Freecom Power parallel port IDE adapter protocol driver");
module_pata_parport_driver(frpw);

View file

@ -301,5 +301,8 @@ static void __exit kbic_exit(void)
}
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Grant R. Guenther <grant@torque.net>");
MODULE_DESCRIPTION("KingByte Information Systems KBIC-951A and KBIC-971A "
"parallel port IDE adapter protocol driver");
module_init(kbic_init)
module_exit(kbic_exit)

View file

@ -106,4 +106,6 @@ static struct pi_protocol ktti = {
};
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Grant R. Guenther <grant@torque.net>");
MODULE_DESCRIPTION("KT Technology parallel port IDE adapter protocol driver");
module_pata_parport_driver(ktti);

View file

@ -142,4 +142,6 @@ static struct pi_protocol on20 = {
};
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Grant R. Guenther <grant@torque.net>");
MODULE_DESCRIPTION("Onspec 90c20 parallel port IDE adapter protocol driver");
module_pata_parport_driver(on20);

View file

@ -310,4 +310,6 @@ static struct pi_protocol on26 = {
};
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Grant R. Guenther <grant@torque.net>");
MODULE_DESCRIPTION("Onspec 90c26 parallel port IDE adapter protocol driver");
module_pata_parport_driver(on26);

View file

@ -471,6 +471,8 @@ static int regcache_rbtree_sync(struct regmap *map, unsigned int min,
unsigned int start, end;
int ret;
map->async = true;
rbtree_ctx = map->cache;
for (node = rb_first(&rbtree_ctx->root); node; node = rb_next(node)) {
rbnode = rb_entry(node, struct regcache_rbtree_node, node);
@ -499,6 +501,8 @@ static int regcache_rbtree_sync(struct regmap *map, unsigned int min,
return ret;
}
map->async = false;
return regmap_async_complete(map);
}

View file

@ -368,8 +368,6 @@ int regcache_sync(struct regmap *map)
if (!map->cache_dirty)
goto out;
map->async = true;
/* Apply any patch first */
map->cache_bypass = true;
for (i = 0; i < map->patch_regs; i++) {
@ -392,7 +390,6 @@ int regcache_sync(struct regmap *map)
out:
/* Restore the bypass state */
map->async = false;
map->cache_bypass = bypass;
map->no_sync_defaults = false;
map->unlock(map->lock_arg);

View file

@ -242,8 +242,8 @@ static int regmap_i2c_smbus_i2c_read(void *context, const void *reg,
static const struct regmap_bus regmap_i2c_smbus_i2c_block = {
.write = regmap_i2c_smbus_i2c_write,
.read = regmap_i2c_smbus_i2c_read,
.max_raw_read = I2C_SMBUS_BLOCK_MAX,
.max_raw_write = I2C_SMBUS_BLOCK_MAX,
.max_raw_read = I2C_SMBUS_BLOCK_MAX - 1,
.max_raw_write = I2C_SMBUS_BLOCK_MAX - 1,
};
static int regmap_i2c_smbus_i2c_write_reg16(void *context, const void *data,
@ -299,8 +299,8 @@ static int regmap_i2c_smbus_i2c_read_reg16(void *context, const void *reg,
static const struct regmap_bus regmap_i2c_smbus_i2c_block_reg16 = {
.write = regmap_i2c_smbus_i2c_write_reg16,
.read = regmap_i2c_smbus_i2c_read_reg16,
.max_raw_read = I2C_SMBUS_BLOCK_MAX,
.max_raw_write = I2C_SMBUS_BLOCK_MAX,
.max_raw_read = I2C_SMBUS_BLOCK_MAX - 2,
.max_raw_write = I2C_SMBUS_BLOCK_MAX - 2,
};
static const struct regmap_bus *regmap_get_i2c_bus(struct i2c_client *i2c,

View file

@ -58,6 +58,9 @@ static struct regmap *gen_regmap(struct regmap_config *config,
int i;
struct reg_default *defaults;
config->disable_locking = config->cache_type == REGCACHE_RBTREE ||
config->cache_type == REGCACHE_MAPLE;
buf = kmalloc(size, GFP_KERNEL);
if (!buf)
return ERR_PTR(-ENOMEM);
@ -889,6 +892,8 @@ static struct regmap *gen_raw_regmap(struct regmap_config *config,
config->cache_type = test_type->cache_type;
config->val_format_endian = test_type->val_endian;
config->disable_locking = config->cache_type == REGCACHE_RBTREE ||
config->cache_type == REGCACHE_MAPLE;
buf = kmalloc(size, GFP_KERNEL);
if (!buf)

View file

@ -660,7 +660,7 @@ static const struct regmap_bus regmap_spi_avmm_bus = {
.reg_format_endian_default = REGMAP_ENDIAN_NATIVE,
.val_format_endian_default = REGMAP_ENDIAN_NATIVE,
.max_raw_read = SPI_AVMM_VAL_SIZE * MAX_READ_CNT,
.max_raw_write = SPI_AVMM_REG_SIZE + SPI_AVMM_VAL_SIZE * MAX_WRITE_CNT,
.max_raw_write = SPI_AVMM_VAL_SIZE * MAX_WRITE_CNT,
.free_context = spi_avmm_bridge_ctx_free,
};

View file

@ -2082,8 +2082,6 @@ int _regmap_raw_write(struct regmap *map, unsigned int reg,
size_t val_count = val_len / val_bytes;
size_t chunk_count, chunk_bytes;
size_t chunk_regs = val_count;
size_t max_data = map->max_raw_write - map->format.reg_bytes -
map->format.pad_bytes;
int ret, i;
if (!val_count)
@ -2091,8 +2089,8 @@ int _regmap_raw_write(struct regmap *map, unsigned int reg,
if (map->use_single_write)
chunk_regs = 1;
else if (map->max_raw_write && val_len > max_data)
chunk_regs = max_data / val_bytes;
else if (map->max_raw_write && val_len > map->max_raw_write)
chunk_regs = map->max_raw_write / val_bytes;
chunk_count = val_count / chunk_regs;
chunk_bytes = chunk_regs * val_bytes;

View file

@ -1775,14 +1775,43 @@ static const struct block_device_operations lo_fops = {
/*
* If max_loop is specified, create that many devices upfront.
* This also becomes a hard limit. If max_loop is not specified,
* the default isn't a hard limit (as before commit 85c50197716c
* changed the default value from 0 for max_loop=0 reasons), just
* create CONFIG_BLK_DEV_LOOP_MIN_COUNT loop devices at module
* init time. Loop devices can be requested on-demand with the
* /dev/loop-control interface, or be instantiated by accessing
* a 'dead' device node.
*/
static int max_loop = CONFIG_BLK_DEV_LOOP_MIN_COUNT;
module_param(max_loop, int, 0444);
#ifdef CONFIG_BLOCK_LEGACY_AUTOLOAD
static bool max_loop_specified;
static int max_loop_param_set_int(const char *val,
const struct kernel_param *kp)
{
int ret;
ret = param_set_int(val, kp);
if (ret < 0)
return ret;
max_loop_specified = true;
return 0;
}
static const struct kernel_param_ops max_loop_param_ops = {
.set = max_loop_param_set_int,
.get = param_get_int,
};
module_param_cb(max_loop, &max_loop_param_ops, &max_loop, 0444);
MODULE_PARM_DESC(max_loop, "Maximum number of loop devices");
#else
module_param(max_loop, int, 0444);
MODULE_PARM_DESC(max_loop, "Initial number of loop devices");
#endif
module_param(max_part, int, 0444);
MODULE_PARM_DESC(max_part, "Maximum number of partitions per loop device");
@ -2093,14 +2122,18 @@ static void loop_remove(struct loop_device *lo)
put_disk(lo->lo_disk);
}
#ifdef CONFIG_BLOCK_LEGACY_AUTOLOAD
static void loop_probe(dev_t dev)
{
int idx = MINOR(dev) >> part_shift;
if (max_loop && idx >= max_loop)
if (max_loop_specified && max_loop && idx >= max_loop)
return;
loop_add(idx);
}
#else
#define loop_probe NULL
#endif /* !CONFIG_BLOCK_LEGACY_AUTOLOAD */
static int loop_control_remove(int idx)
{
@ -2281,6 +2314,9 @@ module_exit(loop_exit);
static int __init max_loop_setup(char *str)
{
max_loop = simple_strtol(str, NULL, 0);
#ifdef CONFIG_BLOCK_LEGACY_AUTOLOAD
max_loop_specified = true;
#endif
return 1;
}

View file

@ -4104,6 +4104,7 @@ static int btusb_probe(struct usb_interface *intf,
BT_DBG("intf %p id %p", intf, id);
if ((id->driver_info & BTUSB_IFNUM_2) &&
(intf->cur_altsetting->desc.bInterfaceNumber != 0) &&
(intf->cur_altsetting->desc.bInterfaceNumber != 2))
return -ENODEV;

View file

@ -518,6 +518,7 @@ static int tpm_add_legacy_sysfs(struct tpm_chip *chip)
* 6.x.y.z series: 6.0.18.6 +
* 3.x.y.z series: 3.57.y.5 +
*/
#ifdef CONFIG_X86
static bool tpm_amd_is_rng_defective(struct tpm_chip *chip)
{
u32 val1, val2;
@ -566,6 +567,12 @@ static bool tpm_amd_is_rng_defective(struct tpm_chip *chip)
return true;
}
#else
static inline bool tpm_amd_is_rng_defective(struct tpm_chip *chip)
{
return false;
}
#endif /* CONFIG_X86 */
static int tpm_hwrng_read(struct hwrng *rng, void *data, size_t max, bool wait)
{

View file

@ -563,15 +563,18 @@ static int crb_map_io(struct acpi_device *device, struct crb_priv *priv,
u32 rsp_size;
int ret;
INIT_LIST_HEAD(&acpi_resource_list);
ret = acpi_dev_get_resources(device, &acpi_resource_list,
crb_check_resource, iores_array);
if (ret < 0)
return ret;
acpi_dev_free_resource_list(&acpi_resource_list);
/* Pluton doesn't appear to define ACPI memory regions */
/*
* Pluton sometimes does not define ACPI memory regions.
* Mapping is then done in crb_map_pluton
*/
if (priv->sm != ACPI_TPM2_COMMAND_BUFFER_WITH_PLUTON) {
INIT_LIST_HEAD(&acpi_resource_list);
ret = acpi_dev_get_resources(device, &acpi_resource_list,
crb_check_resource, iores_array);
if (ret < 0)
return ret;
acpi_dev_free_resource_list(&acpi_resource_list);
if (resource_type(iores_array) != IORESOURCE_MEM) {
dev_err(dev, FW_BUG "TPM2 ACPI table does not define a memory resource\n");
return -EINVAL;

View file

@ -114,6 +114,22 @@ static int tpm_tis_disable_irq(const struct dmi_system_id *d)
}
static const struct dmi_system_id tpm_tis_dmi_table[] = {
{
.callback = tpm_tis_disable_irq,
.ident = "Framework Laptop (12th Gen Intel Core)",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Framework"),
DMI_MATCH(DMI_PRODUCT_NAME, "Laptop (12th Gen Intel Core)"),
},
},
{
.callback = tpm_tis_disable_irq,
.ident = "Framework Laptop (13th Gen Intel Core)",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Framework"),
DMI_MATCH(DMI_PRODUCT_NAME, "Laptop (13th Gen Intel Core)"),
},
},
{
.callback = tpm_tis_disable_irq,
.ident = "ThinkPad T490s",
@ -138,11 +154,20 @@ static const struct dmi_system_id tpm_tis_dmi_table[] = {
DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad L490"),
},
},
{
.callback = tpm_tis_disable_irq,
.ident = "ThinkPad L590",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad L590"),
},
},
{
.callback = tpm_tis_disable_irq,
.ident = "UPX-TGL",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "AAEON"),
DMI_MATCH(DMI_PRODUCT_VERSION, "UPX-TGL"),
},
},
{}

View file

@ -24,9 +24,12 @@
#include <linux/wait.h>
#include <linux/acpi.h>
#include <linux/freezer.h>
#include <linux/dmi.h>
#include "tpm.h"
#include "tpm_tis_core.h"
#define TPM_TIS_MAX_UNHANDLED_IRQS 1000
static void tpm_tis_clkrun_enable(struct tpm_chip *chip, bool value);
static bool wait_for_tpm_stat_cond(struct tpm_chip *chip, u8 mask,
@ -468,25 +471,29 @@ static int tpm_tis_send_data(struct tpm_chip *chip, const u8 *buf, size_t len)
return rc;
}
static void disable_interrupts(struct tpm_chip *chip)
static void __tpm_tis_disable_interrupts(struct tpm_chip *chip)
{
struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
u32 int_mask = 0;
tpm_tis_read32(priv, TPM_INT_ENABLE(priv->locality), &int_mask);
int_mask &= ~TPM_GLOBAL_INT_ENABLE;
tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality), int_mask);
chip->flags &= ~TPM_CHIP_FLAG_IRQ;
}
static void tpm_tis_disable_interrupts(struct tpm_chip *chip)
{
struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
u32 intmask;
int rc;
if (priv->irq == 0)
return;
rc = tpm_tis_read32(priv, TPM_INT_ENABLE(priv->locality), &intmask);
if (rc < 0)
intmask = 0;
intmask &= ~TPM_GLOBAL_INT_ENABLE;
rc = tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality), intmask);
__tpm_tis_disable_interrupts(chip);
devm_free_irq(chip->dev.parent, priv->irq, chip);
priv->irq = 0;
chip->flags &= ~TPM_CHIP_FLAG_IRQ;
}
/*
@ -552,7 +559,7 @@ static int tpm_tis_send(struct tpm_chip *chip, u8 *buf, size_t len)
if (!test_bit(TPM_TIS_IRQ_TESTED, &priv->flags))
tpm_msleep(1);
if (!test_bit(TPM_TIS_IRQ_TESTED, &priv->flags))
disable_interrupts(chip);
tpm_tis_disable_interrupts(chip);
set_bit(TPM_TIS_IRQ_TESTED, &priv->flags);
return rc;
}
@ -752,6 +759,57 @@ static bool tpm_tis_req_canceled(struct tpm_chip *chip, u8 status)
return status == TPM_STS_COMMAND_READY;
}
static irqreturn_t tpm_tis_revert_interrupts(struct tpm_chip *chip)
{
struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
const char *product;
const char *vendor;
dev_warn(&chip->dev, FW_BUG
"TPM interrupt storm detected, polling instead\n");
vendor = dmi_get_system_info(DMI_SYS_VENDOR);
product = dmi_get_system_info(DMI_PRODUCT_VERSION);
if (vendor && product) {
dev_info(&chip->dev,
"Consider adding the following entry to tpm_tis_dmi_table:\n");
dev_info(&chip->dev, "\tDMI_SYS_VENDOR: %s\n", vendor);
dev_info(&chip->dev, "\tDMI_PRODUCT_VERSION: %s\n", product);
}
if (tpm_tis_request_locality(chip, 0) != 0)
return IRQ_NONE;
__tpm_tis_disable_interrupts(chip);
tpm_tis_relinquish_locality(chip, 0);
schedule_work(&priv->free_irq_work);
return IRQ_HANDLED;
}
static irqreturn_t tpm_tis_update_unhandled_irqs(struct tpm_chip *chip)
{
struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
irqreturn_t irqret = IRQ_HANDLED;
if (!(chip->flags & TPM_CHIP_FLAG_IRQ))
return IRQ_HANDLED;
if (time_after(jiffies, priv->last_unhandled_irq + HZ/10))
priv->unhandled_irqs = 1;
else
priv->unhandled_irqs++;
priv->last_unhandled_irq = jiffies;
if (priv->unhandled_irqs > TPM_TIS_MAX_UNHANDLED_IRQS)
irqret = tpm_tis_revert_interrupts(chip);
return irqret;
}
static irqreturn_t tis_int_handler(int dummy, void *dev_id)
{
struct tpm_chip *chip = dev_id;
@ -761,10 +819,10 @@ static irqreturn_t tis_int_handler(int dummy, void *dev_id)
rc = tpm_tis_read32(priv, TPM_INT_STATUS(priv->locality), &interrupt);
if (rc < 0)
return IRQ_NONE;
goto err;
if (interrupt == 0)
return IRQ_NONE;
goto err;
set_bit(TPM_TIS_IRQ_TESTED, &priv->flags);
if (interrupt & TPM_INTF_DATA_AVAIL_INT)
@ -780,10 +838,13 @@ static irqreturn_t tis_int_handler(int dummy, void *dev_id)
rc = tpm_tis_write32(priv, TPM_INT_STATUS(priv->locality), interrupt);
tpm_tis_relinquish_locality(chip, 0);
if (rc < 0)
return IRQ_NONE;
goto err;
tpm_tis_read32(priv, TPM_INT_STATUS(priv->locality), &interrupt);
return IRQ_HANDLED;
err:
return tpm_tis_update_unhandled_irqs(chip);
}
static void tpm_tis_gen_interrupt(struct tpm_chip *chip)
@ -804,6 +865,15 @@ static void tpm_tis_gen_interrupt(struct tpm_chip *chip)
chip->flags &= ~TPM_CHIP_FLAG_IRQ;
}
static void tpm_tis_free_irq_func(struct work_struct *work)
{
struct tpm_tis_data *priv = container_of(work, typeof(*priv), free_irq_work);
struct tpm_chip *chip = priv->chip;
devm_free_irq(chip->dev.parent, priv->irq, chip);
priv->irq = 0;
}
/* Register the IRQ and issue a command that will cause an interrupt. If an
* irq is seen then leave the chip setup for IRQ operation, otherwise reverse
* everything and leave in polling mode. Returns 0 on success.
@ -816,6 +886,7 @@ static int tpm_tis_probe_irq_single(struct tpm_chip *chip, u32 intmask,
int rc;
u32 int_status;
INIT_WORK(&priv->free_irq_work, tpm_tis_free_irq_func);
rc = devm_request_threaded_irq(chip->dev.parent, irq, NULL,
tis_int_handler, IRQF_ONESHOT | flags,
@ -918,6 +989,7 @@ void tpm_tis_remove(struct tpm_chip *chip)
interrupt = 0;
tpm_tis_write32(priv, reg, ~TPM_GLOBAL_INT_ENABLE & interrupt);
flush_work(&priv->free_irq_work);
tpm_tis_clkrun_enable(chip, false);
@ -1021,6 +1093,7 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
chip->timeout_b = msecs_to_jiffies(TIS_TIMEOUT_B_MAX);
chip->timeout_c = msecs_to_jiffies(TIS_TIMEOUT_C_MAX);
chip->timeout_d = msecs_to_jiffies(TIS_TIMEOUT_D_MAX);
priv->chip = chip;
priv->timeout_min = TPM_TIMEOUT_USECS_MIN;
priv->timeout_max = TPM_TIMEOUT_USECS_MAX;
priv->phy_ops = phy_ops;
@ -1179,7 +1252,7 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
rc = tpm_tis_request_locality(chip, 0);
if (rc < 0)
goto out_err;
disable_interrupts(chip);
tpm_tis_disable_interrupts(chip);
tpm_tis_relinquish_locality(chip, 0);
}
}

View file

@ -91,11 +91,15 @@ enum tpm_tis_flags {
};
struct tpm_tis_data {
struct tpm_chip *chip;
u16 manufacturer_id;
struct mutex locality_count_mutex;
unsigned int locality_count;
int locality;
int irq;
struct work_struct free_irq_work;
unsigned long last_unhandled_irq;
unsigned int unhandled_irqs;
unsigned int int_mask;
unsigned long flags;
void __iomem *ilb_base_addr;

View file

@ -189,21 +189,28 @@ static int tpm_tis_i2c_read_bytes(struct tpm_tis_data *data, u32 addr, u16 len,
int ret;
for (i = 0; i < TPM_RETRY; i++) {
/* write register */
msg.len = sizeof(reg);
msg.buf = &reg;
msg.flags = 0;
ret = tpm_tis_i2c_retry_transfer_until_ack(data, &msg);
if (ret < 0)
return ret;
u16 read = 0;
/* read data */
msg.buf = result;
msg.len = len;
msg.flags = I2C_M_RD;
ret = tpm_tis_i2c_retry_transfer_until_ack(data, &msg);
if (ret < 0)
return ret;
while (read < len) {
/* write register */
msg.len = sizeof(reg);
msg.buf = &reg;
msg.flags = 0;
ret = tpm_tis_i2c_retry_transfer_until_ack(data, &msg);
if (ret < 0)
return ret;
/* read data */
msg.buf = result + read;
msg.len = len - read;
msg.flags = I2C_M_RD;
if (msg.len > I2C_SMBUS_BLOCK_MAX)
msg.len = I2C_SMBUS_BLOCK_MAX;
ret = tpm_tis_i2c_retry_transfer_until_ack(data, &msg);
if (ret < 0)
return ret;
read += msg.len;
}
ret = tpm_tis_i2c_sanity_check_read(reg, len, result);
if (ret == 0)
@ -223,19 +230,27 @@ static int tpm_tis_i2c_write_bytes(struct tpm_tis_data *data, u32 addr, u16 len,
struct i2c_msg msg = { .addr = phy->i2c_client->addr };
u8 reg = tpm_tis_i2c_address_to_register(addr);
int ret;
u16 wrote = 0;
if (len > TPM_BUFSIZE - 1)
return -EIO;
/* write register and data in one go */
phy->io_buf[0] = reg;
memcpy(phy->io_buf + sizeof(reg), value, len);
msg.len = sizeof(reg) + len;
msg.buf = phy->io_buf;
ret = tpm_tis_i2c_retry_transfer_until_ack(data, &msg);
if (ret < 0)
return ret;
while (wrote < len) {
/* write register and data in one go */
msg.len = sizeof(reg) + len - wrote;
if (msg.len > I2C_SMBUS_BLOCK_MAX)
msg.len = I2C_SMBUS_BLOCK_MAX;
memcpy(phy->io_buf + sizeof(reg), value + wrote,
msg.len - sizeof(reg));
ret = tpm_tis_i2c_retry_transfer_until_ack(data, &msg);
if (ret < 0)
return ret;
wrote += msg.len - sizeof(reg);
}
return 0;
}

View file

@ -136,6 +136,14 @@ int tpm_tis_spi_transfer(struct tpm_tis_data *data, u32 addr, u16 len,
}
exit:
if (ret < 0) {
/* Deactivate chip select */
memset(&spi_xfer, 0, sizeof(spi_xfer));
spi_message_init(&m);
spi_message_add_tail(&spi_xfer, &m);
spi_sync_locked(phy->spi_device, &m);
}
spi_bus_unlock(phy->spi_device->master);
return ret;
}

View file

@ -683,37 +683,21 @@ static struct miscdevice vtpmx_miscdev = {
.fops = &vtpmx_fops,
};
static int vtpmx_init(void)
{
return misc_register(&vtpmx_miscdev);
}
static void vtpmx_cleanup(void)
{
misc_deregister(&vtpmx_miscdev);
}
static int __init vtpm_module_init(void)
{
int rc;
rc = vtpmx_init();
if (rc) {
pr_err("couldn't create vtpmx device\n");
return rc;
}
workqueue = create_workqueue("tpm-vtpm");
if (!workqueue) {
pr_err("couldn't create workqueue\n");
rc = -ENOMEM;
goto err_vtpmx_cleanup;
return -ENOMEM;
}
return 0;
err_vtpmx_cleanup:
vtpmx_cleanup();
rc = misc_register(&vtpmx_miscdev);
if (rc) {
pr_err("couldn't create vtpmx device\n");
destroy_workqueue(workqueue);
}
return rc;
}
@ -721,7 +705,7 @@ static int __init vtpm_module_init(void)
static void __exit vtpm_module_exit(void)
{
destroy_workqueue(workqueue);
vtpmx_cleanup();
misc_deregister(&vtpmx_miscdev);
}
module_init(vtpm_module_init);

View file

@ -571,6 +571,7 @@ int dma_resv_get_fences(struct dma_resv *obj, enum dma_resv_usage usage,
dma_resv_for_each_fence_unlocked(&cursor, fence) {
if (dma_resv_iter_is_restarted(&cursor)) {
struct dma_fence **new_fences;
unsigned int count;
while (*num_fences)
@ -579,13 +580,17 @@ int dma_resv_get_fences(struct dma_resv *obj, enum dma_resv_usage usage,
count = cursor.num_fences + 1;
/* Eventually re-allocate the array */
*fences = krealloc_array(*fences, count,
sizeof(void *),
GFP_KERNEL);
if (count && !*fences) {
new_fences = krealloc_array(*fences, count,
sizeof(void *),
GFP_KERNEL);
if (count && !new_fences) {
kfree(*fences);
*fences = NULL;
*num_fences = 0;
dma_resv_iter_end(&cursor);
return -ENOMEM;
}
*fences = new_fences;
}
(*fences)[(*num_fences)++] = dma_fence_get(fence);

View file

@ -874,7 +874,7 @@ static int mvebu_pwm_probe(struct platform_device *pdev,
spin_lock_init(&mvpwm->lock);
return pwmchip_add(&mvpwm->chip);
return devm_pwmchip_add(dev, &mvpwm->chip);
}
#ifdef CONFIG_DEBUG_FS
@ -1112,6 +1112,13 @@ static int mvebu_gpio_probe_syscon(struct platform_device *pdev,
return 0;
}
static void mvebu_gpio_remove_irq_domain(void *data)
{
struct irq_domain *domain = data;
irq_domain_remove(domain);
}
static int mvebu_gpio_probe(struct platform_device *pdev)
{
struct mvebu_gpio_chip *mvchip;
@ -1243,17 +1250,21 @@ static int mvebu_gpio_probe(struct platform_device *pdev)
if (!mvchip->domain) {
dev_err(&pdev->dev, "couldn't allocate irq domain %s (DT).\n",
mvchip->chip.label);
err = -ENODEV;
goto err_pwm;
return -ENODEV;
}
err = devm_add_action_or_reset(&pdev->dev, mvebu_gpio_remove_irq_domain,
mvchip->domain);
if (err)
return err;
err = irq_alloc_domain_generic_chips(
mvchip->domain, ngpios, 2, np->name, handle_level_irq,
IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_LEVEL, 0, 0);
if (err) {
dev_err(&pdev->dev, "couldn't allocate irq chips %s (DT).\n",
mvchip->chip.label);
goto err_domain;
return err;
}
/*
@ -1293,13 +1304,6 @@ static int mvebu_gpio_probe(struct platform_device *pdev)
}
return 0;
err_domain:
irq_domain_remove(mvchip->domain);
err_pwm:
pwmchip_remove(&mvchip->mvpwm->chip);
return err;
}
static struct platform_driver mvebu_gpio_driver = {

View file

@ -91,13 +91,13 @@ static int tps68470_gpio_output(struct gpio_chip *gc, unsigned int offset,
struct tps68470_gpio_data *tps68470_gpio = gpiochip_get_data(gc);
struct regmap *regmap = tps68470_gpio->tps68470_regmap;
/* Set the initial value */
tps68470_gpio_set(gc, offset, value);
/* rest are always outputs */
if (offset >= TPS68470_N_REGULAR_GPIO)
return 0;
/* Set the initial value */
tps68470_gpio_set(gc, offset, value);
return regmap_update_bits(regmap, TPS68470_GPIO_CTL_REG_A(offset),
TPS68470_GPIO_MODE_MASK,
TPS68470_GPIO_MODE_OUT_CMOS);

View file

@ -1709,7 +1709,8 @@ int amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu(
alloc_flags |= (flags & KFD_IOC_ALLOC_MEM_FLAGS_PUBLIC) ?
AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED : 0;
}
xcp_id = fpriv->xcp_id == ~0 ? 0 : fpriv->xcp_id;
xcp_id = fpriv->xcp_id == AMDGPU_XCP_NO_PARTITION ?
0 : fpriv->xcp_id;
} else if (flags & KFD_IOC_ALLOC_MEM_FLAGS_GTT) {
domain = alloc_domain = AMDGPU_GEM_DOMAIN_GTT;
alloc_flags = 0;

View file

@ -1229,13 +1229,13 @@ int amdgpu_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv)
pasid = 0;
}
r = amdgpu_vm_init(adev, &fpriv->vm);
r = amdgpu_xcp_open_device(adev, fpriv, file_priv);
if (r)
goto error_pasid;
r = amdgpu_xcp_open_device(adev, fpriv, file_priv);
r = amdgpu_vm_init(adev, &fpriv->vm, fpriv->xcp_id);
if (r)
goto error_vm;
goto error_pasid;
r = amdgpu_vm_set_pasid(adev, &fpriv->vm, pasid);
if (r)

View file

@ -1382,7 +1382,7 @@ int amdgpu_mes_self_test(struct amdgpu_device *adev)
goto error_pasid;
}
r = amdgpu_vm_init(adev, vm);
r = amdgpu_vm_init(adev, vm, -1);
if (r) {
DRM_ERROR("failed to initialize vm\n");
goto error_pasid;

View file

@ -55,8 +55,9 @@ static enum hrtimer_restart amdgpu_vkms_vblank_simulate(struct hrtimer *timer)
DRM_WARN("%s: vblank timer overrun\n", __func__);
ret = drm_crtc_handle_vblank(crtc);
/* Don't queue timer again when vblank is disabled. */
if (!ret)
DRM_ERROR("amdgpu_vkms failure on handling vblank");
return HRTIMER_NORESTART;
return HRTIMER_RESTART;
}
@ -81,7 +82,7 @@ static void amdgpu_vkms_disable_vblank(struct drm_crtc *crtc)
{
struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
hrtimer_cancel(&amdgpu_crtc->vblank_timer);
hrtimer_try_to_cancel(&amdgpu_crtc->vblank_timer);
}
static bool amdgpu_vkms_get_vblank_timestamp(struct drm_crtc *crtc,

View file

@ -2121,13 +2121,14 @@ long amdgpu_vm_wait_idle(struct amdgpu_vm *vm, long timeout)
*
* @adev: amdgpu_device pointer
* @vm: requested vm
* @xcp_id: GPU partition selection id
*
* Init @vm fields.
*
* Returns:
* 0 for success, error for failure.
*/
int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm)
int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm, int32_t xcp_id)
{
struct amdgpu_bo *root_bo;
struct amdgpu_bo_vm *root;
@ -2177,7 +2178,7 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm)
vm->evicting = false;
r = amdgpu_vm_pt_create(adev, vm, adev->vm_manager.root_level,
false, &root);
false, &root, xcp_id);
if (r)
goto error_free_delayed;
root_bo = &root->bo;

View file

@ -392,7 +392,7 @@ int amdgpu_vm_set_pasid(struct amdgpu_device *adev, struct amdgpu_vm *vm,
u32 pasid);
long amdgpu_vm_wait_idle(struct amdgpu_vm *vm, long timeout);
int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm);
int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm, int32_t xcp_id);
int amdgpu_vm_make_compute(struct amdgpu_device *adev, struct amdgpu_vm *vm);
void amdgpu_vm_release_compute(struct amdgpu_device *adev, struct amdgpu_vm *vm);
void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm);
@ -475,7 +475,8 @@ void amdgpu_vm_get_memory(struct amdgpu_vm *vm,
int amdgpu_vm_pt_clear(struct amdgpu_device *adev, struct amdgpu_vm *vm,
struct amdgpu_bo_vm *vmbo, bool immediate);
int amdgpu_vm_pt_create(struct amdgpu_device *adev, struct amdgpu_vm *vm,
int level, bool immediate, struct amdgpu_bo_vm **vmbo);
int level, bool immediate, struct amdgpu_bo_vm **vmbo,
int32_t xcp_id);
void amdgpu_vm_pt_free_root(struct amdgpu_device *adev, struct amdgpu_vm *vm);
bool amdgpu_vm_pt_is_root_clean(struct amdgpu_device *adev,
struct amdgpu_vm *vm);

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