diff --git a/.mailmap b/.mailmap index 369cfe467932d7..b5e240f78b8c2d 100644 --- a/.mailmap +++ b/.mailmap @@ -206,6 +206,7 @@ Danilo Krummrich David Brownell David Collins David Heidelberg +David Hildenbrand David Rheinsberg David Rheinsberg David Rheinsberg @@ -426,7 +427,7 @@ Kenneth W Chen Kenneth Westfield Kiran Gunda Kirill Tkhai -Kirill A. Shutemov +Kiryl Shutsemau Kishon Vijay Abraham I Konrad Dybcio Konrad Dybcio @@ -437,6 +438,7 @@ Krishna Manikandan Krzysztof Kozlowski Krzysztof Kozlowski Krzysztof Kozlowski +Krzysztof Kozlowski Krzysztof Wilczyński Krzysztof Wilczyński Kshitiz Godara @@ -605,7 +607,8 @@ Oleksij Rempel Oleksij Rempel Oliver Hartkopp Oliver Hartkopp -Oliver Upton +Oliver Upton +Oliver Upton Ondřej Jirman Oza Pawandeep Pali Rohár diff --git a/Documentation/devicetree/bindings/gpio/ti,twl4030-gpio.yaml b/Documentation/devicetree/bindings/gpio/ti,twl4030-gpio.yaml index 5e3e199fd9a498..96d50d14c07109 100644 --- a/Documentation/devicetree/bindings/gpio/ti,twl4030-gpio.yaml +++ b/Documentation/devicetree/bindings/gpio/ti,twl4030-gpio.yaml @@ -1,7 +1,7 @@ # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) %YAML 1.2 --- -$id: http://devicetree.org/schemas/ti,twl4030-gpio.yaml# +$id: http://devicetree.org/schemas/gpio/ti,twl4030-gpio.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# title: TI TWL4030 GPIO controller diff --git a/Documentation/devicetree/bindings/pinctrl/toshiba,visconti-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/toshiba,visconti-pinctrl.yaml index 19d47fd414bc06..ce04d2eadec9d5 100644 --- a/Documentation/devicetree/bindings/pinctrl/toshiba,visconti-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/toshiba,visconti-pinctrl.yaml @@ -50,18 +50,20 @@ patternProperties: groups: description: Name of the pin group to use for the functions. - $ref: /schemas/types.yaml#/definitions/string - enum: [i2c0_grp, i2c1_grp, i2c2_grp, i2c3_grp, i2c4_grp, - i2c5_grp, i2c6_grp, i2c7_grp, i2c8_grp, - spi0_grp, spi0_cs0_grp, spi0_cs1_grp, spi0_cs2_grp, - spi1_grp, spi2_grp, spi3_grp, spi4_grp, spi5_grp, spi6_grp, - uart0_grp, uart1_grp, uart2_grp, uart3_grp, - pwm0_gpio4_grp, pwm0_gpio8_grp, pwm0_gpio12_grp, - pwm0_gpio16_grp, pwm1_gpio5_grp, pwm1_gpio9_grp, - pwm1_gpio13_grp, pwm1_gpio17_grp, pwm2_gpio6_grp, - pwm2_gpio10_grp, pwm2_gpio14_grp, pwm2_gpio18_grp, - pwm3_gpio7_grp, pwm3_gpio11_grp, pwm3_gpio15_grp, - pwm3_gpio19_grp, pcmif_out_grp, pcmif_in_grp] + items: + enum: [i2c0_grp, i2c1_grp, i2c2_grp, i2c3_grp, i2c4_grp, + i2c5_grp, i2c6_grp, i2c7_grp, i2c8_grp, + spi0_grp, spi0_cs0_grp, spi0_cs1_grp, spi0_cs2_grp, + spi1_grp, spi2_grp, spi3_grp, spi4_grp, spi5_grp, spi6_grp, + uart0_grp, uart1_grp, uart2_grp, uart3_grp, + pwm0_gpio4_grp, pwm0_gpio8_grp, pwm0_gpio12_grp, + pwm0_gpio16_grp, pwm1_gpio5_grp, pwm1_gpio9_grp, + pwm1_gpio13_grp, pwm1_gpio17_grp, pwm2_gpio6_grp, + pwm2_gpio10_grp, pwm2_gpio14_grp, pwm2_gpio18_grp, + pwm3_gpio7_grp, pwm3_gpio11_grp, pwm3_gpio15_grp, + pwm3_gpio19_grp, pcmif_out_grp, pcmif_in_grp] + minItems: 1 + maxItems: 8 drive-strength: enum: [2, 4, 6, 8, 16, 24, 32] diff --git a/Documentation/devicetree/bindings/pinctrl/xlnx,versal-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/xlnx,versal-pinctrl.yaml index 55ece6a8be5efd..81e2164ea98f65 100644 --- a/Documentation/devicetree/bindings/pinctrl/xlnx,versal-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/xlnx,versal-pinctrl.yaml @@ -74,6 +74,7 @@ patternProperties: '^conf': type: object + unevaluatedProperties: false description: Pinctrl node's client devices use subnodes for pin configurations, which in turn use the standard properties below. diff --git a/Documentation/devicetree/bindings/sound/mediatek,mt8189-afe-pcm.yaml b/Documentation/devicetree/bindings/sound/mediatek,mt8189-afe-pcm.yaml new file mode 100644 index 00000000000000..9c9f21652af9f2 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/mediatek,mt8189-afe-pcm.yaml @@ -0,0 +1,178 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/sound/mediatek,mt8189-afe-pcm.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: MediaTek Audio Front End PCM controller for MT8189 + +maintainers: + - Darren Ye + - Cyril Chao + +properties: + compatible: + const: mediatek,mt8189-afe-pcm + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + memory-region: + maxItems: 1 + + mediatek,apmixedsys: + $ref: /schemas/types.yaml#/definitions/phandle + description: To set up the apll12 tuner + + power-domains: + maxItems: 1 + + clocks: + items: + - description: mux for audio intbus + - description: mux for audio engen1 + - description: mux for audio engen2 + - description: mux for audio h + - description: audio apll1 clock + - description: audio apll2 clock + - description: audio apll1 divide4 + - description: audio apll2 divide4 + - description: audio apll12 divide for i2sin0 + - description: audio apll12 divide for i2sin1 + - description: audio apll12 divide for i2sout0 + - description: audio apll12 divide for i2sout1 + - description: audio apll12 divide for fmi2s + - description: audio apll12 divide for tdmout mck + - description: audio apll12 divide for tdmout bck + - description: mux for audio apll1 + - description: mux for audio apll2 + - description: mux for i2sin0 mck + - description: mux for i2sin1 mck + - description: mux for i2sout0 mck + - description: mux for i2sout1 mck + - description: mux for fmi2s mck + - description: mux for tdmout mck + - description: 26m clock + - description: audio slv clock + - description: audio mst clock + - description: audio intbus clock + + clock-names: + items: + - const: top_aud_intbus + - const: top_aud_eng1 + - const: top_aud_eng2 + - const: top_aud_h + - const: apll1 + - const: apll2 + - const: apll1_d4 + - const: apll2_d4 + - const: apll12_div_i2sin0 + - const: apll12_div_i2sin1 + - const: apll12_div_i2sout0 + - const: apll12_div_i2sout1 + - const: apll12_div_fmi2s + - const: apll12_div_tdmout_m + - const: apll12_div_tdmout_b + - const: top_apll1 + - const: top_apll2 + - const: top_i2sin0 + - const: top_i2sin1 + - const: top_i2sout0 + - const: top_i2sout1 + - const: top_fmi2s + - const: top_dptx + - const: clk26m + - const: aud_slv_ck_peri + - const: aud_mst_ck_peri + - const: aud_intbus_ck_peri + +required: + - compatible + - reg + - interrupts + - memory-region + - power-domains + - clocks + - clock-names + +additionalProperties: false + +examples: + - | + #include + #include + + soc { + #address-cells = <2>; + #size-cells = <2>; + + afe@11050000 { + compatible = "mediatek,mt8189-afe-pcm"; + reg = <0 0x11050000 0 0x10000>; + interrupts = ; + memory-region = <&afe_dma_mem_reserved>; + pinctrl-names = "default"; + pinctrl-0 = <&aud_pins_default>; + power-domains = <&scpsys 1>; //MT8189_POWER_DOMAIN_AUDIO + clocks = <&topckgen_clk 23>, //CLK_TOP_AUD_INTBUS_SEL + <&topckgen_clk 39>, //CLK_TOP_AUD_ENGEN1_SEL + <&topckgen_clk 40>, //CLK_TOP_AUD_ENGEN2_SEL + <&topckgen_clk 49>, //CLK_TOP_AUDIO_H_SEL + <&topckgen_clk 146>, //CLK_TOP_APLL1 + <&topckgen_clk 151>, //CLK_TOP_APLL2 + <&topckgen_clk 148>, //CLK_TOP_APLL1_D4 + <&topckgen_clk 153>, //CLK_TOP_APLL2_D4 + <&topckgen_clk 93>, //CLK_TOP_APLL12_CK_DIV_I2SIN0 + <&topckgen_clk 94>, //CLK_TOP_APLL12_CK_DIV_I2SIN1 + <&topckgen_clk 95>, //CLK_TOP_APLL12_CK_DIV_I2SOUT0 + <&topckgen_clk 96>, //CLK_TOP_APLL12_CK_DIV_I2SOUT1 + <&topckgen_clk 97>, //CLK_TOP_APLL12_CK_DIV_FMI2S + <&topckgen_clk 98>, //CLK_TOP_APLL12_CK_DIV_TDMOUT_M + <&topckgen_clk 99>, //CLK_TOP_APLL12_CK_DIV_TDMOUT_B + <&topckgen_clk 44>, //CLK_TOP_AUD_1_SEL + <&topckgen_clk 45>, //CLK_TOP_AUD_2_SEL + <&topckgen_clk 78>, //CLK_TOP_APLL_I2SIN0_MCK_SEL + <&topckgen_clk 79>, //CLK_TOP_APLL_I2SIN1_MCK_SEL + <&topckgen_clk 84>, //CLK_TOP_APLL_I2SOUT0_MCK_SEL + <&topckgen_clk 85>, //CLK_TOP_APLL_I2SOUT1_MCK_SEL + <&topckgen_clk 90>, //CLK_TOP_APLL_FMI2S_MCK_SEL + <&topckgen_clk 91>, //CLK_TOP_APLL_TDMOUT_MCK_SEL + <&topckgen_clk 191>, //CLK_TOP_TCK_26M_MX9 + <&pericfg_ao_clk 77>, //CLK_PERAO_AUDIO0 + <&pericfg_ao_clk 78>, //CLK_PERAO_AUDIO1 + <&pericfg_ao_clk 79>; //CLK_PERAO_AUDIO2 + clock-names = "top_aud_intbus", + "top_aud_eng1", + "top_aud_eng2", + "top_aud_h", + "apll1", + "apll2", + "apll1_d4", + "apll2_d4", + "apll12_div_i2sin0", + "apll12_div_i2sin1", + "apll12_div_i2sout0", + "apll12_div_i2sout1", + "apll12_div_fmi2s", + "apll12_div_tdmout_m", + "apll12_div_tdmout_b", + "top_apll1", + "top_apll2", + "top_i2sin0", + "top_i2sin1", + "top_i2sout0", + "top_i2sout1", + "top_fmi2s", + "top_dptx", + "clk26m", + "aud_slv_ck_peri", + "aud_mst_ck_peri", + "aud_intbus_ck_peri"; + }; + }; + +... diff --git a/Documentation/devicetree/bindings/sound/mediatek,mt8189-nau8825.yaml b/Documentation/devicetree/bindings/sound/mediatek,mt8189-nau8825.yaml new file mode 100644 index 00000000000000..dd9ee0a3b292ee --- /dev/null +++ b/Documentation/devicetree/bindings/sound/mediatek,mt8189-nau8825.yaml @@ -0,0 +1,101 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/sound/mediatek,mt8189-nau8825.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: MediaTek MT8189 ASoC sound card + +maintainers: + - Darren Ye + - Cyril Chao + +allOf: + - $ref: sound-card-common.yaml# + +properties: + compatible: + enum: + - mediatek,mt8189-nau8825 + - mediatek,mt8189-rt5650 + - mediatek,mt8189-rt5682s + - mediatek,mt8189-rt5682i + - mediatek,mt8189-es8326 + + mediatek,platform: + $ref: /schemas/types.yaml#/definitions/phandle + description: The phandle of MT8189 ASoC platform. + +patternProperties: + "^dai-link-[0-9]+$": + type: object + description: + Container for dai-link level properties and CODEC sub-nodes. + + properties: + link-name: + description: + This property corresponds to the name of the BE dai-link to which + we are going to update parameters in this node. + enum: + - TDM_DPTX_BE + - I2SOUT0_BE + - I2SIN0_BE + - I2SOUT1_BE + + codec: + description: Holds subnode which indicates codec dai. + type: object + additionalProperties: false + + properties: + sound-dai: + minItems: 1 + maxItems: 2 + required: + - sound-dai + + dai-format: + description: audio format. + enum: + - i2s + - right_j + - left_j + - dsp_a + - dsp_b + + mediatek,clk-provider: + $ref: /schemas/types.yaml#/definitions/string + description: Indicates dai-link clock master. + enum: + - cpu + - codec + + additionalProperties: false + + required: + - link-name + +required: + - compatible + - mediatek,platform + +unevaluatedProperties: false + +examples: + - | + sound { + compatible = "mediatek,mt8189-nau8825"; + model = "mt8189_rt9123_8825"; + mediatek,platform = <&afe>; + dai-link-0 { + link-name = "I2SOUT1_BE"; + dai-format = "i2s"; + mediatek,clk-provider = "cpu"; + codec { + sound-dai = <&nau8825>; + }; + }; + }; + +... diff --git a/Documentation/devicetree/bindings/sound/qcom,lpass-rx-macro.yaml b/Documentation/devicetree/bindings/sound/qcom,lpass-rx-macro.yaml index b869469a584807..2eed2277511f89 100644 --- a/Documentation/devicetree/bindings/sound/qcom,lpass-rx-macro.yaml +++ b/Documentation/devicetree/bindings/sound/qcom,lpass-rx-macro.yaml @@ -14,6 +14,7 @@ properties: oneOf: - enum: - qcom,sc7280-lpass-rx-macro + - qcom,sm6115-lpass-rx-macro - qcom,sm8250-lpass-rx-macro - qcom,sm8450-lpass-rx-macro - qcom,sm8550-lpass-rx-macro @@ -81,6 +82,23 @@ allOf: - const: npl - const: fsgen + - if: + properties: + compatible: + enum: + - qcom,sm6115-lpass-rx-macro + then: + properties: + clocks: + minItems: 4 + maxItems: 4 + clock-names: + items: + - const: mclk + - const: npl + - const: dcodec + - const: fsgen + - if: properties: compatible: diff --git a/Documentation/devicetree/bindings/sound/qcom,lpass-va-macro.yaml b/Documentation/devicetree/bindings/sound/qcom,lpass-va-macro.yaml index 5b450f227b70a4..5c42b2b323ee41 100644 --- a/Documentation/devicetree/bindings/sound/qcom,lpass-va-macro.yaml +++ b/Documentation/devicetree/bindings/sound/qcom,lpass-va-macro.yaml @@ -14,6 +14,7 @@ properties: oneOf: - enum: - qcom,sc7280-lpass-va-macro + - qcom,sm6115-lpass-va-macro - qcom,sm8250-lpass-va-macro - qcom,sm8450-lpass-va-macro - qcom,sm8550-lpass-va-macro @@ -42,11 +43,7 @@ properties: clock-names: minItems: 1 - items: - - const: mclk - - const: macro - - const: dcodec - - const: npl + maxItems: 4 clock-output-names: maxItems: 1 @@ -91,29 +88,48 @@ allOf: clocks: maxItems: 1 clock-names: - maxItems: 1 + items: + - const: mclk else: properties: clocks: minItems: 3 maxItems: 3 clock-names: - minItems: 3 - maxItems: 3 - + items: + - const: mclk + - const: macro + - const: dcodec - if: properties: compatible: contains: - const: qcom,sm8250-lpass-va-macro + const: qcom,sm6115-lpass-va-macro then: properties: clocks: minItems: 3 maxItems: 3 clock-names: + items: + - const: mclk + - const: dcodec + - const: npl + - if: + properties: + compatible: + contains: + const: qcom,sm8250-lpass-va-macro + then: + properties: + clocks: minItems: 3 maxItems: 3 + clock-names: + items: + - const: mclk + - const: macro + - const: dcodec - if: properties: @@ -128,8 +144,11 @@ allOf: minItems: 4 maxItems: 4 clock-names: - minItems: 4 - maxItems: 4 + items: + - const: mclk + - const: macro + - const: dcodec + - const: npl - if: properties: @@ -143,8 +162,10 @@ allOf: minItems: 3 maxItems: 3 clock-names: - minItems: 3 - maxItems: 3 + items: + - const: mclk + - const: macro + - const: dcodec unevaluatedProperties: false diff --git a/Documentation/devicetree/bindings/sound/ti,tas2781.yaml b/Documentation/devicetree/bindings/sound/ti,tas2781.yaml index f0bb5faf55c81c..f3a5638f4239c5 100644 --- a/Documentation/devicetree/bindings/sound/ti,tas2781.yaml +++ b/Documentation/devicetree/bindings/sound/ti,tas2781.yaml @@ -34,12 +34,16 @@ description: | https://www.ti.com/lit/gpn/tas2320 https://www.ti.com/lit/gpn/tas2563 https://www.ti.com/lit/gpn/tas2572 + https://www.ti.com/lit/gpn/tas2574 https://www.ti.com/lit/gpn/tas2781 + https://www.ti.com/lit/gpn/tas5806m + https://www.ti.com/lit/gpn/tas5806md https://www.ti.com/lit/gpn/tas5815 https://www.ti.com/lit/gpn/tas5822m https://www.ti.com/lit/gpn/tas5825m https://www.ti.com/lit/gpn/tas5827 https://www.ti.com/lit/gpn/tas5828m + https://www.ti.com/lit/gpn/tas5830 properties: compatible: @@ -58,12 +62,18 @@ properties: ti,tas2563: 6.1-W Boosted Class-D Audio Amplifier With Integrated DSP and IV Sense, 16/20/24/32bit stereo I2S or multichannel TDM. + ti,tas2568: 5.3-W Digital Input Smart Amp with I/V Sense and Integrated + 10.75-V Class-H Boost + ti,tas2570: 5.8-W Digital Input smart amp with I/V sense and integrated 11-V Class-H Boost ti,tas2572: 6.6-W Digital Input smart amp with I/V sense and integrated 13-V Class-H Boost + ti,tas2574: 8.5-W Digital Input smart amp with I/V sense and integrated + 15-V Class-H Boost + ti,tas2781: 24-V Class-D Amplifier with Real Time Integrated Speaker Protection and Audio Processing, 16/20/24/32bit stereo I2S or multichannel TDM. @@ -72,6 +82,14 @@ properties: Audio Amplifier with 96-Khz Extended Processing and Low Idle Power Dissipation. + ti,tas5806m: 23-W, Inductor-Less, Digital Input, Stereo, Closed-Loop + Class-D Audio Amplifier with Enhanced Processing and Low Power + Dissipation. + + ti,tas5806md: 23-W, Inductor-Less, Digital Input, Stereo, Closed-Loop + Class-D Audio Amplifier with Enhanced Processing and DirectPath(TM) + HP Driver + ti,tas5815: 30-W, Digital Input, Stereo, Closed-loop Class-D Audio Amplifier with 96 kHz Enhanced Processing @@ -86,6 +104,9 @@ properties: ti,tas5828: 50-W Stereo, Digital Input, High Efficiency Closed-Loop Class-D Amplifier with Hybrid-Pro Algorithm + + ti,tas5830: 65-W Stereo, Digital Input, High Efficiency Closed-Loop + Class-D Amplifier with Class-H Algorithm oneOf: - items: - enum: @@ -94,14 +115,19 @@ properties: - ti,tas2120 - ti,tas2320 - ti,tas2563 + - ti,tas2568 - ti,tas2570 - ti,tas2572 + - ti,tas2574 - ti,tas5802 + - ti,tas5806m + - ti,tas5806md - ti,tas5815 - ti,tas5822 - ti,tas5825 - ti,tas5827 - ti,tas5828 + - ti,tas5830 - const: ti,tas2781 - enum: - ti,tas2781 @@ -137,6 +163,8 @@ allOf: - ti,tas2118 - ti,tas2120 - ti,tas2320 + - ti,tas2568 + - ti,tas2574 then: properties: reg: @@ -217,6 +245,8 @@ allOf: compatible: contains: enum: + - ti,tas5806m + - ti,tas5806md - ti,tas5822 then: properties: @@ -233,6 +263,7 @@ allOf: enum: - ti,tas5827 - ti,tas5828 + - ti,tas5830 then: properties: reg: diff --git a/Documentation/devicetree/bindings/soundwire/qcom,soundwire.yaml b/Documentation/devicetree/bindings/soundwire/qcom,soundwire.yaml index 95d947fda6a705..003023729fb8ca 100644 --- a/Documentation/devicetree/bindings/soundwire/qcom,soundwire.yaml +++ b/Documentation/devicetree/bindings/soundwire/qcom,soundwire.yaml @@ -23,6 +23,7 @@ properties: - qcom,soundwire-v1.6.0 - qcom,soundwire-v1.7.0 - qcom,soundwire-v2.0.0 + - qcom,soundwire-v3.1.0 - items: - enum: - qcom,soundwire-v2.1.0 @@ -73,10 +74,12 @@ properties: qcom,din-ports: $ref: /schemas/types.yaml#/definitions/uint32 description: count of data in ports + deprecated: true qcom,dout-ports: $ref: /schemas/types.yaml#/definitions/uint32 description: count of data out ports + deprecated: true qcom,ports-word-length: $ref: /schemas/types.yaml#/definitions/uint8-array @@ -223,8 +226,6 @@ required: - '#sound-dai-cells' - '#address-cells' - '#size-cells' - - qcom,dout-ports - - qcom,din-ports - qcom,ports-offset1 - qcom,ports-offset2 @@ -257,9 +258,6 @@ examples: clocks = <&lpass_rx_macro>; clock-names = "iface"; - qcom,din-ports = <0>; - qcom,dout-ports = <5>; - resets = <&lpass_audiocc LPASS_AUDIO_SWR_RX_CGCR>; reset-names = "swr_audio_cgcr"; diff --git a/Documentation/firmware-guide/acpi/i2c-muxes.rst b/Documentation/firmware-guide/acpi/i2c-muxes.rst index f366539acd792a..96ef4012d78fa8 100644 --- a/Documentation/firmware-guide/acpi/i2c-muxes.rst +++ b/Documentation/firmware-guide/acpi/i2c-muxes.rst @@ -37,8 +37,8 @@ which corresponds to the following ASL (in the scope of \_SB):: Name (_HID, ...) Name (_CRS, ResourceTemplate () { I2cSerialBus (0x50, ControllerInitiated, I2C_SPEED, - AddressingMode7Bit, "\\_SB.SMB1.CH00", 0x00, - ResourceConsumer,,) + AddressingMode7Bit, "\\_SB.SMB1.MUX0.CH00", + 0x00, ResourceConsumer,,) } } } @@ -52,8 +52,8 @@ which corresponds to the following ASL (in the scope of \_SB):: Name (_HID, ...) Name (_CRS, ResourceTemplate () { I2cSerialBus (0x50, ControllerInitiated, I2C_SPEED, - AddressingMode7Bit, "\\_SB.SMB1.CH01", 0x00, - ResourceConsumer,,) + AddressingMode7Bit, "\\_SB.SMB1.MUX0.CH01", + 0x00, ResourceConsumer,,) } } } diff --git a/Documentation/input/event-codes.rst b/Documentation/input/event-codes.rst index 1ead9bb8d9c645..4424cbff251f87 100644 --- a/Documentation/input/event-codes.rst +++ b/Documentation/input/event-codes.rst @@ -400,19 +400,30 @@ can report through the rotational axes (absolute and/or relative rx, ry, rz). All other axes retain their meaning. A device must not mix regular directional axes and accelerometer axes on the same event node. -INPUT_PROP_HAPTIC_TOUCHPAD --------------------------- +INPUT_PROP_PRESSUREPAD +---------------------- + +The INPUT_PROP_PRESSUREPAD property indicates that the device provides +simulated haptic feedback (e.g. a vibrator motor situated below the surface) +instead of physical haptic feedback (e.g. a hinge). This property is only set +if the device: -The INPUT_PROP_HAPTIC_TOUCHPAD property indicates that device: -- supports simple haptic auto and manual triggering - can differentiate between at least 5 fingers - uses correct resolution for the X/Y (units and value) -- reports correct force per touch, and correct units for them (newtons or grams) - follows the MT protocol type B +If the simulated haptic feedback is controllable by userspace the device must: + +- support simple haptic auto and manual triggering, and +- report correct force per touch, and correct units for them (newtons or grams), and +- provide the EV_FF FF_HAPTIC force feedback effect. + Summing up, such devices follow the MS spec for input devices in -Win8 and Win8.1, and in addition support the Simple haptic controller HID table, -and report correct units for the pressure. +Win8 and Win8.1, and in addition may support the Simple haptic controller HID +table, and report correct units for the pressure. + +Where applicable, this property is set in addition to INPUT_PROP_BUTTONPAD, it +does not replace that property. Guidelines ========== diff --git a/Documentation/userspace-api/netlink/intro-specs.rst b/Documentation/userspace-api/netlink/intro-specs.rst index a4435ae4628d45..e5ebc617754a38 100644 --- a/Documentation/userspace-api/netlink/intro-specs.rst +++ b/Documentation/userspace-api/netlink/intro-specs.rst @@ -13,10 +13,10 @@ Simple CLI Kernel comes with a simple CLI tool which should be useful when developing Netlink related code. The tool is implemented in Python and can use a YAML specification to issue Netlink requests -to the kernel. Only Generic Netlink is supported. +to the kernel. The tool is located at ``tools/net/ynl/pyynl/cli.py``. It accepts -a handul of arguments, the most important ones are: +a handful of arguments, the most important ones are: - ``--spec`` - point to the spec file - ``--do $name`` / ``--dump $name`` - issue request ``$name`` diff --git a/Documentation/wmi/driver-development-guide.rst b/Documentation/wmi/driver-development-guide.rst index 99ef21fc1c1edd..5680303ae314e0 100644 --- a/Documentation/wmi/driver-development-guide.rst +++ b/Documentation/wmi/driver-development-guide.rst @@ -54,6 +54,7 @@ to matching WMI devices using a struct wmi_device_id table: :: static const struct wmi_device_id foo_id_table[] = { + /* Only use uppercase letters! */ { "936DA01F-9ABD-4D9D-80C7-02AF85C822A8", NULL }, { } }; diff --git a/MAINTAINERS b/MAINTAINERS index 46bd8e0330421d..8c42ca945185b2 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -915,6 +915,7 @@ F: drivers/staging/media/sunxi/cedrus/ ALPHA PORT M: Richard Henderson M: Matt Turner +M: Magnus Lindholm L: linux-alpha@vger.kernel.org S: Odd Fixes F: arch/alpha/ @@ -1757,6 +1758,7 @@ S: Supported W: http://wiki.analog.com/ W: https://ez.analog.com/linux-software-drivers F: Documentation/devicetree/bindings/sound/adi,* +F: Documentation/devicetree/bindings/sound/trivial-codec.yaml F: sound/soc/codecs/ad1* F: sound/soc/codecs/ad7* F: sound/soc/codecs/adau* @@ -2396,9 +2398,9 @@ M: Martin Povišer L: asahi@lists.linux.dev L: linux-sound@vger.kernel.org S: Maintained -F: Documentation/devicetree/bindings/sound/adi,ssm3515.yaml -F: Documentation/devicetree/bindings/sound/cirrus,cs42l84.yaml F: Documentation/devicetree/bindings/sound/apple,* +F: Documentation/devicetree/bindings/sound/cirrus,cs42l84.yaml +F: Documentation/devicetree/bindings/sound/trivial-codec.yaml F: sound/soc/apple/* F: sound/soc/codecs/cs42l83-i2c.c F: sound/soc/codecs/cs42l84.* @@ -3925,7 +3927,7 @@ F: crypto/async_tx/ F: include/linux/async_tx.h AT24 EEPROM DRIVER -M: Bartosz Golaszewski +M: Bartosz Golaszewski L: linux-i2c@vger.kernel.org S: Maintained T: git git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux.git @@ -4398,7 +4400,7 @@ BLOCK LAYER M: Jens Axboe L: linux-block@vger.kernel.org S: Maintained -T: git git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux-block.git +T: git git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux.git F: Documentation/ABI/stable/sysfs-block F: Documentation/block/ F: block/ @@ -4818,6 +4820,7 @@ F: drivers/net/dsa/b53/* F: drivers/net/dsa/bcm_sf2* F: include/linux/dsa/brcm.h F: include/linux/platform_data/b53.h +F: net/dsa/tag_brcm.c BROADCOM BCM2711/BCM2835 ARM ARCHITECTURE M: Florian Fainelli @@ -9207,6 +9210,7 @@ R: Yue Hu R: Jeffle Xu R: Sandeep Dhavale R: Hongbo Li +R: Chunhai Guo L: linux-erofs@lists.ozlabs.org S: Maintained W: https://erofs.docs.kernel.org @@ -9263,7 +9267,6 @@ M: Ido Schimmel L: bridge@lists.linux.dev L: netdev@vger.kernel.org S: Maintained -W: http://www.linuxfoundation.org/en/Net:Bridge F: include/linux/if_bridge.h F: include/uapi/linux/if_bridge.h F: include/linux/netfilter_bridge/ @@ -10676,7 +10679,7 @@ F: tools/gpio/gpio-sloppy-logic-analyzer.sh GPIO SUBSYSTEM M: Linus Walleij -M: Bartosz Golaszewski +M: Bartosz Golaszewski L: linux-gpio@vger.kernel.org S: Maintained T: git git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux.git @@ -10693,7 +10696,7 @@ K: GPIOD_FLAGS_BIT_NONEXCLUSIVE K: devm_gpiod_unhinge GPIO UAPI -M: Bartosz Golaszewski +M: Bartosz Golaszewski R: Kent Gibson L: linux-gpio@vger.kernel.org S: Maintained @@ -11525,7 +11528,7 @@ F: include/linux/platform_data/huawei-gaokun-ec.h HUGETLB SUBSYSTEM M: Muchun Song M: Oscar Salvador -R: David Hildenbrand +R: David Hildenbrand L: linux-mm@kvack.org S: Maintained F: Documentation/ABI/testing/sysfs-kernel-mm-hugepages @@ -12521,6 +12524,7 @@ F: include/linux/avf/virtchnl.h F: include/linux/net/intel/*/ INTEL ETHERNET PROTOCOL DRIVER FOR RDMA +M: Krzysztof Czurylo M: Tatyana Nikolova L: linux-rdma@vger.kernel.org S: Supported @@ -12861,7 +12865,8 @@ F: tools/testing/selftests/sgx/* K: \bSGX_ INTEL SKYLAKE INT3472 ACPI DEVICE DRIVER -M: Daniel Scally +M: Daniel Scally +M: Sakari Ailus S: Maintained F: drivers/platform/x86/intel/int3472/ F: include/linux/platform_data/x86/int3472.h @@ -13656,7 +13661,7 @@ F: virt/kvm/* KERNEL VIRTUAL MACHINE FOR ARM64 (KVM/arm64) M: Marc Zyngier -M: Oliver Upton +M: Oliver Upton R: Joey Gouly R: Suzuki K Poulose R: Zenghui Yu @@ -13730,7 +13735,7 @@ KERNEL VIRTUAL MACHINE for s390 (KVM/s390) M: Christian Borntraeger M: Janosch Frank M: Claudio Imbrenda -R: David Hildenbrand +R: David Hildenbrand L: kvm@vger.kernel.org S: Supported T: git git://git.kernel.org/pub/scm/linux/kernel/git/kvms390/linux.git @@ -15305,7 +15310,7 @@ F: drivers/pwm/pwm-max7360.c F: include/linux/mfd/max7360.h MAXIM MAX77650 PMIC MFD DRIVER -M: Bartosz Golaszewski +M: Bartosz Golaszewski L: linux-kernel@vger.kernel.org S: Maintained F: Documentation/devicetree/bindings/*/*max77650.yaml @@ -16201,7 +16206,7 @@ MEMORY CONTROLLER DRIVERS M: Krzysztof Kozlowski L: linux-kernel@vger.kernel.org S: Maintained -B: mailto:krzysztof.kozlowski@linaro.org +B: mailto:krzk@kernel.org T: git git://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux-mem-ctrl.git F: Documentation/devicetree/bindings/memory-controllers/ F: drivers/memory/ @@ -16217,7 +16222,7 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/chanwoo/linux.git F: drivers/devfreq/tegra30-devfreq.c MEMORY HOT(UN)PLUG -M: David Hildenbrand +M: David Hildenbrand M: Oscar Salvador L: linux-mm@kvack.org S: Maintained @@ -16242,7 +16247,7 @@ F: tools/mm/ MEMORY MANAGEMENT - CORE M: Andrew Morton -M: David Hildenbrand +M: David Hildenbrand R: Lorenzo Stoakes R: Liam R. Howlett R: Vlastimil Babka @@ -16298,7 +16303,7 @@ F: mm/execmem.c MEMORY MANAGEMENT - GUP (GET USER PAGES) M: Andrew Morton -M: David Hildenbrand +M: David Hildenbrand R: Jason Gunthorpe R: John Hubbard R: Peter Xu @@ -16314,7 +16319,7 @@ F: tools/testing/selftests/mm/gup_test.c MEMORY MANAGEMENT - KSM (Kernel Samepage Merging) M: Andrew Morton -M: David Hildenbrand +M: David Hildenbrand R: Xu Xin R: Chengming Zhou L: linux-mm@kvack.org @@ -16330,7 +16335,7 @@ F: mm/mm_slot.h MEMORY MANAGEMENT - MEMORY POLICY AND MIGRATION M: Andrew Morton -M: David Hildenbrand +M: David Hildenbrand R: Zi Yan R: Matthew Brost R: Joshua Hahn @@ -16370,7 +16375,7 @@ F: mm/workingset.c MEMORY MANAGEMENT - MISC M: Andrew Morton -M: David Hildenbrand +M: David Hildenbrand R: Lorenzo Stoakes R: Liam R. Howlett R: Vlastimil Babka @@ -16458,7 +16463,7 @@ F: mm/shuffle.h MEMORY MANAGEMENT - RECLAIM M: Andrew Morton M: Johannes Weiner -R: David Hildenbrand +R: David Hildenbrand R: Michal Hocko R: Qi Zheng R: Shakeel Butt @@ -16471,7 +16476,7 @@ F: mm/workingset.c MEMORY MANAGEMENT - RMAP (REVERSE MAPPING) M: Andrew Morton -M: David Hildenbrand +M: David Hildenbrand M: Lorenzo Stoakes R: Rik van Riel R: Liam R. Howlett @@ -16495,12 +16500,12 @@ F: mm/secretmem.c MEMORY MANAGEMENT - SWAP M: Andrew Morton +M: Chris Li +M: Kairui Song R: Kemeng Shi -R: Kairui Song R: Nhat Pham R: Baoquan He R: Barry Song -R: Chris Li L: linux-mm@kvack.org S: Maintained F: Documentation/mm/swap-table.rst @@ -16516,7 +16521,7 @@ F: mm/swapfile.c MEMORY MANAGEMENT - THP (TRANSPARENT HUGE PAGE) M: Andrew Morton -M: David Hildenbrand +M: David Hildenbrand M: Lorenzo Stoakes R: Zi Yan R: Baolin Wang @@ -16618,7 +16623,7 @@ MEMORY MAPPING - MADVISE (MEMORY ADVICE) M: Andrew Morton M: Liam R. Howlett M: Lorenzo Stoakes -M: David Hildenbrand +M: David Hildenbrand R: Vlastimil Babka R: Jann Horn L: linux-mm@kvack.org @@ -18672,7 +18677,7 @@ NXP TFA9879 DRIVER M: Peter Rosin L: linux-sound@vger.kernel.org S: Maintained -F: Documentation/devicetree/bindings/sound/nxp,tfa9879.yaml +F: Documentation/devicetree/bindings/sound/trivial-codec.yaml F: sound/soc/codecs/tfa9879* NXP-NCI NFC DRIVER @@ -18776,6 +18781,10 @@ S: Maintained F: arch/arm/*omap*/*clock* OMAP DEVICE TREE SUPPORT +M: Aaro Koskinen +M: Andreas Kemnade +M: Kevin Hilman +M: Roger Quadros M: Tony Lindgren L: linux-omap@vger.kernel.org L: devicetree@vger.kernel.org @@ -19895,7 +19904,7 @@ F: drivers/pci/p2pdma.c F: include/linux/pci-p2pdma.h PCI POWER CONTROL -M: Bartosz Golaszewski +M: Bartosz Golaszewski L: linux-pci@vger.kernel.org S: Maintained T: git git://git.kernel.org/pub/scm/linux/kernel/git/pci/pci.git @@ -20160,6 +20169,7 @@ R: Alexander Shishkin R: Jiri Olsa R: Ian Rogers R: Adrian Hunter +R: James Clark L: linux-perf-users@vger.kernel.org L: linux-kernel@vger.kernel.org S: Supported @@ -20491,7 +20501,7 @@ F: include/linux/powercap.h F: kernel/configs/nopm.config POWER SEQUENCING -M: Bartosz Golaszewski +M: Bartosz Golaszewski L: linux-pm@vger.kernel.org S: Maintained T: git git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux.git @@ -21173,7 +21183,7 @@ F: Documentation/devicetree/bindings/i2c/qcom,i2c-cci.yaml F: drivers/i2c/busses/i2c-qcom-cci.c QUALCOMM INTERCONNECT BWMON DRIVER -M: Krzysztof Kozlowski +M: Krzysztof Kozlowski L: linux-arm-msm@vger.kernel.org S: Maintained F: Documentation/devicetree/bindings/interconnect/qcom,msm8998-bwmon.yaml @@ -21294,7 +21304,7 @@ F: Documentation/tee/qtee.rst F: drivers/tee/qcomtee/ QUALCOMM TRUST ZONE MEMORY ALLOCATOR -M: Bartosz Golaszewski +M: Bartosz Golaszewski L: linux-arm-msm@vger.kernel.org S: Maintained F: drivers/firmware/qcom/qcom_tzmem.c @@ -25662,7 +25672,7 @@ F: Documentation/devicetree/bindings/crypto/ti,am62l-dthev2.yaml F: drivers/crypto/ti/ TI DAVINCI MACHINE SUPPORT -M: Bartosz Golaszewski +M: Bartosz Golaszewski L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained T: git git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux.git @@ -27084,7 +27094,7 @@ F: net/vmw_vsock/virtio_transport_common.c VIRTIO BALLOON M: "Michael S. Tsirkin" -M: David Hildenbrand +M: David Hildenbrand L: virtualization@lists.linux.dev S: Maintained F: drivers/virtio/virtio_balloon.c @@ -27239,7 +27249,7 @@ F: drivers/iommu/virtio-iommu.c F: include/uapi/linux/virtio_iommu.h VIRTIO MEM DRIVER -M: David Hildenbrand +M: David Hildenbrand L: virtualization@lists.linux.dev S: Maintained W: https://virtio-mem.gitlab.io/ @@ -27662,6 +27672,7 @@ F: Documentation/devicetree/bindings/extcon/wlf,arizona.yaml F: Documentation/devicetree/bindings/mfd/wlf,arizona.yaml F: Documentation/devicetree/bindings/mfd/wm831x.txt F: Documentation/devicetree/bindings/regulator/wlf,arizona.yaml +F: Documentation/devicetree/bindings/sound/trivial-codec.yaml F: Documentation/devicetree/bindings/sound/wlf,*.yaml F: Documentation/devicetree/bindings/sound/wm* F: Documentation/hwmon/wm83??.rst @@ -27845,7 +27856,7 @@ F: arch/x86/kernel/stacktrace.c F: arch/x86/kernel/unwind_*.c X86 TRUST DOMAIN EXTENSIONS (TDX) -M: Kirill A. Shutemov +M: Kiryl Shutsemau R: Dave Hansen R: Rick Edgecombe L: x86@kernel.org diff --git a/Makefile b/Makefile index 088565edc911ce..d208066bcbb661 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ VERSION = 6 PATCHLEVEL = 18 SUBLEVEL = 0 -EXTRAVERSION = -rc4 +EXTRAVERSION = -rc7 NAME = Baby Opossum Posse # *DOCUMENTATION* diff --git a/arch/Kconfig b/arch/Kconfig index 74ff0113353223..61130b88964b94 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -917,6 +917,13 @@ config ARCH_USES_CFI_TRAPS An architecture should select this option if it requires the .kcfi_traps section for KCFI trap handling. +config ARCH_USES_CFI_GENERIC_LLVM_PASS + bool + help + An architecture should select this option if it uses the generic + KCFIPass in LLVM to expand kCFI bundles instead of architecture-specific + lowering. + config CFI bool "Use Kernel Control Flow Integrity (kCFI)" default CFI_CLANG diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 2e3f93b690f47e..4fb985b76e97f7 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -44,6 +44,8 @@ config ARM select ARCH_USE_BUILTIN_BSWAP select ARCH_USE_CMPXCHG_LOCKREF select ARCH_USE_MEMTEST + # https://github.com/llvm/llvm-project/commit/d130f402642fba3d065aacb506cb061c899558de + select ARCH_USES_CFI_GENERIC_LLVM_PASS if CLANG_VERSION < 220000 select ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT if MMU select ARCH_WANT_GENERAL_HUGETLB select ARCH_WANT_IPC_PARSE_VERSION diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-fuji-data64.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-fuji-data64.dts index aa9576d8ab5693..48ca25f57ef612 100644 --- a/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-fuji-data64.dts +++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-fuji-data64.dts @@ -1254,3 +1254,17 @@ max-frequency = <25000000>; bus-width = <4>; }; + +/* + * FIXME: rgmii delay is introduced by MAC (configured in u-boot now) + * instead of PCB on fuji board, so the "phy-mode" should be updated to + * "rgmii-[tx|rx]id" when the aspeed-mac driver can handle the delay + * properly. + */ +&mac3 { + status = "okay"; + phy-mode = "rgmii"; + phy-handle = <ðphy3>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_rgmii4_default>; +}; diff --git a/arch/arm/boot/dts/broadcom/bcm47189-luxul-xap-1440.dts b/arch/arm/boot/dts/broadcom/bcm47189-luxul-xap-1440.dts index ac44c745bdf8e6..a39a021a39107e 100644 --- a/arch/arm/boot/dts/broadcom/bcm47189-luxul-xap-1440.dts +++ b/arch/arm/boot/dts/broadcom/bcm47189-luxul-xap-1440.dts @@ -55,8 +55,8 @@ mdio { /delete-node/ switch@1e; - bcm54210e: ethernet-phy@0 { - reg = <0>; + bcm54210e: ethernet-phy@25 { + reg = <25>; }; }; }; diff --git a/arch/arm/boot/dts/nxp/imx/imx51-zii-rdu1.dts b/arch/arm/boot/dts/nxp/imx/imx51-zii-rdu1.dts index 06545a6052f716..43ff5eafb2bb81 100644 --- a/arch/arm/boot/dts/nxp/imx/imx51-zii-rdu1.dts +++ b/arch/arm/boot/dts/nxp/imx/imx51-zii-rdu1.dts @@ -259,7 +259,7 @@ pinctrl-0 = <&pinctrl_audmux>; status = "okay"; - ssi2 { + mux-ssi2 { fsl,audmux-port = <1>; fsl,port-config = < (IMX_AUDMUX_V2_PTCR_SYN | @@ -271,7 +271,7 @@ >; }; - aud3 { + mux-aud3 { fsl,audmux-port = <2>; fsl,port-config = < IMX_AUDMUX_V2_PTCR_SYN diff --git a/arch/arm/boot/dts/nxp/imx/imx6ull-engicam-microgea-rmm.dts b/arch/arm/boot/dts/nxp/imx/imx6ull-engicam-microgea-rmm.dts index 107b00b9a93997..540642e99a4159 100644 --- a/arch/arm/boot/dts/nxp/imx/imx6ull-engicam-microgea-rmm.dts +++ b/arch/arm/boot/dts/nxp/imx/imx6ull-engicam-microgea-rmm.dts @@ -136,7 +136,7 @@ interrupt-parent = <&gpio2>; interrupts = <8 IRQ_TYPE_EDGE_FALLING>; reset-gpios = <&gpio2 14 GPIO_ACTIVE_LOW>; - report-rate-hz = <6>; + report-rate-hz = <60>; /* settings valid only for Hycon touchscreen */ touchscreen-size-x = <1280>; touchscreen-size-y = <800>; diff --git a/arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b.dts b/arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b.dts index b8f2565450222c..3e0319fdb93f7b 100644 --- a/arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b.dts +++ b/arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b.dts @@ -18,11 +18,21 @@ #include "bcm2712-rpi-5-b-ovl-rp1.dts" +/ { + aliases { + ethernet0 = &rp1_eth; + }; +}; + &pcie2 { #include "rp1-nexus.dtsi" }; &rp1_eth { + assigned-clocks = <&rp1_clocks RP1_CLK_ETH_TSU>, + <&rp1_clocks RP1_CLK_ETH>; + assigned-clock-rates = <50000000>, + <125000000>; status = "okay"; phy-mode = "rgmii-id"; phy-handle = <&phy1>; diff --git a/arch/arm64/boot/dts/freescale/imx8-ss-img.dtsi b/arch/arm64/boot/dts/freescale/imx8-ss-img.dtsi index 2cf0f7208350a4..a72b2f1c4a1b2e 100644 --- a/arch/arm64/boot/dts/freescale/imx8-ss-img.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8-ss-img.dtsi @@ -67,7 +67,6 @@ img_subsys: bus@58000000 { power-domains = <&pd IMX_SC_R_CSI_0>; fsl,channel = <0>; fsl,num-irqs = <32>; - status = "disabled"; }; gpio0_mipi_csi0: gpio@58222000 { @@ -144,7 +143,6 @@ img_subsys: bus@58000000 { power-domains = <&pd IMX_SC_R_CSI_1>; fsl,channel = <0>; fsl,num-irqs = <32>; - status = "disabled"; }; gpio0_mipi_csi1: gpio@58242000 { diff --git a/arch/arm64/boot/dts/freescale/imx8mp-kontron-bl-osm-s.dts b/arch/arm64/boot/dts/freescale/imx8mp-kontron-bl-osm-s.dts index 614b4ce330b1cb..0924ac50fd2dbc 100644 --- a/arch/arm64/boot/dts/freescale/imx8mp-kontron-bl-osm-s.dts +++ b/arch/arm64/boot/dts/freescale/imx8mp-kontron-bl-osm-s.dts @@ -16,11 +16,20 @@ ethernet1 = &eqos; }; - extcon_usbc: usbc { - compatible = "linux,extcon-usb-gpio"; + connector { + compatible = "gpio-usb-b-connector", "usb-b-connector"; + id-gpios = <&gpio1 10 GPIO_ACTIVE_HIGH>; + label = "Type-C"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_usb1_id>; - id-gpios = <&gpio1 10 GPIO_ACTIVE_HIGH>; + type = "micro"; + vbus-supply = <®_usb1_vbus>; + + port { + usb_dr_connector: endpoint { + remote-endpoint = <&usb3_dwc>; + }; + }; }; leds { @@ -244,9 +253,15 @@ hnp-disable; srp-disable; dr_mode = "otg"; - extcon = <&extcon_usbc>; usb-role-switch; + role-switch-default-mode = "peripheral"; status = "okay"; + + port { + usb3_dwc: endpoint { + remote-endpoint = <&usb_dr_connector>; + }; + }; }; &usb_dwc3_1 { @@ -273,7 +288,6 @@ }; &usb3_phy0 { - vbus-supply = <®_usb1_vbus>; status = "okay"; }; diff --git a/arch/arm64/boot/dts/freescale/imx95.dtsi b/arch/arm64/boot/dts/freescale/imx95.dtsi index 1292677cbe4eb8..6da961eb3fe5cc 100644 --- a/arch/arm64/boot/dts/freescale/imx95.dtsi +++ b/arch/arm64/boot/dts/freescale/imx95.dtsi @@ -1886,7 +1886,7 @@ assigned-clock-rates = <3600000000>, <100000000>, <10000000>; assigned-clock-parents = <0>, <0>, <&scmi_clk IMX95_CLK_SYSPLL1_PFD1_DIV2>; - msi-map = <0x0 &its 0x98 0x1>; + msi-map = <0x0 &its 0x10 0x1>; power-domains = <&scmi_devpd IMX95_PD_HSIO_TOP>; status = "disabled"; }; @@ -1963,6 +1963,7 @@ assigned-clock-rates = <3600000000>, <100000000>, <10000000>; assigned-clock-parents = <0>, <0>, <&scmi_clk IMX95_CLK_SYSPLL1_PFD1_DIV2>; + msi-map = <0x0 &its 0x98 0x1>; power-domains = <&scmi_devpd IMX95_PD_HSIO_TOP>; status = "disabled"; }; diff --git a/arch/arm64/boot/dts/nvidia/tegra194-p3668.dtsi b/arch/arm64/boot/dts/nvidia/tegra194-p3668.dtsi index a410fc335fa3bb..c0f17f8189fad2 100644 --- a/arch/arm64/boot/dts/nvidia/tegra194-p3668.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra194-p3668.dtsi @@ -42,6 +42,7 @@ interrupt-parent = <&gpio>; interrupts = ; #phy-cells = <0>; + wakeup-source; }; }; }; diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi index 283d9cbc4368f3..03b7c431375060 100644 --- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi @@ -598,7 +598,6 @@ pinctrl-2 = <&otp_pin>; resets = <&cru SRST_TSADC>; reset-names = "tsadc-apb"; - rockchip,grf = <&grf>; rockchip,hw-tshut-temp = <100000>; #thermal-sensor-cells = <1>; status = "disabled"; diff --git a/arch/arm64/boot/dts/rockchip/rk3399-op1.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-op1.dtsi index c4f4f1ff6117b3..9da6fd82e46b29 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-op1.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3399-op1.dtsi @@ -3,7 +3,7 @@ * Copyright (c) 2016-2017 Fuzhou Rockchip Electronics Co., Ltd */ -#include "rk3399.dtsi" +#include "rk3399-base.dtsi" / { cluster0_opp: opp-table-0 { diff --git a/arch/arm64/boot/dts/rockchip/rk3399-puma-haikou-video-demo.dtso b/arch/arm64/boot/dts/rockchip/rk3399-puma-haikou-video-demo.dtso index 5e8f729c2cf220..141a921a06e472 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-puma-haikou-video-demo.dtso +++ b/arch/arm64/boot/dts/rockchip/rk3399-puma-haikou-video-demo.dtso @@ -45,11 +45,11 @@ cam_dovdd_1v8: regulator-cam-dovdd-1v8 { compatible = "regulator-fixed"; - gpio = <&pca9670 3 GPIO_ACTIVE_LOW>; - regulator-max-microvolt = <1800000>; - regulator-min-microvolt = <1800000>; - regulator-name = "cam-dovdd-1v8"; - vin-supply = <&vcc1v8_video>; + gpio = <&pca9670 3 GPIO_ACTIVE_LOW>; + regulator-max-microvolt = <1800000>; + regulator-min-microvolt = <1800000>; + regulator-name = "cam-dovdd-1v8"; + vin-supply = <&vcc1v8_video>; }; cam_dvdd_1v2: regulator-cam-dvdd-1v2 { diff --git a/arch/arm64/boot/dts/rockchip/rk3566-bigtreetech-cb2.dtsi b/arch/arm64/boot/dts/rockchip/rk3566-bigtreetech-cb2.dtsi index 7f578c50b4ad1e..b6cf03a7ba66bc 100644 --- a/arch/arm64/boot/dts/rockchip/rk3566-bigtreetech-cb2.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3566-bigtreetech-cb2.dtsi @@ -120,7 +120,7 @@ compatible = "regulator-fixed"; regulator-name = "vcc3v3_pcie"; enable-active-high; - gpios = <&gpio0 RK_PB1 GPIO_ACTIVE_HIGH>; + gpios = <&gpio4 RK_PB1 GPIO_ACTIVE_HIGH>; pinctrl-names = "default"; pinctrl-0 = <&pcie_drv>; regulator-always-on; @@ -187,7 +187,7 @@ vcc5v0_usb2b: regulator-vcc5v0-usb2b { compatible = "regulator-fixed"; enable-active-high; - gpio = <&gpio0 RK_PC4 GPIO_ACTIVE_HIGH>; + gpio = <&gpio4 RK_PC4 GPIO_ACTIVE_HIGH>; pinctrl-names = "default"; pinctrl-0 = <&vcc5v0_usb2b_en>; regulator-name = "vcc5v0_usb2b"; @@ -199,7 +199,7 @@ vcc5v0_usb2t: regulator-vcc5v0-usb2t { compatible = "regulator-fixed"; enable-active-high; - gpios = <&gpio0 RK_PD5 GPIO_ACTIVE_HIGH>; + gpios = <&gpio3 RK_PD5 GPIO_ACTIVE_HIGH>; pinctrl-names = "default"; pinctrl-0 = <&vcc5v0_usb2t_en>; regulator-name = "vcc5v0_usb2t"; diff --git a/arch/arm64/boot/dts/rockchip/rk3566-pinetab2.dtsi b/arch/arm64/boot/dts/rockchip/rk3566-pinetab2.dtsi index d0e38412d56a43..08bf40de17ead8 100644 --- a/arch/arm64/boot/dts/rockchip/rk3566-pinetab2.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3566-pinetab2.dtsi @@ -789,7 +789,7 @@ vccio1-supply = <&vccio_acodec>; vccio2-supply = <&vcc_1v8>; vccio3-supply = <&vccio_sd>; - vccio4-supply = <&vcc_1v8>; + vccio4-supply = <&vcca1v8_pmu>; vccio5-supply = <&vcc_1v8>; vccio6-supply = <&vcc1v8_dvp>; vccio7-supply = <&vcc_3v3>; diff --git a/arch/arm64/boot/dts/rockchip/rk3568-odroid-m1.dts b/arch/arm64/boot/dts/rockchip/rk3568-odroid-m1.dts index 0f844806ec542e..442a2bc43ba8ed 100644 --- a/arch/arm64/boot/dts/rockchip/rk3568-odroid-m1.dts +++ b/arch/arm64/boot/dts/rockchip/rk3568-odroid-m1.dts @@ -482,6 +482,8 @@ }; &i2s1_8ch { + pinctrl-names = "default"; + pinctrl-0 = <&i2s1m0_sclktx &i2s1m0_lrcktx &i2s1m0_sdi0 &i2s1m0_sdo0>; rockchip,trcm-sync-tx-only; status = "okay"; }; diff --git a/arch/arm64/boot/dts/rockchip/rk3576.dtsi b/arch/arm64/boot/dts/rockchip/rk3576.dtsi index fc4e9e07f1cf35..a86fc6b4e8c458 100644 --- a/arch/arm64/boot/dts/rockchip/rk3576.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3576.dtsi @@ -276,12 +276,6 @@ opp-microvolt = <900000 900000 950000>; clock-latency-ns = <40000>; }; - - opp-2208000000 { - opp-hz = /bits/ 64 <2208000000>; - opp-microvolt = <950000 950000 950000>; - clock-latency-ns = <40000>; - }; }; cluster1_opp_table: opp-table-cluster1 { @@ -348,12 +342,6 @@ opp-microvolt = <925000 925000 950000>; clock-latency-ns = <40000>; }; - - opp-2304000000 { - opp-hz = /bits/ 64 <2304000000>; - opp-microvolt = <950000 950000 950000>; - clock-latency-ns = <40000>; - }; }; gpu_opp_table: opp-table-gpu { @@ -2561,8 +2549,6 @@ interrupts = ; pinctrl-names = "default"; pinctrl-0 = <&i2c9m0_xfer>; - resets = <&cru SRST_I2C9>, <&cru SRST_P_I2C9>; - reset-names = "i2c", "apb"; #address-cells = <1>; #size-cells = <0>; status = "disabled"; diff --git a/arch/arm64/boot/dts/rockchip/rk3588-opp.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-opp.dtsi index 0f1a7769735163..b5d630d2c879fc 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588-opp.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3588-opp.dtsi @@ -115,7 +115,7 @@ }; }; - gpu_opp_table: opp-table { + gpu_opp_table: opp-table-gpu { compatible = "operating-points-v2"; opp-300000000 { diff --git a/arch/arm64/boot/dts/rockchip/rk3588-tiger.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-tiger.dtsi index b44e89e1bb1599..365c1d958f2d5c 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588-tiger.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3588-tiger.dtsi @@ -382,14 +382,12 @@ cap-mmc-highspeed; mmc-ddr-1_8v; mmc-hs200-1_8v; - mmc-hs400-1_8v; - mmc-hs400-enhanced-strobe; mmc-pwrseq = <&emmc_pwrseq>; no-sdio; no-sd; non-removable; pinctrl-names = "default"; - pinctrl-0 = <&emmc_bus8 &emmc_cmd &emmc_clk &emmc_data_strobe>; + pinctrl-0 = <&emmc_bus8 &emmc_cmd &emmc_clk>; vmmc-supply = <&vcc_3v3_s3>; vqmmc-supply = <&vcc_1v8_s3>; status = "okay"; diff --git a/arch/arm64/boot/dts/rockchip/rk3588j.dtsi b/arch/arm64/boot/dts/rockchip/rk3588j.dtsi index 9884a5df47dfed..e1e0e3fc0ca70f 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588j.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3588j.dtsi @@ -66,7 +66,7 @@ }; }; - gpu_opp_table: opp-table { + gpu_opp_table: opp-table-gpu { compatible = "operating-points-v2"; opp-300000000 { diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5.dts b/arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5.dts index ad6d04793b0ac7..83b9b6645a1e40 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5.dts +++ b/arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5.dts @@ -14,8 +14,8 @@ gpios = <&gpio0 RK_PC5 GPIO_ACTIVE_HIGH>; regulator-name = "vcc3v3_pcie20"; regulator-boot-on; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; startup-delay-us = <50000>; vin-supply = <&vcc5v0_sys>; }; diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index e3a2d37bd10423..1a48faad2473a9 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -1341,7 +1341,7 @@ CONFIG_COMMON_CLK_RS9_PCIE=y CONFIG_COMMON_CLK_VC3=y CONFIG_COMMON_CLK_VC5=y CONFIG_COMMON_CLK_BD718XX=m -CONFIG_CLK_RASPBERRYPI=m +CONFIG_CLK_RASPBERRYPI=y CONFIG_CLK_IMX8MM=y CONFIG_CLK_IMX8MN=y CONFIG_CLK_IMX8MP=y diff --git a/arch/arm64/include/asm/alternative.h b/arch/arm64/include/asm/alternative.h index 00d97b8a757f42..51746005239bca 100644 --- a/arch/arm64/include/asm/alternative.h +++ b/arch/arm64/include/asm/alternative.h @@ -26,9 +26,12 @@ void __init apply_alternatives_all(void); bool alternative_is_applied(u16 cpucap); #ifdef CONFIG_MODULES -void apply_alternatives_module(void *start, size_t length); +int apply_alternatives_module(void *start, size_t length); #else -static inline void apply_alternatives_module(void *start, size_t length) { } +static inline int apply_alternatives_module(void *start, size_t length) +{ + return 0; +} #endif void alt_cb_patch_nops(struct alt_instr *alt, __le32 *origptr, diff --git a/arch/arm64/include/asm/kfence.h b/arch/arm64/include/asm/kfence.h index a81937fae9f6da..21dbc9dda7478c 100644 --- a/arch/arm64/include/asm/kfence.h +++ b/arch/arm64/include/asm/kfence.h @@ -10,8 +10,6 @@ #include -static inline bool arch_kfence_init_pool(void) { return true; } - static inline bool kfence_protect_page(unsigned long addr, bool protect) { set_memory_valid(addr, 1, !protect); @@ -25,6 +23,7 @@ static inline bool arm64_kfence_can_set_direct_map(void) { return !kfence_early_init; } +bool arch_kfence_init_pool(void); #else /* CONFIG_KFENCE */ static inline bool arm64_kfence_can_set_direct_map(void) { return false; } #endif /* CONFIG_KFENCE */ diff --git a/arch/arm64/include/asm/page.h b/arch/arm64/include/asm/page.h index 2312e6ee595fda..258cca4b487344 100644 --- a/arch/arm64/include/asm/page.h +++ b/arch/arm64/include/asm/page.h @@ -33,8 +33,8 @@ struct folio *vma_alloc_zeroed_movable_folio(struct vm_area_struct *vma, unsigned long vaddr); #define vma_alloc_zeroed_movable_folio vma_alloc_zeroed_movable_folio -void tag_clear_highpage(struct page *to); -#define __HAVE_ARCH_TAG_CLEAR_HIGHPAGE +bool tag_clear_highpages(struct page *to, int numpages); +#define __HAVE_ARCH_TAG_CLEAR_HIGHPAGES #define clear_user_page(page, vaddr, pg) clear_page(page) #define copy_user_page(to, from, vaddr, pg) copy_page(to, from) diff --git a/arch/arm64/include/asm/percpu.h b/arch/arm64/include/asm/percpu.h index 9abcc8ef3087b7..b57b2bb0096774 100644 --- a/arch/arm64/include/asm/percpu.h +++ b/arch/arm64/include/asm/percpu.h @@ -77,7 +77,7 @@ __percpu_##name##_case_##sz(void *ptr, unsigned long val) \ " stxr" #sfx "\t%w[loop], %" #w "[tmp], %[ptr]\n" \ " cbnz %w[loop], 1b", \ /* LSE atomics */ \ - #op_lse "\t%" #w "[val], %[ptr]\n" \ + #op_lse "\t%" #w "[val], %" #w "[tmp], %[ptr]\n" \ __nops(3)) \ : [loop] "=&r" (loop), [tmp] "=&r" (tmp), \ [ptr] "+Q"(*(u##sz *)ptr) \ @@ -124,9 +124,16 @@ PERCPU_RW_OPS(8) PERCPU_RW_OPS(16) PERCPU_RW_OPS(32) PERCPU_RW_OPS(64) -PERCPU_OP(add, add, stadd) -PERCPU_OP(andnot, bic, stclr) -PERCPU_OP(or, orr, stset) + +/* + * Use value-returning atomics for CPU-local ops as they are more likely + * to execute "near" to the CPU (e.g. in L1$). + * + * https://lore.kernel.org/r/e7d539ed-ced0-4b96-8ecd-048a5b803b85@paulmck-laptop + */ +PERCPU_OP(add, add, ldadd) +PERCPU_OP(andnot, bic, ldclr) +PERCPU_OP(or, orr, ldset) PERCPU_RET_OP(add, add, ldadd) #undef PERCPU_RW_OPS diff --git a/arch/arm64/include/asm/scs.h b/arch/arm64/include/asm/scs.h index a76f9b387a269e..c59f6324f2bbdb 100644 --- a/arch/arm64/include/asm/scs.h +++ b/arch/arm64/include/asm/scs.h @@ -53,7 +53,7 @@ enum { EDYNSCS_INVALID_CFA_OPCODE = 4, }; -int __pi_scs_patch(const u8 eh_frame[], int size); +int __pi_scs_patch(const u8 eh_frame[], int size, bool skip_dry_run); #endif /* __ASSEMBLY __ */ diff --git a/arch/arm64/include/asm/spectre.h b/arch/arm64/include/asm/spectre.h index 8fef1262609011..900454aaa29264 100644 --- a/arch/arm64/include/asm/spectre.h +++ b/arch/arm64/include/asm/spectre.h @@ -117,6 +117,7 @@ void spectre_bhb_patch_wa3(struct alt_instr *alt, __le32 *origptr, __le32 *updptr, int nr_inst); void spectre_bhb_patch_clearbhb(struct alt_instr *alt, __le32 *origptr, __le32 *updptr, int nr_inst); +void spectre_print_disabled_mitigations(void); #endif /* __ASSEMBLY__ */ #endif /* __ASM_SPECTRE_H */ diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c index 7aca29e1d30b24..c022c1acb8c7d9 100644 --- a/arch/arm64/kernel/acpi.c +++ b/arch/arm64/kernel/acpi.c @@ -197,8 +197,6 @@ static int __init acpi_fadt_sanity_check(void) */ void __init acpi_boot_table_init(void) { - int ret; - /* * Enable ACPI instead of device tree unless * - ACPI has been disabled explicitly (acpi=off), or @@ -252,12 +250,8 @@ void __init acpi_boot_table_init(void) * behaviour, use acpi=nospcr to disable console in ACPI SPCR * table as default serial console. */ - ret = acpi_parse_spcr(earlycon_acpi_spcr_enable, + acpi_parse_spcr(earlycon_acpi_spcr_enable, !param_acpi_nospcr); - if (!ret || param_acpi_nospcr || !IS_ENABLED(CONFIG_ACPI_SPCR_TABLE)) - pr_info("Use ACPI SPCR as default console: No\n"); - else - pr_info("Use ACPI SPCR as default console: Yes\n"); if (IS_ENABLED(CONFIG_ACPI_BGRT)) acpi_table_parse(ACPI_SIG_BGRT, acpi_parse_bgrt); diff --git a/arch/arm64/kernel/alternative.c b/arch/arm64/kernel/alternative.c index 8ff6610af49664..f5ec7e7c1d3fdb 100644 --- a/arch/arm64/kernel/alternative.c +++ b/arch/arm64/kernel/alternative.c @@ -139,9 +139,9 @@ static noinstr void clean_dcache_range_nopatch(u64 start, u64 end) } while (cur += d_size, cur < end); } -static void __apply_alternatives(const struct alt_region *region, - bool is_module, - unsigned long *cpucap_mask) +static int __apply_alternatives(const struct alt_region *region, + bool is_module, + unsigned long *cpucap_mask) { struct alt_instr *alt; __le32 *origptr, *updptr; @@ -166,10 +166,13 @@ static void __apply_alternatives(const struct alt_region *region, updptr = is_module ? origptr : lm_alias(origptr); nr_inst = alt->orig_len / AARCH64_INSN_SIZE; - if (ALT_HAS_CB(alt)) + if (ALT_HAS_CB(alt)) { alt_cb = ALT_REPL_PTR(alt); - else + if (is_module && !core_kernel_text((unsigned long)alt_cb)) + return -ENOEXEC; + } else { alt_cb = patch_alternative; + } alt_cb(alt, origptr, updptr, nr_inst); @@ -193,6 +196,8 @@ static void __apply_alternatives(const struct alt_region *region, bitmap_and(applied_alternatives, applied_alternatives, system_cpucaps, ARM64_NCAPS); } + + return 0; } static void __init apply_alternatives_vdso(void) @@ -277,7 +282,7 @@ void __init apply_boot_alternatives(void) } #ifdef CONFIG_MODULES -void apply_alternatives_module(void *start, size_t length) +int apply_alternatives_module(void *start, size_t length) { struct alt_region region = { .begin = start, @@ -287,7 +292,7 @@ void apply_alternatives_module(void *start, size_t length) bitmap_fill(all_capabilities, ARM64_NCAPS); - __apply_alternatives(®ion, true, &all_capabilities[0]); + return __apply_alternatives(®ion, true, &all_capabilities[0]); } #endif diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c index 5ed401ff79e3e3..e25b0f84a22daf 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c @@ -95,6 +95,7 @@ #include #include +#include /* Kernel representation of AT_HWCAP and AT_HWCAP2 */ static DECLARE_BITMAP(elf_hwcap, MAX_CPU_FEATURES) __read_mostly; @@ -3875,6 +3876,11 @@ static void __init setup_system_capabilities(void) */ if (system_uses_ttbr0_pan()) pr_info("emulated: Privileged Access Never (PAN) using TTBR0_EL1 switching\n"); + + /* + * Report Spectre mitigations status. + */ + spectre_print_disabled_mitigations(); } void __init setup_system_features(void) diff --git a/arch/arm64/kernel/module.c b/arch/arm64/kernel/module.c index d6d443c4a01aca..24adb581af0eb2 100644 --- a/arch/arm64/kernel/module.c +++ b/arch/arm64/kernel/module.c @@ -489,16 +489,29 @@ int module_finalize(const Elf_Ehdr *hdr, int ret; s = find_section(hdr, sechdrs, ".altinstructions"); - if (s) - apply_alternatives_module((void *)s->sh_addr, s->sh_size); + if (s) { + ret = apply_alternatives_module((void *)s->sh_addr, s->sh_size); + if (ret < 0) { + pr_err("module %s: error occurred when applying alternatives\n", me->name); + return ret; + } + } if (scs_is_dynamic()) { s = find_section(hdr, sechdrs, ".init.eh_frame"); if (s) { - ret = __pi_scs_patch((void *)s->sh_addr, s->sh_size); - if (ret) + /* + * Because we can reject modules that are malformed + * so SCS patching fails, skip dry run and try to patch + * it in place. If patching fails, the module would not + * be loaded anyway. + */ + ret = __pi_scs_patch((void *)s->sh_addr, s->sh_size, true); + if (ret) { pr_err("module %s: error occurred during dynamic SCS patching (%d)\n", me->name, ret); + return -ENOEXEC; + } } } diff --git a/arch/arm64/kernel/mte.c b/arch/arm64/kernel/mte.c index 43f7a2f394036b..32148bf09c1dc0 100644 --- a/arch/arm64/kernel/mte.c +++ b/arch/arm64/kernel/mte.c @@ -476,7 +476,8 @@ static int __access_remote_tags(struct mm_struct *mm, unsigned long addr, folio = page_folio(page); if (folio_test_hugetlb(folio)) - WARN_ON_ONCE(!folio_test_hugetlb_mte_tagged(folio)); + WARN_ON_ONCE(!folio_test_hugetlb_mte_tagged(folio) && + !is_huge_zero_folio(folio)); else WARN_ON_ONCE(!page_mte_tagged(page) && !is_zero_page(page)); diff --git a/arch/arm64/kernel/pi/map_kernel.c b/arch/arm64/kernel/pi/map_kernel.c index e8ddbde31a833d..659297f87cfa6e 100644 --- a/arch/arm64/kernel/pi/map_kernel.c +++ b/arch/arm64/kernel/pi/map_kernel.c @@ -104,7 +104,7 @@ static void __init map_kernel(u64 kaslr_offset, u64 va_offset, int root_level) if (enable_scs) { scs_patch(__eh_frame_start + va_offset, - __eh_frame_end - __eh_frame_start); + __eh_frame_end - __eh_frame_start, false); asm("ic ialluis"); dynamic_scs_is_enabled = true; diff --git a/arch/arm64/kernel/pi/patch-scs.c b/arch/arm64/kernel/pi/patch-scs.c index 55d0cd64ef71e6..bbe7d30ed12b32 100644 --- a/arch/arm64/kernel/pi/patch-scs.c +++ b/arch/arm64/kernel/pi/patch-scs.c @@ -225,7 +225,7 @@ static int scs_handle_fde_frame(const struct eh_frame *frame, return 0; } -int scs_patch(const u8 eh_frame[], int size) +int scs_patch(const u8 eh_frame[], int size, bool skip_dry_run) { int code_alignment_factor = 1; bool fde_use_sdata8 = false; @@ -277,11 +277,13 @@ int scs_patch(const u8 eh_frame[], int size) } } else { ret = scs_handle_fde_frame(frame, code_alignment_factor, - fde_use_sdata8, true); + fde_use_sdata8, !skip_dry_run); if (ret) return ret; - scs_handle_fde_frame(frame, code_alignment_factor, - fde_use_sdata8, false); + + if (!skip_dry_run) + scs_handle_fde_frame(frame, code_alignment_factor, + fde_use_sdata8, false); } p += sizeof(frame->size) + frame->size; diff --git a/arch/arm64/kernel/pi/pi.h b/arch/arm64/kernel/pi/pi.h index 08ef9f80456bcc..aec3172d400332 100644 --- a/arch/arm64/kernel/pi/pi.h +++ b/arch/arm64/kernel/pi/pi.h @@ -27,7 +27,7 @@ extern pgd_t init_pg_dir[], init_pg_end[]; void init_feature_override(u64 boot_status, const void *fdt, int chosen); u64 kaslr_early_init(void *fdt, int chosen); void relocate_kernel(u64 offset); -int scs_patch(const u8 eh_frame[], int size); +int scs_patch(const u8 eh_frame[], int size, bool skip_dry_run); void map_range(phys_addr_t *pte, u64 start, u64 end, phys_addr_t pa, pgprot_t prot, int level, pte_t *tbl, bool may_use_cont, diff --git a/arch/arm64/kernel/probes/kprobes.c b/arch/arm64/kernel/probes/kprobes.c index 8ab6104a4883dc..43a0361a8bf045 100644 --- a/arch/arm64/kernel/probes/kprobes.c +++ b/arch/arm64/kernel/probes/kprobes.c @@ -49,7 +49,10 @@ void *alloc_insn_page(void) addr = execmem_alloc(EXECMEM_KPROBES, PAGE_SIZE); if (!addr) return NULL; - set_memory_rox((unsigned long)addr, 1); + if (set_memory_rox((unsigned long)addr, 1)) { + execmem_free(addr); + return NULL; + } return addr; } diff --git a/arch/arm64/kernel/proton-pack.c b/arch/arm64/kernel/proton-pack.c index f9a32dfde00671..c7d70d04c164ca 100644 --- a/arch/arm64/kernel/proton-pack.c +++ b/arch/arm64/kernel/proton-pack.c @@ -91,12 +91,7 @@ early_param("nospectre_v2", parse_spectre_v2_param); static bool spectre_v2_mitigations_off(void) { - bool ret = __nospectre_v2 || cpu_mitigations_off(); - - if (ret) - pr_info_once("spectre-v2 mitigation disabled by command line option\n"); - - return ret; + return __nospectre_v2 || cpu_mitigations_off(); } static const char *get_bhb_affected_string(enum mitigation_state bhb_state) @@ -421,13 +416,8 @@ early_param("ssbd", parse_spectre_v4_param); */ static bool spectre_v4_mitigations_off(void) { - bool ret = cpu_mitigations_off() || - __spectre_v4_policy == SPECTRE_V4_POLICY_MITIGATION_DISABLED; - - if (ret) - pr_info_once("spectre-v4 mitigation disabled by command-line option\n"); - - return ret; + return cpu_mitigations_off() || + __spectre_v4_policy == SPECTRE_V4_POLICY_MITIGATION_DISABLED; } /* Do we need to toggle the mitigation state on entry to/exit from the kernel? */ @@ -1042,10 +1032,6 @@ void spectre_bhb_enable_mitigation(const struct arm64_cpu_capabilities *entry) if (arm64_get_spectre_v2_state() == SPECTRE_VULNERABLE) { /* No point mitigating Spectre-BHB alone. */ - } else if (!IS_ENABLED(CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY)) { - pr_info_once("spectre-bhb mitigation disabled by compile time option\n"); - } else if (cpu_mitigations_off() || __nospectre_bhb) { - pr_info_once("spectre-bhb mitigation disabled by command line option\n"); } else if (supports_ecbhb(SCOPE_LOCAL_CPU)) { state = SPECTRE_MITIGATED; set_bit(BHB_HW, &system_bhb_mitigations); @@ -1199,3 +1185,18 @@ void unpriv_ebpf_notify(int new_state) pr_err("WARNING: %s", EBPF_WARN); } #endif + +void spectre_print_disabled_mitigations(void) +{ + /* Keep a single copy of the common message suffix to avoid duplication. */ + const char *spectre_disabled_suffix = "mitigation disabled by command-line option\n"; + + if (spectre_v2_mitigations_off()) + pr_info("spectre-v2 %s", spectre_disabled_suffix); + + if (spectre_v4_mitigations_off()) + pr_info("spectre-v4 %s", spectre_disabled_suffix); + + if (__nospectre_bhb || cpu_mitigations_off()) + pr_info("spectre-bhb %s", spectre_disabled_suffix); +} diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index 870953b4a8a74f..052bf0d4d0b035 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -624,6 +624,7 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) kvm_timer_vcpu_load(vcpu); kvm_vgic_load(vcpu); kvm_vcpu_load_debug(vcpu); + kvm_vcpu_load_fgt(vcpu); if (has_vhe()) kvm_vcpu_load_vhe(vcpu); kvm_arch_vcpu_load_fp(vcpu); @@ -642,7 +643,6 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) vcpu->arch.hcr_el2 |= HCR_TWI; vcpu_set_pauth_traps(vcpu); - kvm_vcpu_load_fgt(vcpu); if (is_protected_kvm_enabled()) { kvm_call_hyp_nvhe(__pkvm_vcpu_load, diff --git a/arch/arm64/kvm/hyp/nvhe/ffa.c b/arch/arm64/kvm/hyp/nvhe/ffa.c index 4e16f9b96f6375..58b7d0c477d7fc 100644 --- a/arch/arm64/kvm/hyp/nvhe/ffa.c +++ b/arch/arm64/kvm/hyp/nvhe/ffa.c @@ -479,7 +479,7 @@ static void __do_ffa_mem_xfer(const u64 func_id, struct ffa_mem_region_attributes *ep_mem_access; struct ffa_composite_mem_region *reg; struct ffa_mem_region *buf; - u32 offset, nr_ranges; + u32 offset, nr_ranges, checked_offset; int ret = 0; if (addr_mbz || npages_mbz || fraglen > len || @@ -516,7 +516,12 @@ static void __do_ffa_mem_xfer(const u64 func_id, goto out_unlock; } - if (fraglen < offset + sizeof(struct ffa_composite_mem_region)) { + if (check_add_overflow(offset, sizeof(struct ffa_composite_mem_region), &checked_offset)) { + ret = FFA_RET_INVALID_PARAMETERS; + goto out_unlock; + } + + if (fraglen < checked_offset) { ret = FFA_RET_INVALID_PARAMETERS; goto out_unlock; } diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c index ddc8beb55eee6d..49db32f3ddf715 100644 --- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c +++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c @@ -367,6 +367,19 @@ static int host_stage2_unmap_dev_all(void) return kvm_pgtable_stage2_unmap(pgt, addr, BIT(pgt->ia_bits) - addr); } +/* + * Ensure the PFN range is contained within PA-range. + * + * This check is also robust to overflows and is therefore a requirement before + * using a pfn/nr_pages pair from an untrusted source. + */ +static bool pfn_range_is_valid(u64 pfn, u64 nr_pages) +{ + u64 limit = BIT(kvm_phys_shift(&host_mmu.arch.mmu) - PAGE_SHIFT); + + return pfn < limit && ((limit - pfn) >= nr_pages); +} + struct kvm_mem_range { u64 start; u64 end; @@ -776,6 +789,9 @@ int __pkvm_host_donate_hyp(u64 pfn, u64 nr_pages) void *virt = __hyp_va(phys); int ret; + if (!pfn_range_is_valid(pfn, nr_pages)) + return -EINVAL; + host_lock_component(); hyp_lock_component(); @@ -804,6 +820,9 @@ int __pkvm_hyp_donate_host(u64 pfn, u64 nr_pages) u64 virt = (u64)__hyp_va(phys); int ret; + if (!pfn_range_is_valid(pfn, nr_pages)) + return -EINVAL; + host_lock_component(); hyp_lock_component(); @@ -887,6 +906,9 @@ int __pkvm_host_share_ffa(u64 pfn, u64 nr_pages) u64 size = PAGE_SIZE * nr_pages; int ret; + if (!pfn_range_is_valid(pfn, nr_pages)) + return -EINVAL; + host_lock_component(); ret = __host_check_page_state_range(phys, size, PKVM_PAGE_OWNED); if (!ret) @@ -902,6 +924,9 @@ int __pkvm_host_unshare_ffa(u64 pfn, u64 nr_pages) u64 size = PAGE_SIZE * nr_pages; int ret; + if (!pfn_range_is_valid(pfn, nr_pages)) + return -EINVAL; + host_lock_component(); ret = __host_check_page_state_range(phys, size, PKVM_PAGE_SHARED_OWNED); if (!ret) @@ -945,6 +970,9 @@ int __pkvm_host_share_guest(u64 pfn, u64 gfn, u64 nr_pages, struct pkvm_hyp_vcpu if (prot & ~KVM_PGTABLE_PROT_RWX) return -EINVAL; + if (!pfn_range_is_valid(pfn, nr_pages)) + return -EINVAL; + ret = __guest_check_transition_size(phys, ipa, nr_pages, &size); if (ret) return ret; diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index e67eb39ddc1184..ec3fbe0b8d525b 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c @@ -2595,19 +2595,23 @@ static bool bad_redir_trap(struct kvm_vcpu *vcpu, .val = 0, \ } -/* sys_reg_desc initialiser for known cpufeature ID registers */ -#define AA32_ID_SANITISED(name) { \ - ID_DESC(name), \ - .visibility = aa32_id_visibility, \ - .val = 0, \ -} - /* sys_reg_desc initialiser for writable ID registers */ #define ID_WRITABLE(name, mask) { \ ID_DESC(name), \ .val = mask, \ } +/* + * 32bit ID regs are fully writable when the guest is 32bit + * capable. Nothing in the KVM code should rely on 32bit features + * anyway, only 64bit, so let the VMM do its worse. + */ +#define AA32_ID_WRITABLE(name) { \ + ID_DESC(name), \ + .visibility = aa32_id_visibility, \ + .val = GENMASK(31, 0), \ +} + /* sys_reg_desc initialiser for cpufeature ID registers that need filtering */ #define ID_FILTERED(sysreg, name, mask) { \ ID_DESC(sysreg), \ @@ -3128,40 +3132,39 @@ static const struct sys_reg_desc sys_reg_descs[] = { /* AArch64 mappings of the AArch32 ID registers */ /* CRm=1 */ - AA32_ID_SANITISED(ID_PFR0_EL1), - AA32_ID_SANITISED(ID_PFR1_EL1), + AA32_ID_WRITABLE(ID_PFR0_EL1), + AA32_ID_WRITABLE(ID_PFR1_EL1), { SYS_DESC(SYS_ID_DFR0_EL1), .access = access_id_reg, .get_user = get_id_reg, .set_user = set_id_dfr0_el1, .visibility = aa32_id_visibility, .reset = read_sanitised_id_dfr0_el1, - .val = ID_DFR0_EL1_PerfMon_MASK | - ID_DFR0_EL1_CopDbg_MASK, }, + .val = GENMASK(31, 0) }, ID_HIDDEN(ID_AFR0_EL1), - AA32_ID_SANITISED(ID_MMFR0_EL1), - AA32_ID_SANITISED(ID_MMFR1_EL1), - AA32_ID_SANITISED(ID_MMFR2_EL1), - AA32_ID_SANITISED(ID_MMFR3_EL1), + AA32_ID_WRITABLE(ID_MMFR0_EL1), + AA32_ID_WRITABLE(ID_MMFR1_EL1), + AA32_ID_WRITABLE(ID_MMFR2_EL1), + AA32_ID_WRITABLE(ID_MMFR3_EL1), /* CRm=2 */ - AA32_ID_SANITISED(ID_ISAR0_EL1), - AA32_ID_SANITISED(ID_ISAR1_EL1), - AA32_ID_SANITISED(ID_ISAR2_EL1), - AA32_ID_SANITISED(ID_ISAR3_EL1), - AA32_ID_SANITISED(ID_ISAR4_EL1), - AA32_ID_SANITISED(ID_ISAR5_EL1), - AA32_ID_SANITISED(ID_MMFR4_EL1), - AA32_ID_SANITISED(ID_ISAR6_EL1), + AA32_ID_WRITABLE(ID_ISAR0_EL1), + AA32_ID_WRITABLE(ID_ISAR1_EL1), + AA32_ID_WRITABLE(ID_ISAR2_EL1), + AA32_ID_WRITABLE(ID_ISAR3_EL1), + AA32_ID_WRITABLE(ID_ISAR4_EL1), + AA32_ID_WRITABLE(ID_ISAR5_EL1), + AA32_ID_WRITABLE(ID_MMFR4_EL1), + AA32_ID_WRITABLE(ID_ISAR6_EL1), /* CRm=3 */ - AA32_ID_SANITISED(MVFR0_EL1), - AA32_ID_SANITISED(MVFR1_EL1), - AA32_ID_SANITISED(MVFR2_EL1), + AA32_ID_WRITABLE(MVFR0_EL1), + AA32_ID_WRITABLE(MVFR1_EL1), + AA32_ID_WRITABLE(MVFR2_EL1), ID_UNALLOCATED(3,3), - AA32_ID_SANITISED(ID_PFR2_EL1), + AA32_ID_WRITABLE(ID_PFR2_EL1), ID_HIDDEN(ID_DFR1_EL1), - AA32_ID_SANITISED(ID_MMFR5_EL1), + AA32_ID_WRITABLE(ID_MMFR5_EL1), ID_UNALLOCATED(3,7), /* AArch64 ID registers */ @@ -5606,11 +5609,17 @@ int kvm_finalize_sys_regs(struct kvm_vcpu *vcpu) guard(mutex)(&kvm->arch.config_lock); - if (!(static_branch_unlikely(&kvm_vgic_global_state.gicv3_cpuif) && - irqchip_in_kernel(kvm) && - kvm->arch.vgic.vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3)) { - kvm->arch.id_regs[IDREG_IDX(SYS_ID_AA64PFR0_EL1)] &= ~ID_AA64PFR0_EL1_GIC_MASK; - kvm->arch.id_regs[IDREG_IDX(SYS_ID_PFR1_EL1)] &= ~ID_PFR1_EL1_GIC_MASK; + /* + * This hacks into the ID registers, so only perform it when the + * first vcpu runs, or the kvm_set_vm_id_reg() helper will scream. + */ + if (!irqchip_in_kernel(kvm) && !kvm_vm_has_ran_once(kvm)) { + u64 val; + + val = kvm_read_vm_id_reg(kvm, SYS_ID_AA64PFR0_EL1) & ~ID_AA64PFR0_EL1_GIC; + kvm_set_vm_id_reg(kvm, SYS_ID_AA64PFR0_EL1, val); + val = kvm_read_vm_id_reg(kvm, SYS_ID_PFR1_EL1) & ~ID_PFR1_EL1_GIC; + kvm_set_vm_id_reg(kvm, SYS_ID_PFR1_EL1, val); } if (vcpu_has_nv(vcpu)) { diff --git a/arch/arm64/kvm/vgic/vgic-debug.c b/arch/arm64/kvm/vgic/vgic-debug.c index 4c1209261b65d4..bb92853d1fd3a5 100644 --- a/arch/arm64/kvm/vgic/vgic-debug.c +++ b/arch/arm64/kvm/vgic/vgic-debug.c @@ -64,29 +64,37 @@ static void iter_next(struct kvm *kvm, struct vgic_state_iter *iter) static int iter_mark_lpis(struct kvm *kvm) { struct vgic_dist *dist = &kvm->arch.vgic; + unsigned long intid, flags; struct vgic_irq *irq; - unsigned long intid; int nr_lpis = 0; + xa_lock_irqsave(&dist->lpi_xa, flags); + xa_for_each(&dist->lpi_xa, intid, irq) { if (!vgic_try_get_irq_ref(irq)) continue; - xa_set_mark(&dist->lpi_xa, intid, LPI_XA_MARK_DEBUG_ITER); + __xa_set_mark(&dist->lpi_xa, intid, LPI_XA_MARK_DEBUG_ITER); nr_lpis++; } + xa_unlock_irqrestore(&dist->lpi_xa, flags); + return nr_lpis; } static void iter_unmark_lpis(struct kvm *kvm) { struct vgic_dist *dist = &kvm->arch.vgic; + unsigned long intid, flags; struct vgic_irq *irq; - unsigned long intid; xa_for_each_marked(&dist->lpi_xa, intid, irq, LPI_XA_MARK_DEBUG_ITER) { - xa_clear_mark(&dist->lpi_xa, intid, LPI_XA_MARK_DEBUG_ITER); + xa_lock_irqsave(&dist->lpi_xa, flags); + __xa_clear_mark(&dist->lpi_xa, intid, LPI_XA_MARK_DEBUG_ITER); + xa_unlock_irqrestore(&dist->lpi_xa, flags); + + /* vgic_put_irq() expects to be called outside of the xa_lock */ vgic_put_irq(kvm, irq); } } diff --git a/arch/arm64/kvm/vgic/vgic-init.c b/arch/arm64/kvm/vgic/vgic-init.c index 1796b1a22a72a1..da62edbc1205ad 100644 --- a/arch/arm64/kvm/vgic/vgic-init.c +++ b/arch/arm64/kvm/vgic/vgic-init.c @@ -53,7 +53,7 @@ void kvm_vgic_early_init(struct kvm *kvm) { struct vgic_dist *dist = &kvm->arch.vgic; - xa_init(&dist->lpi_xa); + xa_init_flags(&dist->lpi_xa, XA_FLAGS_LOCK_IRQ); } /* CREATION */ @@ -71,6 +71,7 @@ static int vgic_allocate_private_irqs_locked(struct kvm_vcpu *vcpu, u32 type); int kvm_vgic_create(struct kvm *kvm, u32 type) { struct kvm_vcpu *vcpu; + u64 aa64pfr0, pfr1; unsigned long i; int ret; @@ -161,10 +162,19 @@ int kvm_vgic_create(struct kvm *kvm, u32 type) kvm->arch.vgic.vgic_dist_base = VGIC_ADDR_UNDEF; - if (type == KVM_DEV_TYPE_ARM_VGIC_V2) + aa64pfr0 = kvm_read_vm_id_reg(kvm, SYS_ID_AA64PFR0_EL1) & ~ID_AA64PFR0_EL1_GIC; + pfr1 = kvm_read_vm_id_reg(kvm, SYS_ID_PFR1_EL1) & ~ID_PFR1_EL1_GIC; + + if (type == KVM_DEV_TYPE_ARM_VGIC_V2) { kvm->arch.vgic.vgic_cpu_base = VGIC_ADDR_UNDEF; - else + } else { INIT_LIST_HEAD(&kvm->arch.vgic.rd_regions); + aa64pfr0 |= SYS_FIELD_PREP_ENUM(ID_AA64PFR0_EL1, GIC, IMP); + pfr1 |= SYS_FIELD_PREP_ENUM(ID_PFR1_EL1, GIC, GICv3); + } + + kvm_set_vm_id_reg(kvm, SYS_ID_AA64PFR0_EL1, aa64pfr0); + kvm_set_vm_id_reg(kvm, SYS_ID_PFR1_EL1, pfr1); if (type == KVM_DEV_TYPE_ARM_VGIC_V3) kvm->arch.vgic.nassgicap = system_supports_direct_sgis(); diff --git a/arch/arm64/kvm/vgic/vgic-its.c b/arch/arm64/kvm/vgic/vgic-its.c index ce3e3ed3f29f04..3f1c4b10fed900 100644 --- a/arch/arm64/kvm/vgic/vgic-its.c +++ b/arch/arm64/kvm/vgic/vgic-its.c @@ -78,6 +78,7 @@ static struct vgic_irq *vgic_add_lpi(struct kvm *kvm, u32 intid, { struct vgic_dist *dist = &kvm->arch.vgic; struct vgic_irq *irq = vgic_get_irq(kvm, intid), *oldirq; + unsigned long flags; int ret; /* In this case there is no put, since we keep the reference. */ @@ -88,7 +89,7 @@ static struct vgic_irq *vgic_add_lpi(struct kvm *kvm, u32 intid, if (!irq) return ERR_PTR(-ENOMEM); - ret = xa_reserve(&dist->lpi_xa, intid, GFP_KERNEL_ACCOUNT); + ret = xa_reserve_irq(&dist->lpi_xa, intid, GFP_KERNEL_ACCOUNT); if (ret) { kfree(irq); return ERR_PTR(ret); @@ -103,7 +104,7 @@ static struct vgic_irq *vgic_add_lpi(struct kvm *kvm, u32 intid, irq->target_vcpu = vcpu; irq->group = 1; - xa_lock(&dist->lpi_xa); + xa_lock_irqsave(&dist->lpi_xa, flags); /* * There could be a race with another vgic_add_lpi(), so we need to @@ -114,21 +115,18 @@ static struct vgic_irq *vgic_add_lpi(struct kvm *kvm, u32 intid, /* Someone was faster with adding this LPI, lets use that. */ kfree(irq); irq = oldirq; - - goto out_unlock; + } else { + ret = xa_err(__xa_store(&dist->lpi_xa, intid, irq, 0)); } - ret = xa_err(__xa_store(&dist->lpi_xa, intid, irq, 0)); + xa_unlock_irqrestore(&dist->lpi_xa, flags); + if (ret) { xa_release(&dist->lpi_xa, intid); kfree(irq); - } - -out_unlock: - xa_unlock(&dist->lpi_xa); - if (ret) return ERR_PTR(ret); + } /* * We "cache" the configuration table entries in our struct vgic_irq's. diff --git a/arch/arm64/kvm/vgic/vgic-v3.c b/arch/arm64/kvm/vgic/vgic-v3.c index 6fbb4b09985521..2f75ef14d33999 100644 --- a/arch/arm64/kvm/vgic/vgic-v3.c +++ b/arch/arm64/kvm/vgic/vgic-v3.c @@ -301,7 +301,8 @@ void vcpu_set_ich_hcr(struct kvm_vcpu *vcpu) return; /* Hide GICv3 sysreg if necessary */ - if (vcpu->kvm->arch.vgic.vgic_model == KVM_DEV_TYPE_ARM_VGIC_V2) { + if (vcpu->kvm->arch.vgic.vgic_model == KVM_DEV_TYPE_ARM_VGIC_V2 || + !irqchip_in_kernel(vcpu->kvm)) { vgic_v3->vgic_hcr |= (ICH_HCR_EL2_TALL0 | ICH_HCR_EL2_TALL1 | ICH_HCR_EL2_TC); return; diff --git a/arch/arm64/kvm/vgic/vgic.c b/arch/arm64/kvm/vgic/vgic.c index 6dd5a10081e27e..8d20c53faef02c 100644 --- a/arch/arm64/kvm/vgic/vgic.c +++ b/arch/arm64/kvm/vgic/vgic.c @@ -28,7 +28,7 @@ struct vgic_global kvm_vgic_global_state __ro_after_init = { * kvm->arch.config_lock (mutex) * its->cmd_lock (mutex) * its->its_lock (mutex) - * vgic_dist->lpi_xa.xa_lock + * vgic_dist->lpi_xa.xa_lock must be taken with IRQs disabled * vgic_cpu->ap_list_lock must be taken with IRQs disabled * vgic_irq->irq_lock must be taken with IRQs disabled * @@ -141,32 +141,39 @@ static __must_check bool vgic_put_irq_norelease(struct kvm *kvm, struct vgic_irq void vgic_put_irq(struct kvm *kvm, struct vgic_irq *irq) { struct vgic_dist *dist = &kvm->arch.vgic; + unsigned long flags; - if (irq->intid >= VGIC_MIN_LPI) - might_lock(&dist->lpi_xa.xa_lock); + /* + * Normally the lock is only taken when the refcount drops to 0. + * Acquire/release it early on lockdep kernels to make locking issues + * in rare release paths a bit more obvious. + */ + if (IS_ENABLED(CONFIG_LOCKDEP) && irq->intid >= VGIC_MIN_LPI) { + guard(spinlock_irqsave)(&dist->lpi_xa.xa_lock); + } if (!__vgic_put_irq(kvm, irq)) return; - xa_lock(&dist->lpi_xa); + xa_lock_irqsave(&dist->lpi_xa, flags); vgic_release_lpi_locked(dist, irq); - xa_unlock(&dist->lpi_xa); + xa_unlock_irqrestore(&dist->lpi_xa, flags); } static void vgic_release_deleted_lpis(struct kvm *kvm) { struct vgic_dist *dist = &kvm->arch.vgic; - unsigned long intid; + unsigned long flags, intid; struct vgic_irq *irq; - xa_lock(&dist->lpi_xa); + xa_lock_irqsave(&dist->lpi_xa, flags); xa_for_each(&dist->lpi_xa, intid, irq) { if (irq->pending_release) vgic_release_lpi_locked(dist, irq); } - xa_unlock(&dist->lpi_xa); + xa_unlock_irqrestore(&dist->lpi_xa, flags); } void vgic_flush_pending_lpis(struct kvm_vcpu *vcpu) diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c index d816ff44faff94..a193b6a5d1e65f 100644 --- a/arch/arm64/mm/fault.c +++ b/arch/arm64/mm/fault.c @@ -967,10 +967,21 @@ struct folio *vma_alloc_zeroed_movable_folio(struct vm_area_struct *vma, return vma_alloc_folio(flags, 0, vma, vaddr); } -void tag_clear_highpage(struct page *page) +bool tag_clear_highpages(struct page *page, int numpages) { - /* Newly allocated page, shouldn't have been tagged yet */ - WARN_ON_ONCE(!try_page_mte_tagging(page)); - mte_zero_clear_page_tags(page_address(page)); - set_page_mte_tagged(page); + /* + * Check if MTE is supported and fall back to clear_highpage(). + * get_huge_zero_folio() unconditionally passes __GFP_ZEROTAGS and + * post_alloc_hook() will invoke tag_clear_highpages(). + */ + if (!system_supports_mte()) + return false; + + /* Newly allocated pages, shouldn't have been tagged yet */ + for (int i = 0; i < numpages; i++, page++) { + WARN_ON_ONCE(!try_page_mte_tagging(page)); + mte_zero_clear_page_tags(page_address(page)); + set_page_mte_tagged(page); + } + return true; } diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c index b8d37eb037fcca..2ba01dc8ef822a 100644 --- a/arch/arm64/mm/mmu.c +++ b/arch/arm64/mm/mmu.c @@ -708,6 +708,30 @@ static int split_kernel_leaf_mapping_locked(unsigned long addr) return ret; } +static inline bool force_pte_mapping(void) +{ + const bool bbml2 = system_capabilities_finalized() ? + system_supports_bbml2_noabort() : cpu_supports_bbml2_noabort(); + + if (debug_pagealloc_enabled()) + return true; + if (bbml2) + return false; + return rodata_full || arm64_kfence_can_set_direct_map() || is_realm_world(); +} + +static inline bool split_leaf_mapping_possible(void) +{ + /* + * !BBML2_NOABORT systems should never run into scenarios where we would + * have to split. So exit early and let calling code detect it and raise + * a warning. + */ + if (!system_supports_bbml2_noabort()) + return false; + return !force_pte_mapping(); +} + static DEFINE_MUTEX(pgtable_split_lock); int split_kernel_leaf_mapping(unsigned long start, unsigned long end) @@ -715,12 +739,11 @@ int split_kernel_leaf_mapping(unsigned long start, unsigned long end) int ret; /* - * !BBML2_NOABORT systems should not be trying to change permissions on - * anything that is not pte-mapped in the first place. Just return early - * and let the permission change code raise a warning if not already - * pte-mapped. + * Exit early if the region is within a pte-mapped area or if we can't + * split. For the latter case, the permission change code will raise a + * warning if not already pte-mapped. */ - if (!system_supports_bbml2_noabort()) + if (!split_leaf_mapping_possible() || is_kfence_address((void *)start)) return 0; /* @@ -758,30 +781,30 @@ int split_kernel_leaf_mapping(unsigned long start, unsigned long end) return ret; } -static int __init split_to_ptes_pud_entry(pud_t *pudp, unsigned long addr, - unsigned long next, - struct mm_walk *walk) +static int split_to_ptes_pud_entry(pud_t *pudp, unsigned long addr, + unsigned long next, struct mm_walk *walk) { + gfp_t gfp = *(gfp_t *)walk->private; pud_t pud = pudp_get(pudp); int ret = 0; if (pud_leaf(pud)) - ret = split_pud(pudp, pud, GFP_ATOMIC, false); + ret = split_pud(pudp, pud, gfp, false); return ret; } -static int __init split_to_ptes_pmd_entry(pmd_t *pmdp, unsigned long addr, - unsigned long next, - struct mm_walk *walk) +static int split_to_ptes_pmd_entry(pmd_t *pmdp, unsigned long addr, + unsigned long next, struct mm_walk *walk) { + gfp_t gfp = *(gfp_t *)walk->private; pmd_t pmd = pmdp_get(pmdp); int ret = 0; if (pmd_leaf(pmd)) { if (pmd_cont(pmd)) split_contpmd(pmdp); - ret = split_pmd(pmdp, pmd, GFP_ATOMIC, false); + ret = split_pmd(pmdp, pmd, gfp, false); /* * We have split the pmd directly to ptes so there is no need to @@ -793,9 +816,8 @@ static int __init split_to_ptes_pmd_entry(pmd_t *pmdp, unsigned long addr, return ret; } -static int __init split_to_ptes_pte_entry(pte_t *ptep, unsigned long addr, - unsigned long next, - struct mm_walk *walk) +static int split_to_ptes_pte_entry(pte_t *ptep, unsigned long addr, + unsigned long next, struct mm_walk *walk) { pte_t pte = __ptep_get(ptep); @@ -805,12 +827,24 @@ static int __init split_to_ptes_pte_entry(pte_t *ptep, unsigned long addr, return 0; } -static const struct mm_walk_ops split_to_ptes_ops __initconst = { +static const struct mm_walk_ops split_to_ptes_ops = { .pud_entry = split_to_ptes_pud_entry, .pmd_entry = split_to_ptes_pmd_entry, .pte_entry = split_to_ptes_pte_entry, }; +static int range_split_to_ptes(unsigned long start, unsigned long end, gfp_t gfp) +{ + int ret; + + arch_enter_lazy_mmu_mode(); + ret = walk_kernel_page_table_range_lockless(start, end, + &split_to_ptes_ops, NULL, &gfp); + arch_leave_lazy_mmu_mode(); + + return ret; +} + static bool linear_map_requires_bbml2 __initdata; u32 idmap_kpti_bbml2_flag; @@ -847,11 +881,9 @@ static int __init linear_map_split_to_ptes(void *__unused) * PTE. The kernel alias remains static throughout runtime so * can continue to be safely mapped with large mappings. */ - ret = walk_kernel_page_table_range_lockless(lstart, kstart, - &split_to_ptes_ops, NULL, NULL); + ret = range_split_to_ptes(lstart, kstart, GFP_ATOMIC); if (!ret) - ret = walk_kernel_page_table_range_lockless(kend, lend, - &split_to_ptes_ops, NULL, NULL); + ret = range_split_to_ptes(kend, lend, GFP_ATOMIC); if (ret) panic("Failed to split linear map\n"); flush_tlb_kernel_range(lstart, lend); @@ -1002,6 +1034,33 @@ static void __init arm64_kfence_map_pool(phys_addr_t kfence_pool, pgd_t *pgdp) memblock_clear_nomap(kfence_pool, KFENCE_POOL_SIZE); __kfence_pool = phys_to_virt(kfence_pool); } + +bool arch_kfence_init_pool(void) +{ + unsigned long start = (unsigned long)__kfence_pool; + unsigned long end = start + KFENCE_POOL_SIZE; + int ret; + + /* Exit early if we know the linear map is already pte-mapped. */ + if (!split_leaf_mapping_possible()) + return true; + + /* Kfence pool is already pte-mapped for the early init case. */ + if (kfence_early_init) + return true; + + mutex_lock(&pgtable_split_lock); + ret = range_split_to_ptes(start, end, GFP_PGTABLE_KERNEL); + mutex_unlock(&pgtable_split_lock); + + /* + * Since the system supports bbml2_noabort, tlb invalidation is not + * required here; the pgtable mappings have been split to pte but larger + * entries may safely linger in the TLB. + */ + + return !ret; +} #else /* CONFIG_KFENCE */ static inline phys_addr_t arm64_kfence_alloc_pool(void) { return 0; } @@ -1009,16 +1068,6 @@ static inline void arm64_kfence_map_pool(phys_addr_t kfence_pool, pgd_t *pgdp) { #endif /* CONFIG_KFENCE */ -static inline bool force_pte_mapping(void) -{ - bool bbml2 = system_capabilities_finalized() ? - system_supports_bbml2_noabort() : cpu_supports_bbml2_noabort(); - - return (!bbml2 && (rodata_full || arm64_kfence_can_set_direct_map() || - is_realm_world())) || - debug_pagealloc_enabled(); -} - static void __init map_mem(pgd_t *pgdp) { static const u64 direct_map_end = _PAGE_END(VA_BITS_MIN); diff --git a/arch/loongarch/Makefile b/arch/loongarch/Makefile index dc5bd3f1b8d2cb..96ca1a688984e9 100644 --- a/arch/loongarch/Makefile +++ b/arch/loongarch/Makefile @@ -109,7 +109,7 @@ endif ifdef CONFIG_RUSTC_HAS_ANNOTATE_TABLEJUMP KBUILD_RUSTFLAGS += -Cllvm-args=--loongarch-annotate-tablejump else -KBUILD_RUSTFLAGS += -Zno-jump-tables # keep compatibility with older compilers +KBUILD_RUSTFLAGS += $(if $(call rustc-min-version,109300),-Cjump-tables=n,-Zno-jump-tables) # keep compatibility with older compilers endif ifdef CONFIG_LTO_CLANG # The annotate-tablejump option can not be passed to LLVM backend when LTO is enabled. diff --git a/arch/loongarch/include/asm/cpu-features.h b/arch/loongarch/include/asm/cpu-features.h index fc83bb32f9f09d..bd5f0457ad21d8 100644 --- a/arch/loongarch/include/asm/cpu-features.h +++ b/arch/loongarch/include/asm/cpu-features.h @@ -67,6 +67,8 @@ #define cpu_has_hypervisor cpu_opt(LOONGARCH_CPU_HYPERVISOR) #define cpu_has_ptw cpu_opt(LOONGARCH_CPU_PTW) #define cpu_has_lspw cpu_opt(LOONGARCH_CPU_LSPW) +#define cpu_has_msgint cpu_opt(LOONGARCH_CPU_MSGINT) #define cpu_has_avecint cpu_opt(LOONGARCH_CPU_AVECINT) +#define cpu_has_redirectint cpu_opt(LOONGARCH_CPU_REDIRECTINT) #endif /* __ASM_CPU_FEATURES_H */ diff --git a/arch/loongarch/include/asm/cpu.h b/arch/loongarch/include/asm/cpu.h index dfb982fe870192..f3efb00b61414a 100644 --- a/arch/loongarch/include/asm/cpu.h +++ b/arch/loongarch/include/asm/cpu.h @@ -55,6 +55,27 @@ enum cpu_type_enum { CPU_LAST }; +static inline char *id_to_core_name(unsigned int id) +{ + if ((id & PRID_COMP_MASK) != PRID_COMP_LOONGSON) + return "Unknown"; + + switch (id & PRID_SERIES_MASK) { + case PRID_SERIES_LA132: + return "LA132"; + case PRID_SERIES_LA264: + return "LA264"; + case PRID_SERIES_LA364: + return "LA364"; + case PRID_SERIES_LA464: + return "LA464"; + case PRID_SERIES_LA664: + return "LA664"; + default: + return "Unknown"; + } +} + #endif /* !__ASSEMBLER__ */ /* @@ -101,7 +122,9 @@ enum cpu_type_enum { #define CPU_FEATURE_HYPERVISOR 26 /* CPU has hypervisor (running in VM) */ #define CPU_FEATURE_PTW 27 /* CPU has hardware page table walker */ #define CPU_FEATURE_LSPW 28 /* CPU has LSPW (lddir/ldpte instructions) */ -#define CPU_FEATURE_AVECINT 29 /* CPU has AVEC interrupt */ +#define CPU_FEATURE_MSGINT 29 /* CPU has MSG interrupt */ +#define CPU_FEATURE_AVECINT 30 /* CPU has AVEC interrupt */ +#define CPU_FEATURE_REDIRECTINT 31 /* CPU has interrupt remapping */ #define LOONGARCH_CPU_CPUCFG BIT_ULL(CPU_FEATURE_CPUCFG) #define LOONGARCH_CPU_LAM BIT_ULL(CPU_FEATURE_LAM) @@ -132,6 +155,8 @@ enum cpu_type_enum { #define LOONGARCH_CPU_HYPERVISOR BIT_ULL(CPU_FEATURE_HYPERVISOR) #define LOONGARCH_CPU_PTW BIT_ULL(CPU_FEATURE_PTW) #define LOONGARCH_CPU_LSPW BIT_ULL(CPU_FEATURE_LSPW) +#define LOONGARCH_CPU_MSGINT BIT_ULL(CPU_FEATURE_MSGINT) #define LOONGARCH_CPU_AVECINT BIT_ULL(CPU_FEATURE_AVECINT) +#define LOONGARCH_CPU_REDIRECTINT BIT_ULL(CPU_FEATURE_REDIRECTINT) #endif /* _ASM_CPU_H */ diff --git a/arch/loongarch/include/asm/hw_breakpoint.h b/arch/loongarch/include/asm/hw_breakpoint.h index 13b2462f3d8c9d..5faa97a87a9e2d 100644 --- a/arch/loongarch/include/asm/hw_breakpoint.h +++ b/arch/loongarch/include/asm/hw_breakpoint.h @@ -134,13 +134,13 @@ static inline void hw_breakpoint_thread_switch(struct task_struct *next) /* Determine number of BRP registers available. */ static inline int get_num_brps(void) { - return csr_read64(LOONGARCH_CSR_FWPC) & CSR_FWPC_NUM; + return csr_read32(LOONGARCH_CSR_FWPC) & CSR_FWPC_NUM; } /* Determine number of WRP registers available. */ static inline int get_num_wrps(void) { - return csr_read64(LOONGARCH_CSR_MWPC) & CSR_MWPC_NUM; + return csr_read32(LOONGARCH_CSR_MWPC) & CSR_MWPC_NUM; } #endif /* __KERNEL__ */ diff --git a/arch/loongarch/include/asm/io.h b/arch/loongarch/include/asm/io.h index eaff72b38dc822..0130185e03494e 100644 --- a/arch/loongarch/include/asm/io.h +++ b/arch/loongarch/include/asm/io.h @@ -14,7 +14,7 @@ #include #include -extern void __init __iomem *early_ioremap(u64 phys_addr, unsigned long size); +extern void __init __iomem *early_ioremap(phys_addr_t phys_addr, unsigned long size); extern void __init early_iounmap(void __iomem *addr, unsigned long size); #define early_memremap early_ioremap @@ -25,6 +25,9 @@ extern void __init early_iounmap(void __iomem *addr, unsigned long size); static inline void __iomem *ioremap_prot(phys_addr_t offset, unsigned long size, pgprot_t prot) { + if (offset > TO_PHYS_MASK) + return NULL; + switch (pgprot_val(prot) & _CACHE_MASK) { case _CACHE_CC: return (void __iomem *)(unsigned long)(CACHE_BASE + offset); diff --git a/arch/loongarch/include/asm/loongarch.h b/arch/loongarch/include/asm/loongarch.h index 09dfd7eb406e7e..3de03cb864b248 100644 --- a/arch/loongarch/include/asm/loongarch.h +++ b/arch/loongarch/include/asm/loongarch.h @@ -128,6 +128,7 @@ #define CPUCFG6_PMNUM GENMASK(7, 4) #define CPUCFG6_PMNUM_SHIFT 4 #define CPUCFG6_PMBITS GENMASK(13, 8) +#define CPUCFG6_PMBITS_SHIFT 8 #define CPUCFG6_UPM BIT(14) #define LOONGARCH_CPUCFG16 0x10 @@ -1137,6 +1138,7 @@ #define IOCSRF_FLATMODE BIT_ULL(10) #define IOCSRF_VM BIT_ULL(11) #define IOCSRF_AVEC BIT_ULL(15) +#define IOCSRF_REDIRECT BIT_ULL(16) #define LOONGARCH_IOCSR_VENDOR 0x10 diff --git a/arch/loongarch/include/asm/pgalloc.h b/arch/loongarch/include/asm/pgalloc.h index 1c63a9d9a6d35d..08dcc698ec1848 100644 --- a/arch/loongarch/include/asm/pgalloc.h +++ b/arch/loongarch/include/asm/pgalloc.h @@ -88,7 +88,7 @@ static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address) static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long address) { pud_t *pud; - struct ptdesc *ptdesc = pagetable_alloc(GFP_KERNEL & ~__GFP_HIGHMEM, 0); + struct ptdesc *ptdesc = pagetable_alloc(GFP_KERNEL, 0); if (!ptdesc) return NULL; diff --git a/arch/loongarch/include/asm/pgtable.h b/arch/loongarch/include/asm/pgtable.h index bd128696e96d0b..03fb60432fde79 100644 --- a/arch/loongarch/include/asm/pgtable.h +++ b/arch/loongarch/include/asm/pgtable.h @@ -424,6 +424,9 @@ static inline unsigned long pte_accessible(struct mm_struct *mm, pte_t a) static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) { + if (pte_val(pte) & _PAGE_DIRTY) + pte_val(pte) |= _PAGE_MODIFIED; + return __pte((pte_val(pte) & _PAGE_CHG_MASK) | (pgprot_val(newprot) & ~_PAGE_CHG_MASK)); } @@ -547,9 +550,11 @@ static inline struct page *pmd_page(pmd_t pmd) static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot) { - pmd_val(pmd) = (pmd_val(pmd) & _HPAGE_CHG_MASK) | - (pgprot_val(newprot) & ~_HPAGE_CHG_MASK); - return pmd; + if (pmd_val(pmd) & _PAGE_DIRTY) + pmd_val(pmd) |= _PAGE_MODIFIED; + + return __pmd((pmd_val(pmd) & _HPAGE_CHG_MASK) | + (pgprot_val(newprot) & ~_HPAGE_CHG_MASK)); } static inline pmd_t pmd_mkinvalid(pmd_t pmd) diff --git a/arch/loongarch/include/uapi/asm/ptrace.h b/arch/loongarch/include/uapi/asm/ptrace.h index aafb3cd9e943e5..215e0f9e8aa32a 100644 --- a/arch/loongarch/include/uapi/asm/ptrace.h +++ b/arch/loongarch/include/uapi/asm/ptrace.h @@ -10,10 +10,6 @@ #include -#ifndef __KERNEL__ -#include -#endif - /* * For PTRACE_{POKE,PEEK}USR. 0 - 31 are GPRs, * 32 is syscall's original ARG0, 33 is PC, 34 is BADVADDR. @@ -41,44 +37,44 @@ struct user_pt_regs { } __attribute__((aligned(8))); struct user_fp_state { - uint64_t fpr[32]; - uint64_t fcc; - uint32_t fcsr; + __u64 fpr[32]; + __u64 fcc; + __u32 fcsr; }; struct user_lsx_state { /* 32 registers, 128 bits width per register. */ - uint64_t vregs[32*2]; + __u64 vregs[32*2]; }; struct user_lasx_state { /* 32 registers, 256 bits width per register. */ - uint64_t vregs[32*4]; + __u64 vregs[32*4]; }; struct user_lbt_state { - uint64_t scr[4]; - uint32_t eflags; - uint32_t ftop; + __u64 scr[4]; + __u32 eflags; + __u32 ftop; }; struct user_watch_state { - uint64_t dbg_info; + __u64 dbg_info; struct { - uint64_t addr; - uint64_t mask; - uint32_t ctrl; - uint32_t pad; + __u64 addr; + __u64 mask; + __u32 ctrl; + __u32 pad; } dbg_regs[8]; }; struct user_watch_state_v2 { - uint64_t dbg_info; + __u64 dbg_info; struct { - uint64_t addr; - uint64_t mask; - uint32_t ctrl; - uint32_t pad; + __u64 addr; + __u64 mask; + __u32 ctrl; + __u32 pad; } dbg_regs[14]; }; diff --git a/arch/loongarch/kernel/cpu-probe.c b/arch/loongarch/kernel/cpu-probe.c index cbfce2872d7165..a2060a24b39fd7 100644 --- a/arch/loongarch/kernel/cpu-probe.c +++ b/arch/loongarch/kernel/cpu-probe.c @@ -157,6 +157,8 @@ static void cpu_probe_common(struct cpuinfo_loongarch *c) c->options |= LOONGARCH_CPU_TLB; if (config & CPUCFG1_IOCSR) c->options |= LOONGARCH_CPU_IOCSR; + if (config & CPUCFG1_MSGINT) + c->options |= LOONGARCH_CPU_MSGINT; if (config & CPUCFG1_UAL) { c->options |= LOONGARCH_CPU_UAL; elf_hwcap |= HWCAP_LOONGARCH_UAL; @@ -275,7 +277,7 @@ static inline void cpu_probe_loongson(struct cpuinfo_loongarch *c, unsigned int uint32_t config; uint64_t *vendor = (void *)(&cpu_full_name[VENDOR_OFFSET]); uint64_t *cpuname = (void *)(&cpu_full_name[CPUNAME_OFFSET]); - const char *core_name = "Unknown"; + const char *core_name = id_to_core_name(c->processor_id); switch (BIT(fls(c->isa_level) - 1)) { case LOONGARCH_CPU_ISA_LA32R: @@ -289,35 +291,23 @@ static inline void cpu_probe_loongson(struct cpuinfo_loongarch *c, unsigned int break; } - switch (c->processor_id & PRID_SERIES_MASK) { - case PRID_SERIES_LA132: - core_name = "LA132"; - break; - case PRID_SERIES_LA264: - core_name = "LA264"; - break; - case PRID_SERIES_LA364: - core_name = "LA364"; - break; - case PRID_SERIES_LA464: - core_name = "LA464"; - break; - case PRID_SERIES_LA664: - core_name = "LA664"; - break; - } - pr_info("%s Processor probed (%s Core)\n", __cpu_family[cpu], core_name); - if (!cpu_has_iocsr) + if (!cpu_has_iocsr) { + __cpu_full_name[cpu] = "Unknown"; return; - - if (!__cpu_full_name[cpu]) - __cpu_full_name[cpu] = cpu_full_name; + } *vendor = iocsr_read64(LOONGARCH_IOCSR_VENDOR); *cpuname = iocsr_read64(LOONGARCH_IOCSR_CPUNAME); + if (!__cpu_full_name[cpu]) { + if (((char *)vendor)[0] == 0) + __cpu_full_name[cpu] = "Unknown"; + else + __cpu_full_name[cpu] = cpu_full_name; + } + config = iocsr_read32(LOONGARCH_IOCSR_FEATURES); if (config & IOCSRF_CSRIPI) c->options |= LOONGARCH_CPU_CSRIPI; @@ -331,6 +321,8 @@ static inline void cpu_probe_loongson(struct cpuinfo_loongarch *c, unsigned int c->options |= LOONGARCH_CPU_EIODECODE; if (config & IOCSRF_AVEC) c->options |= LOONGARCH_CPU_AVECINT; + if (config & IOCSRF_REDIRECT) + c->options |= LOONGARCH_CPU_REDIRECTINT; if (config & IOCSRF_VM) c->options |= LOONGARCH_CPU_HYPERVISOR; } diff --git a/arch/loongarch/kernel/kexec_efi.c b/arch/loongarch/kernel/kexec_efi.c index 45121b914f8f79..5ee78ebb1546e2 100644 --- a/arch/loongarch/kernel/kexec_efi.c +++ b/arch/loongarch/kernel/kexec_efi.c @@ -42,7 +42,7 @@ static void *efi_kexec_load(struct kimage *image, { int ret; unsigned long text_offset, kernel_segment_number; - struct kexec_buf kbuf; + struct kexec_buf kbuf = {}; struct kexec_segment *kernel_segment; struct loongarch_image_header *h; diff --git a/arch/loongarch/kernel/kexec_elf.c b/arch/loongarch/kernel/kexec_elf.c index 97b2f049801a8f..1b6b64744c7fde 100644 --- a/arch/loongarch/kernel/kexec_elf.c +++ b/arch/loongarch/kernel/kexec_elf.c @@ -59,7 +59,7 @@ static void *elf_kexec_load(struct kimage *image, int ret; unsigned long text_offset, kernel_segment_number; struct elfhdr ehdr; - struct kexec_buf kbuf; + struct kexec_buf kbuf = {}; struct kexec_elf_info elf_info; struct kexec_segment *kernel_segment; diff --git a/arch/loongarch/kernel/machine_kexec.c b/arch/loongarch/kernel/machine_kexec.c index e4b2bbc47e6235..d7fafda1d5417c 100644 --- a/arch/loongarch/kernel/machine_kexec.c +++ b/arch/loongarch/kernel/machine_kexec.c @@ -39,34 +39,12 @@ static unsigned long systable_ptr; static unsigned long start_addr; static unsigned long first_ind_entry; -static void kexec_image_info(const struct kimage *kimage) -{ - unsigned long i; - - pr_debug("kexec kimage info:\n"); - pr_debug("\ttype: %d\n", kimage->type); - pr_debug("\tstart: %lx\n", kimage->start); - pr_debug("\thead: %lx\n", kimage->head); - pr_debug("\tnr_segments: %lu\n", kimage->nr_segments); - - for (i = 0; i < kimage->nr_segments; i++) { - pr_debug("\t segment[%lu]: %016lx - %016lx", i, - kimage->segment[i].mem, - kimage->segment[i].mem + kimage->segment[i].memsz); - pr_debug("\t\t0x%lx bytes, %lu pages\n", - (unsigned long)kimage->segment[i].memsz, - (unsigned long)kimage->segment[i].memsz / PAGE_SIZE); - } -} - int machine_kexec_prepare(struct kimage *kimage) { int i; char *bootloader = "kexec"; void *cmdline_ptr = (void *)KEXEC_CMDLINE_ADDR; - kexec_image_info(kimage); - kimage->arch.efi_boot = fw_arg0; kimage->arch.systable_ptr = fw_arg2; @@ -259,6 +237,7 @@ void machine_crash_shutdown(struct pt_regs *regs) #ifdef CONFIG_SMP crash_smp_send_stop(); #endif + machine_kexec_mask_interrupts(); cpumask_set_cpu(crashing_cpu, &cpus_in_crash); pr_info("Starting crashdump kernel...\n"); @@ -296,6 +275,7 @@ void machine_kexec(struct kimage *image) /* We do not want to be bothered. */ local_irq_disable(); + machine_kexec_mask_interrupts(); pr_notice("EFI boot flag: 0x%lx\n", efi_boot); pr_notice("Command line addr: 0x%lx\n", cmdline_ptr); diff --git a/arch/loongarch/kernel/machine_kexec_file.c b/arch/loongarch/kernel/machine_kexec_file.c index dda236b51a881f..fb57026f5f25e5 100644 --- a/arch/loongarch/kernel/machine_kexec_file.c +++ b/arch/loongarch/kernel/machine_kexec_file.c @@ -143,7 +143,7 @@ int load_other_segments(struct kimage *image, unsigned long initrd_load_addr = 0; unsigned long orig_segments = image->nr_segments; char *modified_cmdline = NULL; - struct kexec_buf kbuf; + struct kexec_buf kbuf = {}; kbuf.image = image; /* Don't allocate anything below the kernel */ diff --git a/arch/loongarch/kernel/mem.c b/arch/loongarch/kernel/mem.c index aed901c57fb439..8ab1ffedc52c51 100644 --- a/arch/loongarch/kernel/mem.c +++ b/arch/loongarch/kernel/mem.c @@ -13,7 +13,7 @@ void __init memblock_init(void) { u32 mem_type; - u64 mem_start, mem_end, mem_size; + u64 mem_start, mem_size; efi_memory_desc_t *md; /* Parse memory information */ @@ -21,7 +21,6 @@ void __init memblock_init(void) mem_type = md->type; mem_start = md->phys_addr; mem_size = md->num_pages << EFI_PAGE_SHIFT; - mem_end = mem_start + mem_size; switch (mem_type) { case EFI_LOADER_CODE: @@ -31,8 +30,6 @@ void __init memblock_init(void) case EFI_PERSISTENT_MEMORY: case EFI_CONVENTIONAL_MEMORY: memblock_add(mem_start, mem_size); - if (max_low_pfn < (mem_end >> PAGE_SHIFT)) - max_low_pfn = mem_end >> PAGE_SHIFT; break; case EFI_PAL_CODE: case EFI_UNUSABLE_MEMORY: @@ -49,6 +46,8 @@ void __init memblock_init(void) } } + max_pfn = PFN_DOWN(memblock_end_of_DRAM()); + max_low_pfn = min(PFN_DOWN(HIGHMEM_START), max_pfn); memblock_set_current_limit(PFN_PHYS(max_low_pfn)); /* Reserve the first 2MB */ diff --git a/arch/loongarch/kernel/numa.c b/arch/loongarch/kernel/numa.c index d6e73e8f9c0b66..8b89898e20df10 100644 --- a/arch/loongarch/kernel/numa.c +++ b/arch/loongarch/kernel/numa.c @@ -158,35 +158,9 @@ static void __init node_mem_init(unsigned int node) #ifdef CONFIG_ACPI_NUMA -/* - * add_numamem_region - * - * Add a uasable memory region described by BIOS. The - * routine gets each intersection between BIOS's region - * and node's region, and adds them into node's memblock - * pool. - * - */ -static void __init add_numamem_region(u64 start, u64 end, u32 type) -{ - u32 node = pa_to_nid(start); - u64 size = end - start; - static unsigned long num_physpages; - - if (start >= end) { - pr_debug("Invalid region: %016llx-%016llx\n", start, end); - return; - } - - num_physpages += (size >> PAGE_SHIFT); - pr_info("Node%d: mem_type:%d, mem_start:0x%llx, mem_size:0x%llx Bytes\n", - node, type, start, size); - pr_info(" start_pfn:0x%llx, end_pfn:0x%llx, num_physpages:0x%lx\n", - start >> PAGE_SHIFT, end >> PAGE_SHIFT, num_physpages); - memblock_set_node(start, size, &memblock.memory, node); -} +static unsigned long num_physpages; -static void __init init_node_memblock(void) +static void __init info_node_memblock(void) { u32 mem_type; u64 mem_end, mem_start, mem_size; @@ -206,12 +180,20 @@ static void __init init_node_memblock(void) case EFI_BOOT_SERVICES_DATA: case EFI_PERSISTENT_MEMORY: case EFI_CONVENTIONAL_MEMORY: - add_numamem_region(mem_start, mem_end, mem_type); + num_physpages += (mem_size >> PAGE_SHIFT); + pr_info("Node%d: mem_type:%d, mem_start:0x%llx, mem_size:0x%llx Bytes\n", + (u32)pa_to_nid(mem_start), mem_type, mem_start, mem_size); + pr_info(" start_pfn:0x%llx, end_pfn:0x%llx, num_physpages:0x%lx\n", + mem_start >> PAGE_SHIFT, mem_end >> PAGE_SHIFT, num_physpages); break; case EFI_PAL_CODE: case EFI_UNUSABLE_MEMORY: case EFI_ACPI_RECLAIM_MEMORY: - add_numamem_region(mem_start, mem_end, mem_type); + num_physpages += (mem_size >> PAGE_SHIFT); + pr_info("Node%d: mem_type:%d, mem_start:0x%llx, mem_size:0x%llx Bytes\n", + (u32)pa_to_nid(mem_start), mem_type, mem_start, mem_size); + pr_info(" start_pfn:0x%llx, end_pfn:0x%llx, num_physpages:0x%lx\n", + mem_start >> PAGE_SHIFT, mem_end >> PAGE_SHIFT, num_physpages); fallthrough; case EFI_RESERVED_TYPE: case EFI_RUNTIME_SERVICES_CODE: @@ -249,22 +231,16 @@ int __init init_numa_memory(void) for (i = 0; i < NR_CPUS; i++) set_cpuid_to_node(i, NUMA_NO_NODE); - numa_reset_distance(); - nodes_clear(numa_nodes_parsed); - nodes_clear(node_possible_map); - nodes_clear(node_online_map); - WARN_ON(memblock_clear_hotplug(0, PHYS_ADDR_MAX)); - /* Parse SRAT and SLIT if provided by firmware. */ - ret = acpi_disabled ? fake_numa_init() : acpi_numa_init(); + if (!acpi_disabled) + ret = numa_memblks_init(acpi_numa_init, false); + else + ret = numa_memblks_init(fake_numa_init, false); + if (ret < 0) return ret; - node_possible_map = numa_nodes_parsed; - if (WARN_ON(nodes_empty(node_possible_map))) - return -EINVAL; - - init_node_memblock(); + info_node_memblock(); if (!memblock_validate_numa_coverage(SZ_1M)) return -EINVAL; @@ -272,7 +248,8 @@ int __init init_numa_memory(void) node_mem_init(node); node_set_online(node); } - max_low_pfn = PHYS_PFN(memblock_end_of_DRAM()); + max_pfn = PFN_DOWN(memblock_end_of_DRAM()); + max_low_pfn = min(PFN_DOWN(HIGHMEM_START), max_pfn); setup_nr_node_ids(); loongson_sysconf.nr_nodes = nr_node_ids; @@ -283,26 +260,6 @@ int __init init_numa_memory(void) #endif -void __init paging_init(void) -{ - unsigned int node; - unsigned long zones_size[MAX_NR_ZONES] = {0, }; - - for_each_online_node(node) { - unsigned long start_pfn, end_pfn; - - get_pfn_range_for_nid(node, &start_pfn, &end_pfn); - - if (end_pfn > max_low_pfn) - max_low_pfn = end_pfn; - } -#ifdef CONFIG_ZONE_DMA32 - zones_size[ZONE_DMA32] = MAX_DMA32_PFN; -#endif - zones_size[ZONE_NORMAL] = max_low_pfn; - free_area_init(zones_size); -} - int pcibus_to_node(struct pci_bus *bus) { return dev_to_node(&bus->dev); diff --git a/arch/loongarch/kernel/perf_event.c b/arch/loongarch/kernel/perf_event.c index 8ad09870348893..9d257c8519c902 100644 --- a/arch/loongarch/kernel/perf_event.c +++ b/arch/loongarch/kernel/perf_event.c @@ -845,13 +845,14 @@ static const struct loongarch_perf_event *loongarch_pmu_map_raw_event(u64 config static int __init init_hw_perf_events(void) { - int counters; + int bits, counters; if (!cpu_has_pmp) return -ENODEV; pr_info("Performance counters: "); - counters = ((read_cpucfg(LOONGARCH_CPUCFG6) & CPUCFG6_PMNUM) >> 4) + 1; + bits = ((read_cpucfg(LOONGARCH_CPUCFG6) & CPUCFG6_PMBITS) >> CPUCFG6_PMBITS_SHIFT) + 1; + counters = ((read_cpucfg(LOONGARCH_CPUCFG6) & CPUCFG6_PMNUM) >> CPUCFG6_PMNUM_SHIFT) + 1; loongarch_pmu.num_counters = counters; loongarch_pmu.max_period = (1ULL << 63) - 1; @@ -867,7 +868,7 @@ static int __init init_hw_perf_events(void) on_each_cpu(reset_counters, NULL, 1); pr_cont("%s PMU enabled, %d %d-bit counters available to each CPU.\n", - loongarch_pmu.name, counters, 64); + loongarch_pmu.name, counters, bits); perf_pmu_register(&pmu, "cpu", PERF_TYPE_RAW); diff --git a/arch/loongarch/kernel/proc.c b/arch/loongarch/kernel/proc.c index cea30768ae92a6..63d2b7e7e844b0 100644 --- a/arch/loongarch/kernel/proc.c +++ b/arch/loongarch/kernel/proc.c @@ -17,6 +17,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) { unsigned long n = (unsigned long) v - 1; unsigned int isa = cpu_data[n].isa_level; + unsigned int prid = cpu_data[n].processor_id; unsigned int version = cpu_data[n].processor_id & 0xff; unsigned int fp_version = cpu_data[n].fpu_vers; @@ -37,6 +38,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) seq_printf(m, "global_id\t\t: %d\n", cpu_data[n].global_id); seq_printf(m, "CPU Family\t\t: %s\n", __cpu_family[n]); seq_printf(m, "Model Name\t\t: %s\n", __cpu_full_name[n]); + seq_printf(m, "PRID\t\t\t: %s (%08x)\n", id_to_core_name(prid), prid); seq_printf(m, "CPU Revision\t\t: 0x%02x\n", version); seq_printf(m, "FPU Revision\t\t: 0x%02x\n", fp_version); seq_printf(m, "CPU MHz\t\t\t: %llu.%02llu\n", diff --git a/arch/loongarch/kernel/setup.c b/arch/loongarch/kernel/setup.c index 69c17d162fff3c..25a87378e48e43 100644 --- a/arch/loongarch/kernel/setup.c +++ b/arch/loongarch/kernel/setup.c @@ -294,8 +294,6 @@ static void __init fdt_setup(void) early_init_dt_scan(fdt_pointer, __pa(fdt_pointer)); early_init_fdt_reserve_self(); - - max_low_pfn = PFN_PHYS(memblock_end_of_DRAM()); #endif } @@ -390,7 +388,8 @@ static void __init check_kernel_sections_mem(void) static void __init arch_mem_init(char **cmdline_p) { /* Recalculate max_low_pfn for "mem=xxx" */ - max_pfn = max_low_pfn = PHYS_PFN(memblock_end_of_DRAM()); + max_pfn = PFN_DOWN(memblock_end_of_DRAM()); + max_low_pfn = min(PFN_DOWN(HIGHMEM_START), max_pfn); if (usermem) pr_info("User-defined physical RAM map overwrite\n"); diff --git a/arch/loongarch/kernel/traps.c b/arch/loongarch/kernel/traps.c index 3d9be6ca7ec557..da5926fead4af9 100644 --- a/arch/loongarch/kernel/traps.c +++ b/arch/loongarch/kernel/traps.c @@ -1131,8 +1131,8 @@ static void configure_exception_vector(void) tlbrentry = (unsigned long)exception_handlers + 80*VECSIZE; csr_write64(eentry, LOONGARCH_CSR_EENTRY); - csr_write64(eentry, LOONGARCH_CSR_MERRENTRY); - csr_write64(tlbrentry, LOONGARCH_CSR_TLBRENTRY); + csr_write64(__pa(eentry), LOONGARCH_CSR_MERRENTRY); + csr_write64(__pa(tlbrentry), LOONGARCH_CSR_TLBRENTRY); } void per_cpu_trap_init(int cpu) diff --git a/arch/loongarch/kvm/intc/eiointc.c b/arch/loongarch/kvm/intc/eiointc.c index c3233369538184..a1cc116b4daceb 100644 --- a/arch/loongarch/kvm/intc/eiointc.c +++ b/arch/loongarch/kvm/intc/eiointc.c @@ -439,7 +439,7 @@ static int kvm_eiointc_ctrl_access(struct kvm_device *dev, spin_lock_irqsave(&s->lock, flags); switch (type) { case KVM_DEV_LOONGARCH_EXTIOI_CTRL_INIT_NUM_CPU: - if (val >= EIOINTC_ROUTE_MAX_VCPUS) + if (val > EIOINTC_ROUTE_MAX_VCPUS) ret = -EINVAL; else s->num_cpu = val; diff --git a/arch/loongarch/kvm/mmu.c b/arch/loongarch/kvm/mmu.c index 7c8143e79c1279..a7fa458e33605e 100644 --- a/arch/loongarch/kvm/mmu.c +++ b/arch/loongarch/kvm/mmu.c @@ -857,7 +857,7 @@ static int kvm_map_page(struct kvm_vcpu *vcpu, unsigned long gpa, bool write) if (writeable) { prot_bits = kvm_pte_mkwriteable(prot_bits); - if (write) + if (write || !kvm_slot_dirty_track_enabled(memslot)) prot_bits = kvm_pte_mkdirty(prot_bits); } diff --git a/arch/loongarch/kvm/timer.c b/arch/loongarch/kvm/timer.c index 32dc213374beac..29c2aaba63c33b 100644 --- a/arch/loongarch/kvm/timer.c +++ b/arch/loongarch/kvm/timer.c @@ -4,6 +4,7 @@ */ #include +#include #include #include @@ -95,6 +96,7 @@ void kvm_restore_timer(struct kvm_vcpu *vcpu) * and set CSR TVAL with -1 */ write_gcsr_timertick(0); + __delay(2); /* Wait cycles until timer interrupt injected */ /* * Writing CSR_TINTCLR_TI to LOONGARCH_CSR_TINTCLR will clear diff --git a/arch/loongarch/kvm/vcpu.c b/arch/loongarch/kvm/vcpu.c index 30e3b089a59665..1245a6b358966f 100644 --- a/arch/loongarch/kvm/vcpu.c +++ b/arch/loongarch/kvm/vcpu.c @@ -132,6 +132,9 @@ static void kvm_lose_pmu(struct kvm_vcpu *vcpu) * Clear KVM_LARCH_PMU if the guest is not using PMU CSRs when * exiting the guest, so that the next time trap into the guest. * We don't need to deal with PMU CSRs contexts. + * + * Otherwise set the request bit KVM_REQ_PMU to restore guest PMU + * before entering guest VM */ val = kvm_read_sw_gcsr(csr, LOONGARCH_CSR_PERFCTRL0); val |= kvm_read_sw_gcsr(csr, LOONGARCH_CSR_PERFCTRL1); @@ -139,16 +142,12 @@ static void kvm_lose_pmu(struct kvm_vcpu *vcpu) val |= kvm_read_sw_gcsr(csr, LOONGARCH_CSR_PERFCTRL3); if (!(val & KVM_PMU_EVENT_ENABLED)) vcpu->arch.aux_inuse &= ~KVM_LARCH_PMU; + else + kvm_make_request(KVM_REQ_PMU, vcpu); kvm_restore_host_pmu(vcpu); } -static void kvm_restore_pmu(struct kvm_vcpu *vcpu) -{ - if ((vcpu->arch.aux_inuse & KVM_LARCH_PMU)) - kvm_make_request(KVM_REQ_PMU, vcpu); -} - static void kvm_check_pmu(struct kvm_vcpu *vcpu) { if (kvm_check_request(KVM_REQ_PMU, vcpu)) { @@ -299,7 +298,10 @@ static int kvm_pre_enter_guest(struct kvm_vcpu *vcpu) vcpu->arch.aux_inuse &= ~KVM_LARCH_SWCSR_LATEST; if (kvm_request_pending(vcpu) || xfer_to_guest_mode_work_pending()) { - kvm_lose_pmu(vcpu); + if (vcpu->arch.aux_inuse & KVM_LARCH_PMU) { + kvm_lose_pmu(vcpu); + kvm_make_request(KVM_REQ_PMU, vcpu); + } /* make sure the vcpu mode has been written */ smp_store_mb(vcpu->mode, OUTSIDE_GUEST_MODE); local_irq_enable(); @@ -1604,9 +1606,6 @@ static int _kvm_vcpu_load(struct kvm_vcpu *vcpu, int cpu) kvm_restore_timer(vcpu); kvm_make_request(KVM_REQ_STEAL_UPDATE, vcpu); - /* Restore hardware PMU CSRs */ - kvm_restore_pmu(vcpu); - /* Don't bother restoring registers multiple times unless necessary */ if (vcpu->arch.aux_inuse & KVM_LARCH_HWCSR_USABLE) return 0; diff --git a/arch/loongarch/mm/init.c b/arch/loongarch/mm/init.c index c3e4586a797578..6bfd4b8dad1b65 100644 --- a/arch/loongarch/mm/init.c +++ b/arch/loongarch/mm/init.c @@ -60,7 +60,6 @@ int __ref page_is_ram(unsigned long pfn) return memblock_is_memory(addr) && !memblock_is_reserved(addr); } -#ifndef CONFIG_NUMA void __init paging_init(void) { unsigned long max_zone_pfns[MAX_NR_ZONES]; @@ -72,7 +71,6 @@ void __init paging_init(void) free_area_init(max_zone_pfns); } -#endif /* !CONFIG_NUMA */ void __ref free_initmem(void) { diff --git a/arch/loongarch/mm/ioremap.c b/arch/loongarch/mm/ioremap.c index df949a3d0f34a7..27c336959fe8ac 100644 --- a/arch/loongarch/mm/ioremap.c +++ b/arch/loongarch/mm/ioremap.c @@ -6,7 +6,7 @@ #include #include -void __init __iomem *early_ioremap(u64 phys_addr, unsigned long size) +void __init __iomem *early_ioremap(phys_addr_t phys_addr, unsigned long size) { return ((void __iomem *)TO_CACHE(phys_addr)); } diff --git a/arch/loongarch/net/bpf_jit.c b/arch/loongarch/net/bpf_jit.c index cbe53d0b7fb063..f97dc993640174 100644 --- a/arch/loongarch/net/bpf_jit.c +++ b/arch/loongarch/net/bpf_jit.c @@ -1624,6 +1624,9 @@ static int __arch_prepare_bpf_trampoline(struct jit_ctx *ctx, struct bpf_tramp_i /* Direct jump skips 5 NOP instructions */ else if (is_bpf_text_address((unsigned long)orig_call)) orig_call += LOONGARCH_BPF_FENTRY_NBYTES; + /* Module tracing not supported - cause kernel lockups */ + else if (is_module_text_address((unsigned long)orig_call)) + return -ENOTSUPP; if (flags & BPF_TRAMP_F_CALL_ORIG) { move_addr(ctx, LOONGARCH_GPR_A0, (const u64)im); diff --git a/arch/loongarch/pci/pci.c b/arch/loongarch/pci/pci.c index 5bc9627a6cf9cb..d9fc5d520b3778 100644 --- a/arch/loongarch/pci/pci.c +++ b/arch/loongarch/pci/pci.c @@ -50,11 +50,11 @@ static int __init pcibios_init(void) */ lsize = cpu_last_level_cache_line_size(); - BUG_ON(!lsize); + if (lsize) { + pci_dfl_cache_line_size = lsize >> 2; - pci_dfl_cache_line_size = lsize >> 2; - - pr_debug("PCI: pci_cache_line_size set to %d bytes\n", lsize); + pr_debug("PCI: pci_cache_line_size set to %d bytes\n", lsize); + } return 0; } diff --git a/arch/mips/boot/dts/econet/en751221.dtsi b/arch/mips/boot/dts/econet/en751221.dtsi index 66197e73d4f04b..2abeef5b744a88 100644 --- a/arch/mips/boot/dts/econet/en751221.dtsi +++ b/arch/mips/boot/dts/econet/en751221.dtsi @@ -18,7 +18,7 @@ cpu@0 { device_type = "cpu"; - compatible = "mips,mips24KEc"; + compatible = "mips,mips34Kc"; reg = <0>; }; }; diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c index 29191fa1801e2a..a3101f2268c6c8 100644 --- a/arch/mips/kernel/process.c +++ b/arch/mips/kernel/process.c @@ -692,7 +692,7 @@ unsigned long mips_stack_top(void) /* Space for the VDSO, data page & GIC user page */ if (current->thread.abi) { top -= PAGE_ALIGN(current->thread.abi->vdso->size); - top -= PAGE_SIZE; + top -= VDSO_NR_PAGES * PAGE_SIZE; top -= mips_gic_present() ? PAGE_SIZE : 0; /* Space to randomize the VDSO base */ diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c index 347126dc010dd5..3facf7cc6c7d3f 100644 --- a/arch/mips/mm/tlb-r4k.c +++ b/arch/mips/mm/tlb-r4k.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -508,54 +509,78 @@ static int __init set_ntlb(char *str) __setup("ntlb=", set_ntlb); -/* Initialise all TLB entries with unique values */ + +/* Comparison function for EntryHi VPN fields. */ +static int r4k_vpn_cmp(const void *a, const void *b) +{ + long v = *(unsigned long *)a - *(unsigned long *)b; + int s = sizeof(long) > sizeof(int) ? sizeof(long) * 8 - 1: 0; + return s ? (v != 0) | v >> s : v; +} + +/* + * Initialise all TLB entries with unique values that do not clash with + * what we have been handed over and what we'll be using ourselves. + */ static void r4k_tlb_uniquify(void) { - int entry = num_wired_entries(); + unsigned long tlb_vpns[1 << MIPS_CONF1_TLBS_SIZE]; + int tlbsize = current_cpu_data.tlbsize; + int start = num_wired_entries(); + unsigned long vpn_mask; + int cnt, ent, idx, i; + + vpn_mask = GENMASK(cpu_vmbits - 1, 13); + vpn_mask |= IS_ENABLED(CONFIG_64BIT) ? 3ULL << 62 : 1 << 31; htw_stop(); + + for (i = start, cnt = 0; i < tlbsize; i++, cnt++) { + unsigned long vpn; + + write_c0_index(i); + mtc0_tlbr_hazard(); + tlb_read(); + tlb_read_hazard(); + vpn = read_c0_entryhi(); + vpn &= vpn_mask & PAGE_MASK; + tlb_vpns[cnt] = vpn; + + /* Prevent any large pages from overlapping regular ones. */ + write_c0_pagemask(read_c0_pagemask() & PM_DEFAULT_MASK); + mtc0_tlbw_hazard(); + tlb_write_indexed(); + tlbw_use_hazard(); + } + + sort(tlb_vpns, cnt, sizeof(tlb_vpns[0]), r4k_vpn_cmp, NULL); + + write_c0_pagemask(PM_DEFAULT_MASK); write_c0_entrylo0(0); write_c0_entrylo1(0); - while (entry < current_cpu_data.tlbsize) { - unsigned long asid_mask = cpu_asid_mask(¤t_cpu_data); - unsigned long asid = 0; - int idx; + idx = 0; + ent = tlbsize; + for (i = start; i < tlbsize; i++) + while (1) { + unsigned long entryhi, vpn; - /* Skip wired MMID to make ginvt_mmid work */ - if (cpu_has_mmid) - asid = MMID_KERNEL_WIRED + 1; + entryhi = UNIQUE_ENTRYHI(ent); + vpn = entryhi & vpn_mask & PAGE_MASK; - /* Check for match before using UNIQUE_ENTRYHI */ - do { - if (cpu_has_mmid) { - write_c0_memorymapid(asid); - write_c0_entryhi(UNIQUE_ENTRYHI(entry)); + if (idx >= cnt || vpn < tlb_vpns[idx]) { + write_c0_entryhi(entryhi); + write_c0_index(i); + mtc0_tlbw_hazard(); + tlb_write_indexed(); + ent++; + break; + } else if (vpn == tlb_vpns[idx]) { + ent++; } else { - write_c0_entryhi(UNIQUE_ENTRYHI(entry) | asid); + idx++; } - mtc0_tlbw_hazard(); - tlb_probe(); - tlb_probe_hazard(); - idx = read_c0_index(); - /* No match or match is on current entry */ - if (idx < 0 || idx == entry) - break; - /* - * If we hit a match, we need to try again with - * a different ASID. - */ - asid++; - } while (asid < asid_mask); - - if (idx >= 0 && idx != entry) - panic("Unable to uniquify TLB entry %d", idx); - - write_c0_index(entry); - mtc0_tlbw_hazard(); - tlb_write_indexed(); - entry++; - } + } tlbw_use_hazard(); htw_start(); @@ -602,6 +627,7 @@ static void r4k_tlb_configure(void) /* From this point on the ARC firmware is dead. */ r4k_tlb_uniquify(); + local_flush_tlb_all(); /* Did I tell you that ARC SUCKS? */ } diff --git a/arch/mips/mti-malta/malta-init.c b/arch/mips/mti-malta/malta-init.c index 000d6d50520a89..82b0fd8576a241 100644 --- a/arch/mips/mti-malta/malta-init.c +++ b/arch/mips/mti-malta/malta-init.c @@ -241,16 +241,22 @@ void __init prom_init(void) #endif /* - * Setup the Malta max (2GB) memory for PCI DMA in host bridge - * in transparent addressing mode. + * Set up memory mapping in host bridge for PCI DMA masters, + * in transparent addressing mode. For EVA use the Malta + * maximum of 2 GiB memory in the alias space at 0x80000000 + * as per PHYS_OFFSET. Otherwise use 256 MiB of memory in + * the regular space, avoiding mapping the PCI MMIO window + * for DMA as it seems to confuse the system controller's + * logic, causing PCI MMIO to stop working. */ - mask = PHYS_OFFSET | PCI_BASE_ADDRESS_MEM_PREFETCH; - MSC_WRITE(MSC01_PCI_BAR0, mask); - MSC_WRITE(MSC01_PCI_HEAD4, mask); + mask = PHYS_OFFSET ? PHYS_OFFSET : 0xf0000000; + MSC_WRITE(MSC01_PCI_BAR0, + mask | PCI_BASE_ADDRESS_MEM_PREFETCH); + MSC_WRITE(MSC01_PCI_HEAD4, + PHYS_OFFSET | PCI_BASE_ADDRESS_MEM_PREFETCH); - mask &= MSC01_PCI_BAR0_SIZE_MSK; MSC_WRITE(MSC01_PCI_P2SCMSKL, mask); - MSC_WRITE(MSC01_PCI_P2SCMAPL, mask); + MSC_WRITE(MSC01_PCI_P2SCMAPL, PHYS_OFFSET); /* Don't handle target retries indefinitely. */ if ((data & MSC01_PCI_CFG_MAXRTRY_MSK) == diff --git a/arch/parisc/kernel/unwind.c b/arch/parisc/kernel/unwind.c index f7e0fee5ee55a3..7ac88ff13d3c98 100644 --- a/arch/parisc/kernel/unwind.c +++ b/arch/parisc/kernel/unwind.c @@ -35,6 +35,8 @@ #define KERNEL_START (KERNEL_BINARY_TEXT_START) +#define ALIGNMENT_OK(ptr, type) (((ptr) & (sizeof(type) - 1)) == 0) + extern struct unwind_table_entry __start___unwind[]; extern struct unwind_table_entry __stop___unwind[]; @@ -257,12 +259,15 @@ static int unwind_special(struct unwind_frame_info *info, unsigned long pc, int if (pc_is_kernel_fn(pc, _switch_to) || pc == (unsigned long)&_switch_to_ret) { info->prev_sp = info->sp - CALLEE_SAVE_FRAME_SIZE; - info->prev_ip = *(unsigned long *)(info->prev_sp - RP_OFFSET); + if (ALIGNMENT_OK(info->prev_sp, long)) + info->prev_ip = *(unsigned long *)(info->prev_sp - RP_OFFSET); + else + info->prev_ip = info->prev_sp = 0; return 1; } #ifdef CONFIG_IRQSTACKS - if (pc == (unsigned long)&_call_on_stack) { + if (pc == (unsigned long)&_call_on_stack && ALIGNMENT_OK(info->sp, long)) { info->prev_sp = *(unsigned long *)(info->sp - FRAME_SIZE - REG_SZ); info->prev_ip = *(unsigned long *)(info->sp - FRAME_SIZE - RP_OFFSET); return 1; @@ -370,8 +375,10 @@ static void unwind_frame_regs(struct unwind_frame_info *info) info->prev_sp = info->sp - frame_size; if (e->Millicode) info->rp = info->r31; - else if (rpoffset) + else if (rpoffset && ALIGNMENT_OK(info->prev_sp, long)) info->rp = *(unsigned long *)(info->prev_sp - rpoffset); + else + info->rp = 0; info->prev_ip = info->rp; info->rp = 0; } diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index e24f4d88885ae5..9537a61ebae02d 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -137,6 +137,7 @@ config PPC select ARCH_HAS_DMA_OPS if PPC64 select ARCH_HAS_FORTIFY_SOURCE select ARCH_HAS_GCOV_PROFILE_ALL + select ARCH_HAS_GIGANTIC_PAGE if ARCH_SUPPORTS_HUGETLBFS select ARCH_HAS_KCOV select ARCH_HAS_KERNEL_FPU_SUPPORT if PPC64 && PPC_FPU select ARCH_HAS_MEMBARRIER_CALLBACKS diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype index 7b527d18aa5eeb..4c321a8ea89654 100644 --- a/arch/powerpc/platforms/Kconfig.cputype +++ b/arch/powerpc/platforms/Kconfig.cputype @@ -423,7 +423,6 @@ config PPC_64S_HASH_MMU config PPC_RADIX_MMU bool "Radix MMU Support" depends on PPC_BOOK3S_64 - select ARCH_HAS_GIGANTIC_PAGE default y help Enable support for the Power ISA 3.0 Radix style MMU. Currently this diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index 22cda9c452d2a9..fadec20b87a8e3 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -367,7 +367,7 @@ config RISCV_NONSTANDARD_CACHE_OPS systems to handle cache management. config AS_HAS_INSN - def_bool $(as-instr,.insn r 51$(comma) 0$(comma) 0$(comma) t0$(comma) t0$(comma) zero) + def_bool $(as-instr,.insn 0x100000f) config AS_HAS_OPTION_ARCH # https://github.com/llvm/llvm-project/commit/9e8ed3403c191ab9c4903e8eeb8f732ff8a43cb4 diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile index ecf2fcce2d923b..4c6de57f65ef0e 100644 --- a/arch/riscv/Makefile +++ b/arch/riscv/Makefile @@ -134,21 +134,6 @@ endif CHECKFLAGS += -D__riscv -D__riscv_xlen=$(BITS) # Default target when executing plain make -boot := arch/riscv/boot -ifeq ($(CONFIG_XIP_KERNEL),y) -KBUILD_IMAGE := $(boot)/xipImage -else -ifeq ($(CONFIG_RISCV_M_MODE)$(CONFIG_SOC_CANAAN_K210),yy) -KBUILD_IMAGE := $(boot)/loader.bin -else -ifeq ($(CONFIG_EFI_ZBOOT),) -KBUILD_IMAGE := $(boot)/Image.gz -else -KBUILD_IMAGE := $(boot)/vmlinuz.efi -endif -endif -endif - boot := arch/riscv/boot boot-image-y := Image boot-image-$(CONFIG_KERNEL_BZIP2) := Image.bz2 @@ -159,7 +144,7 @@ boot-image-$(CONFIG_KERNEL_LZO) := Image.lzo boot-image-$(CONFIG_KERNEL_ZSTD) := Image.zst boot-image-$(CONFIG_KERNEL_XZ) := Image.xz ifdef CONFIG_RISCV_M_MODE -boot-image-$(CONFIG_ARCH_CANAAN) := loader.bin +boot-image-$(CONFIG_SOC_CANAAN_K210) := loader.bin endif boot-image-$(CONFIG_EFI_ZBOOT) := vmlinuz.efi boot-image-$(CONFIG_XIP_KERNEL) := xipImage diff --git a/arch/riscv/include/asm/asm.h b/arch/riscv/include/asm/asm.h index ac28066bb564c1..e9e8ba83e632f9 100644 --- a/arch/riscv/include/asm/asm.h +++ b/arch/riscv/include/asm/asm.h @@ -12,6 +12,12 @@ #define __ASM_STR(x) #x #endif +#ifdef CONFIG_AS_HAS_INSN +#define ASM_INSN_I(__x) ".insn " __x +#else +#define ASM_INSN_I(__x) ".4byte " __x +#endif + #if __riscv_xlen == 64 #define __REG_SEL(a, b) __ASM_STR(a) #elif __riscv_xlen == 32 diff --git a/arch/riscv/include/asm/insn-def.h b/arch/riscv/include/asm/insn-def.h index c9cfcea52cbbcf..d29da6ccd3dd84 100644 --- a/arch/riscv/include/asm/insn-def.h +++ b/arch/riscv/include/asm/insn-def.h @@ -256,10 +256,10 @@ INSN_S(OPCODE_OP_IMM, FUNC3(6), __RS2(3), \ SIMM12((offset) & 0xfe0), RS1(base)) -#define RISCV_PAUSE ".4byte 0x100000f" -#define ZAWRS_WRS_NTO ".4byte 0x00d00073" -#define ZAWRS_WRS_STO ".4byte 0x01d00073" -#define RISCV_NOP4 ".4byte 0x00000013" +#define RISCV_PAUSE ASM_INSN_I("0x100000f") +#define ZAWRS_WRS_NTO ASM_INSN_I("0x00d00073") +#define ZAWRS_WRS_STO ASM_INSN_I("0x01d00073") +#define RISCV_NOP4 ASM_INSN_I("0x00000013") #define RISCV_INSN_NOP4 _AC(0x00000013, U) diff --git a/arch/riscv/include/asm/vendor_extensions/mips.h b/arch/riscv/include/asm/vendor_extensions/mips.h index ea8ca747d691df..ffeb12dc17a378 100644 --- a/arch/riscv/include/asm/vendor_extensions/mips.h +++ b/arch/riscv/include/asm/vendor_extensions/mips.h @@ -30,8 +30,8 @@ extern struct riscv_isa_vendor_ext_data_list riscv_isa_vendor_ext_list_mips; * allowing any subsequent instructions to fetch. */ -#define MIPS_PAUSE ".4byte 0x00501013\n\t" -#define MIPS_EHB ".4byte 0x00301013\n\t" -#define MIPS_IHB ".4byte 0x00101013\n\t" +#define MIPS_PAUSE ASM_INSN_I("0x00501013\n\t") +#define MIPS_EHB ASM_INSN_I("0x00301013\n\t") +#define MIPS_IHB ASM_INSN_I("0x00101013\n\t") #endif // _ASM_RISCV_VENDOR_EXTENSIONS_MIPS_H diff --git a/arch/riscv/include/asm/vendorid_list.h b/arch/riscv/include/asm/vendorid_list.h index 3b09874d7a6dfb..7f5030ee1fcf83 100644 --- a/arch/riscv/include/asm/vendorid_list.h +++ b/arch/riscv/include/asm/vendorid_list.h @@ -7,8 +7,8 @@ #define ANDES_VENDOR_ID 0x31e #define MICROCHIP_VENDOR_ID 0x029 +#define MIPS_VENDOR_ID 0x127 #define SIFIVE_VENDOR_ID 0x489 #define THEAD_VENDOR_ID 0x5b7 -#define MIPS_VENDOR_ID 0x722 #endif diff --git a/arch/riscv/kernel/kgdb.c b/arch/riscv/kernel/kgdb.c index 9f3db3503dabd6..15fec5d1e6decf 100644 --- a/arch/riscv/kernel/kgdb.c +++ b/arch/riscv/kernel/kgdb.c @@ -265,10 +265,10 @@ void kgdb_arch_handle_qxfer_pkt(char *remcom_in_buffer, { if (!strncmp(remcom_in_buffer, gdb_xfer_read_target, sizeof(gdb_xfer_read_target))) - strcpy(remcom_out_buffer, riscv_gdb_stub_target_desc); + strscpy(remcom_out_buffer, riscv_gdb_stub_target_desc, BUFMAX); else if (!strncmp(remcom_in_buffer, gdb_xfer_read_cpuxml, sizeof(gdb_xfer_read_cpuxml))) - strcpy(remcom_out_buffer, riscv_gdb_stub_cpuxml); + strscpy(remcom_out_buffer, riscv_gdb_stub_cpuxml, BUFMAX); } static inline void kgdb_arch_update_addr(struct pt_regs *regs, diff --git a/arch/riscv/kernel/module-sections.c b/arch/riscv/kernel/module-sections.c index 75551ac6504c5d..1675cbad8619d1 100644 --- a/arch/riscv/kernel/module-sections.c +++ b/arch/riscv/kernel/module-sections.c @@ -119,6 +119,7 @@ int module_frob_arch_sections(Elf_Ehdr *ehdr, Elf_Shdr *sechdrs, unsigned int num_plts = 0; unsigned int num_gots = 0; Elf_Rela *scratch = NULL; + Elf_Rela *new_scratch; size_t scratch_size = 0; int i; @@ -168,9 +169,12 @@ int module_frob_arch_sections(Elf_Ehdr *ehdr, Elf_Shdr *sechdrs, scratch_size_needed = (num_scratch_relas + num_relas) * sizeof(*scratch); if (scratch_size_needed > scratch_size) { scratch_size = scratch_size_needed; - scratch = kvrealloc(scratch, scratch_size, GFP_KERNEL); - if (!scratch) + new_scratch = kvrealloc(scratch, scratch_size, GFP_KERNEL); + if (!new_scratch) { + kvfree(scratch); return -ENOMEM; + } + scratch = new_scratch; } for (size_t j = 0; j < num_relas; j++) diff --git a/arch/riscv/kernel/sbi.c b/arch/riscv/kernel/sbi.c index 5e8cde05526435..c443337056ab7d 100644 --- a/arch/riscv/kernel/sbi.c +++ b/arch/riscv/kernel/sbi.c @@ -648,9 +648,9 @@ int sbi_debug_console_read(char *bytes, unsigned int num_bytes) void __init sbi_init(void) { + bool srst_power_off = false; int ret; - sbi_set_power_off(); ret = sbi_get_spec_version(); if (ret > 0) sbi_spec_version = ret; @@ -683,6 +683,7 @@ void __init sbi_init(void) sbi_probe_extension(SBI_EXT_SRST)) { pr_info("SBI SRST extension detected\n"); register_platform_power_off(sbi_srst_power_off); + srst_power_off = true; sbi_srst_reboot_nb.notifier_call = sbi_srst_reboot; sbi_srst_reboot_nb.priority = 192; register_restart_handler(&sbi_srst_reboot_nb); @@ -702,4 +703,7 @@ void __init sbi_init(void) __sbi_send_ipi = __sbi_send_ipi_v01; __sbi_rfence = __sbi_rfence_v01; } + + if (!srst_power_off) + sbi_set_power_off(); } diff --git a/arch/riscv/kernel/stacktrace.c b/arch/riscv/kernel/stacktrace.c index 3fe9e6edef8f1c..b41b6255751cb1 100644 --- a/arch/riscv/kernel/stacktrace.c +++ b/arch/riscv/kernel/stacktrace.c @@ -16,6 +16,22 @@ #ifdef CONFIG_FRAME_POINTER +/* + * This disables KASAN checking when reading a value from another task's stack, + * since the other task could be running on another CPU and could have poisoned + * the stack in the meantime. + */ +#define READ_ONCE_TASK_STACK(task, x) \ +({ \ + unsigned long val; \ + unsigned long addr = x; \ + if ((task) == current) \ + val = READ_ONCE(addr); \ + else \ + val = READ_ONCE_NOCHECK(addr); \ + val; \ +}) + extern asmlinkage void handle_exception(void); extern unsigned long ret_from_exception_end; @@ -69,8 +85,9 @@ void notrace walk_stackframe(struct task_struct *task, struct pt_regs *regs, fp = frame->ra; pc = regs->ra; } else { - fp = frame->fp; - pc = ftrace_graph_ret_addr(current, &graph_idx, frame->ra, + fp = READ_ONCE_TASK_STACK(task, frame->fp); + pc = READ_ONCE_TASK_STACK(task, frame->ra); + pc = ftrace_graph_ret_addr(current, &graph_idx, pc, &frame->ra); if (pc >= (unsigned long)handle_exception && pc < (unsigned long)&ret_from_exception_end) { diff --git a/arch/riscv/kernel/tests/Kconfig.debug b/arch/riscv/kernel/tests/Kconfig.debug index 5db4df44279e9d..40f8dafffa0ab6 100644 --- a/arch/riscv/kernel/tests/Kconfig.debug +++ b/arch/riscv/kernel/tests/Kconfig.debug @@ -31,7 +31,7 @@ config RISCV_MODULE_LINKING_KUNIT If unsure, say N. config RISCV_KPROBES_KUNIT - bool "KUnit test for riscv kprobes" if !KUNIT_ALL_TESTS + tristate "KUnit test for riscv kprobes" if !KUNIT_ALL_TESTS depends on KUNIT depends on KPROBES default KUNIT_ALL_TESTS diff --git a/arch/riscv/kernel/tests/kprobes/Makefile b/arch/riscv/kernel/tests/kprobes/Makefile index 4cb6c66a98e8ea..df7256f62313e2 100644 --- a/arch/riscv/kernel/tests/kprobes/Makefile +++ b/arch/riscv/kernel/tests/kprobes/Makefile @@ -1 +1,3 @@ -obj-y += test-kprobes.o test-kprobes-asm.o +obj-$(CONFIG_RISCV_KPROBES_KUNIT) += kprobes_riscv_kunit.o + +kprobes_riscv_kunit-objs := test-kprobes.o test-kprobes-asm.o diff --git a/arch/riscv/kernel/tests/kprobes/test-kprobes.c b/arch/riscv/kernel/tests/kprobes/test-kprobes.c index 6f6cdfbf5a9588..664535ca0a98a0 100644 --- a/arch/riscv/kernel/tests/kprobes/test-kprobes.c +++ b/arch/riscv/kernel/tests/kprobes/test-kprobes.c @@ -49,8 +49,11 @@ static struct kunit_case kprobes_testcases[] = { }; static struct kunit_suite kprobes_test_suite = { - .name = "kprobes_test_riscv", + .name = "kprobes_riscv", .test_cases = kprobes_testcases, }; kunit_test_suites(&kprobes_test_suite); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("KUnit test for riscv kprobes"); diff --git a/arch/riscv/kvm/aia_imsic.c b/arch/riscv/kvm/aia_imsic.c index fda0346f0ea1fb..11422cb95a6440 100644 --- a/arch/riscv/kvm/aia_imsic.c +++ b/arch/riscv/kvm/aia_imsic.c @@ -689,8 +689,20 @@ bool kvm_riscv_vcpu_aia_imsic_has_interrupt(struct kvm_vcpu *vcpu) */ read_lock_irqsave(&imsic->vsfile_lock, flags); - if (imsic->vsfile_cpu > -1) - ret = !!(csr_read(CSR_HGEIP) & BIT(imsic->vsfile_hgei)); + if (imsic->vsfile_cpu > -1) { + /* + * This function is typically called from kvm_vcpu_block() via + * kvm_arch_vcpu_runnable() upon WFI trap. The kvm_vcpu_block() + * can be preempted and the blocking VCPU might resume on a + * different CPU. This means it is possible that current CPU + * does not match the imsic->vsfile_cpu hence this function + * must check imsic->vsfile_cpu before accessing HGEIP CSR. + */ + if (imsic->vsfile_cpu != vcpu->cpu) + ret = true; + else + ret = !!(csr_read(CSR_HGEIP) & BIT(imsic->vsfile_hgei)); + } read_unlock_irqrestore(&imsic->vsfile_lock, flags); return ret; diff --git a/arch/riscv/kvm/mmu.c b/arch/riscv/kvm/mmu.c index 525fb5a330c0d2..58f5f3536ffdff 100644 --- a/arch/riscv/kvm/mmu.c +++ b/arch/riscv/kvm/mmu.c @@ -171,7 +171,6 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm, enum kvm_mr_change change) { hva_t hva, reg_end, size; - gpa_t base_gpa; bool writable; int ret = 0; @@ -190,15 +189,13 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm, hva = new->userspace_addr; size = new->npages << PAGE_SHIFT; reg_end = hva + size; - base_gpa = new->base_gfn << PAGE_SHIFT; writable = !(new->flags & KVM_MEM_READONLY); mmap_read_lock(current->mm); /* * A memory region could potentially cover multiple VMAs, and - * any holes between them, so iterate over all of them to find - * out if we can map any of them right now. + * any holes between them, so iterate over all of them. * * +--------------------------------------------+ * +---------------+----------------+ +----------------+ @@ -209,7 +206,7 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm, */ do { struct vm_area_struct *vma; - hva_t vm_start, vm_end; + hva_t vm_end; vma = find_vma_intersection(current->mm, hva, reg_end); if (!vma) @@ -225,36 +222,18 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm, } /* Take the intersection of this VMA with the memory region */ - vm_start = max(hva, vma->vm_start); vm_end = min(reg_end, vma->vm_end); if (vma->vm_flags & VM_PFNMAP) { - gpa_t gpa = base_gpa + (vm_start - hva); - phys_addr_t pa; - - pa = (phys_addr_t)vma->vm_pgoff << PAGE_SHIFT; - pa += vm_start - vma->vm_start; - /* IO region dirty page logging not allowed */ if (new->flags & KVM_MEM_LOG_DIRTY_PAGES) { ret = -EINVAL; goto out; } - - ret = kvm_riscv_mmu_ioremap(kvm, gpa, pa, vm_end - vm_start, - writable, false); - if (ret) - break; } hva = vm_end; } while (hva < reg_end); - if (change == KVM_MR_FLAGS_ONLY) - goto out; - - if (ret) - kvm_riscv_mmu_iounmap(kvm, base_gpa, size); - out: mmap_read_unlock(current->mm); return ret; diff --git a/arch/riscv/kvm/vcpu.c b/arch/riscv/kvm/vcpu.c index bccb919ca6153f..5ce35aba60696c 100644 --- a/arch/riscv/kvm/vcpu.c +++ b/arch/riscv/kvm/vcpu.c @@ -212,7 +212,7 @@ int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu) int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu) { - return (kvm_riscv_vcpu_has_interrupts(vcpu, -1UL) && + return (kvm_riscv_vcpu_has_interrupts(vcpu, -1ULL) && !kvm_riscv_vcpu_stopped(vcpu) && !vcpu->arch.pause); } diff --git a/arch/riscv/mm/ptdump.c b/arch/riscv/mm/ptdump.c index 3b51690cc87605..34299c2b231f15 100644 --- a/arch/riscv/mm/ptdump.c +++ b/arch/riscv/mm/ptdump.c @@ -21,7 +21,7 @@ #define pt_dump_seq_puts(m, fmt) \ ({ \ if (m) \ - seq_printf(m, fmt); \ + seq_puts(m, fmt); \ }) /* diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h index b7100c6a405449..6663f1619abbae 100644 --- a/arch/s390/include/asm/pgtable.h +++ b/arch/s390/include/asm/pgtable.h @@ -1154,17 +1154,15 @@ static inline pte_t pte_mkhuge(pte_t pte) #define IPTE_NODAT 0x400 #define IPTE_GUEST_ASCE 0x800 -static __always_inline void __ptep_rdp(unsigned long addr, pte_t *ptep, - unsigned long opt, unsigned long asce, - int local) +static __always_inline void __ptep_rdp(unsigned long addr, pte_t *ptep, int local) { unsigned long pto; pto = __pa(ptep) & ~(PTRS_PER_PTE * sizeof(pte_t) - 1); - asm volatile(".insn rrf,0xb98b0000,%[r1],%[r2],%[asce],%[m4]" + asm volatile(".insn rrf,0xb98b0000,%[r1],%[r2],%%r0,%[m4]" : "+m" (*ptep) - : [r1] "a" (pto), [r2] "a" ((addr & PAGE_MASK) | opt), - [asce] "a" (asce), [m4] "i" (local)); + : [r1] "a" (pto), [r2] "a" (addr & PAGE_MASK), + [m4] "i" (local)); } static __always_inline void __ptep_ipte(unsigned long address, pte_t *ptep, @@ -1348,7 +1346,7 @@ static inline void flush_tlb_fix_spurious_fault(struct vm_area_struct *vma, * A local RDP can be used to do the flush. */ if (cpu_has_rdp() && !(pte_val(*ptep) & _PAGE_PROTECT)) - __ptep_rdp(address, ptep, 0, 0, 1); + __ptep_rdp(address, ptep, 1); } #define flush_tlb_fix_spurious_fault flush_tlb_fix_spurious_fault diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c index 0fde20bbc50bf3..05974304d6222e 100644 --- a/arch/s390/mm/pgtable.c +++ b/arch/s390/mm/pgtable.c @@ -274,9 +274,9 @@ void ptep_reset_dat_prot(struct mm_struct *mm, unsigned long addr, pte_t *ptep, preempt_disable(); atomic_inc(&mm->context.flush_count); if (cpumask_equal(mm_cpumask(mm), cpumask_of(smp_processor_id()))) - __ptep_rdp(addr, ptep, 0, 0, 1); + __ptep_rdp(addr, ptep, 1); else - __ptep_rdp(addr, ptep, 0, 0, 0); + __ptep_rdp(addr, ptep, 0); /* * PTE is not invalidated by RDP, only _PAGE_PROTECT is cleared. That * means it is still valid and active, and must not be changed according diff --git a/arch/x86/Makefile b/arch/x86/Makefile index 8fbff3106c56eb..1a27efcf3c205a 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile @@ -98,7 +98,7 @@ ifeq ($(CONFIG_X86_KERNEL_IBT),y) # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104816 # KBUILD_CFLAGS += $(call cc-option,-fcf-protection=branch -fno-jump-tables) -KBUILD_RUSTFLAGS += -Zcf-protection=branch -Zno-jump-tables +KBUILD_RUSTFLAGS += -Zcf-protection=branch $(if $(call rustc-min-version,109300),-Cjump-tables=n,-Zno-jump-tables) else KBUILD_CFLAGS += $(call cc-option,-fcf-protection=none) endif diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c index 745caa6c15a32d..fa6c47b509897a 100644 --- a/arch/x86/events/core.c +++ b/arch/x86/events/core.c @@ -2789,13 +2789,13 @@ perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, struct pt_regs *re return; } - if (perf_callchain_store(entry, regs->ip)) - return; - - if (perf_hw_regs(regs)) + if (perf_hw_regs(regs)) { + if (perf_callchain_store(entry, regs->ip)) + return; unwind_start(&state, current, regs, NULL); - else + } else { unwind_start(&state, current, NULL, (void *)regs->sp); + } for (; !unwind_done(&state); unwind_next_frame(&state)) { addr = unwind_get_return_address(&state); diff --git a/arch/x86/events/intel/uncore.c b/arch/x86/events/intel/uncore.c index d6c945cc5d07c2..e228e564b15ea6 100644 --- a/arch/x86/events/intel/uncore.c +++ b/arch/x86/events/intel/uncore.c @@ -1325,8 +1325,6 @@ static void uncore_pci_sub_driver_init(void) continue; pmu = &type->pmus[UNCORE_PCI_DEV_IDX(ids->driver_data)]; - if (!pmu) - continue; if (uncore_pci_get_dev_die_info(pci_sub_dev, &die)) continue; diff --git a/arch/x86/include/asm/amd/node.h b/arch/x86/include/asm/amd/node.h index 23fe617898a8f3..a672b8765fa8a2 100644 --- a/arch/x86/include/asm/amd/node.h +++ b/arch/x86/include/asm/amd/node.h @@ -23,7 +23,6 @@ #define AMD_NODE0_PCI_SLOT 0x18 struct pci_dev *amd_node_get_func(u16 node, u8 func); -struct pci_dev *amd_node_get_root(u16 node); static inline u16 amd_num_nodes(void) { diff --git a/arch/x86/include/asm/ftrace.h b/arch/x86/include/asm/ftrace.h index 93156ac4ffe098..b08c95872eed9f 100644 --- a/arch/x86/include/asm/ftrace.h +++ b/arch/x86/include/asm/ftrace.h @@ -56,6 +56,11 @@ arch_ftrace_get_regs(struct ftrace_regs *fregs) return &arch_ftrace_regs(fregs)->regs; } +#define arch_ftrace_partial_regs(regs) do { \ + regs->flags &= ~X86_EFLAGS_FIXED; \ + regs->cs = __KERNEL_CS; \ +} while (0) + #define arch_ftrace_fill_perf_regs(fregs, _regs) do { \ (_regs)->ip = arch_ftrace_regs(fregs)->regs.ip; \ (_regs)->sp = arch_ftrace_regs(fregs)->regs.sp; \ diff --git a/arch/x86/include/asm/runtime-const.h b/arch/x86/include/asm/runtime-const.h index 8d983cfd06ea62..e5a13dc8816e2b 100644 --- a/arch/x86/include/asm/runtime-const.h +++ b/arch/x86/include/asm/runtime-const.h @@ -2,6 +2,10 @@ #ifndef _ASM_RUNTIME_CONST_H #define _ASM_RUNTIME_CONST_H +#ifdef MODULE + #error "Cannot use runtime-const infrastructure from modules" +#endif + #ifdef __ASSEMBLY__ .macro RUNTIME_CONST_PTR sym reg diff --git a/arch/x86/include/asm/uaccess_64.h b/arch/x86/include/asm/uaccess_64.h index c8a5ae35c8714a..641f45c22f9dab 100644 --- a/arch/x86/include/asm/uaccess_64.h +++ b/arch/x86/include/asm/uaccess_64.h @@ -12,12 +12,12 @@ #include #include #include -#include -/* - * Virtual variable: there's no actual backing store for this, - * it can purely be used as 'runtime_const_ptr(USER_PTR_MAX)' - */ +#ifdef MODULE + #define runtime_const_ptr(sym) (sym) +#else + #include +#endif extern unsigned long USER_PTR_MAX; #ifdef CONFIG_ADDRESS_MASKING diff --git a/arch/x86/include/uapi/asm/vmx.h b/arch/x86/include/uapi/asm/vmx.h index 9792e329343e87..1baa86dfe02932 100644 --- a/arch/x86/include/uapi/asm/vmx.h +++ b/arch/x86/include/uapi/asm/vmx.h @@ -93,6 +93,7 @@ #define EXIT_REASON_TPAUSE 68 #define EXIT_REASON_BUS_LOCK 74 #define EXIT_REASON_NOTIFY 75 +#define EXIT_REASON_SEAMCALL 76 #define EXIT_REASON_TDCALL 77 #define EXIT_REASON_MSR_READ_IMM 84 #define EXIT_REASON_MSR_WRITE_IMM 85 diff --git a/arch/x86/kernel/acpi/cppc.c b/arch/x86/kernel/acpi/cppc.c index 7047124490f64b..d7c8ef1e354d30 100644 --- a/arch/x86/kernel/acpi/cppc.c +++ b/arch/x86/kernel/acpi/cppc.c @@ -196,7 +196,7 @@ int amd_detect_prefcore(bool *detected) break; } - for_each_present_cpu(cpu) { + for_each_online_cpu(cpu) { u32 tmp; int ret; diff --git a/arch/x86/kernel/amd_node.c b/arch/x86/kernel/amd_node.c index a40176b62eb59a..3d0a4768d603cc 100644 --- a/arch/x86/kernel/amd_node.c +++ b/arch/x86/kernel/amd_node.c @@ -34,62 +34,6 @@ struct pci_dev *amd_node_get_func(u16 node, u8 func) return pci_get_domain_bus_and_slot(0, 0, PCI_DEVFN(AMD_NODE0_PCI_SLOT + node, func)); } -#define DF_BLK_INST_CNT 0x040 -#define DF_CFG_ADDR_CNTL_LEGACY 0x084 -#define DF_CFG_ADDR_CNTL_DF4 0xC04 - -#define DF_MAJOR_REVISION GENMASK(27, 24) - -static u16 get_cfg_addr_cntl_offset(struct pci_dev *df_f0) -{ - u32 reg; - - /* - * Revision fields added for DF4 and later. - * - * Major revision of '0' is found pre-DF4. Field is Read-as-Zero. - */ - if (pci_read_config_dword(df_f0, DF_BLK_INST_CNT, ®)) - return 0; - - if (reg & DF_MAJOR_REVISION) - return DF_CFG_ADDR_CNTL_DF4; - - return DF_CFG_ADDR_CNTL_LEGACY; -} - -struct pci_dev *amd_node_get_root(u16 node) -{ - struct pci_dev *root; - u16 cntl_off; - u8 bus; - - if (!cpu_feature_enabled(X86_FEATURE_ZEN)) - return NULL; - - /* - * D18F0xXXX [Config Address Control] (DF::CfgAddressCntl) - * Bits [7:0] (SecBusNum) holds the bus number of the root device for - * this Data Fabric instance. The segment, device, and function will be 0. - */ - struct pci_dev *df_f0 __free(pci_dev_put) = amd_node_get_func(node, 0); - if (!df_f0) - return NULL; - - cntl_off = get_cfg_addr_cntl_offset(df_f0); - if (!cntl_off) - return NULL; - - if (pci_read_config_byte(df_f0, cntl_off, &bus)) - return NULL; - - /* Grab the pointer for the actual root device instance. */ - root = pci_get_domain_bus_and_slot(0, bus, 0); - - pci_dbg(root, "is root for AMD node %u\n", node); - return root; -} - static struct pci_dev **amd_roots; /* Protect the PCI config register pairs used for SMN. */ @@ -274,51 +218,21 @@ DEFINE_SHOW_STORE_ATTRIBUTE(smn_node); DEFINE_SHOW_STORE_ATTRIBUTE(smn_address); DEFINE_SHOW_STORE_ATTRIBUTE(smn_value); -static int amd_cache_roots(void) -{ - u16 node, num_nodes = amd_num_nodes(); - - amd_roots = kcalloc(num_nodes, sizeof(*amd_roots), GFP_KERNEL); - if (!amd_roots) - return -ENOMEM; - - for (node = 0; node < num_nodes; node++) - amd_roots[node] = amd_node_get_root(node); - - return 0; -} - -static int reserve_root_config_spaces(void) +static struct pci_dev *get_next_root(struct pci_dev *root) { - struct pci_dev *root = NULL; - struct pci_bus *bus = NULL; - - while ((bus = pci_find_next_bus(bus))) { - /* Root device is Device 0 Function 0 on each Primary Bus. */ - root = pci_get_slot(bus, 0); - if (!root) + while ((root = pci_get_class(PCI_CLASS_BRIDGE_HOST << 8, root))) { + /* Root device is Device 0 Function 0. */ + if (root->devfn) continue; if (root->vendor != PCI_VENDOR_ID_AMD && root->vendor != PCI_VENDOR_ID_HYGON) continue; - pci_dbg(root, "Reserving PCI config space\n"); - - /* - * There are a few SMN index/data pairs and other registers - * that shouldn't be accessed by user space. - * So reserve the entire PCI config space for simplicity rather - * than covering specific registers piecemeal. - */ - if (!pci_request_config_region_exclusive(root, 0, PCI_CFG_SPACE_SIZE, NULL)) { - pci_err(root, "Failed to reserve config space\n"); - return -EEXIST; - } + break; } - smn_exclusive = true; - return 0; + return root; } static bool enable_dfs; @@ -332,7 +246,8 @@ __setup("amd_smn_debugfs_enable", amd_smn_enable_dfs); static int __init amd_smn_init(void) { - int err; + u16 count, num_roots, roots_per_node, node, num_nodes; + struct pci_dev *root; if (!cpu_feature_enabled(X86_FEATURE_ZEN)) return 0; @@ -342,13 +257,48 @@ static int __init amd_smn_init(void) if (amd_roots) return 0; - err = amd_cache_roots(); - if (err) - return err; + num_roots = 0; + root = NULL; + while ((root = get_next_root(root))) { + pci_dbg(root, "Reserving PCI config space\n"); - err = reserve_root_config_spaces(); - if (err) - return err; + /* + * There are a few SMN index/data pairs and other registers + * that shouldn't be accessed by user space. So reserve the + * entire PCI config space for simplicity rather than covering + * specific registers piecemeal. + */ + if (!pci_request_config_region_exclusive(root, 0, PCI_CFG_SPACE_SIZE, NULL)) { + pci_err(root, "Failed to reserve config space\n"); + return -EEXIST; + } + + num_roots++; + } + + pr_debug("Found %d AMD root devices\n", num_roots); + + if (!num_roots) + return -ENODEV; + + num_nodes = amd_num_nodes(); + amd_roots = kcalloc(num_nodes, sizeof(*amd_roots), GFP_KERNEL); + if (!amd_roots) + return -ENOMEM; + + roots_per_node = num_roots / num_nodes; + + count = 0; + node = 0; + root = NULL; + while (node < num_nodes && (root = get_next_root(root))) { + /* Use one root for each node and skip the rest. */ + if (count++ % roots_per_node) + continue; + + pci_dbg(root, "is root for AMD node %u\n", node); + amd_roots[node++] = root; + } if (enable_dfs) { debugfs_dir = debugfs_create_dir("amd_smn", arch_debugfs_dir); @@ -358,6 +308,8 @@ static int __init amd_smn_init(void) debugfs_create_file("value", 0600, debugfs_dir, NULL, &smn_value_fops); } + smn_exclusive = true; + return 0; } diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c index 8e36964a772128..5d46709c58d0b8 100644 --- a/arch/x86/kernel/cpu/amd.c +++ b/arch/x86/kernel/cpu/amd.c @@ -1037,7 +1037,15 @@ static void init_amd_zen4(struct cpuinfo_x86 *c) static const struct x86_cpu_id zen5_rdseed_microcode[] = { ZEN_MODEL_STEP_UCODE(0x1a, 0x02, 0x1, 0x0b00215a), + ZEN_MODEL_STEP_UCODE(0x1a, 0x08, 0x1, 0x0b008121), ZEN_MODEL_STEP_UCODE(0x1a, 0x11, 0x0, 0x0b101054), + ZEN_MODEL_STEP_UCODE(0x1a, 0x24, 0x0, 0x0b204037), + ZEN_MODEL_STEP_UCODE(0x1a, 0x44, 0x0, 0x0b404035), + ZEN_MODEL_STEP_UCODE(0x1a, 0x44, 0x1, 0x0b404108), + ZEN_MODEL_STEP_UCODE(0x1a, 0x60, 0x0, 0x0b600037), + ZEN_MODEL_STEP_UCODE(0x1a, 0x68, 0x0, 0x0b608038), + ZEN_MODEL_STEP_UCODE(0x1a, 0x70, 0x0, 0x0b700037), + {}, }; static void init_amd_zen5(struct cpuinfo_x86 *c) diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index c7d3512914ca97..02d97834a1d4d0 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -78,6 +78,10 @@ DEFINE_PER_CPU_READ_MOSTLY(struct cpuinfo_x86, cpu_info); EXPORT_PER_CPU_SYMBOL(cpu_info); +/* Used for modules: built-in code uses runtime constants */ +unsigned long USER_PTR_MAX; +EXPORT_SYMBOL(USER_PTR_MAX); + u32 elf_hwcap2 __read_mostly; /* Number of siblings per CPU package */ @@ -2579,7 +2583,7 @@ void __init arch_cpu_finalize_init(void) alternative_instructions(); if (IS_ENABLED(CONFIG_X86_64)) { - unsigned long USER_PTR_MAX = TASK_SIZE_MAX; + USER_PTR_MAX = TASK_SIZE_MAX; /* * Enable this when LAM is gated on LASS support diff --git a/arch/x86/kernel/cpu/microcode/amd.c b/arch/x86/kernel/cpu/microcode/amd.c index b7c797dc94f452..a881bf4c201143 100644 --- a/arch/x86/kernel/cpu/microcode/amd.c +++ b/arch/x86/kernel/cpu/microcode/amd.c @@ -220,10 +220,13 @@ static bool need_sha_check(u32 cur_rev) case 0xaa001: return cur_rev <= 0xaa00116; break; case 0xaa002: return cur_rev <= 0xaa00218; break; case 0xb0021: return cur_rev <= 0xb002146; break; + case 0xb0081: return cur_rev <= 0xb008111; break; case 0xb1010: return cur_rev <= 0xb101046; break; case 0xb2040: return cur_rev <= 0xb204031; break; case 0xb4040: return cur_rev <= 0xb404031; break; + case 0xb4041: return cur_rev <= 0xb404101; break; case 0xb6000: return cur_rev <= 0xb600031; break; + case 0xb6080: return cur_rev <= 0xb608031; break; case 0xb7000: return cur_rev <= 0xb700031; break; default: break; } diff --git a/arch/x86/kernel/ftrace_64.S b/arch/x86/kernel/ftrace_64.S index 367da36381678f..823dbdd0eb4109 100644 --- a/arch/x86/kernel/ftrace_64.S +++ b/arch/x86/kernel/ftrace_64.S @@ -354,12 +354,17 @@ SYM_CODE_START(return_to_handler) UNWIND_HINT_UNDEFINED ANNOTATE_NOENDBR + /* Restore return_to_handler value that got eaten by previous ret instruction. */ + subq $8, %rsp + UNWIND_HINT_FUNC + /* Save ftrace_regs for function exit context */ subq $(FRAME_SIZE), %rsp movq %rax, RAX(%rsp) movq %rdx, RDX(%rsp) movq %rbp, RBP(%rsp) + movq %rsp, RSP(%rsp) movq %rsp, %rdi call ftrace_return_to_handler @@ -368,7 +373,8 @@ SYM_CODE_START(return_to_handler) movq RDX(%rsp), %rdx movq RAX(%rsp), %rax - addq $(FRAME_SIZE), %rsp + addq $(FRAME_SIZE) + 8, %rsp + /* * Jump back to the old return address. This cannot be JMP_NOSPEC rdi * since IBT would demand that contain ENDBR, which simply isn't so for diff --git a/arch/x86/kvm/svm/avic.c b/arch/x86/kvm/svm/avic.c index f286b5706d7c14..fef00546c88566 100644 --- a/arch/x86/kvm/svm/avic.c +++ b/arch/x86/kvm/svm/avic.c @@ -216,7 +216,7 @@ static void avic_deactivate_vmcb(struct vcpu_svm *svm) * This function is called from IOMMU driver to notify * SVM to schedule in a particular vCPU of a particular VM. */ -int avic_ga_log_notifier(u32 ga_tag) +static int avic_ga_log_notifier(u32 ga_tag) { unsigned long flags; struct kvm_svm *kvm_svm; @@ -788,7 +788,7 @@ int avic_init_vcpu(struct vcpu_svm *svm) struct kvm_vcpu *vcpu = &svm->vcpu; INIT_LIST_HEAD(&svm->ir_list); - spin_lock_init(&svm->ir_list_lock); + raw_spin_lock_init(&svm->ir_list_lock); if (!enable_apicv || !irqchip_in_kernel(vcpu->kvm)) return 0; @@ -816,9 +816,9 @@ static void svm_ir_list_del(struct kvm_kernel_irqfd *irqfd) if (!vcpu) return; - spin_lock_irqsave(&to_svm(vcpu)->ir_list_lock, flags); + raw_spin_lock_irqsave(&to_svm(vcpu)->ir_list_lock, flags); list_del(&irqfd->vcpu_list); - spin_unlock_irqrestore(&to_svm(vcpu)->ir_list_lock, flags); + raw_spin_unlock_irqrestore(&to_svm(vcpu)->ir_list_lock, flags); } int avic_pi_update_irte(struct kvm_kernel_irqfd *irqfd, struct kvm *kvm, @@ -855,7 +855,7 @@ int avic_pi_update_irte(struct kvm_kernel_irqfd *irqfd, struct kvm *kvm, * list of IRQs being posted to the vCPU, to ensure the IRTE * isn't programmed with stale pCPU/IsRunning information. */ - guard(spinlock_irqsave)(&svm->ir_list_lock); + guard(raw_spinlock_irqsave)(&svm->ir_list_lock); /* * Update the target pCPU for IOMMU doorbells if the vCPU is @@ -972,7 +972,7 @@ static void __avic_vcpu_load(struct kvm_vcpu *vcpu, int cpu, * up-to-date entry information, or that this task will wait until * svm_ir_list_add() completes to set the new target pCPU. */ - spin_lock_irqsave(&svm->ir_list_lock, flags); + raw_spin_lock_irqsave(&svm->ir_list_lock, flags); entry = svm->avic_physical_id_entry; WARN_ON_ONCE(entry & AVIC_PHYSICAL_ID_ENTRY_IS_RUNNING_MASK); @@ -997,7 +997,7 @@ static void __avic_vcpu_load(struct kvm_vcpu *vcpu, int cpu, avic_update_iommu_vcpu_affinity(vcpu, h_physical_id, action); - spin_unlock_irqrestore(&svm->ir_list_lock, flags); + raw_spin_unlock_irqrestore(&svm->ir_list_lock, flags); } void avic_vcpu_load(struct kvm_vcpu *vcpu, int cpu) @@ -1035,7 +1035,7 @@ static void __avic_vcpu_put(struct kvm_vcpu *vcpu, enum avic_vcpu_action action) * or that this task will wait until svm_ir_list_add() completes to * mark the vCPU as not running. */ - spin_lock_irqsave(&svm->ir_list_lock, flags); + raw_spin_lock_irqsave(&svm->ir_list_lock, flags); avic_update_iommu_vcpu_affinity(vcpu, -1, action); @@ -1059,7 +1059,7 @@ static void __avic_vcpu_put(struct kvm_vcpu *vcpu, enum avic_vcpu_action action) svm->avic_physical_id_entry = entry; - spin_unlock_irqrestore(&svm->ir_list_lock, flags); + raw_spin_unlock_irqrestore(&svm->ir_list_lock, flags); } void avic_vcpu_put(struct kvm_vcpu *vcpu) @@ -1243,3 +1243,9 @@ bool __init avic_hardware_setup(void) return true; } + +void avic_hardware_unsetup(void) +{ + if (avic) + amd_iommu_register_ga_log_notifier(NULL); +} diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c index a6443feab2520d..da6e80b3ac353c 100644 --- a/arch/x86/kvm/svm/nested.c +++ b/arch/x86/kvm/svm/nested.c @@ -677,11 +677,10 @@ static void nested_vmcb02_prepare_save(struct vcpu_svm *svm, struct vmcb *vmcb12 */ svm_copy_lbrs(vmcb02, vmcb12); vmcb02->save.dbgctl &= ~DEBUGCTL_RESERVED_BITS; - svm_update_lbrv(&svm->vcpu); - - } else if (unlikely(vmcb01->control.virt_ext & LBR_CTL_ENABLE_MASK)) { + } else { svm_copy_lbrs(vmcb02, vmcb01); } + svm_update_lbrv(&svm->vcpu); } static inline bool is_evtinj_soft(u32 evtinj) @@ -833,11 +832,7 @@ static void nested_vmcb02_prepare_control(struct vcpu_svm *svm, svm->soft_int_next_rip = vmcb12_rip; } - vmcb02->control.virt_ext = vmcb01->control.virt_ext & - LBR_CTL_ENABLE_MASK; - if (guest_cpu_cap_has(vcpu, X86_FEATURE_LBRV)) - vmcb02->control.virt_ext |= - (svm->nested.ctl.virt_ext & LBR_CTL_ENABLE_MASK); + /* LBR_CTL_ENABLE_MASK is controlled by svm_update_lbrv() */ if (!nested_vmcb_needs_vls_intercept(svm)) vmcb02->control.virt_ext |= VIRTUAL_VMLOAD_VMSAVE_ENABLE_MASK; @@ -1189,13 +1184,12 @@ int nested_svm_vmexit(struct vcpu_svm *svm) kvm_make_request(KVM_REQ_EVENT, &svm->vcpu); if (unlikely(guest_cpu_cap_has(vcpu, X86_FEATURE_LBRV) && - (svm->nested.ctl.virt_ext & LBR_CTL_ENABLE_MASK))) { + (svm->nested.ctl.virt_ext & LBR_CTL_ENABLE_MASK))) svm_copy_lbrs(vmcb12, vmcb02); - svm_update_lbrv(vcpu); - } else if (unlikely(vmcb01->control.virt_ext & LBR_CTL_ENABLE_MASK)) { + else svm_copy_lbrs(vmcb01, vmcb02); - svm_update_lbrv(vcpu); - } + + svm_update_lbrv(vcpu); if (vnmi) { if (vmcb02->control.int_ctl & V_NMI_BLOCKING_MASK) diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index 153c12dbf3eb15..9d29b2e7e855d6 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -705,7 +705,11 @@ void *svm_alloc_permissions_map(unsigned long size, gfp_t gfp_mask) static void svm_recalc_lbr_msr_intercepts(struct kvm_vcpu *vcpu) { - bool intercept = !(to_svm(vcpu)->vmcb->control.virt_ext & LBR_CTL_ENABLE_MASK); + struct vcpu_svm *svm = to_svm(vcpu); + bool intercept = !(svm->vmcb->control.virt_ext & LBR_CTL_ENABLE_MASK); + + if (intercept == svm->lbr_msrs_intercepted) + return; svm_set_intercept_for_msr(vcpu, MSR_IA32_LASTBRANCHFROMIP, MSR_TYPE_RW, intercept); svm_set_intercept_for_msr(vcpu, MSR_IA32_LASTBRANCHTOIP, MSR_TYPE_RW, intercept); @@ -714,6 +718,8 @@ static void svm_recalc_lbr_msr_intercepts(struct kvm_vcpu *vcpu) if (sev_es_guest(vcpu->kvm)) svm_set_intercept_for_msr(vcpu, MSR_IA32_DEBUGCTLMSR, MSR_TYPE_RW, intercept); + + svm->lbr_msrs_intercepted = intercept; } void svm_vcpu_free_msrpm(void *msrpm) @@ -806,60 +812,43 @@ void svm_copy_lbrs(struct vmcb *to_vmcb, struct vmcb *from_vmcb) vmcb_mark_dirty(to_vmcb, VMCB_LBR); } -void svm_enable_lbrv(struct kvm_vcpu *vcpu) +static void __svm_enable_lbrv(struct kvm_vcpu *vcpu) { - struct vcpu_svm *svm = to_svm(vcpu); - - svm->vmcb->control.virt_ext |= LBR_CTL_ENABLE_MASK; - svm_recalc_lbr_msr_intercepts(vcpu); - - /* Move the LBR msrs to the vmcb02 so that the guest can see them. */ - if (is_guest_mode(vcpu)) - svm_copy_lbrs(svm->vmcb, svm->vmcb01.ptr); + to_svm(vcpu)->vmcb->control.virt_ext |= LBR_CTL_ENABLE_MASK; } -static void svm_disable_lbrv(struct kvm_vcpu *vcpu) +void svm_enable_lbrv(struct kvm_vcpu *vcpu) { - struct vcpu_svm *svm = to_svm(vcpu); - - KVM_BUG_ON(sev_es_guest(vcpu->kvm), vcpu->kvm); - svm->vmcb->control.virt_ext &= ~LBR_CTL_ENABLE_MASK; + __svm_enable_lbrv(vcpu); svm_recalc_lbr_msr_intercepts(vcpu); - - /* - * Move the LBR msrs back to the vmcb01 to avoid copying them - * on nested guest entries. - */ - if (is_guest_mode(vcpu)) - svm_copy_lbrs(svm->vmcb01.ptr, svm->vmcb); } -static struct vmcb *svm_get_lbr_vmcb(struct vcpu_svm *svm) +static void __svm_disable_lbrv(struct kvm_vcpu *vcpu) { - /* - * If LBR virtualization is disabled, the LBR MSRs are always kept in - * vmcb01. If LBR virtualization is enabled and L1 is running VMs of - * its own, the MSRs are moved between vmcb01 and vmcb02 as needed. - */ - return svm->vmcb->control.virt_ext & LBR_CTL_ENABLE_MASK ? svm->vmcb : - svm->vmcb01.ptr; + KVM_BUG_ON(sev_es_guest(vcpu->kvm), vcpu->kvm); + to_svm(vcpu)->vmcb->control.virt_ext &= ~LBR_CTL_ENABLE_MASK; } void svm_update_lbrv(struct kvm_vcpu *vcpu) { struct vcpu_svm *svm = to_svm(vcpu); bool current_enable_lbrv = svm->vmcb->control.virt_ext & LBR_CTL_ENABLE_MASK; - bool enable_lbrv = (svm_get_lbr_vmcb(svm)->save.dbgctl & DEBUGCTLMSR_LBR) || + bool enable_lbrv = (svm->vmcb->save.dbgctl & DEBUGCTLMSR_LBR) || (is_guest_mode(vcpu) && guest_cpu_cap_has(vcpu, X86_FEATURE_LBRV) && (svm->nested.ctl.virt_ext & LBR_CTL_ENABLE_MASK)); - if (enable_lbrv == current_enable_lbrv) - return; + if (enable_lbrv && !current_enable_lbrv) + __svm_enable_lbrv(vcpu); + else if (!enable_lbrv && current_enable_lbrv) + __svm_disable_lbrv(vcpu); - if (enable_lbrv) - svm_enable_lbrv(vcpu); - else - svm_disable_lbrv(vcpu); + /* + * During nested transitions, it is possible that the current VMCB has + * LBR_CTL set, but the previous LBR_CTL had it cleared (or vice versa). + * In this case, even though LBR_CTL does not need an update, intercepts + * do, so always recalculate the intercepts here. + */ + svm_recalc_lbr_msr_intercepts(vcpu); } void disable_nmi_singlestep(struct vcpu_svm *svm) @@ -921,6 +910,8 @@ static void svm_hardware_unsetup(void) { int cpu; + avic_hardware_unsetup(); + sev_hardware_unsetup(); for_each_possible_cpu(cpu) @@ -1236,6 +1227,7 @@ static int svm_vcpu_create(struct kvm_vcpu *vcpu) } svm->x2avic_msrs_intercepted = true; + svm->lbr_msrs_intercepted = true; svm->vmcb01.ptr = page_address(vmcb01_page); svm->vmcb01.pa = __sme_set(page_to_pfn(vmcb01_page) << PAGE_SHIFT); @@ -2722,19 +2714,19 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) msr_info->data = svm->tsc_aux; break; case MSR_IA32_DEBUGCTLMSR: - msr_info->data = svm_get_lbr_vmcb(svm)->save.dbgctl; + msr_info->data = svm->vmcb->save.dbgctl; break; case MSR_IA32_LASTBRANCHFROMIP: - msr_info->data = svm_get_lbr_vmcb(svm)->save.br_from; + msr_info->data = svm->vmcb->save.br_from; break; case MSR_IA32_LASTBRANCHTOIP: - msr_info->data = svm_get_lbr_vmcb(svm)->save.br_to; + msr_info->data = svm->vmcb->save.br_to; break; case MSR_IA32_LASTINTFROMIP: - msr_info->data = svm_get_lbr_vmcb(svm)->save.last_excp_from; + msr_info->data = svm->vmcb->save.last_excp_from; break; case MSR_IA32_LASTINTTOIP: - msr_info->data = svm_get_lbr_vmcb(svm)->save.last_excp_to; + msr_info->data = svm->vmcb->save.last_excp_to; break; case MSR_VM_HSAVE_PA: msr_info->data = svm->nested.hsave_msr; @@ -3002,7 +2994,11 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr) if (data & DEBUGCTL_RESERVED_BITS) return 1; - svm_get_lbr_vmcb(svm)->save.dbgctl = data; + if (svm->vmcb->save.dbgctl == data) + break; + + svm->vmcb->save.dbgctl = data; + vmcb_mark_dirty(svm->vmcb, VMCB_LBR); svm_update_lbrv(vcpu); break; case MSR_VM_HSAVE_PA: @@ -5386,12 +5382,6 @@ static __init int svm_hardware_setup(void) svm_hv_hardware_setup(); - for_each_possible_cpu(cpu) { - r = svm_cpu_init(cpu); - if (r) - goto err; - } - enable_apicv = avic_hardware_setup(); if (!enable_apicv) { enable_ipiv = false; @@ -5435,6 +5425,13 @@ static __init int svm_hardware_setup(void) svm_set_cpu_caps(); kvm_caps.inapplicable_quirks &= ~KVM_X86_QUIRK_CD_NW_CLEARED; + + for_each_possible_cpu(cpu) { + r = svm_cpu_init(cpu); + if (r) + goto err; + } + return 0; err: diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h index e4b04f435b3d03..dd78e64023450b 100644 --- a/arch/x86/kvm/svm/svm.h +++ b/arch/x86/kvm/svm/svm.h @@ -329,13 +329,14 @@ struct vcpu_svm { * back into remapped mode). */ struct list_head ir_list; - spinlock_t ir_list_lock; + raw_spinlock_t ir_list_lock; struct vcpu_sev_es_state sev_es; bool guest_state_loaded; bool x2avic_msrs_intercepted; + bool lbr_msrs_intercepted; /* Guest GIF value, used when vGIF is not enabled */ bool guest_gif; @@ -805,7 +806,7 @@ extern struct kvm_x86_nested_ops svm_nested_ops; ) bool __init avic_hardware_setup(void); -int avic_ga_log_notifier(u32 ga_tag); +void avic_hardware_unsetup(void); void avic_vm_destroy(struct kvm *kvm); int avic_vm_init(struct kvm *kvm); void avic_init_vmcb(struct vcpu_svm *svm, struct vmcb *vmcb); diff --git a/arch/x86/kvm/vmx/common.h b/arch/x86/kvm/vmx/common.h index bc5ece76533ae2..412d0829d7a217 100644 --- a/arch/x86/kvm/vmx/common.h +++ b/arch/x86/kvm/vmx/common.h @@ -98,7 +98,7 @@ static inline int __vmx_handle_ept_violation(struct kvm_vcpu *vcpu, gpa_t gpa, error_code |= (exit_qualification & EPT_VIOLATION_PROT_MASK) ? PFERR_PRESENT_MASK : 0; - if (error_code & EPT_VIOLATION_GVA_IS_VALID) + if (exit_qualification & EPT_VIOLATION_GVA_IS_VALID) error_code |= (exit_qualification & EPT_VIOLATION_GVA_TRANSLATED) ? PFERR_GUEST_FINAL_MASK : PFERR_GUEST_PAGE_MASK; diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c index 76271962cb7083..bcea087b642fd0 100644 --- a/arch/x86/kvm/vmx/nested.c +++ b/arch/x86/kvm/vmx/nested.c @@ -6728,6 +6728,14 @@ static bool nested_vmx_l1_wants_exit(struct kvm_vcpu *vcpu, case EXIT_REASON_NOTIFY: /* Notify VM exit is not exposed to L1 */ return false; + case EXIT_REASON_SEAMCALL: + case EXIT_REASON_TDCALL: + /* + * SEAMCALL and TDCALL unconditionally VM-Exit, but aren't + * virtualized by KVM for L1 hypervisors, i.e. L1 should + * never want or expect such an exit. + */ + return false; default: return true; } diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index f87c216d976d7d..91b6f2f3edc2ab 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -6032,6 +6032,12 @@ static int handle_vmx_instruction(struct kvm_vcpu *vcpu) return 1; } +static int handle_tdx_instruction(struct kvm_vcpu *vcpu) +{ + kvm_queue_exception(vcpu, UD_VECTOR); + return 1; +} + #ifndef CONFIG_X86_SGX_KVM static int handle_encls(struct kvm_vcpu *vcpu) { @@ -6157,6 +6163,8 @@ static int (*kvm_vmx_exit_handlers[])(struct kvm_vcpu *vcpu) = { [EXIT_REASON_ENCLS] = handle_encls, [EXIT_REASON_BUS_LOCK] = handle_bus_lock_vmexit, [EXIT_REASON_NOTIFY] = handle_notify, + [EXIT_REASON_SEAMCALL] = handle_tdx_instruction, + [EXIT_REASON_TDCALL] = handle_tdx_instruction, [EXIT_REASON_MSR_READ_IMM] = handle_rdmsr_imm, [EXIT_REASON_MSR_WRITE_IMM] = handle_wrmsr_imm, }; diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index b4b5d2d0963467..c9c2aa6f4705e1 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -3874,15 +3874,9 @@ static void record_steal_time(struct kvm_vcpu *vcpu) /* * Returns true if the MSR in question is managed via XSTATE, i.e. is context - * switched with the rest of guest FPU state. Note! S_CET is _not_ context - * switched via XSTATE even though it _is_ saved/restored via XSAVES/XRSTORS. - * Because S_CET is loaded on VM-Enter and VM-Exit via dedicated VMCS fields, - * the value saved/restored via XSTATE is always the host's value. That detail - * is _extremely_ important, as the guest's S_CET must _never_ be resident in - * hardware while executing in the host. Loading guest values for U_CET and - * PL[0-3]_SSP while executing in the kernel is safe, as U_CET is specific to - * userspace, and PL[0-3]_SSP are only consumed when transitioning to lower - * privilege levels, i.e. are effectively only consumed by userspace as well. + * switched with the rest of guest FPU state. + * + * Note, S_CET is _not_ saved/restored via XSAVES/XRSTORS. */ static bool is_xstate_managed_msr(struct kvm_vcpu *vcpu, u32 msr) { @@ -3905,6 +3899,11 @@ static bool is_xstate_managed_msr(struct kvm_vcpu *vcpu, u32 msr) * MSR that is managed via XSTATE. Note, the caller is responsible for doing * the initial FPU load, this helper only ensures that guest state is resident * in hardware (the kernel can load its FPU state in IRQ context). + * + * Note, loading guest values for U_CET and PL[0-3]_SSP while executing in the + * kernel is safe, as U_CET is specific to userspace, and PL[0-3]_SSP are only + * consumed when transitioning to lower privilege levels, i.e. are effectively + * only consumed by userspace as well. */ static __always_inline void kvm_access_xstate_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info, @@ -11807,6 +11806,9 @@ static int complete_emulated_mmio(struct kvm_vcpu *vcpu) /* Swap (qemu) user FPU context for the guest FPU context. */ static void kvm_load_guest_fpu(struct kvm_vcpu *vcpu) { + if (KVM_BUG_ON(vcpu->arch.guest_fpu.fpstate->in_use, vcpu->kvm)) + return; + /* Exclude PKRU, it's restored separately immediately after VM-Exit. */ fpu_swap_kvm_fpstate(&vcpu->arch.guest_fpu, true); trace_kvm_fpu(1); @@ -11815,6 +11817,9 @@ static void kvm_load_guest_fpu(struct kvm_vcpu *vcpu) /* When vcpu_run ends, restore user space FPU context. */ static void kvm_put_guest_fpu(struct kvm_vcpu *vcpu) { + if (KVM_BUG_ON(!vcpu->arch.guest_fpu.fpstate->in_use, vcpu->kvm)) + return; + fpu_swap_kvm_fpstate(&vcpu->arch.guest_fpu, false); ++vcpu->stat.fpu_reload; trace_kvm_fpu(0); @@ -12137,9 +12142,6 @@ int kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu, int r; vcpu_load(vcpu); - if (kvm_mpx_supported()) - kvm_load_guest_fpu(vcpu); - kvm_vcpu_srcu_read_lock(vcpu); r = kvm_apic_accept_events(vcpu); @@ -12156,9 +12158,6 @@ int kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu, out: kvm_vcpu_srcu_read_unlock(vcpu); - - if (kvm_mpx_supported()) - kvm_put_guest_fpu(vcpu); vcpu_put(vcpu); return r; } @@ -12788,6 +12787,7 @@ static void kvm_xstate_reset(struct kvm_vcpu *vcpu, bool init_event) { struct fpstate *fpstate = vcpu->arch.guest_fpu.fpstate; u64 xfeatures_mask; + bool fpu_in_use; int i; /* @@ -12811,13 +12811,23 @@ static void kvm_xstate_reset(struct kvm_vcpu *vcpu, bool init_event) BUILD_BUG_ON(sizeof(xfeatures_mask) * BITS_PER_BYTE <= XFEATURE_MAX); /* - * All paths that lead to INIT are required to load the guest's FPU - * state (because most paths are buried in KVM_RUN). - */ - kvm_put_guest_fpu(vcpu); + * Unload guest FPU state (if necessary) before zeroing XSTATE fields + * as the kernel can only modify the state when its resident in memory, + * i.e. when it's not loaded into hardware. + * + * WARN if the vCPU's desire to run, i.e. whether or not its in KVM_RUN, + * doesn't match the loaded/in-use state of the FPU, as KVM_RUN is the + * only path that can trigger INIT emulation _and_ loads FPU state, and + * KVM_RUN should _always_ load FPU state. + */ + WARN_ON_ONCE(vcpu->wants_to_run != fpstate->in_use); + fpu_in_use = fpstate->in_use; + if (fpu_in_use) + kvm_put_guest_fpu(vcpu); for_each_set_bit(i, (unsigned long *)&xfeatures_mask, XFEATURE_MAX) fpstate_clear_xstate_component(fpstate, i); - kvm_load_guest_fpu(vcpu); + if (fpu_in_use) + kvm_load_guest_fpu(vcpu); } void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event) diff --git a/block/bdev.c b/block/bdev.c index 810707cca9703e..638f0cd458ae48 100644 --- a/block/bdev.c +++ b/block/bdev.c @@ -231,7 +231,7 @@ int sb_set_blocksize(struct super_block *sb, int size) EXPORT_SYMBOL(sb_set_blocksize); -int sb_min_blocksize(struct super_block *sb, int size) +int __must_check sb_min_blocksize(struct super_block *sb, int size) { int minsize = bdev_logical_block_size(sb->s_bdev); if (size < minsize) diff --git a/drivers/acpi/acpi_mrrm.c b/drivers/acpi/acpi_mrrm.c index a6dbf623e5571f..6d69554c940ed2 100644 --- a/drivers/acpi/acpi_mrrm.c +++ b/drivers/acpi/acpi_mrrm.c @@ -152,26 +152,49 @@ ATTRIBUTE_GROUPS(memory_range); static __init int add_boot_memory_ranges(void) { - struct kobject *pkobj, *kobj; + struct kobject *pkobj, *kobj, **kobjs; int ret = -EINVAL; - char *name; + char name[16]; + int i; pkobj = kobject_create_and_add("memory_ranges", acpi_kobj); + if (!pkobj) + return -ENOMEM; - for (int i = 0; i < mrrm_mem_entry_num; i++) { - name = kasprintf(GFP_KERNEL, "range%d", i); - if (!name) { - ret = -ENOMEM; - break; - } + kobjs = kcalloc(mrrm_mem_entry_num, sizeof(*kobjs), GFP_KERNEL); + if (!kobjs) { + kobject_put(pkobj); + return -ENOMEM; + } + for (i = 0; i < mrrm_mem_entry_num; i++) { + scnprintf(name, sizeof(name), "range%d", i); kobj = kobject_create_and_add(name, pkobj); + if (!kobj) { + ret = -ENOMEM; + goto cleanup; + } ret = sysfs_create_groups(kobj, memory_range_groups); - if (ret) - return ret; + if (ret) { + kobject_put(kobj); + goto cleanup; + } + kobjs[i] = kobj; } + kfree(kobjs); + return 0; + +cleanup: + for (int j = 0; j < i; j++) { + if (kobjs[j]) { + sysfs_remove_groups(kobjs[j], memory_range_groups); + kobject_put(kobjs[j]); + } + } + kfree(kobjs); + kobject_put(pkobj); return ret; } diff --git a/drivers/acpi/apei/einj-core.c b/drivers/acpi/apei/einj-core.c index 3c87953dbd197a..305c240a303f6f 100644 --- a/drivers/acpi/apei/einj-core.c +++ b/drivers/acpi/apei/einj-core.c @@ -182,6 +182,7 @@ bool einj_initialized __ro_after_init; static void __iomem *einj_param; static u32 v5param_size; +static u32 v66param_size; static bool is_v2; static void einj_exec_ctx_init(struct apei_exec_context *ctx) @@ -283,6 +284,24 @@ static void check_vendor_extension(u64 paddr, acpi_os_unmap_iomem(p, sizeof(v)); } +static u32 einjv2_init(struct einjv2_extension_struct *e) +{ + if (e->revision != 1) { + pr_info("Unknown v2 extension revision %u\n", e->revision); + return 0; + } + if (e->length < sizeof(*e) || e->length > PAGE_SIZE) { + pr_info(FW_BUG "Bad1 v2 extension length %u\n", e->length); + return 0; + } + if ((e->length - sizeof(*e)) % sizeof(e->component_arr[0])) { + pr_info(FW_BUG "Bad2 v2 extension length %u\n", e->length); + return 0; + } + + return (e->length - sizeof(*e)) / sizeof(e->component_arr[0]); +} + static void __iomem *einj_get_parameter_address(void) { int i; @@ -310,28 +329,21 @@ static void __iomem *einj_get_parameter_address(void) v5param_size = sizeof(v5param); p = acpi_os_map_iomem(pa_v5, sizeof(*p)); if (p) { - int offset, len; - memcpy_fromio(&v5param, p, v5param_size); acpi5 = 1; check_vendor_extension(pa_v5, &v5param); - if (is_v2 && available_error_type & ACPI65_EINJV2_SUPP) { - len = v5param.einjv2_struct.length; - offset = offsetof(struct einjv2_extension_struct, component_arr); - max_nr_components = (len - offset) / - sizeof(v5param.einjv2_struct.component_arr[0]); - /* - * The first call to acpi_os_map_iomem above does not include the - * component array, instead it is used to read and calculate maximum - * number of components supported by the system. Below, the mapping - * is expanded to include the component array. - */ + if (available_error_type & ACPI65_EINJV2_SUPP) { + struct einjv2_extension_struct *e; + + e = &v5param.einjv2_struct; + max_nr_components = einjv2_init(e); + + /* remap including einjv2_extension_struct */ acpi_os_unmap_iomem(p, v5param_size); - offset = offsetof(struct set_error_type_with_address, einjv2_struct); - v5param_size = offset + struct_size(&v5param.einjv2_struct, - component_arr, max_nr_components); - p = acpi_os_map_iomem(pa_v5, v5param_size); + v66param_size = v5param_size - sizeof(*e) + e->length; + p = acpi_os_map_iomem(pa_v5, v66param_size); } + return p; } } @@ -527,6 +539,7 @@ static int __einj_error_inject(u32 type, u32 flags, u64 param1, u64 param2, u64 param3, u64 param4) { struct apei_exec_context ctx; + u32 param_size = is_v2 ? v66param_size : v5param_size; u64 val, trigger_paddr, timeout = FIRMWARE_TIMEOUT; int i, rc; @@ -539,11 +552,11 @@ static int __einj_error_inject(u32 type, u32 flags, u64 param1, u64 param2, if (acpi5) { struct set_error_type_with_address *v5param; - v5param = kmalloc(v5param_size, GFP_KERNEL); + v5param = kmalloc(param_size, GFP_KERNEL); if (!v5param) return -ENOMEM; - memcpy_fromio(v5param, einj_param, v5param_size); + memcpy_fromio(v5param, einj_param, param_size); v5param->type = type; if (type & ACPI5_VENDOR_BIT) { switch (vendor_flags) { @@ -601,7 +614,7 @@ static int __einj_error_inject(u32 type, u32 flags, u64 param1, u64 param2, break; } } - memcpy_toio(einj_param, v5param, v5param_size); + memcpy_toio(einj_param, v5param, param_size); kfree(v5param); } else { rc = apei_exec_run(&ctx, ACPI_EINJ_SET_ERROR_TYPE); @@ -1132,9 +1145,14 @@ static void einj_remove(struct faux_device *fdev) struct apei_exec_context ctx; if (einj_param) { - acpi_size size = (acpi5) ? - v5param_size : - sizeof(struct einj_parameter); + acpi_size size; + + if (v66param_size) + size = v66param_size; + else if (acpi5) + size = v5param_size; + else + size = sizeof(struct einj_parameter); acpi_os_unmap_iomem(einj_param, size); if (vendor_errors.size) diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c index ab4651205e8adb..3bdeeee3414e68 100644 --- a/drivers/acpi/cppc_acpi.c +++ b/drivers/acpi/cppc_acpi.c @@ -460,7 +460,7 @@ bool acpi_cpc_valid(void) if (acpi_disabled) return false; - for_each_present_cpu(cpu) { + for_each_online_cpu(cpu) { cpc_ptr = per_cpu(cpc_desc_ptr, cpu); if (!cpc_ptr) return false; @@ -476,7 +476,7 @@ bool cppc_allow_fast_switch(void) struct cpc_desc *cpc_ptr; int cpu; - for_each_present_cpu(cpu) { + for_each_online_cpu(cpu) { cpc_ptr = per_cpu(cpc_desc_ptr, cpu); desired_reg = &cpc_ptr->cpc_regs[DESIRED_PERF]; if (!CPC_IN_SYSTEM_MEMORY(desired_reg) && @@ -750,7 +750,7 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr) } /* - * Disregard _CPC if the number of entries in the return pachage is not + * Disregard _CPC if the number of entries in the return package is not * as expected, but support future revisions being proper supersets of * the v3 and only causing more entries to be returned by _CPC. */ @@ -1435,7 +1435,7 @@ bool cppc_perf_ctrs_in_pcc(void) { int cpu; - for_each_present_cpu(cpu) { + for_each_online_cpu(cpu) { struct cpc_register_resource *ref_perf_reg; struct cpc_desc *cpc_desc; diff --git a/drivers/acpi/numa/hmat.c b/drivers/acpi/numa/hmat.c index 5a36d57289b43d..11e4483685c9cf 100644 --- a/drivers/acpi/numa/hmat.c +++ b/drivers/acpi/numa/hmat.c @@ -874,10 +874,32 @@ static void hmat_register_target_devices(struct memory_target *target) } } -static void hmat_register_target(struct memory_target *target) +static void hmat_hotplug_target(struct memory_target *target) { int nid = pxm_to_node(target->memory_pxm); + /* + * Skip offline nodes. This can happen when memory marked EFI_MEMORY_SP, + * "specific purpose", is applied to all the memory in a proximity + * domain leading to * the node being marked offline / unplugged, or if + * memory-only "hotplug" node is offline. + */ + if (nid == NUMA_NO_NODE || !node_online(nid)) + return; + + guard(mutex)(&target_lock); + if (target->registered) + return; + + hmat_register_target_initiators(target); + hmat_register_target_cache(target); + hmat_register_target_perf(target, ACCESS_COORDINATE_LOCAL); + hmat_register_target_perf(target, ACCESS_COORDINATE_CPU); + target->registered = true; +} + +static void hmat_register_target(struct memory_target *target) +{ /* * Devices may belong to either an offline or online * node, so unconditionally add them. @@ -895,25 +917,7 @@ static void hmat_register_target(struct memory_target *target) } mutex_unlock(&target_lock); - /* - * Skip offline nodes. This can happen when memory - * marked EFI_MEMORY_SP, "specific purpose", is applied - * to all the memory in a proximity domain leading to - * the node being marked offline / unplugged, or if - * memory-only "hotplug" node is offline. - */ - if (nid == NUMA_NO_NODE || !node_online(nid)) - return; - - mutex_lock(&target_lock); - if (!target->registered) { - hmat_register_target_initiators(target); - hmat_register_target_cache(target); - hmat_register_target_perf(target, ACCESS_COORDINATE_LOCAL); - hmat_register_target_perf(target, ACCESS_COORDINATE_CPU); - target->registered = true; - } - mutex_unlock(&target_lock); + hmat_hotplug_target(target); } static void hmat_register_targets(void) @@ -939,7 +943,7 @@ static int hmat_callback(struct notifier_block *self, if (!target) return NOTIFY_OK; - hmat_register_target(target); + hmat_hotplug_target(target); return NOTIFY_OK; } diff --git a/drivers/acpi/numa/srat.c b/drivers/acpi/numa/srat.c index 53816dfab64523..aa87ee1583a4e0 100644 --- a/drivers/acpi/numa/srat.c +++ b/drivers/acpi/numa/srat.c @@ -237,7 +237,7 @@ acpi_table_print_srat_entry(struct acpi_subtable_header *header) struct acpi_srat_generic_affinity *p = (struct acpi_srat_generic_affinity *)header; - if (p->device_handle_type == 0) { + if (p->device_handle_type == 1) { /* * For pci devices this may be the only place they * are assigned a proximity domain diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c index a3f95a3fffde20..d3edc3bcbf0112 100644 --- a/drivers/acpi/sbs.c +++ b/drivers/acpi/sbs.c @@ -487,7 +487,7 @@ static int acpi_battery_read(struct acpi_battery *battery) if (result) return result; - battery->present = state & (1 << battery->id); + battery->present = !!(state & (1 << battery->id)); if (!battery->present) return 0; diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 2a210719c4ce5c..f48fb63d7e8549 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -3006,6 +3006,16 @@ int ata_dev_configure(struct ata_device *dev) } dev->n_sectors = ata_id_n_sectors(id); + if (ata_id_is_locked(id)) { + /* + * If Security locked, set capacity to zero to prevent + * any I/O, e.g. partition scanning, as any I/O to a + * locked drive will result in user visible errors. + */ + ata_dev_info(dev, + "Security locked, setting capacity to zero\n"); + dev->n_sectors = 0; + } /* get current R/W Multiple count setting */ if ((dev->id[47] >> 8) == 0x80 && (dev->id[59] & 0x100)) { diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index b43a3196e2be83..434774e71fe61e 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -992,6 +992,13 @@ static void ata_gen_ata_sense(struct ata_queued_cmd *qc) return; } + if (ata_id_is_locked(dev->id)) { + /* Security locked */ + /* LOGICAL UNIT ACCESS NOT AUTHORIZED */ + ata_scsi_set_sense(dev, cmd, DATA_PROTECT, 0x74, 0x71); + return; + } + if (!(qc->flags & ATA_QCFLAG_RTF_FILLED)) { ata_dev_dbg(dev, "Missing result TF: reporting aborted command\n"); @@ -4894,8 +4901,10 @@ void ata_scsi_dev_rescan(struct work_struct *work) spin_unlock_irqrestore(ap->lock, flags); if (do_resume) { ret = scsi_resume_device(sdev); - if (ret == -EWOULDBLOCK) + if (ret == -EWOULDBLOCK) { + scsi_device_put(sdev); goto unlock_scan; + } dev->flags &= ~ATA_DFLAG_RESUMING; } ret = scsi_rescan_device(sdev); diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index e83503bdc1fdb8..1de1cd72b616da 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -888,12 +888,15 @@ static void device_resume_early(struct device *dev, pm_message_t state, bool asy TRACE_DEVICE(dev); TRACE_RESUME(0); - if (dev->power.syscore || dev->power.direct_complete) + if (dev->power.direct_complete) goto Out; if (!dev->power.is_late_suspended) goto Out; + if (dev->power.syscore) + goto Skip; + if (!dpm_wait_for_superior(dev, async)) goto Out; @@ -926,11 +929,11 @@ static void device_resume_early(struct device *dev, pm_message_t state, bool asy Skip: dev->power.is_late_suspended = false; + pm_runtime_enable(dev); Out: TRACE_RESUME(error); - pm_runtime_enable(dev); complete_all(&dev->power.completion); if (error) { @@ -1615,12 +1618,6 @@ static void device_suspend_late(struct device *dev, pm_message_t state, bool asy TRACE_DEVICE(dev); TRACE_SUSPEND(0); - /* - * Disable runtime PM for the device without checking if there is a - * pending resume request for it. - */ - __pm_runtime_disable(dev, false); - dpm_wait_for_subordinate(dev, async); if (READ_ONCE(async_error)) @@ -1631,9 +1628,18 @@ static void device_suspend_late(struct device *dev, pm_message_t state, bool asy goto Complete; } - if (dev->power.syscore || dev->power.direct_complete) + if (dev->power.direct_complete) goto Complete; + /* + * Disable runtime PM for the device without checking if there is a + * pending resume request for it. + */ + __pm_runtime_disable(dev, false); + + if (dev->power.syscore) + goto Skip; + if (dev->pm_domain) { info = "late power domain "; callback = pm_late_early_op(&dev->pm_domain->ops, state); @@ -1664,6 +1670,7 @@ static void device_suspend_late(struct device *dev, pm_message_t state, bool asy WRITE_ONCE(async_error, error); dpm_save_failed_dev(dev_name(dev)); pm_dev_err(dev, state, async ? " async late" : " late", error); + pm_runtime_enable(dev); goto Complete; } dpm_propagate_wakeup_to_parent(dev); diff --git a/drivers/bluetooth/btrtl.c b/drivers/bluetooth/btrtl.c index 6abd962502e368..52794db2739bfc 100644 --- a/drivers/bluetooth/btrtl.c +++ b/drivers/bluetooth/btrtl.c @@ -50,7 +50,7 @@ #define RTL_CHIP_SUBVER (&(struct rtl_vendor_cmd) {{0x10, 0x38, 0x04, 0x28, 0x80}}) #define RTL_CHIP_REV (&(struct rtl_vendor_cmd) {{0x10, 0x3A, 0x04, 0x28, 0x80}}) -#define RTL_SEC_PROJ (&(struct rtl_vendor_cmd) {{0x10, 0xA4, 0x0D, 0x00, 0xb0}}) +#define RTL_SEC_PROJ (&(struct rtl_vendor_cmd) {{0x10, 0xA4, 0xAD, 0x00, 0xb0}}) #define RTL_PATCH_SNIPPETS 0x01 #define RTL_PATCH_DUMMY_HEADER 0x02 @@ -534,7 +534,6 @@ static int rtlbt_parse_firmware_v2(struct hci_dev *hdev, { struct rtl_epatch_header_v2 *hdr; int rc; - u8 reg_val[2]; u8 key_id; u32 num_sections; struct rtl_section *section; @@ -549,14 +548,7 @@ static int rtlbt_parse_firmware_v2(struct hci_dev *hdev, .len = btrtl_dev->fw_len - 7, /* Cut the tail */ }; - rc = btrtl_vendor_read_reg16(hdev, RTL_SEC_PROJ, reg_val); - if (rc < 0) - return -EIO; - key_id = reg_val[0]; - - rtl_dev_dbg(hdev, "%s: key id %u", __func__, key_id); - - btrtl_dev->key_id = key_id; + key_id = btrtl_dev->key_id; hdr = rtl_iov_pull_data(&iov, sizeof(*hdr)); if (!hdr) @@ -625,8 +617,10 @@ static int rtlbt_parse_firmware_v2(struct hci_dev *hdev, len += entry->len; } - if (!len) + if (!len) { + kvfree(ptr); return -EPERM; + } *_buf = ptr; return len; @@ -1068,6 +1062,8 @@ struct btrtl_device_info *btrtl_initialize(struct hci_dev *hdev, u16 hci_rev, lmp_subver; u8 hci_ver, lmp_ver, chip_type = 0; int ret; + int rc; + u8 key_id; u8 reg_val[2]; btrtl_dev = kzalloc(sizeof(*btrtl_dev), GFP_KERNEL); @@ -1178,6 +1174,14 @@ struct btrtl_device_info *btrtl_initialize(struct hci_dev *hdev, goto err_free; } + rc = btrtl_vendor_read_reg16(hdev, RTL_SEC_PROJ, reg_val); + if (rc < 0) + goto err_free; + + key_id = reg_val[0]; + btrtl_dev->key_id = key_id; + rtl_dev_info(hdev, "%s: key id %u", __func__, key_id); + btrtl_dev->fw_len = -EIO; if (lmp_subver == RTL_ROM_LMP_8852A && hci_rev == 0x000c) { snprintf(fw_name, sizeof(fw_name), "%s_v2.bin", @@ -1200,7 +1204,7 @@ struct btrtl_device_info *btrtl_initialize(struct hci_dev *hdev, goto err_free; } - if (btrtl_dev->ic_info->cfg_name) { + if (btrtl_dev->ic_info->cfg_name && !btrtl_dev->key_id) { if (postfix) { snprintf(cfg_name, sizeof(cfg_name), "%s-%s.bin", btrtl_dev->ic_info->cfg_name, postfix); diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 5e9ebf0c53125e..a722446ec73dd8 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -4361,6 +4361,11 @@ static void btusb_disconnect(struct usb_interface *intf) hci_unregister_dev(hdev); + if (data->oob_wake_irq) + device_init_wakeup(&data->udev->dev, false); + if (data->reset_gpio) + gpiod_put(data->reset_gpio); + if (intf == data->intf) { if (data->isoc) usb_driver_release_interface(&btusb_driver, data->isoc); @@ -4371,17 +4376,11 @@ static void btusb_disconnect(struct usb_interface *intf) usb_driver_release_interface(&btusb_driver, data->diag); usb_driver_release_interface(&btusb_driver, data->intf); } else if (intf == data->diag) { - usb_driver_release_interface(&btusb_driver, data->intf); if (data->isoc) usb_driver_release_interface(&btusb_driver, data->isoc); + usb_driver_release_interface(&btusb_driver, data->intf); } - if (data->oob_wake_irq) - device_init_wakeup(&data->udev->dev, false); - - if (data->reset_gpio) - gpiod_put(data->reset_gpio); - hci_free_dev(hdev); } diff --git a/drivers/clk/sunxi-ng/ccu-sun55i-a523-r.c b/drivers/clk/sunxi-ng/ccu-sun55i-a523-r.c index 70ce0ca0cb7db6..0339c4af0fe5b5 100644 --- a/drivers/clk/sunxi-ng/ccu-sun55i-a523-r.c +++ b/drivers/clk/sunxi-ng/ccu-sun55i-a523-r.c @@ -121,11 +121,11 @@ static SUNXI_CCU_GATE_HW(bus_r_ir_rx_clk, "bus-r-ir-rx", &r_apb0_clk.common.hw, 0x1cc, BIT(0), 0); static SUNXI_CCU_GATE_HW(bus_r_dma_clk, "bus-r-dma", - &r_apb0_clk.common.hw, 0x1dc, BIT(0), 0); + &r_apb0_clk.common.hw, 0x1dc, BIT(0), CLK_IS_CRITICAL); static SUNXI_CCU_GATE_HW(bus_r_rtc_clk, "bus-r-rtc", &r_apb0_clk.common.hw, 0x20c, BIT(0), 0); static SUNXI_CCU_GATE_HW(bus_r_cpucfg_clk, "bus-r-cpucfg", - &r_apb0_clk.common.hw, 0x22c, BIT(0), 0); + &r_apb0_clk.common.hw, 0x22c, BIT(0), CLK_IS_CRITICAL); static struct ccu_common *sun55i_a523_r_ccu_clks[] = { &r_ahb_clk.common, diff --git a/drivers/clk/sunxi-ng/ccu-sun55i-a523.c b/drivers/clk/sunxi-ng/ccu-sun55i-a523.c index acb532f8361b6d..20dad06b37ca31 100644 --- a/drivers/clk/sunxi-ng/ccu-sun55i-a523.c +++ b/drivers/clk/sunxi-ng/ccu-sun55i-a523.c @@ -300,7 +300,7 @@ static struct ccu_nm pll_audio0_4x_clk = { .m = _SUNXI_CCU_DIV(16, 6), .sdm = _SUNXI_CCU_SDM(pll_audio0_sdm_table, BIT(24), 0x178, BIT(31)), - .min_rate = 180000000U, + .min_rate = 90000000U, .max_rate = 3000000000U, .common = { .reg = 0x078, diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index 38897bb14a2c6d..492a10f1bdbfa3 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c @@ -603,9 +603,6 @@ static bool turbo_is_disabled(void) { u64 misc_en; - if (!cpu_feature_enabled(X86_FEATURE_IDA)) - return true; - rdmsrq(MSR_IA32_MISC_ENABLE, misc_en); return !!(misc_en & MSR_IA32_MISC_ENABLE_TURBO_DISABLE); @@ -2106,7 +2103,8 @@ static u64 atom_get_val(struct cpudata *cpudata, int pstate) u32 vid; val = (u64)pstate << 8; - if (READ_ONCE(global.no_turbo) && !READ_ONCE(global.turbo_disabled)) + if (READ_ONCE(global.no_turbo) && !READ_ONCE(global.turbo_disabled) && + cpu_feature_enabled(X86_FEATURE_IDA)) val |= (u64)1 << 32; vid_fp = cpudata->vid.min + mul_fp( @@ -2271,7 +2269,8 @@ static u64 core_get_val(struct cpudata *cpudata, int pstate) u64 val; val = (u64)pstate << 8; - if (READ_ONCE(global.no_turbo) && !READ_ONCE(global.turbo_disabled)) + if (READ_ONCE(global.no_turbo) && !READ_ONCE(global.turbo_disabled) && + cpu_feature_enabled(X86_FEATURE_IDA)) val |= (u64)1 << 32; return val; diff --git a/drivers/cpuidle/cpuidle-riscv-sbi.c b/drivers/cpuidle/cpuidle-riscv-sbi.c index a360bc4d20b764..19be6475d35653 100644 --- a/drivers/cpuidle/cpuidle-riscv-sbi.c +++ b/drivers/cpuidle/cpuidle-riscv-sbi.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -303,8 +304,8 @@ static int sbi_cpuidle_init_cpu(struct device *dev, int cpu) drv->states[0].exit_latency = 1; drv->states[0].target_residency = 1; drv->states[0].power_usage = UINT_MAX; - strcpy(drv->states[0].name, "WFI"); - strcpy(drv->states[0].desc, "RISC-V WFI"); + strscpy(drv->states[0].name, "WFI"); + strscpy(drv->states[0].desc, "RISC-V WFI"); /* * If no DT idle states are detected (ret == 0) let the driver diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c index a5b96adf2d1e76..3b391a1466353d 100644 --- a/drivers/crypto/hisilicon/qm.c +++ b/drivers/crypto/hisilicon/qm.c @@ -3871,10 +3871,12 @@ static ssize_t qm_get_qos_value(struct hisi_qm *qm, const char *buf, pdev = container_of(dev, struct pci_dev, dev); if (pci_physfn(pdev) != qm->pdev) { pci_err(qm->pdev, "the pdev input does not match the pf!\n"); + put_device(dev); return -EINVAL; } *fun_index = pdev->devfn; + put_device(dev); return 0; } diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c index b06fee1978ba46..41b64d871c5a1e 100644 --- a/drivers/cxl/core/region.c +++ b/drivers/cxl/core/region.c @@ -3702,6 +3702,7 @@ static int cxl_region_debugfs_poison_inject(void *data, u64 offset) if (validate_region_offset(cxlr, offset)) return -EINVAL; + offset -= cxlr->params.cache_size; rc = region_offset_to_dpa_result(cxlr, offset, &result); if (rc || !result.cxlmd || result.dpa == ULLONG_MAX) { dev_dbg(&cxlr->dev, @@ -3734,6 +3735,7 @@ static int cxl_region_debugfs_poison_clear(void *data, u64 offset) if (validate_region_offset(cxlr, offset)) return -EINVAL; + offset -= cxlr->params.cache_size; rc = region_offset_to_dpa_result(cxlr, offset, &result); if (rc || !result.cxlmd || result.dpa == ULLONG_MAX) { dev_dbg(&cxlr->dev, diff --git a/drivers/edac/altera_edac.c b/drivers/edac/altera_edac.c index 103b2c2eba2aba..0c5b94e64ea157 100644 --- a/drivers/edac/altera_edac.c +++ b/drivers/edac/altera_edac.c @@ -1184,10 +1184,22 @@ altr_check_ocram_deps_init(struct altr_edac_device_dev *device) if (ret) return ret; - /* Verify OCRAM has been initialized */ + /* + * Verify that OCRAM has been initialized. + * During a warm reset, OCRAM contents are retained, but the control + * and status registers are reset to their default values. Therefore, + * ECC must be explicitly re-enabled in the control register. + * Error condition: if INITCOMPLETEA is clear and ECC_EN is already set. + */ if (!ecc_test_bits(ALTR_A10_ECC_INITCOMPLETEA, - (base + ALTR_A10_ECC_INITSTAT_OFST))) - return -ENODEV; + (base + ALTR_A10_ECC_INITSTAT_OFST))) { + if (!ecc_test_bits(ALTR_A10_ECC_EN, + (base + ALTR_A10_ECC_CTRL_OFST))) + ecc_set_bits(ALTR_A10_ECC_EN, + (base + ALTR_A10_ECC_CTRL_OFST)); + else + return -ENODEV; + } /* Enable IRQ on Single Bit Error */ writel(ALTR_A10_ECC_SERRINTEN, (base + ALTR_A10_ECC_ERRINTENS_OFST)); @@ -1357,7 +1369,7 @@ static const struct edac_device_prv_data a10_enetecc_data = { .ue_set_mask = ALTR_A10_ECC_TDERRA, .set_err_ofst = ALTR_A10_ECC_INTTEST_OFST, .ecc_irq_handler = altr_edac_a10_ecc_irq, - .inject_fops = &altr_edac_a10_device_inject2_fops, + .inject_fops = &altr_edac_a10_device_inject_fops, }; #endif /* CONFIG_EDAC_ALTERA_ETHERNET */ @@ -1447,7 +1459,7 @@ static const struct edac_device_prv_data a10_usbecc_data = { .ue_set_mask = ALTR_A10_ECC_TDERRA, .set_err_ofst = ALTR_A10_ECC_INTTEST_OFST, .ecc_irq_handler = altr_edac_a10_ecc_irq, - .inject_fops = &altr_edac_a10_device_inject2_fops, + .inject_fops = &altr_edac_a10_device_inject_fops, }; #endif /* CONFIG_EDAC_ALTERA_USB */ diff --git a/drivers/edac/versalnet_edac.c b/drivers/edac/versalnet_edac.c index 7c5db8bf0595b6..1a1092793092a8 100644 --- a/drivers/edac/versalnet_edac.c +++ b/drivers/edac/versalnet_edac.c @@ -433,7 +433,7 @@ static void handle_error(struct mc_priv *priv, struct ecc_status *stat, phys_addr_t pfn; int err; - if (WARN_ON_ONCE(ctl_num > NUM_CONTROLLERS)) + if (WARN_ON_ONCE(ctl_num >= NUM_CONTROLLERS)) return; mci = priv->mci[ctl_num]; @@ -605,21 +605,23 @@ static int rpmsg_cb(struct rpmsg_device *rpdev, void *data, length = result[MSG_ERR_LENGTH]; offset = result[MSG_ERR_OFFSET]; + /* + * The data can come in two stretches. Construct the regs from two + * messages. The offset indicates the offset from which the data is to + * be taken. + */ + for (i = 0 ; i < length; i++) { + k = offset + i; + j = ERROR_DATA + i; + mc_priv->regs[k] = result[j]; + } + if (result[TOTAL_ERR_LENGTH] > length) { if (!mc_priv->part_len) mc_priv->part_len = length; else mc_priv->part_len += length; - /* - * The data can come in 2 stretches. Construct the regs from 2 - * messages the offset indicates the offset from which the data is to - * be taken - */ - for (i = 0 ; i < length; i++) { - k = offset + i; - j = ERROR_DATA + i; - mc_priv->regs[k] = result[j]; - } + if (mc_priv->part_len < result[TOTAL_ERR_LENGTH]) return 0; mc_priv->part_len = 0; @@ -705,7 +707,7 @@ static int rpmsg_cb(struct rpmsg_device *rpdev, void *data, /* Convert to bytes */ length = result[TOTAL_ERR_LENGTH] * 4; log_non_standard_event(sec_type, &amd_versalnet_guid, mc_priv->message, - sec_sev, (void *)&result[ERROR_DATA], length); + sec_sev, (void *)&mc_priv->regs, length); return 0; } diff --git a/drivers/firewire/core-card.c b/drivers/firewire/core-card.c index e5e0174a0335c2..66e1106db5e740 100644 --- a/drivers/firewire/core-card.c +++ b/drivers/firewire/core-card.c @@ -577,6 +577,8 @@ void fw_card_initialize(struct fw_card *card, INIT_LIST_HEAD(&card->transactions.list); spin_lock_init(&card->transactions.lock); + spin_lock_init(&card->topology_map.lock); + card->split_timeout.hi = DEFAULT_SPLIT_TIMEOUT / 8000; card->split_timeout.lo = (DEFAULT_SPLIT_TIMEOUT % 8000) << 19; card->split_timeout.cycles = DEFAULT_SPLIT_TIMEOUT; diff --git a/drivers/firewire/core-topology.c b/drivers/firewire/core-topology.c index 2f73bcd5696f2b..ed3ae8cdb0cdb6 100644 --- a/drivers/firewire/core-topology.c +++ b/drivers/firewire/core-topology.c @@ -441,12 +441,13 @@ static void update_topology_map(__be32 *buffer, size_t buffer_size, int root_nod const u32 *self_ids, int self_id_count) { __be32 *map = buffer; + u32 next_generation = be32_to_cpu(buffer[1]) + 1; int node_count = (root_node_id & 0x3f) + 1; memset(map, 0, buffer_size); *map++ = cpu_to_be32((self_id_count + 2) << 16); - *map++ = cpu_to_be32(be32_to_cpu(buffer[1]) + 1); + *map++ = cpu_to_be32(next_generation); *map++ = cpu_to_be32((node_count << 16) | self_id_count); while (self_id_count--) diff --git a/drivers/firmware/cirrus/cs_dsp.c b/drivers/firmware/cirrus/cs_dsp.c index f51047d8ea64f5..525ac0f0a75d8f 100644 --- a/drivers/firmware/cirrus/cs_dsp.c +++ b/drivers/firmware/cirrus/cs_dsp.c @@ -9,9 +9,11 @@ * Cirrus Logic International Semiconductor Ltd. */ +#include #include #include #include +#include #include #include #include @@ -316,44 +318,6 @@ struct cs_dsp_alg_region_list_item { struct cs_dsp_alg_region alg_region; }; -struct cs_dsp_buf { - struct list_head list; - void *buf; -}; - -static struct cs_dsp_buf *cs_dsp_buf_alloc(const void *src, size_t len, - struct list_head *list) -{ - struct cs_dsp_buf *buf = kzalloc(sizeof(*buf), GFP_KERNEL); - - if (buf == NULL) - return NULL; - - buf->buf = vmalloc(len); - if (!buf->buf) { - kfree(buf); - return NULL; - } - memcpy(buf->buf, src, len); - - if (list) - list_add_tail(&buf->list, list); - - return buf; -} - -static void cs_dsp_buf_free(struct list_head *list) -{ - while (!list_empty(list)) { - struct cs_dsp_buf *buf = list_first_entry(list, - struct cs_dsp_buf, - list); - list_del(&buf->list); - vfree(buf->buf); - kfree(buf); - } -} - /** * cs_dsp_mem_region_name() - Return a name string for a memory type * @type: the memory type to match @@ -388,18 +352,14 @@ EXPORT_SYMBOL_NS_GPL(cs_dsp_mem_region_name, "FW_CS_DSP"); #ifdef CONFIG_DEBUG_FS static void cs_dsp_debugfs_save_wmfwname(struct cs_dsp *dsp, const char *s) { - char *tmp = kasprintf(GFP_KERNEL, "%s\n", s); - kfree(dsp->wmfw_file_name); - dsp->wmfw_file_name = tmp; + dsp->wmfw_file_name = kstrdup(s, GFP_KERNEL); } static void cs_dsp_debugfs_save_binname(struct cs_dsp *dsp, const char *s) { - char *tmp = kasprintf(GFP_KERNEL, "%s\n", s); - kfree(dsp->bin_file_name); - dsp->bin_file_name = tmp; + dsp->bin_file_name = kstrdup(s, GFP_KERNEL); } static void cs_dsp_debugfs_clear(struct cs_dsp *dsp) @@ -410,24 +370,33 @@ static void cs_dsp_debugfs_clear(struct cs_dsp *dsp) dsp->bin_file_name = NULL; } +static ssize_t cs_dsp_debugfs_string_read(struct cs_dsp *dsp, + char __user *user_buf, + size_t count, loff_t *ppos, + const char **pstr) +{ + const char *str __free(kfree) = NULL; + + scoped_guard(mutex, &dsp->pwr_lock) { + if (!*pstr) + return 0; + + str = kasprintf(GFP_KERNEL, "%s\n", *pstr); + if (!str) + return -ENOMEM; + + return simple_read_from_buffer(user_buf, count, ppos, str, strlen(str)); + } +} + static ssize_t cs_dsp_debugfs_wmfw_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { struct cs_dsp *dsp = file->private_data; - ssize_t ret; - - mutex_lock(&dsp->pwr_lock); - if (!dsp->wmfw_file_name || !dsp->booted) - ret = 0; - else - ret = simple_read_from_buffer(user_buf, count, ppos, - dsp->wmfw_file_name, - strlen(dsp->wmfw_file_name)); - - mutex_unlock(&dsp->pwr_lock); - return ret; + return cs_dsp_debugfs_string_read(dsp, user_buf, count, ppos, + &dsp->wmfw_file_name); } static ssize_t cs_dsp_debugfs_bin_read(struct file *file, @@ -435,19 +404,9 @@ static ssize_t cs_dsp_debugfs_bin_read(struct file *file, size_t count, loff_t *ppos) { struct cs_dsp *dsp = file->private_data; - ssize_t ret; - - mutex_lock(&dsp->pwr_lock); - if (!dsp->bin_file_name || !dsp->booted) - ret = 0; - else - ret = simple_read_from_buffer(user_buf, count, ppos, - dsp->bin_file_name, - strlen(dsp->bin_file_name)); - - mutex_unlock(&dsp->pwr_lock); - return ret; + return cs_dsp_debugfs_string_read(dsp, user_buf, count, ppos, + &dsp->bin_file_name); } static const struct { @@ -479,9 +438,11 @@ static int cs_dsp_debugfs_read_controls_show(struct seq_file *s, void *ignored) struct cs_dsp_coeff_ctl *ctl; unsigned int reg; + guard(mutex)(&dsp->pwr_lock); + list_for_each_entry(ctl, &dsp->ctl_list, list) { cs_dsp_coeff_base_reg(ctl, ®, 0); - seq_printf(s, "%22.*s: %#8zx %s:%08x %#8x %s %#8x %#4x %c%c%c%c %s %s\n", + seq_printf(s, "%22.*s: %#8x %s:%08x %#8x %s %#8x %#4x %c%c%c%c %s %s\n", ctl->subname_len, ctl->subname, ctl->len, cs_dsp_mem_region_name(ctl->alg_region.type), ctl->offset, reg, ctl->fw_name, ctl->alg_region.alg, ctl->type, @@ -1028,7 +989,7 @@ static void cs_dsp_signal_event_controls(struct cs_dsp *dsp, static void cs_dsp_free_ctl_blk(struct cs_dsp_coeff_ctl *ctl) { - kfree(ctl->cache); + kvfree(ctl->cache); kfree(ctl->subname); kfree(ctl); } @@ -1078,7 +1039,7 @@ static int cs_dsp_create_control(struct cs_dsp *dsp, ctl->type = type; ctl->offset = offset; ctl->len = len; - ctl->cache = kzalloc(ctl->len, GFP_KERNEL); + ctl->cache = kvzalloc(ctl->len, GFP_KERNEL); if (!ctl->cache) { ret = -ENOMEM; goto err_ctl_subname; @@ -1096,7 +1057,7 @@ static int cs_dsp_create_control(struct cs_dsp *dsp, err_list_del: list_del(&ctl->list); - kfree(ctl->cache); + kvfree(ctl->cache); err_ctl_subname: kfree(ctl->subname); err_ctl: @@ -1485,7 +1446,9 @@ static int cs_dsp_load(struct cs_dsp *dsp, const struct firmware *firmware, const struct wmfw_region *region; const struct cs_dsp_region *mem; const char *region_name; - struct cs_dsp_buf *buf; + u8 *buf __free(kfree) = NULL; + size_t buf_len = 0; + size_t region_len; unsigned int reg; int regions = 0; int ret, offset, type; @@ -1605,23 +1568,23 @@ static int cs_dsp_load(struct cs_dsp *dsp, const struct firmware *firmware, region_name); if (reg) { - buf = cs_dsp_buf_alloc(region->data, - le32_to_cpu(region->len), - &buf_list); - if (!buf) { - cs_dsp_err(dsp, "Out of memory\n"); - ret = -ENOMEM; - goto out_fw; + region_len = le32_to_cpu(region->len); + if (region_len > buf_len) { + buf_len = round_up(region_len, PAGE_SIZE); + kfree(buf); + buf = kmalloc(buf_len, GFP_KERNEL | GFP_DMA); + if (!buf) { + ret = -ENOMEM; + goto out_fw; + } } - ret = regmap_raw_write(regmap, reg, buf->buf, - le32_to_cpu(region->len)); + memcpy(buf, region->data, region_len); + ret = regmap_raw_write(regmap, reg, buf, region_len); if (ret != 0) { cs_dsp_err(dsp, - "%s.%d: Failed to write %d bytes at %d in %s: %d\n", - file, regions, - le32_to_cpu(region->len), offset, - region_name, ret); + "%s.%d: Failed to write %zu bytes at %d in %s: %d\n", + file, regions, region_len, offset, region_name, ret); goto out_fw; } } @@ -1638,8 +1601,6 @@ static int cs_dsp_load(struct cs_dsp *dsp, const struct firmware *firmware, ret = 0; out_fw: - cs_dsp_buf_free(&buf_list); - if (ret == -EOVERFLOW) cs_dsp_err(dsp, "%s: file content overflows file data\n", file); @@ -2171,7 +2132,9 @@ static int cs_dsp_load_coeff(struct cs_dsp *dsp, const struct firmware *firmware struct cs_dsp_alg_region *alg_region; const char *region_name; int ret, pos, blocks, type, offset, reg, version; - struct cs_dsp_buf *buf; + u8 *buf __free(kfree) = NULL; + size_t buf_len = 0; + size_t region_len; if (!firmware) return 0; @@ -2313,20 +2276,22 @@ static int cs_dsp_load_coeff(struct cs_dsp *dsp, const struct firmware *firmware } if (reg) { - buf = cs_dsp_buf_alloc(blk->data, - le32_to_cpu(blk->len), - &buf_list); - if (!buf) { - cs_dsp_err(dsp, "Out of memory\n"); - ret = -ENOMEM; - goto out_fw; + region_len = le32_to_cpu(blk->len); + if (region_len > buf_len) { + buf_len = round_up(region_len, PAGE_SIZE); + kfree(buf); + buf = kmalloc(buf_len, GFP_KERNEL | GFP_DMA); + if (!buf) { + ret = -ENOMEM; + goto out_fw; + } } - cs_dsp_dbg(dsp, "%s.%d: Writing %d bytes at %x\n", - file, blocks, le32_to_cpu(blk->len), - reg); - ret = regmap_raw_write(regmap, reg, buf->buf, - le32_to_cpu(blk->len)); + memcpy(buf, blk->data, region_len); + + cs_dsp_dbg(dsp, "%s.%d: Writing %zu bytes at %x\n", + file, blocks, region_len, reg); + ret = regmap_raw_write(regmap, reg, buf, region_len); if (ret != 0) { cs_dsp_err(dsp, "%s.%d: Failed to write to %x in %s: %d\n", @@ -2346,8 +2311,6 @@ static int cs_dsp_load_coeff(struct cs_dsp *dsp, const struct firmware *firmware ret = 0; out_fw: - cs_dsp_buf_free(&buf_list); - if (ret == -EOVERFLOW) cs_dsp_err(dsp, "%s: file content overflows file data\n", file); @@ -2366,6 +2329,9 @@ static int cs_dsp_create_name(struct cs_dsp *dsp) return 0; } +static const struct cs_dsp_client_ops cs_dsp_default_client_ops = { +}; + static int cs_dsp_common_init(struct cs_dsp *dsp) { int ret; @@ -2379,6 +2345,9 @@ static int cs_dsp_common_init(struct cs_dsp *dsp) mutex_init(&dsp->pwr_lock); + if (!dsp->client_ops) + dsp->client_ops = &cs_dsp_default_client_ops; + #ifdef CONFIG_DEBUG_FS /* Ensure this is invalid if client never provides a debugfs root */ dsp->debugfs_root = ERR_PTR(-ENODEV); diff --git a/drivers/firmware/cirrus/test/cs_dsp_test_callbacks.c b/drivers/firmware/cirrus/test/cs_dsp_test_callbacks.c index 8a9b66a3b7d35a..e5a389808e5f2e 100644 --- a/drivers/firmware/cirrus/test/cs_dsp_test_callbacks.c +++ b/drivers/firmware/cirrus/test/cs_dsp_test_callbacks.c @@ -600,6 +600,7 @@ KUNIT_ARRAY_PARAM(cs_dsp_callbacks_ops, static const struct cs_dsp_callbacks_test_param cs_dsp_no_callbacks_cases[] = { { .ops = &cs_dsp_callback_test_empty_client_ops, .case_name = "empty ops" }, + { .ops = NULL, .case_name = "NULL ops" }, }; KUNIT_ARRAY_PARAM(cs_dsp_no_callbacks, diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 7ee3afbc2b05da..b8b6537290b067 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -6,6 +6,9 @@ config GPIOLIB_LEGACY def_bool y +config HAVE_SHARED_GPIOS + bool + menuconfig GPIOLIB bool "GPIO Support" help @@ -50,6 +53,11 @@ config OF_GPIO_MM_GPIOCHIP this symbol, but new drivers should use the generic gpio-regmap infrastructure instead. +config GPIO_SHARED + def_bool y + depends on HAVE_SHARED_GPIOS || COMPILE_TEST + select AUXILIARY_BUS + config DEBUG_GPIO bool "Debug GPIO calls" depends on DEBUG_KERNEL @@ -2017,6 +2025,15 @@ config GPIO_SIM This enables the GPIO simulator - a configfs-based GPIO testing driver. +config GPIO_SHARED_PROXY + tristate "Proxy driver for non-exclusive GPIOs" + default m + depends on GPIO_SHARED || COMPILE_TEST + select AUXILIARY_BUS + help + This enables the GPIO shared proxy driver - an abstraction layer + for GPIO pins that are shared by multiple devices. + endmenu menu "GPIO Debugging utilities" diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index ec296fa14bfdb3..d0020bc70b84f6 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -12,6 +12,7 @@ obj-$(CONFIG_GPIO_SYSFS) += gpiolib-sysfs.o obj-$(CONFIG_GPIO_ACPI) += gpiolib-acpi.o gpiolib-acpi-y := gpiolib-acpi-core.o gpiolib-acpi-quirks.o obj-$(CONFIG_GPIOLIB) += gpiolib-swnode.o +obj-$(CONFIG_GPIO_SHARED) += gpiolib-shared.o # Device drivers. Generally keep list sorted alphabetically obj-$(CONFIG_GPIO_REGMAP) += gpio-regmap.o @@ -159,6 +160,7 @@ obj-$(CONFIG_ARCH_SA1100) += gpio-sa1100.o obj-$(CONFIG_GPIO_SAMA5D2_PIOBU) += gpio-sama5d2-piobu.o obj-$(CONFIG_GPIO_SCH311X) += gpio-sch311x.o obj-$(CONFIG_GPIO_SCH) += gpio-sch.o +obj-$(CONFIG_GPIO_SHARED_PROXY) += gpio-shared-proxy.o obj-$(CONFIG_GPIO_SIFIVE) += gpio-sifive.o obj-$(CONFIG_GPIO_SIM) += gpio-sim.o obj-$(CONFIG_GPIO_SIOX) += gpio-siox.o diff --git a/drivers/gpio/gpio-aggregator.c b/drivers/gpio/gpio-aggregator.c index 37600faf4a4b72..416f265d09d070 100644 --- a/drivers/gpio/gpio-aggregator.c +++ b/drivers/gpio/gpio-aggregator.c @@ -723,6 +723,7 @@ struct gpiochip_fwd *devm_gpiochip_fwd_alloc(struct device *dev, chip->get_multiple = gpio_fwd_get_multiple_locked; chip->set = gpio_fwd_set; chip->set_multiple = gpio_fwd_set_multiple_locked; + chip->set_config = gpio_fwd_set_config; chip->to_irq = gpio_fwd_to_irq; chip->base = -1; chip->ngpio = ngpios; diff --git a/drivers/gpio/gpio-shared-proxy.c b/drivers/gpio/gpio-shared-proxy.c new file mode 100644 index 00000000000000..3ef2c40ed15229 --- /dev/null +++ b/drivers/gpio/gpio-shared-proxy.c @@ -0,0 +1,333 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2025 Linaro Ltd. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gpiolib-shared.h" + +struct gpio_shared_proxy_data { + struct gpio_chip gc; + struct gpio_shared_desc *shared_desc; + struct device *dev; + bool voted_high; +}; + +static int +gpio_shared_proxy_set_unlocked(struct gpio_shared_proxy_data *proxy, + int (*set_func)(struct gpio_desc *desc, int value), + int value) +{ + struct gpio_shared_desc *shared_desc = proxy->shared_desc; + struct gpio_desc *desc = shared_desc->desc; + int ret = 0; + + gpio_shared_lockdep_assert(shared_desc); + + if (value) { + /* User wants to set value to high. */ + if (proxy->voted_high) + /* Already voted for high, nothing to do. */ + goto out; + + /* Haven't voted for high yet. */ + if (!shared_desc->highcnt) { + /* + * Current value is low, need to actually set value + * to high. + */ + ret = set_func(desc, 1); + if (ret) + goto out; + } + + shared_desc->highcnt++; + proxy->voted_high = true; + + goto out; + } + + /* Desired value is low. */ + if (!proxy->voted_high) + /* We didn't vote for high, nothing to do. */ + goto out; + + /* We previously voted for high. */ + if (shared_desc->highcnt == 1) { + /* This is the last remaining vote for high, set value to low. */ + ret = set_func(desc, 0); + if (ret) + goto out; + } + + shared_desc->highcnt--; + proxy->voted_high = false; + +out: + if (shared_desc->highcnt) + dev_dbg(proxy->dev, + "Voted for value '%s', effective value is 'high', number of votes for 'high': %u\n", + str_high_low(value), shared_desc->highcnt); + else + dev_dbg(proxy->dev, "Voted for value 'low', effective value is 'low'\n"); + + return ret; +} + +static int gpio_shared_proxy_request(struct gpio_chip *gc, unsigned int offset) +{ + struct gpio_shared_proxy_data *proxy = gpiochip_get_data(gc); + struct gpio_shared_desc *shared_desc = proxy->shared_desc; + + guard(gpio_shared_desc_lock)(shared_desc); + + proxy->shared_desc->usecnt++; + + dev_dbg(proxy->dev, "Shared GPIO requested, number of users: %u\n", + proxy->shared_desc->usecnt); + + return 0; +} + +static void gpio_shared_proxy_free(struct gpio_chip *gc, unsigned int offset) +{ + struct gpio_shared_proxy_data *proxy = gpiochip_get_data(gc); + struct gpio_shared_desc *shared_desc = proxy->shared_desc; + + guard(gpio_shared_desc_lock)(shared_desc); + + proxy->shared_desc->usecnt--; + + dev_dbg(proxy->dev, "Shared GPIO freed, number of users: %u\n", + proxy->shared_desc->usecnt); +} + +static int gpio_shared_proxy_set_config(struct gpio_chip *gc, + unsigned int offset, unsigned long cfg) +{ + struct gpio_shared_proxy_data *proxy = gpiochip_get_data(gc); + struct gpio_shared_desc *shared_desc = proxy->shared_desc; + struct gpio_desc *desc = shared_desc->desc; + int ret; + + guard(gpio_shared_desc_lock)(shared_desc); + + if (shared_desc->usecnt > 1) { + if (shared_desc->cfg != cfg) { + dev_dbg(proxy->dev, + "Shared GPIO's configuration already set, accepting changes but users may conflict!!\n"); + } else { + dev_dbg(proxy->dev, "Equal config requested, nothing to do\n"); + return 0; + } + } + + ret = gpiod_set_config(desc, cfg); + if (ret && ret != -ENOTSUPP) + return ret; + + shared_desc->cfg = cfg; + return 0; +} + +static int gpio_shared_proxy_direction_input(struct gpio_chip *gc, + unsigned int offset) +{ + struct gpio_shared_proxy_data *proxy = gpiochip_get_data(gc); + struct gpio_shared_desc *shared_desc = proxy->shared_desc; + struct gpio_desc *desc = shared_desc->desc; + int dir; + + guard(gpio_shared_desc_lock)(shared_desc); + + if (shared_desc->usecnt == 1) { + dev_dbg(proxy->dev, + "Only one user of this shared GPIO, allowing to set direction to input\n"); + + return gpiod_direction_input(desc); + } + + dir = gpiod_get_direction(desc); + if (dir < 0) + return dir; + + if (dir == GPIO_LINE_DIRECTION_OUT) { + dev_dbg(proxy->dev, + "Shared GPIO's direction already set to output, refusing to change\n"); + return -EPERM; + } + + return 0; +} + +static int gpio_shared_proxy_direction_output(struct gpio_chip *gc, + unsigned int offset, int value) +{ + struct gpio_shared_proxy_data *proxy = gpiochip_get_data(gc); + struct gpio_shared_desc *shared_desc = proxy->shared_desc; + struct gpio_desc *desc = shared_desc->desc; + int ret, dir; + + guard(gpio_shared_desc_lock)(shared_desc); + + if (shared_desc->usecnt == 1) { + dev_dbg(proxy->dev, + "Only one user of this shared GPIO, allowing to set direction to output with value '%s'\n", + str_high_low(value)); + + ret = gpiod_direction_output(desc, value); + if (ret) + return ret; + + if (value) { + proxy->voted_high = true; + shared_desc->highcnt = 1; + } else { + proxy->voted_high = false; + shared_desc->highcnt = 0; + } + + return 0; + } + + dir = gpiod_get_direction(desc); + if (dir < 0) + return dir; + + if (dir == GPIO_LINE_DIRECTION_IN) { + dev_dbg(proxy->dev, + "Shared GPIO's direction already set to input, refusing to change\n"); + return -EPERM; + } + + return gpio_shared_proxy_set_unlocked(proxy, gpiod_direction_output, value); +} + +static int gpio_shared_proxy_get(struct gpio_chip *gc, unsigned int offset) +{ + struct gpio_shared_proxy_data *proxy = gpiochip_get_data(gc); + + return gpiod_get_value(proxy->shared_desc->desc); +} + +static int gpio_shared_proxy_get_cansleep(struct gpio_chip *gc, + unsigned int offset) +{ + struct gpio_shared_proxy_data *proxy = gpiochip_get_data(gc); + + return gpiod_get_value_cansleep(proxy->shared_desc->desc); +} + +static int gpio_shared_proxy_do_set(struct gpio_shared_proxy_data *proxy, + int (*set_func)(struct gpio_desc *desc, int value), + int value) +{ + guard(gpio_shared_desc_lock)(proxy->shared_desc); + + return gpio_shared_proxy_set_unlocked(proxy, set_func, value); +} + +static int gpio_shared_proxy_set(struct gpio_chip *gc, unsigned int offset, + int value) +{ + struct gpio_shared_proxy_data *proxy = gpiochip_get_data(gc); + + return gpio_shared_proxy_do_set(proxy, gpiod_set_value, value); +} + +static int gpio_shared_proxy_set_cansleep(struct gpio_chip *gc, + unsigned int offset, int value) +{ + struct gpio_shared_proxy_data *proxy = gpiochip_get_data(gc); + + return gpio_shared_proxy_do_set(proxy, gpiod_set_value_cansleep, value); +} + +static int gpio_shared_proxy_get_direction(struct gpio_chip *gc, + unsigned int offset) +{ + struct gpio_shared_proxy_data *proxy = gpiochip_get_data(gc); + + return gpiod_get_direction(proxy->shared_desc->desc); +} + +static int gpio_shared_proxy_to_irq(struct gpio_chip *gc, unsigned int offset) +{ + struct gpio_shared_proxy_data *proxy = gpiochip_get_data(gc); + + return gpiod_to_irq(proxy->shared_desc->desc); +} + +static int gpio_shared_proxy_probe(struct auxiliary_device *adev, + const struct auxiliary_device_id *id) +{ + struct gpio_shared_proxy_data *proxy; + struct gpio_shared_desc *shared_desc; + struct device *dev = &adev->dev; + struct gpio_chip *gc; + + shared_desc = devm_gpiod_shared_get(dev); + if (IS_ERR(shared_desc)) + return PTR_ERR(shared_desc); + + proxy = devm_kzalloc(dev, sizeof(*proxy), GFP_KERNEL); + if (!proxy) + return -ENOMEM; + + proxy->shared_desc = shared_desc; + proxy->dev = dev; + + gc = &proxy->gc; + gc->base = -1; + gc->ngpio = 1; + gc->label = dev_name(dev); + gc->parent = dev; + gc->owner = THIS_MODULE; + gc->can_sleep = shared_desc->can_sleep; + + gc->request = gpio_shared_proxy_request; + gc->free = gpio_shared_proxy_free; + gc->set_config = gpio_shared_proxy_set_config; + gc->direction_input = gpio_shared_proxy_direction_input; + gc->direction_output = gpio_shared_proxy_direction_output; + if (gc->can_sleep) { + gc->set = gpio_shared_proxy_set_cansleep; + gc->get = gpio_shared_proxy_get_cansleep; + } else { + gc->set = gpio_shared_proxy_set; + gc->get = gpio_shared_proxy_get; + } + gc->get_direction = gpio_shared_proxy_get_direction; + gc->to_irq = gpio_shared_proxy_to_irq; + + return devm_gpiochip_add_data(dev, &proxy->gc, proxy); +} + +static const struct auxiliary_device_id gpio_shared_proxy_id_table[] = { + { .name = "gpiolib_shared.proxy" }, + {}, +}; +MODULE_DEVICE_TABLE(auxiliary, gpio_shared_proxy_id_table); + +static struct auxiliary_driver gpio_shared_proxy_driver = { + .driver = { + .name = "gpio-shared-proxy", + }, + .probe = gpio_shared_proxy_probe, + .id_table = gpio_shared_proxy_id_table, +}; +module_auxiliary_driver(gpio_shared_proxy_driver); + +MODULE_AUTHOR("Bartosz Golaszewski "); +MODULE_DESCRIPTION("Shared GPIO mux driver."); +MODULE_LICENSE("GPL"); diff --git a/drivers/gpio/gpio-tb10x.c b/drivers/gpio/gpio-tb10x.c index 09a448ce3eec2f..3c8fd322a713a5 100644 --- a/drivers/gpio/gpio-tb10x.c +++ b/drivers/gpio/gpio-tb10x.c @@ -50,25 +50,6 @@ static inline u32 tb10x_reg_read(struct tb10x_gpio *gpio, unsigned int offs) return ioread32(gpio->base + offs); } -static inline void tb10x_reg_write(struct tb10x_gpio *gpio, unsigned int offs, - u32 val) -{ - iowrite32(val, gpio->base + offs); -} - -static inline void tb10x_set_bits(struct tb10x_gpio *gpio, unsigned int offs, - u32 mask, u32 val) -{ - u32 r; - - guard(gpio_generic_lock_irqsave)(&gpio->chip); - - r = tb10x_reg_read(gpio, offs); - r = (r & ~mask) | (val & mask); - - tb10x_reg_write(gpio, offs, r); -} - static int tb10x_gpio_to_irq(struct gpio_chip *chip, unsigned offset) { struct tb10x_gpio *tb10x_gpio = gpiochip_get_data(chip); diff --git a/drivers/gpio/gpiolib-cdev.c b/drivers/gpio/gpiolib-cdev.c index 175836467f216a..d8d93059ac04c8 100644 --- a/drivers/gpio/gpiolib-cdev.c +++ b/drivers/gpio/gpiolib-cdev.c @@ -2548,10 +2548,17 @@ static int lineinfo_changed_notify(struct notifier_block *nb, container_of(nb, struct gpio_chardev_data, lineinfo_changed_nb); struct lineinfo_changed_ctx *ctx; struct gpio_desc *desc = data; + struct file *fp; if (!test_bit(gpio_chip_hwgpio(desc), cdev->watched_lines)) return NOTIFY_DONE; + /* Keep the file descriptor alive for the duration of the notification. */ + fp = get_file_active(&cdev->fp); + if (!fp) + /* Chardev file descriptor was or is being released. */ + return NOTIFY_DONE; + /* * If this is called from atomic context (for instance: with a spinlock * taken by the atomic notifier chain), any sleeping calls must be done @@ -2575,8 +2582,6 @@ static int lineinfo_changed_notify(struct notifier_block *nb, /* Keep the GPIO device alive until we emit the event. */ ctx->gdev = gpio_device_get(desc->gdev); ctx->cdev = cdev; - /* Keep the file descriptor alive too. */ - get_file(ctx->cdev->fp); INIT_WORK(&ctx->work, lineinfo_changed_func); queue_work(ctx->gdev->line_state_wq, &ctx->work); diff --git a/drivers/gpio/gpiolib-shared.c b/drivers/gpio/gpiolib-shared.c new file mode 100644 index 00000000000000..fa1d16635ea781 --- /dev/null +++ b/drivers/gpio/gpiolib-shared.c @@ -0,0 +1,558 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2025 Linaro Ltd. + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gpiolib.h" +#include "gpiolib-shared.h" + +/* Represents a single reference to a GPIO pin. */ +struct gpio_shared_ref { + struct list_head list; + /* Firmware node associated with this GPIO's consumer. */ + struct fwnode_handle *fwnode; + /* GPIO flags this consumer uses for the request. */ + enum gpiod_flags flags; + char *con_id; + int dev_id; + struct auxiliary_device adev; + struct gpiod_lookup_table *lookup; +}; + +/* Represents a single GPIO pin. */ +struct gpio_shared_entry { + struct list_head list; + /* Firmware node associated with the GPIO controller. */ + struct fwnode_handle *fwnode; + /* Hardware offset of the GPIO within its chip. */ + unsigned int offset; + /* Index in the property value array. */ + size_t index; + struct gpio_shared_desc *shared_desc; + struct kref ref; + struct list_head refs; +}; + +static LIST_HEAD(gpio_shared_list); +static DEFINE_MUTEX(gpio_shared_lock); +static DEFINE_IDA(gpio_shared_ida); + +static struct gpio_shared_entry * +gpio_shared_find_entry(struct fwnode_handle *controller_node, + unsigned int offset) +{ + struct gpio_shared_entry *entry; + + list_for_each_entry(entry, &gpio_shared_list, list) { + if (entry->fwnode == controller_node && entry->offset == offset) + return entry; + } + + return NULL; +} + +#if IS_ENABLED(CONFIG_OF) +static int gpio_shared_of_traverse(struct device_node *curr) +{ + struct gpio_shared_entry *entry; + size_t con_id_len, suffix_len; + struct fwnode_handle *fwnode; + struct of_phandle_args args; + struct property *prop; + unsigned int offset; + const char *suffix; + int ret, count, i; + + for_each_property_of_node(curr, prop) { + /* + * The standard name for a GPIO property is "foo-gpios" + * or "foo-gpio". Some bindings also use "gpios" or "gpio". + * There are some legacy device-trees which have a different + * naming convention and for which we have rename quirks in + * place in gpiolib-of.c. I don't think any of them require + * support for shared GPIOs so for now let's just ignore + * them. We can always just export the quirk list and + * iterate over it here. + */ + if (!strends(prop->name, "-gpios") && + !strends(prop->name, "-gpio") && + strcmp(prop->name, "gpios") != 0 && + strcmp(prop->name, "gpio") != 0) + continue; + + count = of_count_phandle_with_args(curr, prop->name, + "#gpio-cells"); + if (count <= 0) + continue; + + for (i = 0; i < count; i++) { + struct device_node *np __free(device_node) = NULL; + + ret = of_parse_phandle_with_args(curr, prop->name, + "#gpio-cells", i, + &args); + if (ret) + continue; + + np = args.np; + + if (!of_property_present(np, "gpio-controller")) + continue; + + /* + * We support 1, 2 and 3 cell GPIO bindings in the + * kernel currently. There's only one old MIPS dts that + * has a one-cell binding but there's no associated + * consumer so it may as well be an error. There don't + * seem to be any 3-cell users of non-exclusive GPIOs, + * so we can skip this as well. Let's occupy ourselves + * with the predominant 2-cell binding with the first + * cell indicating the hardware offset of the GPIO and + * the second defining the GPIO flags of the request. + */ + if (args.args_count != 2) + continue; + + fwnode = of_fwnode_handle(args.np); + offset = args.args[0]; + + entry = gpio_shared_find_entry(fwnode, offset); + if (!entry) { + entry = kzalloc(sizeof(*entry), GFP_KERNEL); + if (!entry) + return -ENOMEM; + + entry->fwnode = fwnode_handle_get(fwnode); + entry->offset = offset; + entry->index = count; + INIT_LIST_HEAD(&entry->refs); + + list_add_tail(&entry->list, &gpio_shared_list); + } + + struct gpio_shared_ref *ref __free(kfree) = + kzalloc(sizeof(*ref), GFP_KERNEL); + if (!ref) + return -ENOMEM; + + ref->fwnode = fwnode_handle_get(of_fwnode_handle(curr)); + ref->flags = args.args[1]; + + if (strends(prop->name, "gpios")) + suffix = "-gpios"; + else if (strends(prop->name, "gpio")) + suffix = "-gpio"; + else + suffix = NULL; + if (!suffix) + continue; + + /* We only set con_id if there's actually one. */ + if (strcmp(prop->name, "gpios") && strcmp(prop->name, "gpio")) { + ref->con_id = kstrdup(prop->name, GFP_KERNEL); + if (!ref->con_id) + return -ENOMEM; + + con_id_len = strlen(ref->con_id); + suffix_len = strlen(suffix); + + ref->con_id[con_id_len - suffix_len] = '\0'; + } + + ref->dev_id = ida_alloc(&gpio_shared_ida, GFP_KERNEL); + if (ref->dev_id < 0) { + kfree(ref->con_id); + return -ENOMEM; + } + + if (!list_empty(&entry->refs)) + pr_debug("GPIO %u at %s is shared by multiple firmware nodes\n", + entry->offset, fwnode_get_name(entry->fwnode)); + + list_add_tail(&no_free_ptr(ref)->list, &entry->refs); + } + } + + for_each_child_of_node_scoped(curr, child) { + ret = gpio_shared_of_traverse(child); + if (ret) + return ret; + } + + return 0; +} + +static int gpio_shared_of_scan(void) +{ + return gpio_shared_of_traverse(of_root); +} +#else +static int gpio_shared_of_scan(void) +{ + return 0; +} +#endif /* CONFIG_OF */ + +static void gpio_shared_adev_release(struct device *dev) +{ + +} + +static int gpio_shared_make_adev(struct gpio_device *gdev, + struct gpio_shared_ref *ref) +{ + struct auxiliary_device *adev = &ref->adev; + int ret; + + lockdep_assert_held(&gpio_shared_lock); + + memset(adev, 0, sizeof(*adev)); + + adev->id = ref->dev_id; + adev->name = "proxy"; + adev->dev.parent = gdev->dev.parent; + adev->dev.release = gpio_shared_adev_release; + + ret = auxiliary_device_init(adev); + if (ret) + return ret; + + ret = auxiliary_device_add(adev); + if (ret) { + auxiliary_device_uninit(adev); + return ret; + } + + pr_debug("Created an auxiliary GPIO proxy %s for GPIO device %s\n", + dev_name(&adev->dev), gpio_device_get_label(gdev)); + + return 0; +} + +int gpio_shared_add_proxy_lookup(struct device *consumer, unsigned long lflags) +{ + const char *dev_id = dev_name(consumer); + struct gpio_shared_entry *entry; + struct gpio_shared_ref *ref; + + struct gpiod_lookup_table *lookup __free(kfree) = + kzalloc(struct_size(lookup, table, 2), GFP_KERNEL); + if (!lookup) + return -ENOMEM; + + guard(mutex)(&gpio_shared_lock); + + list_for_each_entry(entry, &gpio_shared_list, list) { + list_for_each_entry(ref, &entry->refs, list) { + if (!device_match_fwnode(consumer, ref->fwnode)) + continue; + + /* We've already done that on a previous request. */ + if (ref->lookup) + return 0; + + char *key __free(kfree) = + kasprintf(GFP_KERNEL, + KBUILD_MODNAME ".proxy.%u", + ref->adev.id); + if (!key) + return -ENOMEM; + + pr_debug("Adding machine lookup entry for a shared GPIO for consumer %s, with key '%s' and con_id '%s'\n", + dev_id, key, ref->con_id ?: "none"); + + lookup->dev_id = dev_id; + lookup->table[0] = GPIO_LOOKUP(no_free_ptr(key), 0, + ref->con_id, lflags); + + gpiod_add_lookup_table(no_free_ptr(lookup)); + + return 0; + } + } + + /* We warn here because this can only happen if the programmer borked. */ + WARN_ON(1); + return -ENOENT; +} + +static void gpio_shared_remove_adev(struct auxiliary_device *adev) +{ + lockdep_assert_held(&gpio_shared_lock); + + auxiliary_device_uninit(adev); + auxiliary_device_delete(adev); +} + +int gpio_device_setup_shared(struct gpio_device *gdev) +{ + struct gpio_shared_entry *entry; + struct gpio_shared_ref *ref; + unsigned long *flags; + int ret; + + guard(mutex)(&gpio_shared_lock); + + list_for_each_entry(entry, &gpio_shared_list, list) { + list_for_each_entry(ref, &entry->refs, list) { + if (gdev->dev.parent == &ref->adev.dev) { + /* + * This is a shared GPIO proxy. Mark its + * descriptor as such and return here. + */ + __set_bit(GPIOD_FLAG_SHARED_PROXY, + &gdev->descs[0].flags); + return 0; + } + } + } + + /* + * This is not a shared GPIO proxy but it still may be the device + * exposing shared pins. Find them and create the proxy devices. + */ + list_for_each_entry(entry, &gpio_shared_list, list) { + if (!device_match_fwnode(&gdev->dev, entry->fwnode)) + continue; + + if (list_count_nodes(&entry->refs) <= 1) + continue; + + flags = &gdev->descs[entry->offset].flags; + + __set_bit(GPIOD_FLAG_SHARED, flags); + /* + * Shared GPIOs are not requested via the normal path. Make + * them inaccessible to anyone even before we register the + * chip. + */ + __set_bit(GPIOD_FLAG_REQUESTED, flags); + + pr_debug("GPIO %u owned by %s is shared by multiple consumers\n", + entry->offset, gpio_device_get_label(gdev)); + + list_for_each_entry(ref, &entry->refs, list) { + pr_debug("Setting up a shared GPIO entry for %s\n", + fwnode_get_name(ref->fwnode)); + + ret = gpio_shared_make_adev(gdev, ref); + if (ret) + return ret; + } + } + + return 0; +} + +void gpio_device_teardown_shared(struct gpio_device *gdev) +{ + struct gpio_shared_entry *entry; + struct gpio_shared_ref *ref; + + guard(mutex)(&gpio_shared_lock); + + list_for_each_entry(entry, &gpio_shared_list, list) { + if (!device_match_fwnode(&gdev->dev, entry->fwnode)) + continue; + + list_for_each_entry(ref, &entry->refs, list) { + gpiod_remove_lookup_table(ref->lookup); + kfree(ref->lookup->table[0].key); + kfree(ref->lookup); + ref->lookup = NULL; + gpio_shared_remove_adev(&ref->adev); + } + } +} + +static void gpio_shared_release(struct kref *kref) +{ + struct gpio_shared_entry *entry = + container_of(kref, struct gpio_shared_entry, ref); + struct gpio_shared_desc *shared_desc = entry->shared_desc; + + guard(mutex)(&gpio_shared_lock); + + gpio_device_put(shared_desc->desc->gdev); + if (shared_desc->can_sleep) + mutex_destroy(&shared_desc->mutex); + kfree(shared_desc); + entry->shared_desc = NULL; +} + +static void gpiod_shared_put(void *data) +{ + struct gpio_shared_entry *entry = data; + + lockdep_assert_not_held(&gpio_shared_lock); + + kref_put(&entry->ref, gpio_shared_release); +} + +static struct gpio_shared_desc * +gpiod_shared_desc_create(struct gpio_shared_entry *entry) +{ + struct gpio_shared_desc *shared_desc; + struct gpio_device *gdev; + + shared_desc = kzalloc(sizeof(*shared_desc), GFP_KERNEL); + if (!shared_desc) + return ERR_PTR(-ENOMEM); + + gdev = gpio_device_find_by_fwnode(entry->fwnode); + if (!gdev) { + kfree(shared_desc); + return ERR_PTR(-EPROBE_DEFER); + } + + shared_desc->desc = &gdev->descs[entry->offset]; + shared_desc->can_sleep = gpiod_cansleep(shared_desc->desc); + if (shared_desc->can_sleep) + mutex_init(&shared_desc->mutex); + else + spin_lock_init(&shared_desc->spinlock); + + return shared_desc; +} + +static struct gpio_shared_entry *gpiod_shared_find(struct auxiliary_device *adev) +{ + struct gpio_shared_desc *shared_desc; + struct gpio_shared_entry *entry; + struct gpio_shared_ref *ref; + + guard(mutex)(&gpio_shared_lock); + + list_for_each_entry(entry, &gpio_shared_list, list) { + list_for_each_entry(ref, &entry->refs, list) { + if (adev != &ref->adev) + continue; + + if (entry->shared_desc) { + kref_get(&entry->ref); + return entry; + } + + shared_desc = gpiod_shared_desc_create(entry); + if (IS_ERR(shared_desc)) + return ERR_CAST(shared_desc); + + kref_init(&entry->ref); + entry->shared_desc = shared_desc; + + pr_debug("Device %s acquired a reference to the shared GPIO %u owned by %s\n", + dev_name(&adev->dev), gpio_chip_hwgpio(shared_desc->desc), + gpio_device_get_label(shared_desc->desc->gdev)); + + + return entry; + } + } + + return ERR_PTR(-ENOENT); +} + +struct gpio_shared_desc *devm_gpiod_shared_get(struct device *dev) +{ + struct gpio_shared_entry *entry; + int ret; + + entry = gpiod_shared_find(to_auxiliary_dev(dev)); + if (IS_ERR(entry)) + return ERR_CAST(entry); + + ret = devm_add_action_or_reset(dev, gpiod_shared_put, entry); + if (ret) + return ERR_PTR(ret); + + return entry->shared_desc; +} +EXPORT_SYMBOL_GPL(devm_gpiod_shared_get); + +static void gpio_shared_drop_ref(struct gpio_shared_ref *ref) +{ + list_del(&ref->list); + kfree(ref->con_id); + ida_free(&gpio_shared_ida, ref->dev_id); + fwnode_handle_put(ref->fwnode); + kfree(ref); +} + +static void gpio_shared_drop_entry(struct gpio_shared_entry *entry) +{ + list_del(&entry->list); + fwnode_handle_put(entry->fwnode); + kfree(entry); +} + +/* + * This is only called if gpio_shared_init() fails so it's in fact __init and + * not __exit. + */ +static void __init gpio_shared_teardown(void) +{ + struct gpio_shared_entry *entry, *epos; + struct gpio_shared_ref *ref, *rpos; + + list_for_each_entry_safe(entry, epos, &gpio_shared_list, list) { + list_for_each_entry_safe(ref, rpos, &entry->refs, list) + gpio_shared_drop_ref(ref); + + gpio_shared_drop_entry(entry); + } +} + +static void gpio_shared_free_exclusive(void) +{ + struct gpio_shared_entry *entry, *epos; + + list_for_each_entry_safe(entry, epos, &gpio_shared_list, list) { + if (list_count_nodes(&entry->refs) > 1) + continue; + + gpio_shared_drop_ref(list_first_entry(&entry->refs, + struct gpio_shared_ref, + list)); + gpio_shared_drop_entry(entry); + } +} + +static int __init gpio_shared_init(void) +{ + int ret; + + /* Right now, we only support OF-based systems. */ + ret = gpio_shared_of_scan(); + if (ret) { + gpio_shared_teardown(); + pr_err("Failed to scan OF nodes for shared GPIOs: %d\n", ret); + return ret; + } + + gpio_shared_free_exclusive(); + + pr_debug("Finished scanning firmware nodes for shared GPIOs\n"); + return 0; +} +postcore_initcall(gpio_shared_init); diff --git a/drivers/gpio/gpiolib-shared.h b/drivers/gpio/gpiolib-shared.h new file mode 100644 index 00000000000000..667dbdff358506 --- /dev/null +++ b/drivers/gpio/gpiolib-shared.h @@ -0,0 +1,71 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef __LINUX_GPIO_SHARED_H +#define __LINUX_GPIO_SHARED_H + +#include +#include +#include +#include + +struct gpio_device; +struct gpio_desc; +struct device; + +#if IS_ENABLED(CONFIG_GPIO_SHARED) + +int gpio_device_setup_shared(struct gpio_device *gdev); +void gpio_device_teardown_shared(struct gpio_device *gdev); +int gpio_shared_add_proxy_lookup(struct device *consumer, unsigned long lflags); + +#else + +static inline int gpio_device_setup_shared(struct gpio_device *gdev) +{ + return 0; +} + +static inline void gpio_device_teardown_shared(struct gpio_device *gdev) { } + +static inline int gpio_shared_add_proxy_lookup(struct device *consumer, + unsigned long lflags) +{ + return 0; +} + +#endif /* CONFIG_GPIO_SHARED */ + +struct gpio_shared_desc { + struct gpio_desc *desc; + bool can_sleep; + unsigned long cfg; + unsigned int usecnt; + unsigned int highcnt; + union { + struct mutex mutex; + spinlock_t spinlock; + }; +}; + +struct gpio_shared_desc *devm_gpiod_shared_get(struct device *dev); + +DEFINE_LOCK_GUARD_1(gpio_shared_desc_lock, struct gpio_shared_desc, + if (_T->lock->can_sleep) + mutex_lock(&_T->lock->mutex); + else + spin_lock_irqsave(&_T->lock->spinlock, _T->flags), + if (_T->lock->can_sleep) + mutex_unlock(&_T->lock->mutex); + else + spin_unlock_irqrestore(&_T->lock->spinlock, _T->flags), + unsigned long flags) + +static inline void gpio_shared_lockdep_assert(struct gpio_shared_desc *shared_desc) +{ + if (shared_desc->can_sleep) + lockdep_assert_held(&shared_desc->mutex); + else + lockdep_assert_held(&shared_desc->spinlock); +} + +#endif /* __LINUX_GPIO_SHARED_H */ diff --git a/drivers/gpio/gpiolib-swnode.c b/drivers/gpio/gpiolib-swnode.c index f21dbc28cf2c8c..e3806db1c0e077 100644 --- a/drivers/gpio/gpiolib-swnode.c +++ b/drivers/gpio/gpiolib-swnode.c @@ -41,7 +41,7 @@ static struct gpio_device *swnode_get_gpio_device(struct fwnode_handle *fwnode) !strcmp(gdev_node->name, GPIOLIB_SWNODE_UNDEFINED_NAME)) return ERR_PTR(-ENOENT); - gdev = gpio_device_find_by_label(gdev_node->name); + gdev = gpio_device_find_by_fwnode(fwnode); return gdev ?: ERR_PTR(-EPROBE_DEFER); } diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 9952e412da505c..476fcc897d90d5 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -37,6 +37,7 @@ #include "gpiolib-acpi.h" #include "gpiolib-cdev.h" #include "gpiolib-of.h" +#include "gpiolib-shared.h" #include "gpiolib-swnode.h" #include "gpiolib-sysfs.h" #include "gpiolib.h" @@ -1200,6 +1201,10 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data, if (ret) goto err_remove_irqchip_mask; + ret = gpio_device_setup_shared(gdev); + if (ret) + goto err_remove_irqchip; + /* * By first adding the chardev, and then adding the device, * we get a device node entry in sysfs under @@ -1211,10 +1216,13 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data, if (gpiolib_initialized) { ret = gpiochip_setup_dev(gdev); if (ret) - goto err_remove_irqchip; + goto err_teardown_shared; } + return 0; +err_teardown_shared: + gpio_device_teardown_shared(gdev); err_remove_irqchip: gpiochip_irqchip_remove(gc); err_remove_irqchip_mask: @@ -1283,6 +1291,7 @@ void gpiochip_remove(struct gpio_chip *gc) /* Numb the device, cancelling all outstanding operations */ rcu_assign_pointer(gdev->chip, NULL); synchronize_srcu(&gdev->srcu); + gpio_device_teardown_shared(gdev); gpiochip_irqchip_remove(gc); acpi_gpiochip_remove(gc); of_gpiochip_remove(gc); @@ -3981,6 +3990,26 @@ int gpiod_set_consumer_name(struct gpio_desc *desc, const char *name) } EXPORT_SYMBOL_GPL(gpiod_set_consumer_name); +/** + * gpiod_is_shared() - check if this GPIO can be shared by multiple consumers + * @desc: GPIO to inspect + * + * Returns: + * True if this GPIO can be shared by multiple consumers at once. False if it's + * a regular, exclusive GPIO. + * + * Note: + * This function returning true does not mean that this GPIO is currently being + * shared. It means the GPIO core has registered the fact that the firmware + * configuration indicates that it can be shared by multiple consumers and is + * in charge of arbitrating the access. + */ +bool gpiod_is_shared(const struct gpio_desc *desc) +{ + return test_bit(GPIOD_FLAG_SHARED_PROXY, &desc->flags); +} +EXPORT_SYMBOL_GPL(gpiod_is_shared); + /** * gpiod_to_irq() - return the IRQ corresponding to a GPIO * @desc: gpio whose IRQ will be returned (already requested) @@ -4652,11 +4681,29 @@ struct gpio_desc *gpiod_find_and_request(struct device *consumer, scoped_guard(srcu, &gpio_devices_srcu) { desc = gpiod_fwnode_lookup(fwnode, consumer, con_id, idx, &flags, &lookupflags); + if (!IS_ERR_OR_NULL(desc) && + test_bit(GPIOD_FLAG_SHARED, &desc->flags)) { + /* + * We're dealing with a GPIO shared by multiple + * consumers. This is the moment to add the machine + * lookup table for the proxy device as previously + * we only knew the consumer's fwnode. + */ + ret = gpio_shared_add_proxy_lookup(consumer, lookupflags); + if (ret) + return ERR_PTR(ret); + + /* Trigger platform lookup for shared GPIO proxy. */ + desc = ERR_PTR(-ENOENT); + /* Trigger it even for fwnode-only gpiod_get(). */ + platform_lookup_allowed = true; + } + if (gpiod_not_found(desc) && platform_lookup_allowed) { /* * Either we are not using DT or ACPI, or their lookup - * did not return a result. In that case, use platform - * lookup as a fallback. + * did not return a result or this is a shared GPIO. In + * that case, use platform lookup as a fallback. */ dev_dbg(consumer, "using lookup tables for GPIO lookup\n"); @@ -4679,14 +4726,19 @@ struct gpio_desc *gpiod_find_and_request(struct device *consumer, return ERR_PTR(ret); /* - * This happens when there are several consumers for - * the same GPIO line: we just return here without - * further initialization. It is a bit of a hack. - * This is necessary to support fixed regulators. + * This happens when there are several consumers for the same + * GPIO line: we just return here without further + * initialization. It's a hack introduced long ago to support + * fixed regulators. We now have a better solution with + * automated scanning where affected platforms just need to + * select the provided Kconfig option. * - * FIXME: Make this more sane and safe. + * FIXME: Remove the GPIOD_FLAGS_BIT_NONEXCLUSIVE flag after + * making sure all platforms use the new mechanism. */ - dev_info(consumer, "nonexclusive access to GPIO for %s\n", name); + dev_info(consumer, + "nonexclusive access to GPIO for %s, consider updating your code to using gpio-shared-proxy\n", + name); return desc; } @@ -5296,6 +5348,8 @@ static void *gpiolib_seq_start(struct seq_file *s, loff_t *pos) struct gpio_device *gdev; loff_t index = *pos; + s->private = NULL; + priv = kzalloc(sizeof(*priv), GFP_KERNEL); if (!priv) return NULL; @@ -5329,7 +5383,11 @@ static void *gpiolib_seq_next(struct seq_file *s, void *v, loff_t *pos) static void gpiolib_seq_stop(struct seq_file *s, void *v) { - struct gpiolib_seq_priv *priv = s->private; + struct gpiolib_seq_priv *priv; + + priv = s->private; + if (!priv) + return; srcu_read_unlock(&gpio_devices_srcu, priv->idx); kfree(priv); diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h index 2a003a7311e7ac..abd870fb4a3be8 100644 --- a/drivers/gpio/gpiolib.h +++ b/drivers/gpio/gpiolib.h @@ -204,6 +204,8 @@ struct gpio_desc { #define GPIOD_FLAG_EDGE_FALLING 17 /* GPIO CDEV detects falling edge events */ #define GPIOD_FLAG_EVENT_CLOCK_REALTIME 18 /* GPIO CDEV reports REALTIME timestamps in events */ #define GPIOD_FLAG_EVENT_CLOCK_HTE 19 /* GPIO CDEV reports hardware timestamps in events */ +#define GPIOD_FLAG_SHARED 20 /* GPIO is shared by multiple consumers */ +#define GPIOD_FLAG_SHARED_PROXY 21 /* GPIO is a virtual proxy to a physically shared pin. */ /* Connection label */ struct gpio_desc_label __rcu *label; diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index 4b2f7d79427527..da2565e6de71d8 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -245,7 +245,7 @@ always-$(CONFIG_DRM_HEADER_TEST) += \ quiet_cmd_hdrtest = HDRTEST $(patsubst %.hdrtest,%.h,$@) cmd_hdrtest = \ $(CC) $(c_flags) -fsyntax-only -x c /dev/null -include $< -include $<; \ - PYTHONDONTWRITEBYTECODE=1 $(KERNELDOC) -none $(if $(CONFIG_WERROR)$(CONFIG_DRM_WERROR),-Werror) $<; \ + PYTHONDONTWRITEBYTECODE=1 $(PYTHON3) $(KERNELDOC) -none $(if $(CONFIG_WERROR)$(CONFIG_DRM_WERROR),-Werror) $<; \ touch $@ $(obj)/%.hdrtest: $(src)/%.h FORCE diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c index a2ca9acf8c4ea8..923f0fa7350cf8 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c @@ -1267,6 +1267,10 @@ static int unmap_bo_from_gpuvm(struct kgd_mem *mem, (void)amdgpu_vm_bo_unmap(adev, bo_va, entry->va); + /* VM entity stopped if process killed, don't clear freed pt bo */ + if (!amdgpu_vm_ready(vm)) + return 0; + (void)amdgpu_vm_clear_freed(adev, vm, &bo_va->last_pt_update); (void)amdgpu_sync_fence(sync, bo_va->last_pt_update, GFP_KERNEL); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c index f5d5c45ddc0d15..afedea02188dd5 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c @@ -236,7 +236,7 @@ static int amdgpu_ctx_init_entity(struct amdgpu_ctx *ctx, u32 hw_ip, r = amdgpu_xcp_select_scheds(adev, hw_ip, hw_prio, fpriv, &num_scheds, &scheds); if (r) - goto cleanup_entity; + goto error_free_entity; } /* disable load balance if the hw engine retains context among dependent jobs */ diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 3d032c4e2dce1d..076bbc09f30cea 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -3414,10 +3414,11 @@ int amdgpu_device_set_pg_state(struct amdgpu_device *adev, (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GFX || adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_SDMA)) continue; - /* skip CG for VCE/UVD, it's handled specially */ + /* skip CG for VCE/UVD/VPE, it's handled specially */ if (adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_UVD && adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_VCE && adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_VCN && + adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_VPE && adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_JPEG && adev->ip_blocks[i].version->funcs->set_powergating_state) { /* enable powergating to save power */ @@ -5243,10 +5244,6 @@ int amdgpu_device_suspend(struct drm_device *dev, bool notify_clients) if (amdgpu_sriov_vf(adev)) amdgpu_virt_release_full_gpu(adev, false); - r = amdgpu_dpm_notify_rlc_state(adev, false); - if (r) - return r; - return 0; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c index 8561ad7f618000..ed3bef1edfe44e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c @@ -82,6 +82,18 @@ static int amdgpu_dma_buf_attach(struct dma_buf *dmabuf, struct amdgpu_bo *bo = gem_to_amdgpu_bo(obj); struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev); + /* + * Disable peer-to-peer access for DCC-enabled VRAM surfaces on GFX12+. + * Such buffers cannot be safely accessed over P2P due to device-local + * compression metadata. Fallback to system-memory path instead. + * Device supports GFX12 (GC 12.x or newer) + * BO was created with the AMDGPU_GEM_CREATE_GFX12_DCC flag + * + */ + if (amdgpu_ip_version(adev, GC_HWIP, 0) >= IP_VERSION(12, 0, 0) && + bo->flags & AMDGPU_GEM_CREATE_GFX12_DCC) + attach->peer2peer = false; + if (!amdgpu_dmabuf_is_xgmi_accessible(attach_adev, bo) && pci_p2pdma_distance(adev->pdev, attach->dev, false) < 0) attach->peer2peer = false; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index 61268aa82df4d6..7333e19291cf93 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -2632,9 +2632,14 @@ static int amdgpu_pmops_suspend_noirq(struct device *dev) { struct drm_device *drm_dev = dev_get_drvdata(dev); struct amdgpu_device *adev = drm_to_adev(drm_dev); + int r; - if (amdgpu_acpi_should_gpu_reset(adev)) - return amdgpu_asic_reset(adev); + if (amdgpu_acpi_should_gpu_reset(adev)) { + amdgpu_device_lock_reset_domain(adev->reset_domain); + r = amdgpu_asic_reset(adev); + amdgpu_device_unlock_reset_domain(adev->reset_domain); + return r; + } return 0; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_isp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_isp.c index 9cddbf50442a40..37270c4dab8dd7 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_isp.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_isp.c @@ -280,6 +280,8 @@ int isp_kernel_buffer_alloc(struct device *dev, u64 size, if (ret) return ret; + /* Ensure *bo is NULL so a new BO will be created */ + *bo = NULL; ret = amdgpu_bo_create_kernel(adev, size, ISP_MC_ADDR_ALIGN, diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c index 8c0e5d03de50ba..aa7987d0806c6c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c @@ -2355,8 +2355,11 @@ static int psp_securedisplay_initialize(struct psp_context *psp) if (!ret && !psp->securedisplay_context.context.resp_status) { psp->securedisplay_context.context.initialized = true; mutex_init(&psp->securedisplay_context.mutex); - } else + } else { + /* don't try again */ + psp->securedisplay_context.context.bin_desc.size_bytes = 0; return ret; + } mutex_lock(&psp->securedisplay_context.mutex); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index aa9ee5dffa4551..9d568c16beb1e2 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c @@ -1372,7 +1372,7 @@ uint64_t amdgpu_ttm_tt_pde_flags(struct ttm_tt *ttm, struct ttm_resource *mem) mem->mem_type == AMDGPU_PL_MMIO_REMAP)) { flags |= AMDGPU_PTE_SYSTEM; - if (ttm->caching == ttm_cached) + if (ttm && ttm->caching == ttm_cached) flags |= AMDGPU_PTE_SNOOPED; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c index 761bad98da3ec4..4d0096d0baa9d0 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c @@ -151,15 +151,16 @@ void amdgpu_userq_fence_driver_process(struct amdgpu_userq_fence_driver *fence_d { struct amdgpu_userq_fence *userq_fence, *tmp; struct dma_fence *fence; + unsigned long flags; u64 rptr; int i; if (!fence_drv) return; + spin_lock_irqsave(&fence_drv->fence_list_lock, flags); rptr = amdgpu_userq_fence_read(fence_drv); - spin_lock(&fence_drv->fence_list_lock); list_for_each_entry_safe(userq_fence, tmp, &fence_drv->fences, link) { fence = &userq_fence->base; @@ -174,7 +175,7 @@ void amdgpu_userq_fence_driver_process(struct amdgpu_userq_fence_driver *fence_d list_del(&userq_fence->link); dma_fence_put(fence); } - spin_unlock(&fence_drv->fence_list_lock); + spin_unlock_irqrestore(&fence_drv->fence_list_lock, flags); } void amdgpu_userq_fence_driver_destroy(struct kref *ref) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index c1a801203949a3..b1aaef962ad993 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -2078,7 +2078,7 @@ int amdgpu_vm_bo_clear_mappings(struct amdgpu_device *adev, struct amdgpu_bo *bo = before->bo_va->base.bo; amdgpu_vm_it_insert(before, &vm->va); - if (before->flags & AMDGPU_PTE_PRT_FLAG(adev)) + if (before->flags & AMDGPU_VM_PAGE_PRT) amdgpu_vm_prt_get(adev); if (amdgpu_vm_is_bo_always_valid(vm, bo) && @@ -2093,7 +2093,7 @@ int amdgpu_vm_bo_clear_mappings(struct amdgpu_device *adev, struct amdgpu_bo *bo = after->bo_va->base.bo; amdgpu_vm_it_insert(after, &vm->va); - if (after->flags & AMDGPU_PTE_PRT_FLAG(adev)) + if (after->flags & AMDGPU_VM_PAGE_PRT) amdgpu_vm_prt_get(adev); if (amdgpu_vm_is_bo_always_valid(vm, bo) && diff --git a/drivers/gpu/drm/amd/amdgpu/aqua_vanjaram.c b/drivers/gpu/drm/amd/amdgpu/aqua_vanjaram.c index 811124ff88a884..f9e2edf5260bc5 100644 --- a/drivers/gpu/drm/amd/amdgpu/aqua_vanjaram.c +++ b/drivers/gpu/drm/amd/amdgpu/aqua_vanjaram.c @@ -407,7 +407,8 @@ static int aqua_vanjaram_switch_partition_mode(struct amdgpu_xcp_mgr *xcp_mgr, return -EINVAL; } - if (adev->kfd.init_complete && !amdgpu_in_reset(adev)) + if (adev->kfd.init_complete && !amdgpu_in_reset(adev) && + !adev->in_suspend) flags |= AMDGPU_XCP_OPS_KFD; if (flags & AMDGPU_XCP_OPS_KFD) { diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c index d61eb9f187c649..f2be16e700c41a 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c @@ -5872,9 +5872,9 @@ static void gfx_v11_0_ring_emit_ib_gfx(struct amdgpu_ring *ring, if (flags & AMDGPU_IB_PREEMPTED) control |= INDIRECT_BUFFER_PRE_RESUME(1); - if (vmid) + if (vmid && !ring->adev->gfx.rs64_enable) gfx_v11_0_ring_emit_de_meta(ring, - (!amdgpu_sriov_vf(ring->adev) && flags & AMDGPU_IB_PREEMPTED) ? true : false); + !amdgpu_sriov_vf(ring->adev) && (flags & AMDGPU_IB_PREEMPTED)); } amdgpu_ring_write(ring, header); diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v6_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v6_0.c index 7693b79534267e..80565392313f15 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v6_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v6_0.c @@ -3102,6 +3102,11 @@ static int gfx_v6_0_sw_init(struct amdgpu_ip_block *ip_block) return r; } + adev->gfx.gfx_supported_reset = + amdgpu_get_soft_full_reset_mask(&adev->gfx.gfx_ring[0]); + adev->gfx.compute_supported_reset = + amdgpu_get_soft_full_reset_mask(&adev->gfx.compute_ring[0]); + return r; } diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c index 5976ed55d9dbdb..2b7aba22ecc190 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c @@ -4399,6 +4399,11 @@ static int gfx_v7_0_sw_init(struct amdgpu_ip_block *ip_block) gfx_v7_0_gpu_early_init(adev); + adev->gfx.gfx_supported_reset = + amdgpu_get_soft_full_reset_mask(&adev->gfx.gfx_ring[0]); + adev->gfx.compute_supported_reset = + amdgpu_get_soft_full_reset_mask(&adev->gfx.compute_ring[0]); + return r; } diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c index 0856ff65288c0e..8a81713d97aac2 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c @@ -2023,6 +2023,11 @@ static int gfx_v8_0_sw_init(struct amdgpu_ip_block *ip_block) if (r) return r; + adev->gfx.gfx_supported_reset = + amdgpu_get_soft_full_reset_mask(&adev->gfx.gfx_ring[0]); + adev->gfx.compute_supported_reset = + amdgpu_get_soft_full_reset_mask(&adev->gfx.compute_ring[0]); + return 0; } diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c index 77f9d5b9a556be..c90cbe053ef37b 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c @@ -2292,7 +2292,9 @@ static int gfx_v9_4_3_cp_resume(struct amdgpu_device *adev) r = amdgpu_xcp_init(adev->xcp_mgr, num_xcp, mode); } else { - if (amdgpu_xcp_query_partition_mode(adev->xcp_mgr, + if (adev->in_suspend) + amdgpu_xcp_restore_partition_mode(adev->xcp_mgr); + else if (amdgpu_xcp_query_partition_mode(adev->xcp_mgr, AMDGPU_XCP_FL_NONE) == AMDGPU_UNKNOWN_COMPUTE_PARTITION_MODE) r = amdgpu_xcp_switch_partition_mode( diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v5_0_1.c b/drivers/gpu/drm/amd/amdgpu/jpeg_v5_0_1.c index baf097d2e1ac96..ab0bf880d3d8a5 100644 --- a/drivers/gpu/drm/amd/amdgpu/jpeg_v5_0_1.c +++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v5_0_1.c @@ -878,6 +878,7 @@ static const struct amdgpu_ring_funcs jpeg_v5_0_1_dec_ring_vm_funcs = { .get_rptr = jpeg_v5_0_1_dec_ring_get_rptr, .get_wptr = jpeg_v5_0_1_dec_ring_get_wptr, .set_wptr = jpeg_v5_0_1_dec_ring_set_wptr, + .parse_cs = amdgpu_jpeg_dec_parse_cs, .emit_frame_size = SOC15_FLUSH_GPU_TLB_NUM_WREG * 6 + SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 8 + diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c b/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c index 64b240b51f1aa7..a9be7a50502683 100644 --- a/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c @@ -142,13 +142,37 @@ static int psp_v11_0_init_microcode(struct psp_context *psp) return err; } -static int psp_v11_0_wait_for_bootloader(struct psp_context *psp) +static int psp_v11_wait_for_tos_unload(struct psp_context *psp) { struct amdgpu_device *adev = psp->adev; + uint32_t sol_reg1, sol_reg2; + int retry_loop; + /* Wait for the TOS to be unloaded */ + for (retry_loop = 0; retry_loop < 20; retry_loop++) { + sol_reg1 = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_81); + usleep_range(1000, 2000); + sol_reg2 = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_81); + if (sol_reg1 == sol_reg2) + return 0; + } + dev_err(adev->dev, "TOS unload failed, C2PMSG_33: %x C2PMSG_81: %x", + RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_33), + RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_81)); + + return -ETIME; +} + +static int psp_v11_0_wait_for_bootloader(struct psp_context *psp) +{ + struct amdgpu_device *adev = psp->adev; int ret; int retry_loop; + /* For a reset done at the end of S3, only wait for TOS to be unloaded */ + if (adev->in_s3 && !(adev->flags & AMD_IS_APU) && amdgpu_in_reset(adev)) + return psp_v11_wait_for_tos_unload(psp); + for (retry_loop = 0; retry_loop < 20; retry_loop++) { /* Wait for bootloader to signify that is ready having bit 31 of C2PMSG_35 set to 1 */ diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_3.c b/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_3.c index eacf4e93ba2fe4..cb7123ec1a5d1a 100644 --- a/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_3.c +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_3.c @@ -141,7 +141,7 @@ static int vcn_v4_0_3_late_init(struct amdgpu_ip_block *ip_block) adev->vcn.supported_reset = amdgpu_get_soft_full_reset_mask(&adev->vcn.inst[0].ring_enc[0]); - if (amdgpu_dpm_reset_vcn_is_supported(adev)) + if (amdgpu_dpm_reset_vcn_is_supported(adev) && !amdgpu_sriov_vf(adev)) adev->vcn.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE; return 0; diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_1.c b/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_1.c index 714350cabf2fc1..8bd457dea4cff9 100644 --- a/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_1.c +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_1.c @@ -122,7 +122,9 @@ static int vcn_v5_0_1_late_init(struct amdgpu_ip_block *ip_block) switch (amdgpu_ip_version(adev, MP0_HWIP, 0)) { case IP_VERSION(13, 0, 12): - if ((adev->psp.sos.fw_version >= 0x00450025) && amdgpu_dpm_reset_vcn_is_supported(adev)) + if ((adev->psp.sos.fw_version >= 0x00450025) && + amdgpu_dpm_reset_vcn_is_supported(adev) && + !amdgpu_sriov_vf(adev)) adev->vcn.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE; break; default: diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_queue.c b/drivers/gpu/drm/amd/amdkfd/kfd_queue.c index a65c67cf56ff37..f1e7583650c416 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_queue.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_queue.c @@ -297,16 +297,16 @@ int kfd_queue_acquire_buffers(struct kfd_process_device *pdd, struct queue_prope goto out_err_unreserve; } - if (properties->ctx_save_restore_area_size != topo_dev->node_props.cwsr_size) { - pr_debug("queue cwsr size 0x%x not equal to node cwsr size 0x%x\n", + if (properties->ctx_save_restore_area_size < topo_dev->node_props.cwsr_size) { + pr_debug("queue cwsr size 0x%x not sufficient for node cwsr size 0x%x\n", properties->ctx_save_restore_area_size, topo_dev->node_props.cwsr_size); err = -EINVAL; goto out_err_unreserve; } - total_cwsr_size = (topo_dev->node_props.cwsr_size + topo_dev->node_props.debug_memory_size) - * NUM_XCC(pdd->dev->xcc_mask); + total_cwsr_size = (properties->ctx_save_restore_area_size + + topo_dev->node_props.debug_memory_size) * NUM_XCC(pdd->dev->xcc_mask); total_cwsr_size = ALIGN(total_cwsr_size, PAGE_SIZE); err = kfd_queue_buffer_get(vm, (void *)properties->ctx_save_restore_area_address, @@ -352,8 +352,8 @@ int kfd_queue_release_buffers(struct kfd_process_device *pdd, struct queue_prope topo_dev = kfd_topology_device_by_id(pdd->dev->id); if (!topo_dev) return -EINVAL; - total_cwsr_size = (topo_dev->node_props.cwsr_size + topo_dev->node_props.debug_memory_size) - * NUM_XCC(pdd->dev->xcc_mask); + total_cwsr_size = (properties->ctx_save_restore_area_size + + topo_dev->node_props.debug_memory_size) * NUM_XCC(pdd->dev->xcc_mask); total_cwsr_size = ALIGN(total_cwsr_size, PAGE_SIZE); kfd_queue_buffer_svm_put(pdd, properties->ctx_save_restore_area_address, total_cwsr_size); diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c index 9d72411c33791f..74a1d3e1d52bee 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c @@ -3687,6 +3687,8 @@ svm_range_set_attr(struct kfd_process *p, struct mm_struct *mm, svm_range_apply_attrs(p, prange, nattr, attrs, &update_mapping); /* TODO: unmap ranges from GPU that lost access */ } + update_mapping |= !p->xnack_enabled && !list_empty(&remap_list); + list_for_each_entry_safe(prange, next, &remove_list, update_list) { pr_debug("unlink old 0x%p prange 0x%p [0x%lx 0x%lx]\n", prange->svms, prange, prange->start, diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index bfa3199591b67a..2a7a491a62e004 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -3563,6 +3563,7 @@ static int dm_resume(struct amdgpu_ip_block *ip_block) /* Do mst topology probing after resuming cached state*/ drm_connector_list_iter_begin(ddev, &iter); drm_for_each_connector_iter(connector, &iter) { + bool init = false; if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK) continue; @@ -3572,7 +3573,14 @@ static int dm_resume(struct amdgpu_ip_block *ip_block) aconnector->mst_root) continue; - drm_dp_mst_topology_queue_probe(&aconnector->mst_mgr); + scoped_guard(mutex, &aconnector->mst_mgr.lock) { + init = !aconnector->mst_mgr.mst_primary; + } + if (init) + dm_helpers_dp_mst_start_top_mgr(aconnector->dc_link->ctx, + aconnector->dc_link, false); + else + drm_dp_mst_topology_queue_probe(&aconnector->mst_mgr); } drm_connector_list_iter_end(&iter); @@ -3851,6 +3859,97 @@ void amdgpu_dm_update_connector_after_detect( update_subconnector_property(aconnector); } +static bool are_sinks_equal(const struct dc_sink *sink1, const struct dc_sink *sink2) +{ + if (!sink1 || !sink2) + return false; + if (sink1->sink_signal != sink2->sink_signal) + return false; + + if (sink1->dc_edid.length != sink2->dc_edid.length) + return false; + + if (memcmp(sink1->dc_edid.raw_edid, sink2->dc_edid.raw_edid, + sink1->dc_edid.length) != 0) + return false; + return true; +} + + +/** + * DOC: hdmi_hpd_debounce_work + * + * HDMI HPD debounce delay in milliseconds. When an HDMI display toggles HPD + * (such as during power save transitions), this delay determines how long to + * wait before processing the HPD event. This allows distinguishing between a + * physical unplug (>hdmi_hpd_debounce_delay) + * and a spontaneous RX HPD toggle (base; + struct drm_device *dev = connector->dev; + struct amdgpu_device *adev = drm_to_adev(dev); + struct dc *dc = aconnector->dc_link->ctx->dc; + bool fake_reconnect = false; + bool reallow_idle = false; + bool ret = false; + guard(mutex)(&aconnector->hpd_lock); + + /* Re-detect the display */ + scoped_guard(mutex, &adev->dm.dc_lock) { + if (dc->caps.ips_support && dc->ctx->dmub_srv->idle_allowed) { + dc_allow_idle_optimizations(dc, false); + reallow_idle = true; + } + ret = dc_link_detect(aconnector->dc_link, DETECT_REASON_HPD); + } + + if (ret) { + /* Apply workaround delay for certain panels */ + apply_delay_after_dpcd_poweroff(adev, aconnector->dc_sink); + /* Compare sinks to determine if this was a spontaneous HPD toggle */ + if (are_sinks_equal(aconnector->dc_link->local_sink, aconnector->hdmi_prev_sink)) { + /* + * Sinks match - this was a spontaneous HDMI HPD toggle. + */ + drm_dbg_kms(dev, "HDMI HPD: Sink unchanged after debounce, internal re-enable\n"); + fake_reconnect = true; + } + + /* Update connector state */ + amdgpu_dm_update_connector_after_detect(aconnector); + + drm_modeset_lock_all(dev); + dm_restore_drm_connector_state(dev, connector); + drm_modeset_unlock_all(dev); + + /* Only notify OS if sink actually changed */ + if (!fake_reconnect && aconnector->base.force == DRM_FORCE_UNSPECIFIED) + drm_kms_helper_hotplug_event(dev); + } + + /* Release the cached sink reference */ + if (aconnector->hdmi_prev_sink) { + dc_sink_release(aconnector->hdmi_prev_sink); + aconnector->hdmi_prev_sink = NULL; + } + + scoped_guard(mutex, &adev->dm.dc_lock) { + if (reallow_idle && dc->caps.ips_support) + dc_allow_idle_optimizations(dc, true); + } +} + static void handle_hpd_irq_helper(struct amdgpu_dm_connector *aconnector) { struct drm_connector *connector = &aconnector->base; @@ -3860,6 +3959,7 @@ static void handle_hpd_irq_helper(struct amdgpu_dm_connector *aconnector) struct dm_connector_state *dm_con_state = to_dm_connector_state(connector->state); struct dc *dc = aconnector->dc_link->ctx->dc; bool ret = false; + bool debounce_required = false; if (adev->dm.disable_hpd_irq) return; @@ -3882,6 +3982,14 @@ static void handle_hpd_irq_helper(struct amdgpu_dm_connector *aconnector) if (!dc_link_detect_connection_type(aconnector->dc_link, &new_connection_type)) drm_err(adev_to_drm(adev), "KMS: Failed to detect connector\n"); + /* + * Check for HDMI disconnect with debounce enabled. + */ + debounce_required = (aconnector->hdmi_hpd_debounce_delay_ms > 0 && + dc_is_hdmi_signal(aconnector->dc_link->connector_signal) && + new_connection_type == dc_connection_none && + aconnector->dc_link->local_sink != NULL); + if (aconnector->base.force && new_connection_type == dc_connection_none) { emulated_link_detect(aconnector->dc_link); @@ -3891,7 +3999,34 @@ static void handle_hpd_irq_helper(struct amdgpu_dm_connector *aconnector) if (aconnector->base.force == DRM_FORCE_UNSPECIFIED) drm_kms_helper_connector_hotplug_event(connector); + } else if (debounce_required) { + /* + * HDMI disconnect detected - schedule delayed work instead of + * processing immediately. This allows us to coalesce spurious + * HDMI signals from physical unplugs. + */ + drm_dbg_kms(dev, "HDMI HPD: Disconnect detected, scheduling debounce work (%u ms)\n", + aconnector->hdmi_hpd_debounce_delay_ms); + + /* Cache the current sink for later comparison */ + if (aconnector->hdmi_prev_sink) + dc_sink_release(aconnector->hdmi_prev_sink); + aconnector->hdmi_prev_sink = aconnector->dc_link->local_sink; + if (aconnector->hdmi_prev_sink) + dc_sink_retain(aconnector->hdmi_prev_sink); + + /* Schedule delayed detection. */ + if (mod_delayed_work(system_wq, + &aconnector->hdmi_hpd_debounce_work, + msecs_to_jiffies(aconnector->hdmi_hpd_debounce_delay_ms))) + drm_dbg_kms(dev, "HDMI HPD: Re-scheduled debounce work\n"); + } else { + + /* If the aconnector->hdmi_hpd_debounce_work is scheduled, exit early */ + if (delayed_work_pending(&aconnector->hdmi_hpd_debounce_work)) + return; + scoped_guard(mutex, &adev->dm.dc_lock) { dc_exit_ips_for_hw_access(dc); ret = dc_link_detect(aconnector->dc_link, DETECT_REASON_HPD); @@ -7380,6 +7515,13 @@ static void amdgpu_dm_connector_destroy(struct drm_connector *connector) if (aconnector->mst_mgr.dev) drm_dp_mst_topology_mgr_destroy(&aconnector->mst_mgr); + /* Cancel and flush any pending HDMI HPD debounce work */ + cancel_delayed_work_sync(&aconnector->hdmi_hpd_debounce_work); + if (aconnector->hdmi_prev_sink) { + dc_sink_release(aconnector->hdmi_prev_sink); + aconnector->hdmi_prev_sink = NULL; + } + if (aconnector->bl_idx != -1) { backlight_device_unregister(dm->backlight_dev[aconnector->bl_idx]); dm->backlight_dev[aconnector->bl_idx] = NULL; @@ -8030,7 +8172,7 @@ static int dm_encoder_helper_atomic_check(struct drm_encoder *encoder, "mode %dx%d@%dHz is not native, enabling scaling\n", adjusted_mode->hdisplay, adjusted_mode->vdisplay, drm_mode_vrefresh(adjusted_mode)); - dm_new_connector_state->scaling = RMX_FULL; + dm_new_connector_state->scaling = RMX_ASPECT; } return 0; } @@ -8541,6 +8683,10 @@ void amdgpu_dm_connector_init_helper(struct amdgpu_display_manager *dm, mutex_init(&aconnector->hpd_lock); mutex_init(&aconnector->handle_mst_msg_ready); + aconnector->hdmi_hpd_debounce_delay_ms = AMDGPU_DM_HDMI_HPD_DEBOUNCE_MS; + INIT_DELAYED_WORK(&aconnector->hdmi_hpd_debounce_work, hdmi_hpd_debounce_work); + aconnector->hdmi_prev_sink = NULL; + /* * configure support HPD hot plug connector_>polled default value is 0 * which means HPD hot plug not supported diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h index db75e991ac7b07..8ca73895759893 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h @@ -59,6 +59,7 @@ #define AMDGPU_HDR_MULT_DEFAULT (0x100000000LL) +#define AMDGPU_DM_HDMI_HPD_DEBOUNCE_MS 1500 /* #include "include/amdgpu_dal_power_if.h" #include "amdgpu_dm_irq.h" @@ -819,6 +820,11 @@ struct amdgpu_dm_connector { bool pack_sdp_v1_3; enum adaptive_sync_type as_type; struct amdgpu_hdmi_vsdb_info vsdb_info; + + /* HDMI HPD debounce support */ + unsigned int hdmi_hpd_debounce_delay_ms; + struct delayed_work hdmi_hpd_debounce_work; + struct dc_sink *hdmi_prev_sink; }; static inline void amdgpu_dm_set_mst_status(uint8_t *status, diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c index f263e1a4537e16..00dac862b665a9 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c @@ -1302,7 +1302,8 @@ static int odm_combine_segments_show(struct seq_file *m, void *unused) if (connector->status != connector_status_connected) return -ENODEV; - if (pipe_ctx != NULL && pipe_ctx->stream_res.tg->funcs->get_odm_combine_segments) + if (pipe_ctx && pipe_ctx->stream_res.tg && + pipe_ctx->stream_res.tg->funcs->get_odm_combine_segments) pipe_ctx->stream_res.tg->funcs->get_odm_combine_segments(pipe_ctx->stream_res.tg, &segments); seq_printf(m, "%d\n", segments); diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c index 5e92eaa67aa33d..dbd1da4d85d323 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c @@ -884,26 +884,28 @@ struct dsc_mst_fairness_params { }; #if defined(CONFIG_DRM_AMD_DC_FP) -static uint16_t get_fec_overhead_multiplier(struct dc_link *dc_link) +static uint64_t kbps_to_pbn(int kbps, bool is_peak_pbn) { - u8 link_coding_cap; - uint16_t fec_overhead_multiplier_x1000 = PBN_FEC_OVERHEAD_MULTIPLIER_8B_10B; + uint64_t effective_kbps = (uint64_t)kbps; - link_coding_cap = dc_link_dp_mst_decide_link_encoding_format(dc_link); - if (link_coding_cap == DP_128b_132b_ENCODING) - fec_overhead_multiplier_x1000 = PBN_FEC_OVERHEAD_MULTIPLIER_128B_132B; + if (is_peak_pbn) { // add 0.6% (1006/1000) overhead into effective kbps + effective_kbps *= 1006; + effective_kbps = div_u64(effective_kbps, 1000); + } - return fec_overhead_multiplier_x1000; + return (uint64_t) DIV64_U64_ROUND_UP(effective_kbps * 64, (54 * 8 * 1000)); } -static int kbps_to_peak_pbn(int kbps, uint16_t fec_overhead_multiplier_x1000) +static uint32_t pbn_to_kbps(unsigned int pbn, bool with_margin) { - u64 peak_kbps = kbps; + uint64_t pbn_effective = (uint64_t)pbn; + + if (with_margin) // deduct 0.6% (994/1000) overhead from effective pbn + pbn_effective *= (1000000 / PEAK_FACTOR_X1000); + else + pbn_effective *= 1000; - peak_kbps *= 1006; - peak_kbps *= fec_overhead_multiplier_x1000; - peak_kbps = div_u64(peak_kbps, 1000 * 1000); - return (int) DIV64_U64_ROUND_UP(peak_kbps * 64, (54 * 8 * 1000)); + return DIV_U64_ROUND_UP(pbn_effective * 8 * 54, 64); } static void set_dsc_configs_from_fairness_vars(struct dsc_mst_fairness_params *params, @@ -974,7 +976,7 @@ static int bpp_x16_from_pbn(struct dsc_mst_fairness_params param, int pbn) dc_dsc_get_default_config_option(param.sink->ctx->dc, &dsc_options); dsc_options.max_target_bpp_limit_override_x16 = drm_connector->display_info.max_dsc_bpp * 16; - kbps = div_u64((u64)pbn * 994 * 8 * 54, 64); + kbps = pbn_to_kbps(pbn, false); dc_dsc_compute_config( param.sink->ctx->dc->res_pool->dscs[0], ¶m.sink->dsc_caps.dsc_dec_caps, @@ -1003,12 +1005,11 @@ static int increase_dsc_bpp(struct drm_atomic_state *state, int link_timeslots_used; int fair_pbn_alloc; int ret = 0; - uint16_t fec_overhead_multiplier_x1000 = get_fec_overhead_multiplier(dc_link); for (i = 0; i < count; i++) { if (vars[i + k].dsc_enabled) { initial_slack[i] = - kbps_to_peak_pbn(params[i].bw_range.max_kbps, fec_overhead_multiplier_x1000) - vars[i + k].pbn; + kbps_to_pbn(params[i].bw_range.max_kbps, false) - vars[i + k].pbn; bpp_increased[i] = false; remaining_to_increase += 1; } else { @@ -1104,7 +1105,6 @@ static int try_disable_dsc(struct drm_atomic_state *state, int next_index; int remaining_to_try = 0; int ret; - uint16_t fec_overhead_multiplier_x1000 = get_fec_overhead_multiplier(dc_link); int var_pbn; for (i = 0; i < count; i++) { @@ -1137,7 +1137,7 @@ static int try_disable_dsc(struct drm_atomic_state *state, DRM_DEBUG_DRIVER("MST_DSC index #%d, try no compression\n", next_index); var_pbn = vars[next_index].pbn; - vars[next_index].pbn = kbps_to_peak_pbn(params[next_index].bw_range.stream_kbps, fec_overhead_multiplier_x1000); + vars[next_index].pbn = kbps_to_pbn(params[next_index].bw_range.stream_kbps, true); ret = drm_dp_atomic_find_time_slots(state, params[next_index].port->mgr, params[next_index].port, @@ -1197,7 +1197,6 @@ static int compute_mst_dsc_configs_for_link(struct drm_atomic_state *state, int count = 0; int i, k, ret; bool debugfs_overwrite = false; - uint16_t fec_overhead_multiplier_x1000 = get_fec_overhead_multiplier(dc_link); struct drm_connector_state *new_conn_state; memset(params, 0, sizeof(params)); @@ -1278,7 +1277,7 @@ static int compute_mst_dsc_configs_for_link(struct drm_atomic_state *state, DRM_DEBUG_DRIVER("MST_DSC Try no compression\n"); for (i = 0; i < count; i++) { vars[i + k].aconnector = params[i].aconnector; - vars[i + k].pbn = kbps_to_peak_pbn(params[i].bw_range.stream_kbps, fec_overhead_multiplier_x1000); + vars[i + k].pbn = kbps_to_pbn(params[i].bw_range.stream_kbps, false); vars[i + k].dsc_enabled = false; vars[i + k].bpp_x16 = 0; ret = drm_dp_atomic_find_time_slots(state, params[i].port->mgr, params[i].port, @@ -1300,7 +1299,7 @@ static int compute_mst_dsc_configs_for_link(struct drm_atomic_state *state, DRM_DEBUG_DRIVER("MST_DSC Try max compression\n"); for (i = 0; i < count; i++) { if (params[i].compression_possible && params[i].clock_force_enable != DSC_CLK_FORCE_DISABLE) { - vars[i + k].pbn = kbps_to_peak_pbn(params[i].bw_range.min_kbps, fec_overhead_multiplier_x1000); + vars[i + k].pbn = kbps_to_pbn(params[i].bw_range.min_kbps, false); vars[i + k].dsc_enabled = true; vars[i + k].bpp_x16 = params[i].bw_range.min_target_bpp_x16; ret = drm_dp_atomic_find_time_slots(state, params[i].port->mgr, @@ -1308,7 +1307,7 @@ static int compute_mst_dsc_configs_for_link(struct drm_atomic_state *state, if (ret < 0) return ret; } else { - vars[i + k].pbn = kbps_to_peak_pbn(params[i].bw_range.stream_kbps, fec_overhead_multiplier_x1000); + vars[i + k].pbn = kbps_to_pbn(params[i].bw_range.stream_kbps, false); vars[i + k].dsc_enabled = false; vars[i + k].bpp_x16 = 0; ret = drm_dp_atomic_find_time_slots(state, params[i].port->mgr, @@ -1763,18 +1762,6 @@ int pre_validate_dsc(struct drm_atomic_state *state, return ret; } -static uint32_t kbps_from_pbn(unsigned int pbn) -{ - uint64_t kbps = (uint64_t)pbn; - - kbps *= (1000000 / PEAK_FACTOR_X1000); - kbps *= 8; - kbps *= 54; - kbps /= 64; - - return (uint32_t)kbps; -} - static bool is_dsc_common_config_possible(struct dc_stream_state *stream, struct dc_dsc_bw_range *bw_range) { @@ -1873,7 +1860,7 @@ enum dc_status dm_dp_mst_is_port_support_mode( dc_link_get_highest_encoding_format(stream->link)); cur_link_settings = stream->link->verified_link_cap; root_link_bw_in_kbps = dc_link_bandwidth_kbps(aconnector->dc_link, &cur_link_settings); - virtual_channel_bw_in_kbps = kbps_from_pbn(aconnector->mst_output_port->full_pbn); + virtual_channel_bw_in_kbps = pbn_to_kbps(aconnector->mst_output_port->full_pbn, true); /* pick the end to end bw bottleneck */ end_to_end_bw_in_kbps = min(root_link_bw_in_kbps, virtual_channel_bw_in_kbps); @@ -1926,7 +1913,7 @@ enum dc_status dm_dp_mst_is_port_support_mode( immediate_upstream_port = aconnector->mst_output_port->parent->port_parent; if (immediate_upstream_port) { - virtual_channel_bw_in_kbps = kbps_from_pbn(immediate_upstream_port->full_pbn); + virtual_channel_bw_in_kbps = pbn_to_kbps(immediate_upstream_port->full_pbn, true); virtual_channel_bw_in_kbps = min(root_link_bw_in_kbps, virtual_channel_bw_in_kbps); } else { /* For topology LCT 1 case - only one mstb*/ diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c index b11383fba35f1a..1eb04772f5da29 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c @@ -394,6 +394,8 @@ void dcn35_update_clocks(struct clk_mgr *clk_mgr_base, display_count = dcn35_get_active_display_cnt_wa(dc, context, &all_active_disps); if (new_clocks->dtbclk_en && !new_clocks->ref_dtbclk_khz) new_clocks->ref_dtbclk_khz = 600000; + else if (!new_clocks->dtbclk_en && new_clocks->ref_dtbclk_khz > 590000) + new_clocks->ref_dtbclk_khz = 0; /* * if it is safe to lower, but we are already in the lower state, we don't have to do anything @@ -435,7 +437,7 @@ void dcn35_update_clocks(struct clk_mgr *clk_mgr_base, actual_dtbclk = REG_READ(CLK1_CLK4_CURRENT_CNT); - if (actual_dtbclk) { + if (actual_dtbclk > 590000) { clk_mgr_base->clks.ref_dtbclk_khz = new_clocks->ref_dtbclk_khz; clk_mgr_base->clks.dtbclk_en = new_clocks->dtbclk_en; } diff --git a/drivers/gpu/drm/amd/display/dc/dccg/dcn35/dcn35_dccg.c b/drivers/gpu/drm/amd/display/dc/dccg/dcn35/dcn35_dccg.c index de6d62401362e7..c899c09ea31b83 100644 --- a/drivers/gpu/drm/amd/display/dc/dccg/dcn35/dcn35_dccg.c +++ b/drivers/gpu/drm/amd/display/dc/dccg/dcn35/dcn35_dccg.c @@ -1411,7 +1411,7 @@ static void dccg35_set_dtbclk_dto( __func__, params->otg_inst, params->pixclk_khz, params->ref_dtbclk_khz, req_dtbclk_khz, phase, modulo); - } else { + } else if (!params->ref_dtbclk_khz && !req_dtbclk_khz) { switch (params->otg_inst) { case 0: REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, DTBCLK_P0_GATE_DISABLE, 0); diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c index 9477c9f9e1963a..59c42db5382ee1 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c @@ -614,6 +614,14 @@ void dcn20_dpp_pg_control( * DOMAIN11_PGFSM_PWR_STATUS, pwr_status, * 1, 1000); */ + + /* Force disable cursor on plane powerdown on DPP 5 using dpp_force_disable_cursor */ + if (!power_on) { + struct dpp *dpp5 = hws->ctx->dc->res_pool->dpps[dpp_inst]; + if (dpp5 && dpp5->funcs->dpp_force_disable_cursor) + dpp5->funcs->dpp_force_disable_cursor(dpp5); + } + break; default: BREAK_TO_DEBUGGER(); diff --git a/drivers/gpu/drm/amd/display/dc/link/link_detection.c b/drivers/gpu/drm/amd/display/dc/link/link_detection.c index 85303167a55312..1173c53359b009 100644 --- a/drivers/gpu/drm/amd/display/dc/link/link_detection.c +++ b/drivers/gpu/drm/amd/display/dc/link/link_detection.c @@ -1141,6 +1141,7 @@ static bool detect_link_and_local_sink(struct dc_link *link, !sink->edid_caps.edid_hdmi) sink->sink_signal = SIGNAL_TYPE_DVI_SINGLE_LINK; else if (dc_is_dvi_signal(sink->sink_signal) && + dc_is_dvi_signal(link->connector_signal) && aud_support->hdmi_audio_native && sink->edid_caps.edid_hdmi) sink->sink_signal = SIGNAL_TYPE_HDMI_TYPE_A; diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c index b12c11bd6a1498..eb262ce42e2dc5 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c @@ -1691,7 +1691,7 @@ static bool retrieve_link_cap(struct dc_link *link) union edp_configuration_cap edp_config_cap; union dp_downstream_port_present ds_port = { 0 }; enum dc_status status = DC_ERROR_UNEXPECTED; - uint32_t read_dpcd_retry_cnt = 3; + uint32_t read_dpcd_retry_cnt = 20; int i; struct dp_sink_hw_fw_revision dp_hw_fw_revision; const uint32_t post_oui_delay = 30; // 30ms @@ -1734,12 +1734,13 @@ static bool retrieve_link_cap(struct dc_link *link) } dpcd_set_source_specific_data(link); - /* Sink may need to configure internals based on vendor, so allow some - * time before proceeding with possibly vendor specific transactions - */ - msleep(post_oui_delay); for (i = 0; i < read_dpcd_retry_cnt; i++) { + /* + * Sink may need to configure internals based on vendor, so allow some + * time before proceeding with possibly vendor specific transactions + */ + msleep(post_oui_delay); status = core_link_read_dpcd( link, DP_DPCD_REV, diff --git a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c index ce421bcddcb080..1aae46d703ba0b 100644 --- a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c +++ b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c @@ -1260,6 +1260,17 @@ void mod_freesync_handle_v_update(struct mod_freesync *mod_freesync, update_v_total_for_static_ramp( core_freesync, stream, in_out_vrr); } + + /* + * If VRR is inactive, set vtotal min and max to nominal vtotal + */ + if (in_out_vrr->state == VRR_STATE_INACTIVE) { + in_out_vrr->adjust.v_total_min = + mod_freesync_calc_v_total_from_refresh(stream, + in_out_vrr->max_refresh_in_uhz); + in_out_vrr->adjust.v_total_max = in_out_vrr->adjust.v_total_min; + return; + } } unsigned long long mod_freesync_calc_nominal_field_rate( diff --git a/drivers/gpu/drm/amd/pm/amdgpu_dpm.c b/drivers/gpu/drm/amd/pm/amdgpu_dpm.c index 518d07afc7df2e..bc29a923fa6e53 100644 --- a/drivers/gpu/drm/amd/pm/amdgpu_dpm.c +++ b/drivers/gpu/drm/amd/pm/amdgpu_dpm.c @@ -195,24 +195,6 @@ int amdgpu_dpm_set_mp1_state(struct amdgpu_device *adev, return ret; } -int amdgpu_dpm_notify_rlc_state(struct amdgpu_device *adev, bool en) -{ - int ret = 0; - const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs; - - if (pp_funcs && pp_funcs->notify_rlc_state) { - mutex_lock(&adev->pm.mutex); - - ret = pp_funcs->notify_rlc_state( - adev->powerplay.pp_handle, - en); - - mutex_unlock(&adev->pm.mutex); - } - - return ret; -} - int amdgpu_dpm_is_baco_supported(struct amdgpu_device *adev) { const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs; diff --git a/drivers/gpu/drm/amd/pm/amdgpu_pm.c b/drivers/gpu/drm/amd/pm/amdgpu_pm.c index b5fbb0fd1dc090..a7e6d7854b7b2c 100644 --- a/drivers/gpu/drm/amd/pm/amdgpu_pm.c +++ b/drivers/gpu/drm/amd/pm/amdgpu_pm.c @@ -4724,14 +4724,14 @@ int amdgpu_pm_sysfs_init(struct amdgpu_device *adev) ret = devm_device_add_group(adev->dev, &amdgpu_pm_policy_attr_group); if (ret) - goto err_out0; + goto err_out1; } if (amdgpu_dpm_is_temp_metrics_supported(adev, SMU_TEMP_METRIC_GPUBOARD)) { ret = devm_device_add_group(adev->dev, &amdgpu_board_attr_group); if (ret) - goto err_out0; + goto err_out1; if (amdgpu_pm_get_sensor_generic(adev, AMDGPU_PP_SENSOR_MAXNODEPOWERLIMIT, (void *)&tmp) != -EOPNOTSUPP) { sysfs_add_file_to_group(&adev->dev->kobj, diff --git a/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h b/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h index 65c1d98af26c3b..af48aead12f709 100644 --- a/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h +++ b/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h @@ -424,8 +424,6 @@ int amdgpu_dpm_mode1_reset(struct amdgpu_device *adev); int amdgpu_dpm_set_mp1_state(struct amdgpu_device *adev, enum pp_mp1_state mp1_state); -int amdgpu_dpm_notify_rlc_state(struct amdgpu_device *adev, bool en); - int amdgpu_dpm_set_gfx_power_up_by_imu(struct amdgpu_device *adev); int amdgpu_dpm_baco_exit(struct amdgpu_device *adev); diff --git a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c index fb8086859857f5..244b8c364d45f5 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c +++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c @@ -2040,6 +2040,12 @@ static int smu_disable_dpms(struct smu_context *smu) smu->is_apu && (amdgpu_in_reset(adev) || adev->in_s0ix)) return 0; + /* vangogh s0ix */ + if ((amdgpu_ip_version(adev, MP1_HWIP, 0) == IP_VERSION(11, 5, 0) || + amdgpu_ip_version(adev, MP1_HWIP, 0) == IP_VERSION(11, 5, 2)) && + adev->in_s0ix) + return 0; + /* * For gpu reset, runpm and hibernation through BACO, * BACO feature has to be kept enabled. diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c index 2c9869feba610f..0708d0f0938b3d 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c @@ -2217,6 +2217,9 @@ static int vangogh_post_smu_init(struct smu_context *smu) uint32_t total_cu = adev->gfx.config.max_cu_per_sh * adev->gfx.config.max_sh_per_se * adev->gfx.config.max_shader_engines; + if (adev->in_s0ix) + return 0; + /* allow message will be sent after enable message on Vangogh*/ if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_GFXCLK_BIT) && (adev->pg_flags & AMD_PG_SUPPORT_GFX_PG)) { diff --git a/drivers/gpu/drm/clients/drm_client_setup.c b/drivers/gpu/drm/clients/drm_client_setup.c index 72480db1f00d0b..515aceac22b181 100644 --- a/drivers/gpu/drm/clients/drm_client_setup.c +++ b/drivers/gpu/drm/clients/drm_client_setup.c @@ -13,8 +13,8 @@ static char drm_client_default[16] = CONFIG_DRM_CLIENT_DEFAULT; module_param_string(active, drm_client_default, sizeof(drm_client_default), 0444); MODULE_PARM_DESC(active, - "Choose which drm client to start, default is" - CONFIG_DRM_CLIENT_DEFAULT "]"); + "Choose which drm client to start, default is " + CONFIG_DRM_CLIENT_DEFAULT); /** * drm_client_setup() - Setup in-kernel DRM clients diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c index 38f82391bfda57..a30493ed97157f 100644 --- a/drivers/gpu/drm/drm_plane.c +++ b/drivers/gpu/drm/drm_plane.c @@ -210,7 +210,7 @@ static struct drm_property_blob *create_in_format_blob(struct drm_device *dev, formats_size = sizeof(__u32) * plane->format_count; if (WARN_ON(!formats_size)) { /* 0 formats are never expected */ - return 0; + return ERR_PTR(-EINVAL); } modifiers_size = @@ -226,7 +226,7 @@ static struct drm_property_blob *create_in_format_blob(struct drm_device *dev, blob = drm_property_create_blob(dev, blob_size, NULL); if (IS_ERR(blob)) - return NULL; + return blob; blob_data = blob->data; blob_data->version = FORMAT_BLOB_CURRENT; diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index e58c0c158b3ab2..b9157538070865 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -413,7 +413,7 @@ obj-$(CONFIG_DRM_I915_GVT_KVMGT) += kvmgt.o # # Enable locally for CONFIG_DRM_I915_WERROR=y. See also scripts/Makefile.build ifdef CONFIG_DRM_I915_WERROR - cmd_checkdoc = PYTHONDONTWRITEBYTECODE=1 $(KERNELDOC) -none -Werror $< + cmd_checkdoc = PYTHONDONTWRITEBYTECODE=1 $(PYTHON3) $(KERNELDOC) -none -Werror $< endif # header test diff --git a/drivers/gpu/drm/i915/display/intel_cx0_phy.c b/drivers/gpu/drm/i915/display/intel_cx0_phy.c index 801235a5bc0a3e..a2d2cecf71217d 100644 --- a/drivers/gpu/drm/i915/display/intel_cx0_phy.c +++ b/drivers/gpu/drm/i915/display/intel_cx0_phy.c @@ -39,14 +39,12 @@ bool intel_encoder_is_c10phy(struct intel_encoder *encoder) struct intel_display *display = to_intel_display(encoder); enum phy phy = intel_encoder_to_phy(encoder); - /* PTL doesn't have a PHY connected to PORT B; as such, - * there will never be a case where PTL uses PHY B. - * WCL uses PORT A and B with the C10 PHY. - * Reusing the condition for WCL and extending it for PORT B - * should not cause any issues for PTL. - */ - if (display->platform.pantherlake && phy < PHY_C) - return true; + if (display->platform.pantherlake) { + if (display->platform.pantherlake_wildcatlake) + return phy <= PHY_B; + else + return phy == PHY_A; + } if ((display->platform.lunarlake || display->platform.meteorlake) && phy < PHY_C) return true; diff --git a/drivers/gpu/drm/i915/display/intel_display_device.c b/drivers/gpu/drm/i915/display/intel_display_device.c index a002bc6ce7b09e..f3f1f25b0f383f 100644 --- a/drivers/gpu/drm/i915/display/intel_display_device.c +++ b/drivers/gpu/drm/i915/display/intel_display_device.c @@ -1404,8 +1404,20 @@ static const struct platform_desc bmg_desc = { PLATFORM_GROUP(dgfx), }; +static const u16 wcl_ids[] = { + INTEL_WCL_IDS(ID), + 0 +}; + static const struct platform_desc ptl_desc = { PLATFORM(pantherlake), + .subplatforms = (const struct subplatform_desc[]) { + { + SUBPLATFORM(pantherlake, wildcatlake), + .pciidlist = wcl_ids, + }, + {}, + } }; __diag_pop(); @@ -1482,6 +1494,7 @@ static const struct { INTEL_LNL_IDS(INTEL_DISPLAY_DEVICE, &lnl_desc), INTEL_BMG_IDS(INTEL_DISPLAY_DEVICE, &bmg_desc), INTEL_PTL_IDS(INTEL_DISPLAY_DEVICE, &ptl_desc), + INTEL_WCL_IDS(INTEL_DISPLAY_DEVICE, &ptl_desc), }; static const struct { diff --git a/drivers/gpu/drm/i915/display/intel_display_device.h b/drivers/gpu/drm/i915/display/intel_display_device.h index f329f1beafef61..a910642d589c05 100644 --- a/drivers/gpu/drm/i915/display/intel_display_device.h +++ b/drivers/gpu/drm/i915/display/intel_display_device.h @@ -101,7 +101,9 @@ struct pci_dev; /* Display ver 14.1 (based on GMD ID) */ \ func(battlemage) \ /* Display ver 30 (based on GMD ID) */ \ - func(pantherlake) + func(pantherlake) \ + func(pantherlake_wildcatlake) + #define __MEMBER(name) unsigned long name:1; #define __COUNT(x) 1 + diff --git a/drivers/gpu/drm/i915/display/intel_dmc.c b/drivers/gpu/drm/i915/display/intel_dmc.c index 4a4cace1f879d1..e1455fd7277fdf 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc.c +++ b/drivers/gpu/drm/i915/display/intel_dmc.c @@ -127,6 +127,9 @@ static bool dmc_firmware_param_disabled(struct intel_display *display) #define DISPLAY_VER13_DMC_MAX_FW_SIZE 0x20000 #define DISPLAY_VER12_DMC_MAX_FW_SIZE ICL_DMC_MAX_FW_SIZE +#define XE3LPD_3002_DMC_PATH DMC_PATH(xe3lpd_3002) +MODULE_FIRMWARE(XE3LPD_3002_DMC_PATH); + #define XE3LPD_DMC_PATH DMC_PATH(xe3lpd) MODULE_FIRMWARE(XE3LPD_DMC_PATH); @@ -183,9 +186,10 @@ static const char *dmc_firmware_default(struct intel_display *display, u32 *size { const char *fw_path = NULL; u32 max_fw_size = 0; - - if (DISPLAY_VERx100(display) == 3002 || - DISPLAY_VERx100(display) == 3000) { + if (DISPLAY_VERx100(display) == 3002) { + fw_path = XE3LPD_3002_DMC_PATH; + max_fw_size = XE2LPD_DMC_MAX_FW_SIZE; + } else if (DISPLAY_VERx100(display) == 3000) { fw_path = XE3LPD_DMC_PATH; max_fw_size = XE2LPD_DMC_MAX_FW_SIZE; } else if (DISPLAY_VERx100(display) == 2000) { diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index 10eb93a34cf2e5..4619237f13467e 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -585,6 +585,10 @@ static void _panel_replay_init_dpcd(struct intel_dp *intel_dp) struct intel_display *display = to_intel_display(intel_dp); int ret; + /* TODO: Enable Panel Replay on MST once it's properly implemented. */ + if (intel_dp->mst_detect == DRM_DP_MST) + return; + ret = drm_dp_dpcd_read_data(&intel_dp->aux, DP_PANEL_REPLAY_CAP_SUPPORT, &intel_dp->pr_dpcd, sizeof(intel_dp->pr_dpcd)); if (ret < 0) @@ -888,7 +892,8 @@ static bool is_dc5_dc6_blocked(struct intel_dp *intel_dp) { struct intel_display *display = to_intel_display(intel_dp); u32 current_dc_state = intel_display_power_get_current_dc_state(display); - struct drm_vblank_crtc *vblank = &display->drm->vblank[intel_dp->psr.pipe]; + struct intel_crtc *crtc = intel_crtc_for_pipe(display, intel_dp->psr.pipe); + struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(&crtc->base); return (current_dc_state != DC_STATE_EN_UPTO_DC5 && current_dc_state != DC_STATE_EN_UPTO_DC6) || diff --git a/drivers/gpu/drm/i915/gt/intel_gt_clock_utils.c b/drivers/gpu/drm/i915/gt/intel_gt_clock_utils.c index 88b147fa5cb131..c90b35881a2657 100644 --- a/drivers/gpu/drm/i915/gt/intel_gt_clock_utils.c +++ b/drivers/gpu/drm/i915/gt/intel_gt_clock_utils.c @@ -205,7 +205,7 @@ static u64 div_u64_roundup(u64 nom, u32 den) u64 intel_gt_clock_interval_to_ns(const struct intel_gt *gt, u64 count) { - return div_u64_roundup(count * NSEC_PER_SEC, gt->clock_frequency); + return mul_u64_u32_div(count, NSEC_PER_SEC, gt->clock_frequency); } u64 intel_gt_pm_interval_to_ns(const struct intel_gt *gt, u64 count) @@ -215,7 +215,7 @@ u64 intel_gt_pm_interval_to_ns(const struct intel_gt *gt, u64 count) u64 intel_gt_ns_to_clock_interval(const struct intel_gt *gt, u64 ns) { - return div_u64_roundup(gt->clock_frequency * ns, NSEC_PER_SEC); + return mul_u64_u32_div(ns, gt->clock_frequency, NSEC_PER_SEC); } u64 intel_gt_ns_to_pm_interval(const struct intel_gt *gt, u64 ns) diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c index 25e97031d76e46..30d5889fc809d6 100644 --- a/drivers/gpu/drm/i915/i915_vma.c +++ b/drivers/gpu/drm/i915/i915_vma.c @@ -1595,8 +1595,20 @@ int i915_vma_pin_ww(struct i915_vma *vma, struct i915_gem_ww_ctx *ww, err_vma_res: i915_vma_resource_free(vma_res); err_fence: - if (work) - dma_fence_work_commit_imm(&work->base); + if (work) { + /* + * When pinning VMA to GGTT on CHV or BXT with VTD enabled, + * commit VMA binding asynchronously to avoid risk of lock + * inversion among reservation_ww locks held here and + * cpu_hotplug_lock acquired from stop_machine(), which we + * wrap around GGTT updates when running in those environments. + */ + if (i915_vma_is_ggtt(vma) && + intel_vm_no_concurrent_access_wa(vma->vm->i915)) + dma_fence_work_commit(&work->base); + else + dma_fence_work_commit_imm(&work->base); + } err_rpm: intel_runtime_pm_put(&vma->vm->i915->runtime_pm, wakeref); diff --git a/drivers/gpu/drm/imagination/Kconfig b/drivers/gpu/drm/imagination/Kconfig index 682dd2633d0c01..0482bfcefdde35 100644 --- a/drivers/gpu/drm/imagination/Kconfig +++ b/drivers/gpu/drm/imagination/Kconfig @@ -7,6 +7,7 @@ config DRM_POWERVR depends on DRM depends on MMU depends on PM + depends on POWER_SEQUENCING || !POWER_SEQUENCING select DRM_EXEC select DRM_GEM_SHMEM_HELPER select DRM_SCHED diff --git a/drivers/gpu/drm/mediatek/mtk_crtc.c b/drivers/gpu/drm/mediatek/mtk_crtc.c index bc7527542fdc6f..c4c6d0249df562 100644 --- a/drivers/gpu/drm/mediatek/mtk_crtc.c +++ b/drivers/gpu/drm/mediatek/mtk_crtc.c @@ -283,6 +283,10 @@ static void ddp_cmdq_cb(struct mbox_client *cl, void *mssg) unsigned int i; unsigned long flags; + /* release GCE HW usage and start autosuspend */ + pm_runtime_mark_last_busy(cmdq_cl->chan->mbox->dev); + pm_runtime_put_autosuspend(cmdq_cl->chan->mbox->dev); + if (data->sta < 0) return; @@ -618,6 +622,9 @@ static void mtk_crtc_update_config(struct mtk_crtc *mtk_crtc, bool needs_vblank) mtk_crtc->config_updating = false; spin_unlock_irqrestore(&mtk_crtc->config_lock, flags); + if (pm_runtime_resume_and_get(mtk_crtc->cmdq_client.chan->mbox->dev) < 0) + goto update_config_out; + mbox_send_message(mtk_crtc->cmdq_client.chan, cmdq_handle); mbox_client_txdone(mtk_crtc->cmdq_client.chan, 0); goto update_config_out; diff --git a/drivers/gpu/drm/mediatek/mtk_plane.c b/drivers/gpu/drm/mediatek/mtk_plane.c index 02349bd4400176..788b52c1d10c5b 100644 --- a/drivers/gpu/drm/mediatek/mtk_plane.c +++ b/drivers/gpu/drm/mediatek/mtk_plane.c @@ -21,9 +21,6 @@ static const u64 modifiers[] = { DRM_FORMAT_MOD_LINEAR, - DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 | - AFBC_FORMAT_MOD_SPLIT | - AFBC_FORMAT_MOD_SPARSE), DRM_FORMAT_MOD_INVALID, }; @@ -71,26 +68,7 @@ static bool mtk_plane_format_mod_supported(struct drm_plane *plane, uint32_t format, uint64_t modifier) { - if (modifier == DRM_FORMAT_MOD_LINEAR) - return true; - - if (modifier != DRM_FORMAT_MOD_ARM_AFBC( - AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 | - AFBC_FORMAT_MOD_SPLIT | - AFBC_FORMAT_MOD_SPARSE)) - return false; - - if (format != DRM_FORMAT_XRGB8888 && - format != DRM_FORMAT_ARGB8888 && - format != DRM_FORMAT_BGRX8888 && - format != DRM_FORMAT_BGRA8888 && - format != DRM_FORMAT_ABGR8888 && - format != DRM_FORMAT_XBGR8888 && - format != DRM_FORMAT_RGB888 && - format != DRM_FORMAT_BGR888) - return false; - - return true; + return modifier == DRM_FORMAT_MOD_LINEAR; } static void mtk_plane_destroy_state(struct drm_plane *plane, diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c index e97e39abf3a223..12b1dba8e05d51 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c @@ -2867,7 +2867,9 @@ nv50_display_create(struct drm_device *dev) } /* Assign the correct format modifiers */ - if (disp->disp->object.oclass >= TU102_DISP) + if (disp->disp->object.oclass >= GB202_DISP) + nouveau_display(dev)->format_modifiers = wndwca7e_modifiers; + else if (disp->disp->object.oclass >= TU102_DISP) nouveau_display(dev)->format_modifiers = wndwc57e_modifiers; else if (drm->client.device.info.family >= NV_DEVICE_INFO_V0_FERMI) diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.h b/drivers/gpu/drm/nouveau/dispnv50/disp.h index 15f9242b72ac71..5d998f0319dcc2 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/disp.h +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.h @@ -104,4 +104,5 @@ struct nouveau_encoder *nv50_real_outp(struct drm_encoder *encoder); extern const u64 disp50xx_modifiers[]; extern const u64 disp90xx_modifiers[]; extern const u64 wndwc57e_modifiers[]; +extern const u64 wndwca7e_modifiers[]; #endif diff --git a/drivers/gpu/drm/nouveau/dispnv50/wndw.c b/drivers/gpu/drm/nouveau/dispnv50/wndw.c index e2c55f4b9c5a14..ef9e410babbfba 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/wndw.c +++ b/drivers/gpu/drm/nouveau/dispnv50/wndw.c @@ -786,13 +786,14 @@ nv50_wndw_destroy(struct drm_plane *plane) } /* This function assumes the format has already been validated against the plane - * and the modifier was validated against the device-wides modifier list at FB + * and the modifier was validated against the device-wide modifier list at FB * creation time. */ static bool nv50_plane_format_mod_supported(struct drm_plane *plane, u32 format, u64 modifier) { struct nouveau_drm *drm = nouveau_drm(plane->dev); + const struct drm_format_info *info = drm_format_info(format); uint8_t i; /* All chipsets can display all formats in linear layout */ @@ -800,13 +801,32 @@ static bool nv50_plane_format_mod_supported(struct drm_plane *plane, return true; if (drm->client.device.info.chipset < 0xc0) { - const struct drm_format_info *info = drm_format_info(format); const uint8_t kind = (modifier >> 12) & 0xff; if (!format) return false; for (i = 0; i < info->num_planes; i++) if ((info->cpp[i] != 4) && kind != 0x70) return false; + } else if (drm->client.device.info.chipset >= 0x1b2) { + const uint8_t slayout = ((modifier >> 22) & 0x1) | + ((modifier >> 25) & 0x6); + + if (!format) + return false; + + /* + * Note in practice this implies only formats where cpp is equal + * for each plane, or >= 4 for all planes, are supported. + */ + for (i = 0; i < info->num_planes; i++) { + if (((info->cpp[i] == 2) && slayout != 3) || + ((info->cpp[i] == 1) && slayout != 2) || + ((info->cpp[i] >= 4) && slayout != 1)) + return false; + + /* 24-bit not supported. It has yet another layout */ + WARN_ON(info->cpp[i] == 3); + } } return true; diff --git a/drivers/gpu/drm/nouveau/dispnv50/wndwca7e.c b/drivers/gpu/drm/nouveau/dispnv50/wndwca7e.c index 0d8e9a9d1a5730..2cec8cfbd54619 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/wndwca7e.c +++ b/drivers/gpu/drm/nouveau/dispnv50/wndwca7e.c @@ -179,6 +179,39 @@ wndwca7e_ntfy_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) return 0; } +/**************************************************************** + * Log2(block height) ----------------------------+ * + * Page Kind ----------------------------------+ | * + * Gob Height/Page Kind Generation ------+ | | * + * Sector layout -------+ | | | * + * Compression ------+ | | | | */ +const u64 wndwca7e_modifiers[] = { /* | | | | | */ + /* 4cpp+ modifiers */ + DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 2, 0x06, 0), + DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 2, 0x06, 1), + DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 2, 0x06, 2), + DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 2, 0x06, 3), + DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 2, 0x06, 4), + DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 2, 0x06, 5), + /* 1cpp/8bpp modifiers */ + DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 2, 2, 0x06, 0), + DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 2, 2, 0x06, 1), + DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 2, 2, 0x06, 2), + DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 2, 2, 0x06, 3), + DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 2, 2, 0x06, 4), + DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 2, 2, 0x06, 5), + /* 2cpp/16bpp modifiers */ + DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 3, 2, 0x06, 0), + DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 3, 2, 0x06, 1), + DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 3, 2, 0x06, 2), + DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 3, 2, 0x06, 3), + DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 3, 2, 0x06, 4), + DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 3, 2, 0x06, 5), + /* All formats support linear */ + DRM_FORMAT_MOD_LINEAR, + DRM_FORMAT_MOD_INVALID +}; + static const struct nv50_wndw_func wndwca7e = { .acquire = wndwc37e_acquire, diff --git a/drivers/gpu/drm/nouveau/nvkm/falcon/fw.c b/drivers/gpu/drm/nouveau/nvkm/falcon/fw.c index cac6d64ab67d1d..4e8b3f1c7e25d2 100644 --- a/drivers/gpu/drm/nouveau/nvkm/falcon/fw.c +++ b/drivers/gpu/drm/nouveau/nvkm/falcon/fw.c @@ -159,6 +159,8 @@ nvkm_falcon_fw_dtor(struct nvkm_falcon_fw *fw) nvkm_memory_unref(&fw->inst); nvkm_falcon_fw_dtor_sigs(fw); nvkm_firmware_dtor(&fw->fw); + kfree(fw->boot); + fw->boot = NULL; } static const struct nvkm_firmware_func diff --git a/drivers/gpu/drm/panthor/panthor_gem.c b/drivers/gpu/drm/panthor/panthor_gem.c index 156c7a0b62a231..3f43686f019588 100644 --- a/drivers/gpu/drm/panthor/panthor_gem.c +++ b/drivers/gpu/drm/panthor/panthor_gem.c @@ -288,6 +288,23 @@ panthor_gem_create_with_handle(struct drm_file *file, panthor_gem_debugfs_set_usage_flags(bo, 0); + /* If this is a write-combine mapping, we query the sgt to force a CPU + * cache flush (dma_map_sgtable() is called when the sgt is created). + * This ensures the zero-ing is visible to any uncached mapping created + * by vmap/mmap. + * FIXME: Ideally this should be done when pages are allocated, not at + * BO creation time. + */ + if (shmem->map_wc) { + struct sg_table *sgt; + + sgt = drm_gem_shmem_get_pages_sgt(shmem); + if (IS_ERR(sgt)) { + ret = PTR_ERR(sgt); + goto out_put_gem; + } + } + /* * Allocate an id of idr table where the obj is registered * and handle has the id what user can see. @@ -296,6 +313,7 @@ panthor_gem_create_with_handle(struct drm_file *file, if (!ret) *size = bo->base.base.size; +out_put_gem: /* drop reference from allocate - handle holds it now. */ drm_gem_object_put(&shmem->base); diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c index 5b5b54e876d4c2..167d6f122b8efe 100644 --- a/drivers/gpu/drm/radeon/radeon_fence.c +++ b/drivers/gpu/drm/radeon/radeon_fence.c @@ -360,13 +360,6 @@ static bool radeon_fence_is_signaled(struct dma_fence *f) if (atomic64_read(&rdev->fence_drv[ring].last_seq) >= seq) return true; - if (down_read_trylock(&rdev->exclusive_lock)) { - radeon_fence_process(rdev, ring); - up_read(&rdev->exclusive_lock); - - if (atomic64_read(&rdev->fence_drv[ring].last_seq) >= seq) - return true; - } return false; } diff --git a/drivers/gpu/drm/scheduler/sched_entity.c b/drivers/gpu/drm/scheduler/sched_entity.c index c8e949f4a5687c..fe174a4857be7f 100644 --- a/drivers/gpu/drm/scheduler/sched_entity.c +++ b/drivers/gpu/drm/scheduler/sched_entity.c @@ -173,26 +173,15 @@ int drm_sched_entity_error(struct drm_sched_entity *entity) } EXPORT_SYMBOL(drm_sched_entity_error); +static void drm_sched_entity_kill_jobs_cb(struct dma_fence *f, + struct dma_fence_cb *cb); + static void drm_sched_entity_kill_jobs_work(struct work_struct *wrk) { struct drm_sched_job *job = container_of(wrk, typeof(*job), work); - - drm_sched_fence_scheduled(job->s_fence, NULL); - drm_sched_fence_finished(job->s_fence, -ESRCH); - WARN_ON(job->s_fence->parent); - job->sched->ops->free_job(job); -} - -/* Signal the scheduler finished fence when the entity in question is killed. */ -static void drm_sched_entity_kill_jobs_cb(struct dma_fence *f, - struct dma_fence_cb *cb) -{ - struct drm_sched_job *job = container_of(cb, struct drm_sched_job, - finish_cb); + struct dma_fence *f; unsigned long index; - dma_fence_put(f); - /* Wait for all dependencies to avoid data corruptions */ xa_for_each(&job->dependencies, index, f) { struct drm_sched_fence *s_fence = to_drm_sched_fence(f); @@ -220,6 +209,21 @@ static void drm_sched_entity_kill_jobs_cb(struct dma_fence *f, dma_fence_put(f); } + drm_sched_fence_scheduled(job->s_fence, NULL); + drm_sched_fence_finished(job->s_fence, -ESRCH); + WARN_ON(job->s_fence->parent); + job->sched->ops->free_job(job); +} + +/* Signal the scheduler finished fence when the entity in question is killed. */ +static void drm_sched_entity_kill_jobs_cb(struct dma_fence *f, + struct dma_fence_cb *cb) +{ + struct drm_sched_job *job = container_of(cb, struct drm_sched_job, + finish_cb); + + dma_fence_put(f); + INIT_WORK(&job->work, drm_sched_entity_kill_jobs_work); schedule_work(&job->work); } diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c index 59d5c1ba145a82..6c84bd69b11ff4 100644 --- a/drivers/gpu/drm/tegra/dc.c +++ b/drivers/gpu/drm/tegra/dc.c @@ -3148,6 +3148,7 @@ static int tegra_dc_couple(struct tegra_dc *dc) dc->client.parent = &parent->client; dev_dbg(dc->dev, "coupled to %s\n", dev_name(companion)); + put_device(companion); } return 0; diff --git a/drivers/gpu/drm/tegra/dsi.c b/drivers/gpu/drm/tegra/dsi.c index b5089b7722676c..ddfb2858acbf1b 100644 --- a/drivers/gpu/drm/tegra/dsi.c +++ b/drivers/gpu/drm/tegra/dsi.c @@ -913,15 +913,6 @@ static void tegra_dsi_encoder_enable(struct drm_encoder *encoder) u32 value; int err; - /* If the bootloader enabled DSI it needs to be disabled - * in order for the panel initialization commands to be - * properly sent. - */ - value = tegra_dsi_readl(dsi, DSI_POWER_CONTROL); - - if (value & DSI_POWER_CONTROL_ENABLE) - tegra_dsi_disable(dsi); - err = tegra_dsi_prepare(dsi); if (err < 0) { dev_err(dsi->dev, "failed to prepare: %d\n", err); diff --git a/drivers/gpu/drm/tegra/uapi.c b/drivers/gpu/drm/tegra/uapi.c index 5adab6b229164e..d0b6a1fa6efad9 100644 --- a/drivers/gpu/drm/tegra/uapi.c +++ b/drivers/gpu/drm/tegra/uapi.c @@ -114,9 +114,12 @@ int tegra_drm_ioctl_channel_open(struct drm_device *drm, void *data, struct drm_ if (err) goto put_channel; - if (supported) + if (supported) { + struct pid *pid = get_task_pid(current, PIDTYPE_TGID); context->memory_context = host1x_memory_context_alloc( - host, client->base.dev, get_task_pid(current, PIDTYPE_TGID)); + host, client->base.dev, pid); + put_pid(pid); + } if (IS_ERR(context->memory_context)) { if (PTR_ERR(context->memory_context) != -EOPNOTSUPP) { diff --git a/drivers/gpu/drm/tiny/Kconfig b/drivers/gpu/drm/tiny/Kconfig index 7d9e85e932d7fd..f0e72d4b6a4709 100644 --- a/drivers/gpu/drm/tiny/Kconfig +++ b/drivers/gpu/drm/tiny/Kconfig @@ -85,6 +85,7 @@ config DRM_PANEL_MIPI_DBI config DRM_PIXPAPER tristate "DRM support for PIXPAPER display panels" depends on DRM && SPI + depends on MMU select DRM_CLIENT_SELECTION select DRM_GEM_SHMEM_HELPER select DRM_KMS_HELPER diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_cursor_plane.c b/drivers/gpu/drm/vmwgfx/vmwgfx_cursor_plane.c index 718832b08d96e8..c46f17ba7236de 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_cursor_plane.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_cursor_plane.c @@ -100,8 +100,10 @@ vmw_cursor_update_type(struct vmw_private *vmw, struct vmw_plane_state *vps) if (vmw->has_mob) { if ((vmw->capabilities2 & SVGA_CAP2_CURSOR_MOB) != 0) return VMW_CURSOR_UPDATE_MOB; + else + return VMW_CURSOR_UPDATE_GB_ONLY; } - + drm_warn_once(&vmw->drm, "Unknown Cursor Type!\n"); return VMW_CURSOR_UPDATE_NONE; } @@ -139,6 +141,7 @@ static u32 vmw_cursor_mob_size(enum vmw_cursor_update_type update_type, { switch (update_type) { case VMW_CURSOR_UPDATE_LEGACY: + case VMW_CURSOR_UPDATE_GB_ONLY: case VMW_CURSOR_UPDATE_NONE: return 0; case VMW_CURSOR_UPDATE_MOB: @@ -623,6 +626,7 @@ int vmw_cursor_plane_prepare_fb(struct drm_plane *plane, if (!surface || vps->cursor.legacy.id == surface->snooper.id) vps->cursor.update_type = VMW_CURSOR_UPDATE_NONE; break; + case VMW_CURSOR_UPDATE_GB_ONLY: case VMW_CURSOR_UPDATE_MOB: { bo = vmw_user_object_buffer(&vps->uo); if (bo) { @@ -737,6 +741,7 @@ void vmw_cursor_plane_atomic_update(struct drm_plane *plane, struct drm_atomic_state *state) { + struct vmw_bo *bo; struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state, plane); struct drm_plane_state *old_state = @@ -762,6 +767,15 @@ vmw_cursor_plane_atomic_update(struct drm_plane *plane, case VMW_CURSOR_UPDATE_MOB: vmw_cursor_update_mob(dev_priv, vps); break; + case VMW_CURSOR_UPDATE_GB_ONLY: + bo = vmw_user_object_buffer(&vps->uo); + if (bo) + vmw_send_define_cursor_cmd(dev_priv, bo->map.virtual, + vps->base.crtc_w, + vps->base.crtc_h, + vps->base.hotspot_x, + vps->base.hotspot_y); + break; case VMW_CURSOR_UPDATE_NONE: /* do nothing */ break; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_cursor_plane.h b/drivers/gpu/drm/vmwgfx/vmwgfx_cursor_plane.h index 40694925a70e6a..0c2cc0699b0d93 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_cursor_plane.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_cursor_plane.h @@ -33,6 +33,7 @@ static const u32 __maybe_unused vmw_cursor_plane_formats[] = { enum vmw_cursor_update_type { VMW_CURSOR_UPDATE_NONE = 0, VMW_CURSOR_UPDATE_LEGACY, + VMW_CURSOR_UPDATE_GB_ONLY, VMW_CURSOR_UPDATE_MOB, }; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c index d539f25b5fbe0a..3057f8baa7d25b 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c @@ -3668,6 +3668,11 @@ static int vmw_cmd_check(struct vmw_private *dev_priv, cmd_id = header->id; + if (header->size > SVGA_CMD_MAX_DATASIZE) { + VMW_DEBUG_USER("SVGA3D command: %d is too big.\n", + cmd_id + SVGA_3D_CMD_BASE); + return -E2BIG; + } *size = header->size + sizeof(SVGA3dCmdHeader); cmd_id -= SVGA_3D_CMD_BASE; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_page_dirty.c b/drivers/gpu/drm/vmwgfx/vmwgfx_page_dirty.c index 7de20e56082c87..fd4e76486f2d1b 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_page_dirty.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_page_dirty.c @@ -32,22 +32,22 @@ enum vmw_bo_dirty_method { /** * struct vmw_bo_dirty - Dirty information for buffer objects + * @ref_count: Reference count for this structure. Must be first member! * @start: First currently dirty bit * @end: Last currently dirty bit + 1 * @method: The currently used dirty method * @change_count: Number of consecutive method change triggers - * @ref_count: Reference count for this structure * @bitmap_size: The size of the bitmap in bits. Typically equal to the * nuber of pages in the bo. * @bitmap: A bitmap where each bit represents a page. A set bit means a * dirty page. */ struct vmw_bo_dirty { + struct kref ref_count; unsigned long start; unsigned long end; enum vmw_bo_dirty_method method; unsigned int change_count; - unsigned int ref_count; unsigned long bitmap_size; unsigned long bitmap[]; }; @@ -221,7 +221,7 @@ int vmw_bo_dirty_add(struct vmw_bo *vbo) int ret; if (dirty) { - dirty->ref_count++; + kref_get(&dirty->ref_count); return 0; } @@ -235,7 +235,7 @@ int vmw_bo_dirty_add(struct vmw_bo *vbo) dirty->bitmap_size = num_pages; dirty->start = dirty->bitmap_size; dirty->end = 0; - dirty->ref_count = 1; + kref_init(&dirty->ref_count); if (num_pages < PAGE_SIZE / sizeof(pte_t)) { dirty->method = VMW_BO_DIRTY_PAGETABLE; } else { @@ -274,10 +274,8 @@ void vmw_bo_dirty_release(struct vmw_bo *vbo) { struct vmw_bo_dirty *dirty = vbo->dirty; - if (dirty && --dirty->ref_count == 0) { - kvfree(dirty); + if (dirty && kref_put(&dirty->ref_count, (void *)kvfree)) vbo->dirty = NULL; - } } /** diff --git a/drivers/gpu/drm/xe/Kconfig b/drivers/gpu/drm/xe/Kconfig index 7219f6b884b692..4b288eb3f5b0e5 100644 --- a/drivers/gpu/drm/xe/Kconfig +++ b/drivers/gpu/drm/xe/Kconfig @@ -13,7 +13,6 @@ config DRM_XE select TMPFS select DRM_BUDDY select DRM_CLIENT_SELECTION - select DRM_EXEC select DRM_KMS_HELPER select DRM_KUNIT_TEST_HELPERS if DRM_XE_KUNIT_TEST != n select DRM_PANEL diff --git a/drivers/gpu/drm/xe/regs/xe_gt_regs.h b/drivers/gpu/drm/xe/regs/xe_gt_regs.h index 51f2a03847f9d7..f680c8b8f25879 100644 --- a/drivers/gpu/drm/xe/regs/xe_gt_regs.h +++ b/drivers/gpu/drm/xe/regs/xe_gt_regs.h @@ -168,6 +168,7 @@ #define XEHP_SLICE_COMMON_ECO_CHICKEN1 XE_REG_MCR(0x731c, XE_REG_OPTION_MASKED) #define MSC_MSAA_REODER_BUF_BYPASS_DISABLE REG_BIT(14) +#define FAST_CLEAR_VALIGN_FIX REG_BIT(13) #define XE2LPM_CCCHKNREG1 XE_REG(0x82a8) diff --git a/drivers/gpu/drm/xe/tests/xe_mocs.c b/drivers/gpu/drm/xe/tests/xe_mocs.c index 0e502feaca8186..6bb278167aaf69 100644 --- a/drivers/gpu/drm/xe/tests/xe_mocs.c +++ b/drivers/gpu/drm/xe/tests/xe_mocs.c @@ -49,7 +49,7 @@ static void read_l3cc_table(struct xe_gt *gt, fw_ref = xe_force_wake_get(gt_to_fw(gt), XE_FORCEWAKE_ALL); if (!xe_force_wake_ref_has_domain(fw_ref, XE_FORCEWAKE_ALL)) { xe_force_wake_put(gt_to_fw(gt), fw_ref); - KUNIT_ASSERT_TRUE_MSG(test, true, "Forcewake Failed.\n"); + KUNIT_FAIL_AND_ABORT(test, "Forcewake Failed.\n"); } for (i = 0; i < info->num_mocs_regs; i++) { diff --git a/drivers/gpu/drm/xe/xe_device.c b/drivers/gpu/drm/xe/xe_device.c index 34d33965eac24c..456899238377ed 100644 --- a/drivers/gpu/drm/xe/xe_device.c +++ b/drivers/gpu/drm/xe/xe_device.c @@ -988,16 +988,16 @@ void xe_device_shutdown(struct xe_device *xe) drm_dbg(&xe->drm, "Shutting down device\n"); - if (xe_driver_flr_disabled(xe)) { - xe_display_pm_shutdown(xe); + xe_display_pm_shutdown(xe); - xe_irq_suspend(xe); + xe_irq_suspend(xe); - for_each_gt(gt, xe, id) - xe_gt_shutdown(gt); + for_each_gt(gt, xe, id) + xe_gt_shutdown(gt); - xe_display_pm_shutdown_late(xe); - } else { + xe_display_pm_shutdown_late(xe); + + if (!xe_driver_flr_disabled(xe)) { /* BOOM! */ __xe_driver_flr(xe); } diff --git a/drivers/gpu/drm/xe/xe_exec.c b/drivers/gpu/drm/xe/xe_exec.c index 7715e74bb94544..a8ab363a804658 100644 --- a/drivers/gpu/drm/xe/xe_exec.c +++ b/drivers/gpu/drm/xe/xe_exec.c @@ -165,7 +165,8 @@ int xe_exec_ioctl(struct drm_device *dev, void *data, struct drm_file *file) for (num_syncs = 0; num_syncs < args->num_syncs; num_syncs++) { err = xe_sync_entry_parse(xe, xef, &syncs[num_syncs], - &syncs_user[num_syncs], SYNC_PARSE_FLAG_EXEC | + &syncs_user[num_syncs], NULL, 0, + SYNC_PARSE_FLAG_EXEC | (xe_vm_in_lr_mode(vm) ? SYNC_PARSE_FLAG_LR_MODE : 0)); if (err) diff --git a/drivers/gpu/drm/xe/xe_exec_queue.c b/drivers/gpu/drm/xe/xe_exec_queue.c index 37b2b93b73d6c9..cb5f204c08ed6e 100644 --- a/drivers/gpu/drm/xe/xe_exec_queue.c +++ b/drivers/gpu/drm/xe/xe_exec_queue.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include "xe_dep_scheduler.h" @@ -324,6 +325,16 @@ struct xe_exec_queue *xe_exec_queue_create_bind(struct xe_device *xe, } xe_vm_put(migrate_vm); + if (!IS_ERR(q)) { + int err = drm_syncobj_create(&q->ufence_syncobj, + DRM_SYNCOBJ_CREATE_SIGNALED, + NULL); + if (err) { + xe_exec_queue_put(q); + return ERR_PTR(err); + } + } + return q; } ALLOW_ERROR_INJECTION(xe_exec_queue_create_bind, ERRNO); @@ -333,6 +344,9 @@ void xe_exec_queue_destroy(struct kref *ref) struct xe_exec_queue *q = container_of(ref, struct xe_exec_queue, refcount); struct xe_exec_queue *eq, *next; + if (q->ufence_syncobj) + drm_syncobj_put(q->ufence_syncobj); + if (xe_exec_queue_uses_pxp(q)) xe_pxp_exec_queue_remove(gt_to_xe(q->gt)->pxp, q); diff --git a/drivers/gpu/drm/xe/xe_exec_queue_types.h b/drivers/gpu/drm/xe/xe_exec_queue_types.h index 27b76cf9da8958..df1c69dc81f17b 100644 --- a/drivers/gpu/drm/xe/xe_exec_queue_types.h +++ b/drivers/gpu/drm/xe/xe_exec_queue_types.h @@ -15,6 +15,7 @@ #include "xe_hw_fence_types.h" #include "xe_lrc_types.h" +struct drm_syncobj; struct xe_execlist_exec_queue; struct xe_gt; struct xe_guc_exec_queue; @@ -155,6 +156,12 @@ struct xe_exec_queue { struct list_head link; } pxp; + /** @ufence_syncobj: User fence syncobj */ + struct drm_syncobj *ufence_syncobj; + + /** @ufence_timeline_value: User fence timeline value */ + u64 ufence_timeline_value; + /** @ops: submission backend exec queue operations */ const struct xe_exec_queue_ops *ops; diff --git a/drivers/gpu/drm/xe/xe_guc_ct.c b/drivers/gpu/drm/xe/xe_guc_ct.c index 18f6327bf5527a..283d846c35129d 100644 --- a/drivers/gpu/drm/xe/xe_guc_ct.c +++ b/drivers/gpu/drm/xe/xe_guc_ct.c @@ -200,6 +200,9 @@ static void guc_ct_fini(struct drm_device *drm, void *arg) { struct xe_guc_ct *ct = arg; +#if IS_ENABLED(CONFIG_DRM_XE_DEBUG) + cancel_work_sync(&ct->dead.worker); +#endif ct_exit_safe_mode(ct); destroy_workqueue(ct->g2h_wq); xa_destroy(&ct->fence_lookup); diff --git a/drivers/gpu/drm/xe/xe_irq.c b/drivers/gpu/drm/xe/xe_irq.c index 870edaf693887b..06976cc7791807 100644 --- a/drivers/gpu/drm/xe/xe_irq.c +++ b/drivers/gpu/drm/xe/xe_irq.c @@ -847,22 +847,6 @@ static int xe_irq_msix_init(struct xe_device *xe) return 0; } -static irqreturn_t guc2host_irq_handler(int irq, void *arg) -{ - struct xe_device *xe = arg; - struct xe_tile *tile; - u8 id; - - if (!atomic_read(&xe->irq.enabled)) - return IRQ_NONE; - - for_each_tile(tile, xe, id) - xe_guc_irq_handler(&tile->primary_gt->uc.guc, - GUC_INTR_GUC2HOST); - - return IRQ_HANDLED; -} - static irqreturn_t xe_irq_msix_default_hwe_handler(int irq, void *arg) { unsigned int tile_id, gt_id; @@ -979,7 +963,7 @@ int xe_irq_msix_request_irqs(struct xe_device *xe) u16 msix; msix = GUC2HOST_MSIX; - err = xe_irq_msix_request_irq(xe, guc2host_irq_handler, xe, + err = xe_irq_msix_request_irq(xe, xe_irq_handler(xe), xe, DRIVER_NAME "-guc2host", false, &msix); if (err) return err; diff --git a/drivers/gpu/drm/xe/xe_oa.c b/drivers/gpu/drm/xe/xe_oa.c index a4894eb0d7f3f3..125698a9ecf1c4 100644 --- a/drivers/gpu/drm/xe/xe_oa.c +++ b/drivers/gpu/drm/xe/xe_oa.c @@ -10,6 +10,7 @@ #include #include +#include #include #include @@ -1389,7 +1390,9 @@ static int xe_oa_user_extensions(struct xe_oa *oa, enum xe_oa_user_extn_from fro return 0; } -static int xe_oa_parse_syncs(struct xe_oa *oa, struct xe_oa_open_param *param) +static int xe_oa_parse_syncs(struct xe_oa *oa, + struct xe_oa_stream *stream, + struct xe_oa_open_param *param) { int ret, num_syncs, num_ufence = 0; @@ -1409,7 +1412,9 @@ static int xe_oa_parse_syncs(struct xe_oa *oa, struct xe_oa_open_param *param) for (num_syncs = 0; num_syncs < param->num_syncs; num_syncs++) { ret = xe_sync_entry_parse(oa->xe, param->xef, ¶m->syncs[num_syncs], - ¶m->syncs_user[num_syncs], 0); + ¶m->syncs_user[num_syncs], + stream->ufence_syncobj, + ++stream->ufence_timeline_value, 0); if (ret) goto err_syncs; @@ -1539,7 +1544,7 @@ static long xe_oa_config_locked(struct xe_oa_stream *stream, u64 arg) return -ENODEV; param.xef = stream->xef; - err = xe_oa_parse_syncs(stream->oa, ¶m); + err = xe_oa_parse_syncs(stream->oa, stream, ¶m); if (err) goto err_config_put; @@ -1635,6 +1640,7 @@ static void xe_oa_destroy_locked(struct xe_oa_stream *stream) if (stream->exec_q) xe_exec_queue_put(stream->exec_q); + drm_syncobj_put(stream->ufence_syncobj); kfree(stream); } @@ -1826,6 +1832,7 @@ static int xe_oa_stream_open_ioctl_locked(struct xe_oa *oa, struct xe_oa_open_param *param) { struct xe_oa_stream *stream; + struct drm_syncobj *ufence_syncobj; int stream_fd; int ret; @@ -1836,17 +1843,31 @@ static int xe_oa_stream_open_ioctl_locked(struct xe_oa *oa, goto exit; } + ret = drm_syncobj_create(&ufence_syncobj, DRM_SYNCOBJ_CREATE_SIGNALED, + NULL); + if (ret) + goto exit; + stream = kzalloc(sizeof(*stream), GFP_KERNEL); if (!stream) { ret = -ENOMEM; - goto exit; + goto err_syncobj; } - + stream->ufence_syncobj = ufence_syncobj; stream->oa = oa; - ret = xe_oa_stream_init(stream, param); + + ret = xe_oa_parse_syncs(oa, stream, param); if (ret) goto err_free; + ret = xe_oa_stream_init(stream, param); + if (ret) { + while (param->num_syncs--) + xe_sync_entry_cleanup(¶m->syncs[param->num_syncs]); + kfree(param->syncs); + goto err_free; + } + if (!param->disabled) { ret = xe_oa_enable_locked(stream); if (ret) @@ -1870,6 +1891,8 @@ static int xe_oa_stream_open_ioctl_locked(struct xe_oa *oa, xe_oa_stream_destroy(stream); err_free: kfree(stream); +err_syncobj: + drm_syncobj_put(ufence_syncobj); exit: return ret; } @@ -2083,22 +2106,14 @@ int xe_oa_stream_open_ioctl(struct drm_device *dev, u64 data, struct drm_file *f goto err_exec_q; } - ret = xe_oa_parse_syncs(oa, ¶m); - if (ret) - goto err_exec_q; - mutex_lock(¶m.hwe->gt->oa.gt_lock); ret = xe_oa_stream_open_ioctl_locked(oa, ¶m); mutex_unlock(¶m.hwe->gt->oa.gt_lock); if (ret < 0) - goto err_sync_cleanup; + goto err_exec_q; return ret; -err_sync_cleanup: - while (param.num_syncs--) - xe_sync_entry_cleanup(¶m.syncs[param.num_syncs]); - kfree(param.syncs); err_exec_q: if (param.exec_q) xe_exec_queue_put(param.exec_q); diff --git a/drivers/gpu/drm/xe/xe_oa_types.h b/drivers/gpu/drm/xe/xe_oa_types.h index 2628f78c4e8dc4..daf701b5d48b9d 100644 --- a/drivers/gpu/drm/xe/xe_oa_types.h +++ b/drivers/gpu/drm/xe/xe_oa_types.h @@ -15,6 +15,8 @@ #include "regs/xe_reg_defs.h" #include "xe_hw_engine_types.h" +struct drm_syncobj; + #define DEFAULT_XE_OA_BUFFER_SIZE SZ_16M enum xe_oa_report_header { @@ -248,6 +250,12 @@ struct xe_oa_stream { /** @xef: xe_file with which the stream was opened */ struct xe_file *xef; + /** @ufence_syncobj: User fence syncobj */ + struct drm_syncobj *ufence_syncobj; + + /** @ufence_timeline_value: User fence timeline value */ + u64 ufence_timeline_value; + /** @last_fence: fence to use in stream destroy when needed */ struct dma_fence *last_fence; diff --git a/drivers/gpu/drm/xe/xe_pci.c b/drivers/gpu/drm/xe/xe_pci.c index 9a6df79fc5b6ba..89cc6d32f041bd 100644 --- a/drivers/gpu/drm/xe/xe_pci.c +++ b/drivers/gpu/drm/xe/xe_pci.c @@ -375,6 +375,7 @@ static const struct pci_device_id pciidlist[] = { INTEL_LNL_IDS(INTEL_VGA_DEVICE, &lnl_desc), INTEL_BMG_IDS(INTEL_VGA_DEVICE, &bmg_desc), INTEL_PTL_IDS(INTEL_VGA_DEVICE, &ptl_desc), + INTEL_WCL_IDS(INTEL_VGA_DEVICE, &ptl_desc), { } }; MODULE_DEVICE_TABLE(pci, pciidlist); diff --git a/drivers/gpu/drm/xe/xe_sync.c b/drivers/gpu/drm/xe/xe_sync.c index 82872a51f0983a..d48ab7b32ca51c 100644 --- a/drivers/gpu/drm/xe/xe_sync.c +++ b/drivers/gpu/drm/xe/xe_sync.c @@ -113,6 +113,8 @@ static void user_fence_cb(struct dma_fence *fence, struct dma_fence_cb *cb) int xe_sync_entry_parse(struct xe_device *xe, struct xe_file *xef, struct xe_sync_entry *sync, struct drm_xe_sync __user *sync_user, + struct drm_syncobj *ufence_syncobj, + u64 ufence_timeline_value, unsigned int flags) { struct drm_xe_sync sync_in; @@ -192,10 +194,15 @@ int xe_sync_entry_parse(struct xe_device *xe, struct xe_file *xef, if (exec) { sync->addr = sync_in.addr; } else { + sync->ufence_timeline_value = ufence_timeline_value; sync->ufence = user_fence_create(xe, sync_in.addr, sync_in.timeline_value); if (XE_IOCTL_DBG(xe, IS_ERR(sync->ufence))) return PTR_ERR(sync->ufence); + sync->ufence_chain_fence = dma_fence_chain_alloc(); + if (!sync->ufence_chain_fence) + return -ENOMEM; + sync->ufence_syncobj = ufence_syncobj; } break; @@ -239,7 +246,12 @@ void xe_sync_entry_signal(struct xe_sync_entry *sync, struct dma_fence *fence) } else if (sync->ufence) { int err; - dma_fence_get(fence); + drm_syncobj_add_point(sync->ufence_syncobj, + sync->ufence_chain_fence, + fence, sync->ufence_timeline_value); + sync->ufence_chain_fence = NULL; + + fence = drm_syncobj_fence_get(sync->ufence_syncobj); user_fence_get(sync->ufence); err = dma_fence_add_callback(fence, &sync->ufence->cb, user_fence_cb); @@ -259,7 +271,8 @@ void xe_sync_entry_cleanup(struct xe_sync_entry *sync) drm_syncobj_put(sync->syncobj); dma_fence_put(sync->fence); dma_fence_chain_free(sync->chain_fence); - if (sync->ufence) + dma_fence_chain_free(sync->ufence_chain_fence); + if (!IS_ERR_OR_NULL(sync->ufence)) user_fence_put(sync->ufence); } diff --git a/drivers/gpu/drm/xe/xe_sync.h b/drivers/gpu/drm/xe/xe_sync.h index 256ffc1e54dc7c..51f2d803e97766 100644 --- a/drivers/gpu/drm/xe/xe_sync.h +++ b/drivers/gpu/drm/xe/xe_sync.h @@ -8,6 +8,7 @@ #include "xe_sync_types.h" +struct drm_syncobj; struct xe_device; struct xe_exec_queue; struct xe_file; @@ -21,6 +22,8 @@ struct xe_vm; int xe_sync_entry_parse(struct xe_device *xe, struct xe_file *xef, struct xe_sync_entry *sync, struct drm_xe_sync __user *sync_user, + struct drm_syncobj *ufence_syncobj, + u64 ufence_timeline_value, unsigned int flags); int xe_sync_entry_add_deps(struct xe_sync_entry *sync, struct xe_sched_job *job); diff --git a/drivers/gpu/drm/xe/xe_sync_types.h b/drivers/gpu/drm/xe/xe_sync_types.h index 30ac3f51993b94..b88f1833e28cc2 100644 --- a/drivers/gpu/drm/xe/xe_sync_types.h +++ b/drivers/gpu/drm/xe/xe_sync_types.h @@ -18,9 +18,12 @@ struct xe_sync_entry { struct drm_syncobj *syncobj; struct dma_fence *fence; struct dma_fence_chain *chain_fence; + struct dma_fence_chain *ufence_chain_fence; + struct drm_syncobj *ufence_syncobj; struct xe_user_fence *ufence; u64 addr; u64 timeline_value; + u64 ufence_timeline_value; u32 type; u32 flags; }; diff --git a/drivers/gpu/drm/xe/xe_vm.c b/drivers/gpu/drm/xe/xe_vm.c index 63c65e3d207ba6..cdd1dc540a59e6 100644 --- a/drivers/gpu/drm/xe/xe_vm.c +++ b/drivers/gpu/drm/xe/xe_vm.c @@ -3369,8 +3369,10 @@ static int vm_bind_ioctl_check_args(struct xe_device *xe, struct xe_vm *vm, op == DRM_XE_VM_BIND_OP_PREFETCH) || XE_IOCTL_DBG(xe, prefetch_region && op != DRM_XE_VM_BIND_OP_PREFETCH) || - XE_IOCTL_DBG(xe, (prefetch_region != DRM_XE_CONSULT_MEM_ADVISE_PREF_LOC && - !(BIT(prefetch_region) & xe->info.mem_region_mask))) || + XE_IOCTL_DBG(xe, (prefetch_region != DRM_XE_CONSULT_MEM_ADVISE_PREF_LOC && + /* Guard against undefined shift in BIT(prefetch_region) */ + (prefetch_region >= (sizeof(xe->info.mem_region_mask) * 8) || + !(BIT(prefetch_region) & xe->info.mem_region_mask)))) || XE_IOCTL_DBG(xe, obj && op == DRM_XE_VM_BIND_OP_UNMAP) || XE_IOCTL_DBG(xe, (flags & DRM_XE_VM_BIND_FLAG_MADVISE_AUTORESET) && @@ -3606,8 +3608,12 @@ int xe_vm_bind_ioctl(struct drm_device *dev, void *data, struct drm_file *file) syncs_user = u64_to_user_ptr(args->syncs); for (num_syncs = 0; num_syncs < args->num_syncs; num_syncs++) { + struct xe_exec_queue *__q = q ?: vm->q[0]; + err = xe_sync_entry_parse(xe, xef, &syncs[num_syncs], &syncs_user[num_syncs], + __q->ufence_syncobj, + ++__q->ufence_timeline_value, (xe_vm_in_lr_mode(vm) ? SYNC_PARSE_FLAG_LR_MODE : 0) | (!args->num_binds ? diff --git a/drivers/gpu/drm/xe/xe_wa.c b/drivers/gpu/drm/xe/xe_wa.c index cd03891654a153..3cf30718b20039 100644 --- a/drivers/gpu/drm/xe/xe_wa.c +++ b/drivers/gpu/drm/xe/xe_wa.c @@ -679,6 +679,8 @@ static const struct xe_rtp_entry_sr engine_was[] = { }, { XE_RTP_NAME("14023061436"), XE_RTP_RULES(GRAPHICS_VERSION_RANGE(3000, 3001), + FUNC(xe_rtp_match_first_render_or_compute), OR, + GRAPHICS_VERSION_RANGE(3003, 3005), FUNC(xe_rtp_match_first_render_or_compute)), XE_RTP_ACTIONS(SET(TDL_CHICKEN, QID_WAIT_FOR_THREAD_NOT_RUN_DISABLE)) }, @@ -916,6 +918,15 @@ static const struct xe_rtp_entry_sr lrc_was[] = { XE_RTP_RULES(GRAPHICS_VERSION_RANGE(3000, 3003), ENGINE_CLASS(RENDER)), XE_RTP_ACTIONS(SET(COMMON_SLICE_CHICKEN4, SBE_PUSH_CONSTANT_BEHIND_FIX_ENABLE)) }, + { XE_RTP_NAME("14024681466"), + XE_RTP_RULES(GRAPHICS_VERSION_RANGE(3000, 3005), ENGINE_CLASS(RENDER)), + XE_RTP_ACTIONS(SET(XEHP_SLICE_COMMON_ECO_CHICKEN1, FAST_CLEAR_VALIGN_FIX)) + }, + { XE_RTP_NAME("15016589081"), + XE_RTP_RULES(GRAPHICS_VERSION(3000), GRAPHICS_STEP(A0, B0), + ENGINE_CLASS(RENDER)), + XE_RTP_ACTIONS(SET(CHICKEN_RASTER_1, DIS_CLIP_NEGATIVE_BOUNDING_BOX)) + }, }; static __maybe_unused const struct xe_rtp_entry oob_was[] = { diff --git a/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_init.c b/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_init.c index 0a9b44ce4904e4..b0bab2a1ddcc5b 100644 --- a/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_init.c +++ b/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_init.c @@ -194,6 +194,8 @@ static int amd_sfh1_1_hid_client_init(struct amd_mp2_dev *privdata) if (rc) goto cleanup; + mp2_ops->stop(privdata, cl_data->sensor_idx[i]); + amd_sfh_wait_for_response(privdata, cl_data->sensor_idx[i], DISABLE_SENSOR); writel(0, privdata->mmio + amd_get_p2c_val(privdata, 0)); mp2_ops->start(privdata, info); status = amd_sfh_wait_for_response diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c index 61404d7a43ee1e..57da4f86a9fa7f 100644 --- a/drivers/hid/hid-apple.c +++ b/drivers/hid/hid-apple.c @@ -355,6 +355,7 @@ static const struct apple_key_translation swapped_fn_leftctrl_keys[] = { static const struct apple_non_apple_keyboard non_apple_keyboards[] = { { "SONiX USB DEVICE" }, + { "SONiX AK870 PRO" }, { "Keychron" }, { "AONE" }, { "GANSS" }, diff --git a/drivers/hid/hid-corsair-void.c b/drivers/hid/hid-corsair-void.c index fee134a7eba3a2..5e9a5b8f7f167b 100644 --- a/drivers/hid/hid-corsair-void.c +++ b/drivers/hid/hid-corsair-void.c @@ -553,9 +553,8 @@ static void corsair_void_add_battery(struct corsair_void_drvdata *drvdata) if (IS_ERR(new_supply)) { hid_err(drvdata->hid_dev, - "failed to register battery '%s' (reason: %ld)\n", - drvdata->battery_desc.name, - PTR_ERR(new_supply)); + "failed to register battery '%s' (reason: %pe)\n", + drvdata->battery_desc.name, new_supply); return; } diff --git a/drivers/hid/hid-elecom.c b/drivers/hid/hid-elecom.c index 69771fd3500605..981d1b6e96589c 100644 --- a/drivers/hid/hid-elecom.c +++ b/drivers/hid/hid-elecom.c @@ -75,7 +75,8 @@ static const __u8 *elecom_report_fixup(struct hid_device *hdev, __u8 *rdesc, */ mouse_button_fixup(hdev, rdesc, *rsize, 20, 28, 22, 14, 8); break; - case USB_DEVICE_ID_ELECOM_M_XT3URBK: + case USB_DEVICE_ID_ELECOM_M_XT3URBK_00FB: + case USB_DEVICE_ID_ELECOM_M_XT3URBK_018F: case USB_DEVICE_ID_ELECOM_M_XT3DRBK: case USB_DEVICE_ID_ELECOM_M_XT4DRBK: /* @@ -119,7 +120,8 @@ static const __u8 *elecom_report_fixup(struct hid_device *hdev, __u8 *rdesc, static const struct hid_device_id elecom_devices[] = { { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_BM084) }, { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XGL20DLBK) }, - { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT3URBK) }, + { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT3URBK_00FB) }, + { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT3URBK_018F) }, { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT3DRBK) }, { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT4DRBK) }, { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_DT1URBK) }, diff --git a/drivers/hid/hid-haptic.c b/drivers/hid/hid-haptic.c index aa090684c1f23b..fc8a9997f81538 100644 --- a/drivers/hid/hid-haptic.c +++ b/drivers/hid/hid-haptic.c @@ -86,7 +86,7 @@ int hid_haptic_input_configured(struct hid_device *hdev, if (hi->application == HID_DG_TOUCHPAD) { if (haptic->auto_trigger_report && haptic->manual_trigger_report) { - __set_bit(INPUT_PROP_HAPTIC_TOUCHPAD, hi->input->propbit); + __set_bit(INPUT_PROP_PRESSUREPAD, hi->input->propbit); return 1; } return 0; diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 0723b4b1c9eca4..c4589075a5ed68 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -449,7 +449,8 @@ #define USB_VENDOR_ID_ELECOM 0x056e #define USB_DEVICE_ID_ELECOM_BM084 0x0061 #define USB_DEVICE_ID_ELECOM_M_XGL20DLBK 0x00e6 -#define USB_DEVICE_ID_ELECOM_M_XT3URBK 0x00fb +#define USB_DEVICE_ID_ELECOM_M_XT3URBK_00FB 0x00fb +#define USB_DEVICE_ID_ELECOM_M_XT3URBK_018F 0x018f #define USB_DEVICE_ID_ELECOM_M_XT3DRBK 0x00fc #define USB_DEVICE_ID_ELECOM_M_XT4DRBK 0x00fd #define USB_DEVICE_ID_ELECOM_M_DT1URBK 0x00fe @@ -718,6 +719,7 @@ #define USB_DEVICE_ID_ITE_LENOVO_YOGA2 0x8350 #define I2C_DEVICE_ID_ITE_LENOVO_LEGION_Y720 0x837a #define USB_DEVICE_ID_ITE_LENOVO_YOGA900 0x8396 +#define I2C_DEVICE_ID_ITE_LENOVO_YOGA_SLIM_7X_KEYBOARD 0x8987 #define USB_DEVICE_ID_ITE8595 0x8595 #define USB_DEVICE_ID_ITE_MEDION_E1239T 0xce50 @@ -1543,7 +1545,7 @@ #define USB_VENDOR_ID_SIGNOTEC 0x2133 #define USB_DEVICE_ID_SIGNOTEC_VIEWSONIC_PD1011 0x0018 -#define USB_VENDOR_ID_SMARTLINKTECHNOLOGY 0x4c4a -#define USB_DEVICE_ID_SMARTLINKTECHNOLOGY_4155 0x4155 +#define USB_VENDOR_ID_JIELI_SDK_DEFAULT 0x4c4a +#define USB_DEVICE_ID_JIELI_SDK_4155 0x4155 #endif diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index e56e7de5327993..2bbb645c2ff418 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -399,10 +399,11 @@ static const struct hid_device_id hid_battery_quirks[] = { { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_CHROMEBOOK_TROGDOR_POMPOM), HID_BATTERY_QUIRK_AVOID_QUERY }, /* - * Elan I2C-HID touchscreens seem to all report a non present battery, - * set HID_BATTERY_QUIRK_IGNORE for all Elan I2C-HID devices. + * Elan HID touchscreens seem to all report a non present battery, + * set HID_BATTERY_QUIRK_IGNORE for all Elan I2C and USB HID devices. */ { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, HID_ANY_ID), HID_BATTERY_QUIRK_IGNORE }, + { HID_USB_DEVICE(USB_VENDOR_ID_ELAN, HID_ANY_ID), HID_BATTERY_QUIRK_IGNORE }, {} }; diff --git a/drivers/hid/hid-lenovo.c b/drivers/hid/hid-lenovo.c index 654879814f97aa..9cc3e029e9f613 100644 --- a/drivers/hid/hid-lenovo.c +++ b/drivers/hid/hid-lenovo.c @@ -148,6 +148,14 @@ static const __u8 lenovo_tpIIbtkbd_need_fixup_collection[] = { 0x81, 0x01, /* Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) */ }; +static const __u8 lenovo_yoga7x_kbd_need_fixup_collection[] = { + 0x15, 0x00, // Logical Minimum (0) + 0x25, 0x65, // Logical Maximum (101) + 0x05, 0x07, // Usage Page (Keyboard) + 0x19, 0x00, // Usage Minimum (0) + 0x29, 0xDD, // Usage Maximum (221) +}; + static const __u8 *lenovo_report_fixup(struct hid_device *hdev, __u8 *rdesc, unsigned int *rsize) { @@ -177,6 +185,13 @@ static const __u8 *lenovo_report_fixup(struct hid_device *hdev, __u8 *rdesc, rdesc[260] = 0x01; /* report count (2) = 0x01 */ } break; + case I2C_DEVICE_ID_ITE_LENOVO_YOGA_SLIM_7X_KEYBOARD: + if (*rsize == 176 && + memcmp(&rdesc[52], lenovo_yoga7x_kbd_need_fixup_collection, + sizeof(lenovo_yoga7x_kbd_need_fixup_collection)) == 0) { + rdesc[55] = rdesc[61]; // logical maximum = usage maximum + } + break; } return rdesc; } @@ -1538,6 +1553,8 @@ static const struct hid_device_id lenovo_devices[] = { USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_X12_TAB) }, { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_X12_TAB2) }, + { HID_DEVICE(BUS_I2C, HID_GROUP_GENERIC, + USB_VENDOR_ID_ITE, I2C_DEVICE_ID_ITE_LENOVO_YOGA_SLIM_7X_KEYBOARD) }, { } }; diff --git a/drivers/hid/hid-ntrig.c b/drivers/hid/hid-ntrig.c index 0f76e241e0afb4..a7f10c45f62bda 100644 --- a/drivers/hid/hid-ntrig.c +++ b/drivers/hid/hid-ntrig.c @@ -142,13 +142,13 @@ static void ntrig_report_version(struct hid_device *hdev) int ret; char buf[20]; struct usb_device *usb_dev = hid_to_usb_dev(hdev); - unsigned char *data = kmalloc(8, GFP_KERNEL); + unsigned char *data __free(kfree) = kmalloc(8, GFP_KERNEL); if (!hid_is_usb(hdev)) return; if (!data) - goto err_free; + return; ret = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0), USB_REQ_CLEAR_FEATURE, @@ -163,9 +163,6 @@ static void ntrig_report_version(struct hid_device *hdev) hid_info(hdev, "Firmware version: %s (%02x%02x %02x%02x)\n", buf, data[2], data[3], data[4], data[5]); } - -err_free: - kfree(data); } static ssize_t show_phys_width(struct device *dev, diff --git a/drivers/hid/hid-playstation.c b/drivers/hid/hid-playstation.c index 63f6eb9030d13c..128aa6abd10bed 100644 --- a/drivers/hid/hid-playstation.c +++ b/drivers/hid/hid-playstation.c @@ -1942,6 +1942,7 @@ static int dualshock4_get_calibration_data(struct dualshock4 *ds4) "Failed to retrieve DualShock4 calibration info: %d\n", ret); ret = -EILSEQ; + kfree(buf); goto transfer_failed; } else { break; @@ -1959,6 +1960,7 @@ static int dualshock4_get_calibration_data(struct dualshock4 *ds4) if (ret) { hid_warn(hdev, "Failed to retrieve DualShock4 calibration info: %d\n", ret); + kfree(buf); goto transfer_failed; } } diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c index bcd4bccf1a7cee..c89a015686c07e 100644 --- a/drivers/hid/hid-quirks.c +++ b/drivers/hid/hid-quirks.c @@ -410,7 +410,8 @@ static const struct hid_device_id hid_have_special_driver[] = { #if IS_ENABLED(CONFIG_HID_ELECOM) { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_BM084) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XGL20DLBK) }, - { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT3URBK) }, + { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT3URBK_00FB) }, + { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT3URBK_018F) }, { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT3DRBK) }, { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT4DRBK) }, { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_DT1URBK) }, @@ -915,7 +916,6 @@ static const struct hid_device_id hid_ignore_list[] = { #endif { HID_USB_DEVICE(USB_VENDOR_ID_YEALINK, USB_DEVICE_ID_YEALINK_P1K_P4K_B2K) }, { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_HP_5MP_CAMERA_5473) }, - { HID_USB_DEVICE(USB_VENDOR_ID_SMARTLINKTECHNOLOGY, USB_DEVICE_ID_SMARTLINKTECHNOLOGY_4155) }, { } }; @@ -1064,6 +1064,18 @@ bool hid_ignore(struct hid_device *hdev) strlen(elan_acpi_id[i].id))) return true; break; + case USB_VENDOR_ID_JIELI_SDK_DEFAULT: + /* + * Multiple USB devices with identical IDs (mic & touchscreen). + * The touch screen requires hid core processing, but the + * microphone does not. They can be distinguished by manufacturer + * and serial number. + */ + if (hdev->product == USB_DEVICE_ID_JIELI_SDK_4155 && + strncmp(hdev->name, "SmartlinkTechnology", 19) == 0 && + strncmp(hdev->uniq, "20201111000001", 14) == 0) + return true; + break; } if (hdev->type == HID_TYPE_USBMOUSE && diff --git a/drivers/hid/hid-uclogic-params.c b/drivers/hid/hid-uclogic-params.c index ffa14a4621ef45..4c4bac6f792b2f 100644 --- a/drivers/hid/hid-uclogic-params.c +++ b/drivers/hid/hid-uclogic-params.c @@ -1369,8 +1369,10 @@ static int uclogic_params_ugee_v2_init_event_hooks(struct hid_device *hdev, event_hook->hdev = hdev; event_hook->size = ARRAY_SIZE(reconnect_event); event_hook->event = kmemdup(reconnect_event, event_hook->size, GFP_KERNEL); - if (!event_hook->event) + if (!event_hook->event) { + kfree(event_hook); return -ENOMEM; + } list_add_tail(&event_hook->list, &p->event_hooks->list); diff --git a/drivers/hid/usbhid/hid-pidff.c b/drivers/hid/usbhid/hid-pidff.c index edd61ef50e16a2..95377c5f63356b 100644 --- a/drivers/hid/usbhid/hid-pidff.c +++ b/drivers/hid/usbhid/hid-pidff.c @@ -806,8 +806,8 @@ static int pidff_request_effect_upload(struct pidff_device *pidff, int efnum) static int pidff_needs_playback(struct pidff_device *pidff, int effect_id, int n) { - return pidff->effect[effect_id].is_infinite || - pidff->effect[effect_id].loop_count != n; + return !pidff->effect[effect_id].is_infinite || + pidff->effect[effect_id].loop_count != n; } /* diff --git a/drivers/hwmon/gpd-fan.c b/drivers/hwmon/gpd-fan.c index 321794807e8d85..f81c3bc422f4ce 100644 --- a/drivers/hwmon/gpd-fan.c +++ b/drivers/hwmon/gpd-fan.c @@ -12,9 +12,9 @@ * Copyright (c) 2024 Cryolitia PukNgae */ -#include #include #include +#include #include #include #include @@ -276,31 +276,6 @@ static int gpd_generic_read_rpm(void) return (u16)high << 8 | low; } -static void gpd_win4_init_ec(void) -{ - u8 chip_id, chip_ver; - - gpd_ecram_read(0x2000, &chip_id); - - if (chip_id == 0x55) { - gpd_ecram_read(0x1060, &chip_ver); - gpd_ecram_write(0x1060, chip_ver | 0x80); - } -} - -static int gpd_win4_read_rpm(void) -{ - int ret; - - ret = gpd_generic_read_rpm(); - - if (ret == 0) - // Re-init EC when speed is 0 - gpd_win4_init_ec(); - - return ret; -} - static int gpd_wm2_read_rpm(void) { for (u16 pwm_ctr_offset = GPD_PWM_CTR_OFFSET; @@ -320,11 +295,10 @@ static int gpd_wm2_read_rpm(void) static int gpd_read_rpm(void) { switch (gpd_driver_priv.drvdata->board) { + case win4_6800u: case win_mini: case duo: return gpd_generic_read_rpm(); - case win4_6800u: - return gpd_win4_read_rpm(); case win_max_2: return gpd_wm2_read_rpm(); } @@ -607,6 +581,28 @@ static struct hwmon_chip_info gpd_fan_chip_info = { .info = gpd_fan_hwmon_channel_info }; +static void gpd_win4_init_ec(void) +{ + u8 chip_id, chip_ver; + + gpd_ecram_read(0x2000, &chip_id); + + if (chip_id == 0x55) { + gpd_ecram_read(0x1060, &chip_ver); + gpd_ecram_write(0x1060, chip_ver | 0x80); + } +} + +static void gpd_init_ec(void) +{ + // The buggy firmware won't initialize EC properly on boot. + // Before its initialization, reading RPM will always return 0, + // and writing PWM will have no effect. + // Initialize it manually on driver load. + if (gpd_driver_priv.drvdata->board == win4_6800u) + gpd_win4_init_ec(); +} + static int gpd_fan_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -634,6 +630,8 @@ static int gpd_fan_probe(struct platform_device *pdev) return dev_err_probe(dev, PTR_ERR(hwdev), "Failed to register hwmon device\n"); + gpd_init_ec(); + return 0; } diff --git a/drivers/i2c/muxes/i2c-mux-pca954x.c b/drivers/i2c/muxes/i2c-mux-pca954x.c index 75c8d08fa24e56..b9f370c9f018c2 100644 --- a/drivers/i2c/muxes/i2c-mux-pca954x.c +++ b/drivers/i2c/muxes/i2c-mux-pca954x.c @@ -118,6 +118,7 @@ struct pca954x { raw_spinlock_t lock; struct regulator *supply; + struct gpio_desc *reset_gpio; struct reset_control *reset_cont; }; @@ -315,25 +316,6 @@ static u8 pca954x_regval(struct pca954x *data, u8 chan) return 1 << chan; } -static void pca954x_reset_assert(struct pca954x *data) -{ - if (data->reset_cont) - reset_control_assert(data->reset_cont); -} - -static void pca954x_reset_deassert(struct pca954x *data) -{ - if (data->reset_cont) - reset_control_deassert(data->reset_cont); -} - -static void pca954x_reset_mux(struct pca954x *data) -{ - pca954x_reset_assert(data); - udelay(1); - pca954x_reset_deassert(data); -} - static int pca954x_select_chan(struct i2c_mux_core *muxc, u32 chan) { struct pca954x *data = i2c_mux_priv(muxc); @@ -347,8 +329,6 @@ static int pca954x_select_chan(struct i2c_mux_core *muxc, u32 chan) ret = pca954x_reg_write(muxc->parent, client, regval); data->last_chan = ret < 0 ? 0 : regval; } - if (ret == -ETIMEDOUT && data->reset_cont) - pca954x_reset_mux(data); return ret; } @@ -358,7 +338,6 @@ static int pca954x_deselect_mux(struct i2c_mux_core *muxc, u32 chan) struct pca954x *data = i2c_mux_priv(muxc); struct i2c_client *client = data->client; s32 idle_state; - int ret = 0; idle_state = READ_ONCE(data->idle_state); if (idle_state >= 0) @@ -368,10 +347,8 @@ static int pca954x_deselect_mux(struct i2c_mux_core *muxc, u32 chan) if (idle_state == MUX_IDLE_DISCONNECT) { /* Deselect active channel */ data->last_chan = 0; - ret = pca954x_reg_write(muxc->parent, client, - data->last_chan); - if (ret == -ETIMEDOUT && data->reset_cont) - pca954x_reset_mux(data); + return pca954x_reg_write(muxc->parent, client, + data->last_chan); } /* otherwise leave as-is */ @@ -550,10 +527,29 @@ static int pca954x_get_reset(struct device *dev, struct pca954x *data) if (IS_ERR(data->reset_cont)) return dev_err_probe(dev, PTR_ERR(data->reset_cont), "Failed to get reset\n"); + else if (data->reset_cont) + return 0; + + /* + * fallback to legacy reset-gpios + */ + data->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH); + if (IS_ERR(data->reset_gpio)) { + return dev_err_probe(dev, PTR_ERR(data->reset_gpio), + "Failed to get reset gpio"); + } return 0; } +static void pca954x_reset_deassert(struct pca954x *data) +{ + if (data->reset_cont) + reset_control_deassert(data->reset_cont); + else + gpiod_set_value_cansleep(data->reset_gpio, 0); +} + /* * I2C init/probing/exit functions */ @@ -593,7 +589,7 @@ static int pca954x_probe(struct i2c_client *client) if (ret) goto fail_cleanup; - if (data->reset_cont) { + if (data->reset_cont || data->reset_gpio) { udelay(1); pca954x_reset_deassert(data); /* Give the chip some time to recover. */ diff --git a/drivers/infiniband/core/uverbs_std_types_cq.c b/drivers/infiniband/core/uverbs_std_types_cq.c index 37cd3755651040..fab5d914029dd7 100644 --- a/drivers/infiniband/core/uverbs_std_types_cq.c +++ b/drivers/infiniband/core/uverbs_std_types_cq.c @@ -206,6 +206,7 @@ static int UVERBS_HANDLER(UVERBS_METHOD_CQ_CREATE)( return ret; err_free: + ib_umem_release(umem); rdma_restrack_put(&cq->res); kfree(cq); err_event_file: diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/drivers/infiniband/hw/bnxt_re/ib_verbs.c index 4dab5ca7362b56..84ce3fce2826b7 100644 --- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c +++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c @@ -913,7 +913,7 @@ void bnxt_re_unlock_cqs(struct bnxt_re_qp *qp, spin_unlock_irqrestore(&qp->scq->cq_lock, flags); } -static int bnxt_re_destroy_gsi_sqp(struct bnxt_re_qp *qp) +static void bnxt_re_destroy_gsi_sqp(struct bnxt_re_qp *qp) { struct bnxt_re_qp *gsi_sqp; struct bnxt_re_ah *gsi_sah; @@ -933,10 +933,9 @@ static int bnxt_re_destroy_gsi_sqp(struct bnxt_re_qp *qp) ibdev_dbg(&rdev->ibdev, "Destroy the shadow QP\n"); rc = bnxt_qplib_destroy_qp(&rdev->qplib_res, &gsi_sqp->qplib_qp); - if (rc) { + if (rc) ibdev_err(&rdev->ibdev, "Destroy Shadow QP failed"); - goto fail; - } + bnxt_qplib_free_qp_res(&rdev->qplib_res, &gsi_sqp->qplib_qp); /* remove from active qp list */ @@ -951,10 +950,6 @@ static int bnxt_re_destroy_gsi_sqp(struct bnxt_re_qp *qp) rdev->gsi_ctx.gsi_sqp = NULL; rdev->gsi_ctx.gsi_sah = NULL; rdev->gsi_ctx.sqp_tbl = NULL; - - return 0; -fail: - return rc; } static void bnxt_re_del_unique_gid(struct bnxt_re_dev *rdev) diff --git a/drivers/infiniband/hw/efa/efa_verbs.c b/drivers/infiniband/hw/efa/efa_verbs.c index d9a12681f84341..22d3e25c3b9d11 100644 --- a/drivers/infiniband/hw/efa/efa_verbs.c +++ b/drivers/infiniband/hw/efa/efa_verbs.c @@ -1216,13 +1216,13 @@ int efa_create_cq_umem(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr, if (umem->length < cq->size) { ibdev_dbg(&dev->ibdev, "External memory too small\n"); err = -EINVAL; - goto err_free_mem; + goto err_out; } if (!ib_umem_is_contiguous(umem)) { ibdev_dbg(&dev->ibdev, "Non contiguous CQ unsupported\n"); err = -EINVAL; - goto err_free_mem; + goto err_out; } cq->cpu_addr = NULL; @@ -1251,7 +1251,7 @@ int efa_create_cq_umem(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr, err = efa_com_create_cq(&dev->edev, ¶ms, &result); if (err) - goto err_free_mem; + goto err_free_mapped; resp.db_off = result.db_off; resp.cq_idx = result.cq_idx; @@ -1299,12 +1299,10 @@ int efa_create_cq_umem(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr, efa_cq_user_mmap_entries_remove(cq); err_destroy_cq: efa_destroy_cq_idx(dev, cq->cq_idx); -err_free_mem: - if (umem) - ib_umem_release(umem); - else - efa_free_mapped(dev, cq->cpu_addr, cq->dma_addr, cq->size, DMA_FROM_DEVICE); - +err_free_mapped: + if (!umem) + efa_free_mapped(dev, cq->cpu_addr, cq->dma_addr, cq->size, + DMA_FROM_DEVICE); err_out: atomic64_inc(&dev->stats.create_cq_err); return err; diff --git a/drivers/infiniband/hw/hns/hns_roce_cq.c b/drivers/infiniband/hw/hns/hns_roce_cq.c index 3a5c93c9fb3e66..6aa82fe9dd3dfb 100644 --- a/drivers/infiniband/hw/hns/hns_roce_cq.c +++ b/drivers/infiniband/hw/hns/hns_roce_cq.c @@ -30,6 +30,7 @@ * SOFTWARE. */ +#include #include #include #include "hns_roce_device.h" @@ -37,6 +38,43 @@ #include "hns_roce_hem.h" #include "hns_roce_common.h" +void hns_roce_put_cq_bankid_for_uctx(struct hns_roce_ucontext *uctx) +{ + struct hns_roce_dev *hr_dev = to_hr_dev(uctx->ibucontext.device); + struct hns_roce_cq_table *cq_table = &hr_dev->cq_table; + + if (hr_dev->pci_dev->revision < PCI_REVISION_ID_HIP09) + return; + + mutex_lock(&cq_table->bank_mutex); + cq_table->ctx_num[uctx->cq_bank_id]--; + mutex_unlock(&cq_table->bank_mutex); +} + +void hns_roce_get_cq_bankid_for_uctx(struct hns_roce_ucontext *uctx) +{ + struct hns_roce_dev *hr_dev = to_hr_dev(uctx->ibucontext.device); + struct hns_roce_cq_table *cq_table = &hr_dev->cq_table; + u32 least_load = cq_table->ctx_num[0]; + u8 bankid = 0; + u8 i; + + if (hr_dev->pci_dev->revision < PCI_REVISION_ID_HIP09) + return; + + mutex_lock(&cq_table->bank_mutex); + for (i = 1; i < HNS_ROCE_CQ_BANK_NUM; i++) { + if (cq_table->ctx_num[i] < least_load) { + least_load = cq_table->ctx_num[i]; + bankid = i; + } + } + cq_table->ctx_num[bankid]++; + mutex_unlock(&cq_table->bank_mutex); + + uctx->cq_bank_id = bankid; +} + static u8 get_least_load_bankid_for_cq(struct hns_roce_bank *bank) { u32 least_load = bank[0].inuse; @@ -55,7 +93,21 @@ static u8 get_least_load_bankid_for_cq(struct hns_roce_bank *bank) return bankid; } -static int alloc_cqn(struct hns_roce_dev *hr_dev, struct hns_roce_cq *hr_cq) +static u8 select_cq_bankid(struct hns_roce_dev *hr_dev, + struct hns_roce_bank *bank, struct ib_udata *udata) +{ + struct hns_roce_ucontext *uctx = udata ? + rdma_udata_to_drv_context(udata, struct hns_roce_ucontext, + ibucontext) : NULL; + + if (hr_dev->pci_dev->revision >= PCI_REVISION_ID_HIP09) + return uctx ? uctx->cq_bank_id : 0; + + return get_least_load_bankid_for_cq(bank); +} + +static int alloc_cqn(struct hns_roce_dev *hr_dev, struct hns_roce_cq *hr_cq, + struct ib_udata *udata) { struct hns_roce_cq_table *cq_table = &hr_dev->cq_table; struct hns_roce_bank *bank; @@ -63,7 +115,7 @@ static int alloc_cqn(struct hns_roce_dev *hr_dev, struct hns_roce_cq *hr_cq) int id; mutex_lock(&cq_table->bank_mutex); - bankid = get_least_load_bankid_for_cq(cq_table->bank); + bankid = select_cq_bankid(hr_dev, cq_table->bank, udata); bank = &cq_table->bank[bankid]; id = ida_alloc_range(&bank->ida, bank->min, bank->max, GFP_KERNEL); @@ -396,7 +448,7 @@ int hns_roce_create_cq(struct ib_cq *ib_cq, const struct ib_cq_init_attr *attr, goto err_cq_buf; } - ret = alloc_cqn(hr_dev, hr_cq); + ret = alloc_cqn(hr_dev, hr_cq, udata); if (ret) { ibdev_err(ibdev, "failed to alloc CQN, ret = %d.\n", ret); goto err_cq_db; diff --git a/drivers/infiniband/hw/hns/hns_roce_device.h b/drivers/infiniband/hw/hns/hns_roce_device.h index 78ee04a48a74a8..06832c0ac05561 100644 --- a/drivers/infiniband/hw/hns/hns_roce_device.h +++ b/drivers/infiniband/hw/hns/hns_roce_device.h @@ -217,6 +217,7 @@ struct hns_roce_ucontext { struct mutex page_mutex; struct hns_user_mmap_entry *db_mmap_entry; u32 config; + u8 cq_bank_id; }; struct hns_roce_pd { @@ -495,6 +496,7 @@ struct hns_roce_cq_table { struct hns_roce_hem_table table; struct hns_roce_bank bank[HNS_ROCE_CQ_BANK_NUM]; struct mutex bank_mutex; + u32 ctx_num[HNS_ROCE_CQ_BANK_NUM]; }; struct hns_roce_srq_table { @@ -1305,5 +1307,7 @@ hns_roce_user_mmap_entry_insert(struct ib_ucontext *ucontext, u64 address, size_t length, enum hns_roce_mmap_type mmap_type); bool check_sl_valid(struct hns_roce_dev *hr_dev, u8 sl); +void hns_roce_put_cq_bankid_for_uctx(struct hns_roce_ucontext *uctx); +void hns_roce_get_cq_bankid_for_uctx(struct hns_roce_ucontext *uctx); #endif /* _HNS_ROCE_DEVICE_H */ diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c index f82bdd46a9174a..63052c0e76133b 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c @@ -165,6 +165,8 @@ static void set_frmr_seg(struct hns_roce_v2_rc_send_wqe *rc_sq_wqe, hr_reg_write(fseg, FRMR_PBL_BUF_PG_SZ, to_hr_hw_page_shift(mr->pbl_mtr.hem_cfg.buf_pg_shift)); hr_reg_clear(fseg, FRMR_BLK_MODE); + hr_reg_clear(fseg, FRMR_BLOCK_SIZE); + hr_reg_clear(fseg, FRMR_ZBVA); } static void set_atomic_seg(const struct ib_send_wr *wr, @@ -339,9 +341,6 @@ static int set_rwqe_data_seg(struct ib_qp *ibqp, const struct ib_send_wr *wr, int j = 0; int i; - hr_reg_write(rc_sq_wqe, RC_SEND_WQE_MSG_START_SGE_IDX, - (*sge_ind) & (qp->sge.sge_cnt - 1)); - hr_reg_write(rc_sq_wqe, RC_SEND_WQE_INLINE, !!(wr->send_flags & IB_SEND_INLINE)); if (wr->send_flags & IB_SEND_INLINE) @@ -586,6 +585,9 @@ static inline int set_rc_wqe(struct hns_roce_qp *qp, hr_reg_write(rc_sq_wqe, RC_SEND_WQE_CQE, (wr->send_flags & IB_SEND_SIGNALED) ? 1 : 0); + hr_reg_write(rc_sq_wqe, RC_SEND_WQE_MSG_START_SGE_IDX, + curr_idx & (qp->sge.sge_cnt - 1)); + if (wr->opcode == IB_WR_ATOMIC_CMP_AND_SWP || wr->opcode == IB_WR_ATOMIC_FETCH_AND_ADD) { if (msg_len != ATOMIC_WR_LEN) @@ -734,6 +736,9 @@ static int hns_roce_v2_post_send(struct ib_qp *ibqp, owner_bit = ~(((qp->sq.head + nreq) >> ilog2(qp->sq.wqe_cnt)) & 0x1); + /* RC and UD share the same DirectWQE field layout */ + ((struct hns_roce_v2_rc_send_wqe *)wqe)->byte_4 = 0; + /* Corresponding to the QP type, wqe process separately */ if (ibqp->qp_type == IB_QPT_RC) ret = set_rc_wqe(qp, wr, wqe, &sge_idx, owner_bit); @@ -7048,7 +7053,6 @@ static int __hns_roce_hw_v2_init_instance(struct hnae3_handle *handle) goto error_failed_roce_init; } - handle->priv = hr_dev; return 0; diff --git a/drivers/infiniband/hw/hns/hns_roce_main.c b/drivers/infiniband/hw/hns/hns_roce_main.c index d50f36f8a1107e..f3607fe107a7f9 100644 --- a/drivers/infiniband/hw/hns/hns_roce_main.c +++ b/drivers/infiniband/hw/hns/hns_roce_main.c @@ -425,6 +425,8 @@ static int hns_roce_alloc_ucontext(struct ib_ucontext *uctx, if (ret) goto error_fail_copy_to_udata; + hns_roce_get_cq_bankid_for_uctx(context); + return 0; error_fail_copy_to_udata: @@ -447,6 +449,8 @@ static void hns_roce_dealloc_ucontext(struct ib_ucontext *ibcontext) struct hns_roce_ucontext *context = to_hr_ucontext(ibcontext); struct hns_roce_dev *hr_dev = to_hr_dev(ibcontext->device); + hns_roce_put_cq_bankid_for_uctx(context); + if (hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_CQ_RECORD_DB || hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_QP_RECORD_DB) mutex_destroy(&context->page_mutex); diff --git a/drivers/infiniband/hw/hns/hns_roce_qp.c b/drivers/infiniband/hw/hns/hns_roce_qp.c index 6ff1b8ce580c50..bdd879ac12dda2 100644 --- a/drivers/infiniband/hw/hns/hns_roce_qp.c +++ b/drivers/infiniband/hw/hns/hns_roce_qp.c @@ -662,7 +662,6 @@ static int set_user_sq_size(struct hns_roce_dev *hr_dev, hr_qp->sq.wqe_shift = ucmd->log_sq_stride; hr_qp->sq.wqe_cnt = cnt; - cap->max_send_sge = hr_qp->sq.max_gs; return 0; } @@ -744,7 +743,6 @@ static int set_kernel_sq_size(struct hns_roce_dev *hr_dev, /* sync the parameters of kernel QP to user's configuration */ cap->max_send_wr = cnt; - cap->max_send_sge = hr_qp->sq.max_gs; return 0; } diff --git a/drivers/infiniband/hw/irdma/pble.c b/drivers/infiniband/hw/irdma/pble.c index 3091f9345f1249..fa6325adaedecb 100644 --- a/drivers/infiniband/hw/irdma/pble.c +++ b/drivers/infiniband/hw/irdma/pble.c @@ -71,7 +71,7 @@ int irdma_hmc_init_pble(struct irdma_sc_dev *dev, static void get_sd_pd_idx(struct irdma_hmc_pble_rsrc *pble_rsrc, struct sd_pd_idx *idx) { - idx->sd_idx = (u32)pble_rsrc->next_fpm_addr / IRDMA_HMC_DIRECT_BP_SIZE; + idx->sd_idx = pble_rsrc->next_fpm_addr / IRDMA_HMC_DIRECT_BP_SIZE; idx->pd_idx = (u32)(pble_rsrc->next_fpm_addr / IRDMA_HMC_PAGED_BP_SIZE); idx->rel_pd_idx = (idx->pd_idx % IRDMA_HMC_PD_CNT_IN_SD); } diff --git a/drivers/infiniband/hw/irdma/type.h b/drivers/infiniband/hw/irdma/type.h index 4ae77cdde9dc79..c1b8f81ea283db 100644 --- a/drivers/infiniband/hw/irdma/type.h +++ b/drivers/infiniband/hw/irdma/type.h @@ -706,7 +706,7 @@ struct irdma_sc_dev { u32 vchnl_ver; u16 num_vfs; u16 hmc_fn_id; - u8 vf_id; + u16 vf_id; bool privileged:1; bool vchnl_up:1; bool ceq_valid:1; diff --git a/drivers/infiniband/hw/irdma/verbs.c b/drivers/infiniband/hw/irdma/verbs.c index 76ce6137f2ba32..c883c9ea5a831e 100644 --- a/drivers/infiniband/hw/irdma/verbs.c +++ b/drivers/infiniband/hw/irdma/verbs.c @@ -2503,6 +2503,7 @@ static int irdma_create_cq(struct ib_cq *ibcq, spin_lock_init(&iwcq->lock); INIT_LIST_HEAD(&iwcq->resize_list); INIT_LIST_HEAD(&iwcq->cmpl_generated); + iwcq->cq_num = cq_num; info.dev = dev; ukinfo->cq_size = max(entries, 4); ukinfo->cq_id = cq_num; diff --git a/drivers/infiniband/hw/irdma/verbs.h b/drivers/infiniband/hw/irdma/verbs.h index ed21c1b56e8ec6..ac8b3870183502 100644 --- a/drivers/infiniband/hw/irdma/verbs.h +++ b/drivers/infiniband/hw/irdma/verbs.h @@ -140,7 +140,7 @@ struct irdma_srq { struct irdma_cq { struct ib_cq ibcq; struct irdma_sc_cq sc_cq; - u16 cq_num; + u32 cq_num; bool user_mode; atomic_t armed; enum irdma_cmpl_notify last_notify; diff --git a/drivers/infiniband/hw/mlx5/cq.c b/drivers/infiniband/hw/mlx5/cq.c index a23b364e24ffeb..651d76bca114d5 100644 --- a/drivers/infiniband/hw/mlx5/cq.c +++ b/drivers/infiniband/hw/mlx5/cq.c @@ -1020,15 +1020,18 @@ int mlx5_ib_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr, if (cq->create_flags & IB_UVERBS_CQ_FLAGS_IGNORE_OVERRUN) MLX5_SET(cqc, cqc, oi, 1); + if (udata) { + cq->mcq.comp = mlx5_add_cq_to_tasklet; + cq->mcq.tasklet_ctx.comp = mlx5_ib_cq_comp; + } else { + cq->mcq.comp = mlx5_ib_cq_comp; + } + err = mlx5_core_create_cq(dev->mdev, &cq->mcq, cqb, inlen, out, sizeof(out)); if (err) goto err_cqb; mlx5_ib_dbg(dev, "cqn 0x%x\n", cq->mcq.cqn); - if (udata) - cq->mcq.tasklet_ctx.comp = mlx5_ib_cq_comp; - else - cq->mcq.comp = mlx5_ib_cq_comp; cq->mcq.event = mlx5_ib_cq_event; INIT_LIST_HEAD(&cq->wc_list); diff --git a/drivers/input/keyboard/cros_ec_keyb.c b/drivers/input/keyboard/cros_ec_keyb.c index f7209c8ebbccd1..1c6b0461dc3547 100644 --- a/drivers/input/keyboard/cros_ec_keyb.c +++ b/drivers/input/keyboard/cros_ec_keyb.c @@ -261,6 +261,12 @@ static int cros_ec_keyb_work(struct notifier_block *nb, case EC_MKBP_EVENT_KEY_MATRIX: pm_wakeup_event(ckdev->dev, 0); + if (!ckdev->idev) { + dev_warn_once(ckdev->dev, + "Unexpected key matrix event\n"); + return NOTIFY_OK; + } + if (ckdev->ec->event_size != ckdev->cols) { dev_err(ckdev->dev, "Discarded incomplete key matrix event.\n"); diff --git a/drivers/input/keyboard/imx_sc_key.c b/drivers/input/keyboard/imx_sc_key.c index d18839f1f4f60d..b620cd310cdb78 100644 --- a/drivers/input/keyboard/imx_sc_key.c +++ b/drivers/input/keyboard/imx_sc_key.c @@ -158,7 +158,7 @@ static int imx_sc_key_probe(struct platform_device *pdev) return error; } - error = devm_add_action_or_reset(&pdev->dev, imx_sc_key_action, &priv); + error = devm_add_action_or_reset(&pdev->dev, imx_sc_key_action, priv); if (error) return error; diff --git a/drivers/input/misc/arizona-haptics.c b/drivers/input/misc/arizona-haptics.c index 5fa1c9438a859c..bb1544d63c5165 100644 --- a/drivers/input/misc/arizona-haptics.c +++ b/drivers/input/misc/arizona-haptics.c @@ -34,8 +34,6 @@ static void arizona_haptics_work(struct work_struct *work) struct arizona_haptics, work); struct arizona *arizona = haptics->arizona; - struct snd_soc_component *component = - snd_soc_dapm_to_component(arizona->dapm); int ret; if (!haptics->arizona->dapm) { @@ -65,7 +63,7 @@ static void arizona_haptics_work(struct work_struct *work) return; } - ret = snd_soc_component_enable_pin(component, "HAPTICS"); + ret = snd_soc_dapm_enable_pin(arizona->dapm, "HAPTICS"); if (ret != 0) { dev_err(arizona->dev, "Failed to start HAPTICS: %d\n", ret); @@ -80,7 +78,7 @@ static void arizona_haptics_work(struct work_struct *work) } } else { /* This disable sequence will be a noop if already enabled */ - ret = snd_soc_component_disable_pin(component, "HAPTICS"); + ret = snd_soc_dapm_disable_pin(arizona->dapm, "HAPTICS"); if (ret != 0) { dev_err(arizona->dev, "Failed to disable HAPTICS: %d\n", ret); @@ -139,14 +137,12 @@ static int arizona_haptics_play(struct input_dev *input, void *data, static void arizona_haptics_close(struct input_dev *input) { struct arizona_haptics *haptics = input_get_drvdata(input); - struct snd_soc_component *component; + struct snd_soc_dapm_context *dapm = haptics->arizona->dapm; cancel_work_sync(&haptics->work); - if (haptics->arizona->dapm) { - component = snd_soc_dapm_to_component(haptics->arizona->dapm); - snd_soc_component_disable_pin(component, "HAPTICS"); - } + if (dapm) + snd_soc_dapm_disable_pin(dapm, "HAPTICS"); } static int arizona_haptics_probe(struct platform_device *pdev) diff --git a/drivers/input/tablet/pegasus_notetaker.c b/drivers/input/tablet/pegasus_notetaker.c index 8d6b71d5979316..eabb4a0b8a0d2b 100644 --- a/drivers/input/tablet/pegasus_notetaker.c +++ b/drivers/input/tablet/pegasus_notetaker.c @@ -63,6 +63,9 @@ #define BUTTON_PRESSED 0xb5 #define COMMAND_VERSION 0xa9 +/* 1 Status + 1 Color + 2 X + 2 Y = 6 bytes */ +#define NOTETAKER_PACKET_SIZE 6 + /* in xy data packet */ #define BATTERY_NO_REPORT 0x40 #define BATTERY_LOW 0x41 @@ -311,6 +314,12 @@ static int pegasus_probe(struct usb_interface *intf, } pegasus->data_len = usb_maxpacket(dev, pipe); + if (pegasus->data_len < NOTETAKER_PACKET_SIZE) { + dev_err(&intf->dev, "packet size is too small (%d)\n", + pegasus->data_len); + error = -EINVAL; + goto err_free_mem; + } pegasus->data = usb_alloc_coherent(dev, pegasus->data_len, GFP_KERNEL, &pegasus->data_dma); diff --git a/drivers/input/touchscreen/goodix.c b/drivers/input/touchscreen/goodix.c index 252dcae039f8d5..f8798d11ec030f 100644 --- a/drivers/input/touchscreen/goodix.c +++ b/drivers/input/touchscreen/goodix.c @@ -796,17 +796,6 @@ int goodix_reset_no_int_sync(struct goodix_ts_data *ts) usleep_range(6000, 10000); /* T4: > 5ms */ - /* - * Put the reset pin back in to input / high-impedance mode to save - * power. Only do this in the non ACPI case since some ACPI boards - * don't have a pull-up, so there the reset pin must stay active-high. - */ - if (ts->irq_pin_access_method == IRQ_PIN_ACCESS_GPIO) { - error = gpiod_direction_input(ts->gpiod_rst); - if (error) - goto error; - } - return 0; error: @@ -957,14 +946,6 @@ static int goodix_add_acpi_gpio_mappings(struct goodix_ts_data *ts) return -EINVAL; } - /* - * Normally we put the reset pin in input / high-impedance mode to save - * power. But some x86/ACPI boards don't have a pull-up, so for the ACPI - * case, leave the pin as is. This results in the pin not being touched - * at all on x86/ACPI boards, except when needed for error-recover. - */ - ts->gpiod_rst_flags = GPIOD_ASIS; - return devm_acpi_dev_add_driver_gpios(dev, gpio_mapping); } #else @@ -989,12 +970,6 @@ static int goodix_get_gpio_config(struct goodix_ts_data *ts) return -EINVAL; dev = &ts->client->dev; - /* - * By default we request the reset pin as input, leaving it in - * high-impedance when not resetting the controller to save power. - */ - ts->gpiod_rst_flags = GPIOD_IN; - ts->avdd28 = devm_regulator_get(dev, "AVDD28"); if (IS_ERR(ts->avdd28)) return dev_err_probe(dev, PTR_ERR(ts->avdd28), "Failed to get AVDD28 regulator\n"); @@ -1019,7 +994,7 @@ static int goodix_get_gpio_config(struct goodix_ts_data *ts) ts->gpiod_int = gpiod; /* Get the reset line GPIO pin number */ - gpiod = devm_gpiod_get_optional(dev, GOODIX_GPIO_RST_NAME, ts->gpiod_rst_flags); + gpiod = devm_gpiod_get_optional(dev, GOODIX_GPIO_RST_NAME, GPIOD_ASIS); if (IS_ERR(gpiod)) return dev_err_probe(dev, PTR_ERR(gpiod), "Failed to get %s GPIO\n", GOODIX_GPIO_RST_NAME); @@ -1557,6 +1532,7 @@ MODULE_DEVICE_TABLE(i2c, goodix_ts_id); static const struct acpi_device_id goodix_acpi_match[] = { { "GDIX1001", 0 }, { "GDIX1002", 0 }, + { "GDIX1003", 0 }, { "GDX9110", 0 }, { } }; diff --git a/drivers/input/touchscreen/goodix.h b/drivers/input/touchscreen/goodix.h index 87797cc88b3243..0d1e8a8d2cbaac 100644 --- a/drivers/input/touchscreen/goodix.h +++ b/drivers/input/touchscreen/goodix.h @@ -88,7 +88,6 @@ struct goodix_ts_data { struct gpio_desc *gpiod_rst; int gpio_count; int gpio_int_idx; - enum gpiod_flags gpiod_rst_flags; char id[GOODIX_ID_MAX_LEN + 1]; char cfg_name[64]; u16 version; diff --git a/drivers/iommu/iommufd/io_pagetable.c b/drivers/iommu/iommufd/io_pagetable.c index c0360c450880b8..75d60f2ad90082 100644 --- a/drivers/iommu/iommufd/io_pagetable.c +++ b/drivers/iommu/iommufd/io_pagetable.c @@ -707,7 +707,8 @@ static int iopt_unmap_iova_range(struct io_pagetable *iopt, unsigned long start, struct iopt_area *area; unsigned long unmapped_bytes = 0; unsigned int tries = 0; - int rc = -ENOENT; + /* If there are no mapped entries then success */ + int rc = 0; /* * The domains_rwsem must be held in read mode any time any area->pages @@ -777,8 +778,6 @@ static int iopt_unmap_iova_range(struct io_pagetable *iopt, unsigned long start, down_write(&iopt->iova_rwsem); } - if (unmapped_bytes) - rc = 0; out_unlock_iova: up_write(&iopt->iova_rwsem); @@ -815,13 +814,8 @@ int iopt_unmap_iova(struct io_pagetable *iopt, unsigned long iova, int iopt_unmap_all(struct io_pagetable *iopt, unsigned long *unmapped) { - int rc; - - rc = iopt_unmap_iova_range(iopt, 0, ULONG_MAX, unmapped); /* If the IOVAs are empty then unmap all succeeds */ - if (rc == -ENOENT) - return 0; - return rc; + return iopt_unmap_iova_range(iopt, 0, ULONG_MAX, unmapped); } /* The caller must always free all the nodes in the allowed_iova rb_root. */ diff --git a/drivers/iommu/iommufd/ioas.c b/drivers/iommu/iommufd/ioas.c index 1542c5fd10a85c..459a7c5169154b 100644 --- a/drivers/iommu/iommufd/ioas.c +++ b/drivers/iommu/iommufd/ioas.c @@ -367,6 +367,10 @@ int iommufd_ioas_unmap(struct iommufd_ucmd *ucmd) &unmapped); if (rc) goto out_put; + if (!unmapped) { + rc = -ENOENT; + goto out_put; + } } cmd->length = unmapped; diff --git a/drivers/iommu/iommufd/iova_bitmap.c b/drivers/iommu/iommufd/iova_bitmap.c index 4514575818fc07..b5b67a9d3fb35e 100644 --- a/drivers/iommu/iommufd/iova_bitmap.c +++ b/drivers/iommu/iommufd/iova_bitmap.c @@ -130,9 +130,8 @@ struct iova_bitmap { static unsigned long iova_bitmap_offset_to_index(struct iova_bitmap *bitmap, unsigned long iova) { - unsigned long pgsize = 1UL << bitmap->mapped.pgshift; - - return iova / (BITS_PER_TYPE(*bitmap->bitmap) * pgsize); + return (iova >> bitmap->mapped.pgshift) / + BITS_PER_TYPE(*bitmap->bitmap); } /* diff --git a/drivers/irqchip/irq-riscv-intc.c b/drivers/irqchip/irq-riscv-intc.c index e5805885394ee3..70290b35b3173e 100644 --- a/drivers/irqchip/irq-riscv-intc.c +++ b/drivers/irqchip/irq-riscv-intc.c @@ -166,7 +166,8 @@ static int riscv_intc_domain_alloc(struct irq_domain *domain, static const struct irq_domain_ops riscv_intc_domain_ops = { .map = riscv_intc_domain_map, .xlate = irq_domain_xlate_onecell, - .alloc = riscv_intc_domain_alloc + .alloc = riscv_intc_domain_alloc, + .free = irq_domain_free_irqs_top, }; static struct fwnode_handle *riscv_intc_hwnode(void) diff --git a/drivers/isdn/hardware/mISDN/hfcsusb.c b/drivers/isdn/hardware/mISDN/hfcsusb.c index e54419a4e731f4..541a20cb58f16b 100644 --- a/drivers/isdn/hardware/mISDN/hfcsusb.c +++ b/drivers/isdn/hardware/mISDN/hfcsusb.c @@ -1904,13 +1904,13 @@ setup_instance(struct hfcsusb *hw, struct device *parent) mISDN_freebchannel(&hw->bch[1]); mISDN_freebchannel(&hw->bch[0]); mISDN_freedchannel(&hw->dch); - kfree(hw); return err; } static int hfcsusb_probe(struct usb_interface *intf, const struct usb_device_id *id) { + int err; struct hfcsusb *hw; struct usb_device *dev = interface_to_usbdev(intf); struct usb_host_interface *iface = intf->cur_altsetting; @@ -2101,20 +2101,28 @@ hfcsusb_probe(struct usb_interface *intf, const struct usb_device_id *id) if (!hw->ctrl_urb) { pr_warn("%s: No memory for control urb\n", driver_info->vend_name); - kfree(hw); - return -ENOMEM; + err = -ENOMEM; + goto err_free_hw; } pr_info("%s: %s: detected \"%s\" (%s, if=%d alt=%d)\n", hw->name, __func__, driver_info->vend_name, conf_str[small_match], ifnum, alt_used); - if (setup_instance(hw, dev->dev.parent)) - return -EIO; + if (setup_instance(hw, dev->dev.parent)) { + err = -EIO; + goto err_free_urb; + } hw->intf = intf; usb_set_intfdata(hw->intf, hw); return 0; + +err_free_urb: + usb_free_urb(hw->ctrl_urb); +err_free_hw: + kfree(hw); + return err; } /* function called when an active device is removed */ diff --git a/drivers/media/common/videobuf2/videobuf2-v4l2.c b/drivers/media/common/videobuf2/videobuf2-v4l2.c index d911021c1bb052..83862d57b126d6 100644 --- a/drivers/media/common/videobuf2/videobuf2-v4l2.c +++ b/drivers/media/common/videobuf2/videobuf2-v4l2.c @@ -1010,6 +1010,11 @@ int vb2_ioctl_remove_bufs(struct file *file, void *priv, if (vb2_queue_is_busy(vdev->queue, file)) return -EBUSY; + if (vb2_fileio_is_active(vdev->queue)) { + dprintk(vdev->queue, 1, "file io in progress\n"); + return -EBUSY; + } + return vb2_core_remove_bufs(vdev->queue, d->index, d->count); } EXPORT_SYMBOL_GPL(vb2_ioctl_remove_bufs); diff --git a/drivers/media/pci/cx18/cx18-driver.c b/drivers/media/pci/cx18/cx18-driver.c index b62fd12c93c1a3..74c59a94b2b051 100644 --- a/drivers/media/pci/cx18/cx18-driver.c +++ b/drivers/media/pci/cx18/cx18-driver.c @@ -1136,11 +1136,8 @@ int cx18_init_on_first_open(struct cx18 *cx) int video_input; int fw_retry_count = 3; struct v4l2_frequency vf; - struct cx18_open_id fh; v4l2_std_id std; - fh.cx = cx; - if (test_bit(CX18_F_I_FAILED, &cx->i_flags)) return -ENXIO; @@ -1220,14 +1217,14 @@ int cx18_init_on_first_open(struct cx18 *cx) video_input = cx->active_input; cx->active_input++; /* Force update of input */ - cx18_s_input(NULL, &fh, video_input); + cx18_do_s_input(cx, video_input); /* Let the VIDIOC_S_STD ioctl do all the work, keeps the code in one place. */ cx->std++; /* Force full standard initialization */ std = (cx->tuner_std == V4L2_STD_ALL) ? V4L2_STD_NTSC_M : cx->tuner_std; - cx18_s_std(NULL, &fh, std); - cx18_s_frequency(NULL, &fh, &vf); + cx18_do_s_std(cx, std); + cx18_do_s_frequency(cx, &vf); return 0; } diff --git a/drivers/media/pci/cx18/cx18-ioctl.c b/drivers/media/pci/cx18/cx18-ioctl.c index 0f3019739d03da..0d676a57e24ec9 100644 --- a/drivers/media/pci/cx18/cx18-ioctl.c +++ b/drivers/media/pci/cx18/cx18-ioctl.c @@ -521,10 +521,8 @@ static int cx18_g_input(struct file *file, void *fh, unsigned int *i) return 0; } -int cx18_s_input(struct file *file, void *fh, unsigned int inp) +int cx18_do_s_input(struct cx18 *cx, unsigned int inp) { - struct cx18_open_id *id = file2id(file); - struct cx18 *cx = id->cx; v4l2_std_id std = V4L2_STD_ALL; const struct cx18_card_video_input *card_input = cx->card->video_inputs + inp; @@ -558,6 +556,11 @@ int cx18_s_input(struct file *file, void *fh, unsigned int inp) return 0; } +static int cx18_s_input(struct file *file, void *fh, unsigned int inp) +{ + return cx18_do_s_input(file2id(file)->cx, inp); +} + static int cx18_g_frequency(struct file *file, void *fh, struct v4l2_frequency *vf) { @@ -570,11 +573,8 @@ static int cx18_g_frequency(struct file *file, void *fh, return 0; } -int cx18_s_frequency(struct file *file, void *fh, const struct v4l2_frequency *vf) +int cx18_do_s_frequency(struct cx18 *cx, const struct v4l2_frequency *vf) { - struct cx18_open_id *id = file2id(file); - struct cx18 *cx = id->cx; - if (vf->tuner != 0) return -EINVAL; @@ -585,6 +585,12 @@ int cx18_s_frequency(struct file *file, void *fh, const struct v4l2_frequency *v return 0; } +static int cx18_s_frequency(struct file *file, void *fh, + const struct v4l2_frequency *vf) +{ + return cx18_do_s_frequency(file2id(file)->cx, vf); +} + static int cx18_g_std(struct file *file, void *fh, v4l2_std_id *std) { struct cx18 *cx = file2id(file)->cx; @@ -593,11 +599,8 @@ static int cx18_g_std(struct file *file, void *fh, v4l2_std_id *std) return 0; } -int cx18_s_std(struct file *file, void *fh, v4l2_std_id std) +int cx18_do_s_std(struct cx18 *cx, v4l2_std_id std) { - struct cx18_open_id *id = file2id(file); - struct cx18 *cx = id->cx; - if ((std & V4L2_STD_ALL) == 0) return -EINVAL; @@ -642,6 +645,11 @@ int cx18_s_std(struct file *file, void *fh, v4l2_std_id std) return 0; } +static int cx18_s_std(struct file *file, void *fh, v4l2_std_id std) +{ + return cx18_do_s_std(file2id(file)->cx, std); +} + static int cx18_s_tuner(struct file *file, void *fh, const struct v4l2_tuner *vt) { struct cx18_open_id *id = file2id(file); diff --git a/drivers/media/pci/cx18/cx18-ioctl.h b/drivers/media/pci/cx18/cx18-ioctl.h index 97cd9f99e22d96..42a8acd6973546 100644 --- a/drivers/media/pci/cx18/cx18-ioctl.h +++ b/drivers/media/pci/cx18/cx18-ioctl.h @@ -12,6 +12,8 @@ u16 cx18_service2vbi(int type); void cx18_expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal); u16 cx18_get_service_set(struct v4l2_sliced_vbi_format *fmt); void cx18_set_funcs(struct video_device *vdev); -int cx18_s_std(struct file *file, void *fh, v4l2_std_id std); -int cx18_s_frequency(struct file *file, void *fh, const struct v4l2_frequency *vf); -int cx18_s_input(struct file *file, void *fh, unsigned int inp); + +struct cx18; +int cx18_do_s_std(struct cx18 *cx, v4l2_std_id std); +int cx18_do_s_frequency(struct cx18 *cx, const struct v4l2_frequency *vf); +int cx18_do_s_input(struct cx18 *cx, unsigned int inp); diff --git a/drivers/media/pci/ivtv/ivtv-driver.c b/drivers/media/pci/ivtv/ivtv-driver.c index 72a8f76a41f450..459eb6cc370cc0 100644 --- a/drivers/media/pci/ivtv/ivtv-driver.c +++ b/drivers/media/pci/ivtv/ivtv-driver.c @@ -1247,15 +1247,12 @@ static int ivtv_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) int ivtv_init_on_first_open(struct ivtv *itv) { - struct v4l2_frequency vf; /* Needed to call ioctls later */ - struct ivtv_open_id fh; + struct ivtv_stream *s = &itv->streams[IVTV_ENC_STREAM_TYPE_MPG]; + struct v4l2_frequency vf; int fw_retry_count = 3; int video_input; - fh.itv = itv; - fh.type = IVTV_ENC_STREAM_TYPE_MPG; - if (test_bit(IVTV_F_I_FAILED, &itv->i_flags)) return -ENXIO; @@ -1297,13 +1294,13 @@ int ivtv_init_on_first_open(struct ivtv *itv) video_input = itv->active_input; itv->active_input++; /* Force update of input */ - ivtv_s_input(NULL, &fh, video_input); + ivtv_do_s_input(itv, video_input); /* Let the VIDIOC_S_STD ioctl do all the work, keeps the code in one place. */ itv->std++; /* Force full standard initialization */ itv->std_out = itv->std; - ivtv_s_frequency(NULL, &fh, &vf); + ivtv_do_s_frequency(s, &vf); if (itv->card->v4l2_capabilities & V4L2_CAP_VIDEO_OUTPUT) { /* Turn on the TV-out: ivtv_init_mpeg_decoder() initializes diff --git a/drivers/media/pci/ivtv/ivtv-ioctl.c b/drivers/media/pci/ivtv/ivtv-ioctl.c index 84c73bd22f2daf..8d5ea3aec06f3d 100644 --- a/drivers/media/pci/ivtv/ivtv-ioctl.c +++ b/drivers/media/pci/ivtv/ivtv-ioctl.c @@ -974,9 +974,8 @@ static int ivtv_g_input(struct file *file, void *fh, unsigned int *i) return 0; } -int ivtv_s_input(struct file *file, void *fh, unsigned int inp) +int ivtv_do_s_input(struct ivtv *itv, unsigned int inp) { - struct ivtv *itv = file2id(file)->itv; v4l2_std_id std; int i; @@ -1017,6 +1016,11 @@ int ivtv_s_input(struct file *file, void *fh, unsigned int inp) return 0; } +static int ivtv_s_input(struct file *file, void *fh, unsigned int inp) +{ + return ivtv_do_s_input(file2id(file)->itv, inp); +} + static int ivtv_g_output(struct file *file, void *fh, unsigned int *i) { struct ivtv *itv = file2id(file)->itv; @@ -1065,10 +1069,9 @@ static int ivtv_g_frequency(struct file *file, void *fh, struct v4l2_frequency * return 0; } -int ivtv_s_frequency(struct file *file, void *fh, const struct v4l2_frequency *vf) +int ivtv_do_s_frequency(struct ivtv_stream *s, const struct v4l2_frequency *vf) { - struct ivtv *itv = file2id(file)->itv; - struct ivtv_stream *s = &itv->streams[file2id(file)->type]; + struct ivtv *itv = s->itv; if (s->vdev.vfl_dir) return -ENOTTY; @@ -1082,6 +1085,15 @@ int ivtv_s_frequency(struct file *file, void *fh, const struct v4l2_frequency *v return 0; } +static int ivtv_s_frequency(struct file *file, void *fh, + const struct v4l2_frequency *vf) +{ + struct ivtv_open_id *id = file2id(file); + struct ivtv *itv = id->itv; + + return ivtv_do_s_frequency(&itv->streams[id->type], vf); +} + static int ivtv_g_std(struct file *file, void *fh, v4l2_std_id *std) { struct ivtv *itv = file2id(file)->itv; diff --git a/drivers/media/pci/ivtv/ivtv-ioctl.h b/drivers/media/pci/ivtv/ivtv-ioctl.h index 7f8c6f43d397f0..96ca7e2ef973f7 100644 --- a/drivers/media/pci/ivtv/ivtv-ioctl.h +++ b/drivers/media/pci/ivtv/ivtv-ioctl.h @@ -9,6 +9,8 @@ #ifndef IVTV_IOCTL_H #define IVTV_IOCTL_H +struct ivtv; + u16 ivtv_service2vbi(int type); void ivtv_expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal); u16 ivtv_get_service_set(struct v4l2_sliced_vbi_format *fmt); @@ -17,7 +19,7 @@ int ivtv_set_speed(struct ivtv *itv, int speed); void ivtv_set_funcs(struct video_device *vdev); void ivtv_s_std_enc(struct ivtv *itv, v4l2_std_id std); void ivtv_s_std_dec(struct ivtv *itv, v4l2_std_id std); -int ivtv_s_frequency(struct file *file, void *fh, const struct v4l2_frequency *vf); -int ivtv_s_input(struct file *file, void *fh, unsigned int inp); +int ivtv_do_s_frequency(struct ivtv_stream *s, const struct v4l2_frequency *vf); +int ivtv_do_s_input(struct ivtv *itv, unsigned int inp); #endif diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c index fb6afb8e84f009..ee4f54d6834962 100644 --- a/drivers/media/usb/uvc/uvc_driver.c +++ b/drivers/media/usb/uvc/uvc_driver.c @@ -167,13 +167,26 @@ static struct uvc_entity *uvc_entity_by_reference(struct uvc_device *dev, static struct uvc_streaming *uvc_stream_by_id(struct uvc_device *dev, int id) { - struct uvc_streaming *stream; + struct uvc_streaming *stream, *last_stream; + unsigned int count = 0; list_for_each_entry(stream, &dev->streams, list) { + count += 1; + last_stream = stream; if (stream->header.bTerminalLink == id) return stream; } + /* + * If the streaming entity is referenced by an invalid ID, notify the + * user and use heuristics to guess the correct entity. + */ + if (count == 1 && id == UVC_INVALID_ENTITY_ID) { + dev_warn(&dev->intf->dev, + "UVC non compliance: Invalid USB header. The streaming entity has an invalid ID, guessing the correct one."); + return last_stream; + } + return NULL; } diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c index 1da953629010b0..25e66bf18f5fc9 100644 --- a/drivers/media/v4l2-core/v4l2-subdev.c +++ b/drivers/media/v4l2-core/v4l2-subdev.c @@ -2608,7 +2608,7 @@ EXPORT_SYMBOL_GPL(v4l2_subdev_is_streaming); int v4l2_subdev_get_privacy_led(struct v4l2_subdev *sd) { #if IS_REACHABLE(CONFIG_LEDS_CLASS) - sd->privacy_led = led_get(sd->dev, "privacy-led"); + sd->privacy_led = led_get(sd->dev, "privacy"); if (IS_ERR(sd->privacy_led) && PTR_ERR(sd->privacy_led) != -ENOENT) return dev_err_probe(sd->dev, PTR_ERR(sd->privacy_led), "getting privacy LED\n"); diff --git a/drivers/memory/tegra/tegra210.c b/drivers/memory/tegra/tegra210.c index cfa61dd885577a..3c2949c16fdef4 100644 --- a/drivers/memory/tegra/tegra210.c +++ b/drivers/memory/tegra/tegra210.c @@ -1015,7 +1015,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { }, }, }, { - .id = TEGRA210_MC_SESRD, + .id = TEGRA210_MC_SESWR, .name = "seswr", .swgroup = TEGRA_SWGROUP_SE, .regs = { @@ -1079,7 +1079,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { }, }, }, { - .id = TEGRA210_MC_ETRR, + .id = TEGRA210_MC_ETRW, .name = "etrw", .swgroup = TEGRA_SWGROUP_ETR, .regs = { diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index 2c963cb6724b9e..10d0ef58ef4931 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -950,7 +950,7 @@ config MMC_USHC config MMC_WMT tristate "Wondermedia SD/MMC Host Controller support" depends on ARCH_VT8500 || COMPILE_TEST - default y + default ARCH_VT8500 help This selects support for the SD/MMC Host Controller on Wondermedia WM8505/WM8650 based SoCs. diff --git a/drivers/mmc/host/dw_mmc-rockchip.c b/drivers/mmc/host/dw_mmc-rockchip.c index 82dd906bb002cb..681354942e9741 100644 --- a/drivers/mmc/host/dw_mmc-rockchip.c +++ b/drivers/mmc/host/dw_mmc-rockchip.c @@ -42,7 +42,7 @@ struct dw_mci_rockchip_priv_data { */ static int rockchip_mmc_get_internal_phase(struct dw_mci *host, bool sample) { - unsigned long rate = clk_get_rate(host->ciu_clk); + unsigned long rate = clk_get_rate(host->ciu_clk) / RK3288_CLKGEN_DIV; u32 raw_value; u16 degrees; u32 delay_num = 0; @@ -85,7 +85,7 @@ static int rockchip_mmc_get_phase(struct dw_mci *host, bool sample) static int rockchip_mmc_set_internal_phase(struct dw_mci *host, bool sample, int degrees) { - unsigned long rate = clk_get_rate(host->ciu_clk); + unsigned long rate = clk_get_rate(host->ciu_clk) / RK3288_CLKGEN_DIV; u8 nineties, remainder; u8 delay_num; u32 raw_value; diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c index 26d03352af6308..b5ea058ed46787 100644 --- a/drivers/mmc/host/pxamci.c +++ b/drivers/mmc/host/pxamci.c @@ -652,10 +652,9 @@ static int pxamci_probe(struct platform_device *pdev) host->clkrt = CLKRT_OFF; host->clk = devm_clk_get(dev, NULL); - if (IS_ERR(host->clk)) { - host->clk = NULL; - return PTR_ERR(host->clk); - } + if (IS_ERR(host->clk)) + return dev_err_probe(dev, PTR_ERR(host->clk), + "Failed to acquire clock\n"); host->clkrate = clk_get_rate(host->clk); @@ -703,46 +702,37 @@ static int pxamci_probe(struct platform_device *pdev) platform_set_drvdata(pdev, mmc); - host->dma_chan_rx = dma_request_chan(dev, "rx"); - if (IS_ERR(host->dma_chan_rx)) { - host->dma_chan_rx = NULL; + host->dma_chan_rx = devm_dma_request_chan(dev, "rx"); + if (IS_ERR(host->dma_chan_rx)) return dev_err_probe(dev, PTR_ERR(host->dma_chan_rx), "unable to request rx dma channel\n"); - } - host->dma_chan_tx = dma_request_chan(dev, "tx"); - if (IS_ERR(host->dma_chan_tx)) { - dev_err(dev, "unable to request tx dma channel\n"); - ret = PTR_ERR(host->dma_chan_tx); - host->dma_chan_tx = NULL; - goto out; - } + + host->dma_chan_tx = devm_dma_request_chan(dev, "tx"); + if (IS_ERR(host->dma_chan_tx)) + return dev_err_probe(dev, PTR_ERR(host->dma_chan_tx), + "unable to request tx dma channel\n"); if (host->pdata) { host->detect_delay_ms = host->pdata->detect_delay_ms; host->power = devm_gpiod_get_optional(dev, "power", GPIOD_OUT_LOW); - if (IS_ERR(host->power)) { - ret = PTR_ERR(host->power); - dev_err(dev, "Failed requesting gpio_power\n"); - goto out; - } + if (IS_ERR(host->power)) + return dev_err_probe(dev, PTR_ERR(host->power), + "Failed requesting gpio_power\n"); /* FIXME: should we pass detection delay to debounce? */ ret = mmc_gpiod_request_cd(mmc, "cd", 0, false, 0); - if (ret && ret != -ENOENT) { - dev_err(dev, "Failed requesting gpio_cd\n"); - goto out; - } + if (ret && ret != -ENOENT) + return dev_err_probe(dev, ret, "Failed requesting gpio_cd\n"); if (!host->pdata->gpio_card_ro_invert) mmc->caps2 |= MMC_CAP2_RO_ACTIVE_HIGH; ret = mmc_gpiod_request_ro(mmc, "wp", 0, 0); - if (ret && ret != -ENOENT) { - dev_err(dev, "Failed requesting gpio_ro\n"); - goto out; - } + if (ret && ret != -ENOENT) + return dev_err_probe(dev, ret, "Failed requesting gpio_ro\n"); + if (!ret) host->use_ro_gpio = true; @@ -759,16 +749,8 @@ static int pxamci_probe(struct platform_device *pdev) if (ret) { if (host->pdata && host->pdata->exit) host->pdata->exit(dev, mmc); - goto out; } - return 0; - -out: - if (host->dma_chan_rx) - dma_release_channel(host->dma_chan_rx); - if (host->dma_chan_tx) - dma_release_channel(host->dma_chan_tx); return ret; } @@ -791,8 +773,6 @@ static void pxamci_remove(struct platform_device *pdev) dmaengine_terminate_all(host->dma_chan_rx); dmaengine_terminate_all(host->dma_chan_tx); - dma_release_channel(host->dma_chan_rx); - dma_release_channel(host->dma_chan_tx); } } diff --git a/drivers/mmc/host/sdhci-of-dwcmshc.c b/drivers/mmc/host/sdhci-of-dwcmshc.c index eebd4538995663..5b61401a7f3ded 100644 --- a/drivers/mmc/host/sdhci-of-dwcmshc.c +++ b/drivers/mmc/host/sdhci-of-dwcmshc.c @@ -94,7 +94,7 @@ #define DLL_TXCLK_TAPNUM_DEFAULT 0x10 #define DLL_TXCLK_TAPNUM_90_DEGREES 0xA #define DLL_TXCLK_TAPNUM_FROM_SW BIT(24) -#define DLL_STRBIN_TAPNUM_DEFAULT 0x8 +#define DLL_STRBIN_TAPNUM_DEFAULT 0x4 #define DLL_STRBIN_TAPNUM_FROM_SW BIT(24) #define DLL_STRBIN_DELAY_NUM_SEL BIT(26) #define DLL_STRBIN_DELAY_NUM_OFFSET 16 diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c index 8dc4f5c493fcba..335c702633ffe0 100644 --- a/drivers/mtd/mtdchar.c +++ b/drivers/mtd/mtdchar.c @@ -599,6 +599,7 @@ mtdchar_write_ioctl(struct mtd_info *mtd, struct mtd_write_req __user *argp) uint8_t *datbuf = NULL, *oobbuf = NULL; size_t datbuf_len, oobbuf_len; int ret = 0; + u64 end; if (copy_from_user(&req, argp, sizeof(req))) return -EFAULT; @@ -618,7 +619,7 @@ mtdchar_write_ioctl(struct mtd_info *mtd, struct mtd_write_req __user *argp) req.len &= 0xffffffff; req.ooblen &= 0xffffffff; - if (req.start + req.len > mtd->size) + if (check_add_overflow(req.start, req.len, &end) || end > mtd->size) return -EINVAL; datbuf_len = min_t(size_t, req.len, mtd->erasesize); @@ -698,6 +699,7 @@ mtdchar_read_ioctl(struct mtd_info *mtd, struct mtd_read_req __user *argp) size_t datbuf_len, oobbuf_len; size_t orig_len, orig_ooblen; int ret = 0; + u64 end; if (copy_from_user(&req, argp, sizeof(req))) return -EFAULT; @@ -724,7 +726,7 @@ mtdchar_read_ioctl(struct mtd_info *mtd, struct mtd_read_req __user *argp) req.len &= 0xffffffff; req.ooblen &= 0xffffffff; - if (req.start + req.len > mtd->size) { + if (check_add_overflow(req.start, req.len, &end) || end > mtd->size) { ret = -EINVAL; goto out; } diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index 4a17271076bc1c..1e57c8de857825 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig @@ -63,7 +63,7 @@ config MTD_NAND_ECC_MEDIATEK config MTD_NAND_ECC_REALTEK tristate "Realtek RTL93xx hardware ECC engine" - depends on HAS_IOMEM + depends on HAS_IOMEM && HAS_DMA depends on MACH_REALTEK_RTL || COMPILE_TEST select MTD_NAND_ECC help diff --git a/drivers/mtd/nand/ecc-realtek.c b/drivers/mtd/nand/ecc-realtek.c index 7d718934c90962..0046da37ea3e5d 100644 --- a/drivers/mtd/nand/ecc-realtek.c +++ b/drivers/mtd/nand/ecc-realtek.c @@ -380,7 +380,7 @@ static void rtl_ecc_cleanup_ctx(struct nand_device *nand) nand_ecc_cleanup_req_tweaking(&ctx->req_ctx); } -static struct nand_ecc_engine_ops rtl_ecc_engine_ops = { +static const struct nand_ecc_engine_ops rtl_ecc_engine_ops = { .init_ctx = rtl_ecc_init_ctx, .cleanup_ctx = rtl_ecc_cleanup_ctx, .prepare_io_req = rtl_ecc_prepare_io_req, @@ -418,8 +418,8 @@ static int rtl_ecc_probe(struct platform_device *pdev) rtlc->buf = dma_alloc_noncoherent(dev, RTL_ECC_DMA_SIZE, &rtlc->buf_dma, DMA_BIDIRECTIONAL, GFP_KERNEL); - if (IS_ERR(rtlc->buf)) - return PTR_ERR(rtlc->buf); + if (!rtlc->buf) + return -ENOMEM; rtlc->dev = dev; rtlc->engine.dev = dev; diff --git a/drivers/mtd/nand/onenand/onenand_samsung.c b/drivers/mtd/nand/onenand/onenand_samsung.c index f37a6138e461f2..6d6aa709a21f8e 100644 --- a/drivers/mtd/nand/onenand/onenand_samsung.c +++ b/drivers/mtd/nand/onenand/onenand_samsung.c @@ -906,7 +906,7 @@ static int s3c_onenand_probe(struct platform_device *pdev) err = devm_request_irq(&pdev->dev, r->start, s5pc110_onenand_irq, IRQF_SHARED, "onenand", - &onenand); + onenand); if (err) { dev_err(&pdev->dev, "failed to get irq\n"); return err; diff --git a/drivers/mtd/nand/raw/cadence-nand-controller.c b/drivers/mtd/nand/raw/cadence-nand-controller.c index 6667eea9559773..32ed38b8939478 100644 --- a/drivers/mtd/nand/raw/cadence-nand-controller.c +++ b/drivers/mtd/nand/raw/cadence-nand-controller.c @@ -2871,7 +2871,7 @@ cadence_nand_irq_cleanup(int irqnum, struct cdns_nand_ctrl *cdns_ctrl) static int cadence_nand_init(struct cdns_nand_ctrl *cdns_ctrl) { dma_cap_mask_t mask; - struct dma_device *dma_dev = cdns_ctrl->dmac->device; + struct dma_device *dma_dev; int ret; cdns_ctrl->cdma_desc = dma_alloc_coherent(cdns_ctrl->dev, @@ -2915,6 +2915,7 @@ static int cadence_nand_init(struct cdns_nand_ctrl *cdns_ctrl) } } + dma_dev = cdns_ctrl->dmac->device; cdns_ctrl->io.iova_dma = dma_map_resource(dma_dev->dev, cdns_ctrl->io.dma, cdns_ctrl->io.size, DMA_BIDIRECTIONAL, 0); diff --git a/drivers/mtd/nand/spi/fmsh.c b/drivers/mtd/nand/spi/fmsh.c index 8b2097bfc77160..c2b9a8c113cbe8 100644 --- a/drivers/mtd/nand/spi/fmsh.c +++ b/drivers/mtd/nand/spi/fmsh.c @@ -58,7 +58,7 @@ static const struct spinand_info fmsh_spinand_table[] = { SPINAND_INFO_OP_VARIANTS(&read_cache_variants, &write_cache_variants, &update_cache_variants), - SPINAND_HAS_QE_BIT, + 0, SPINAND_ECCINFO(&fm25s01a_ooblayout, NULL)), }; diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index e95e593cd12d76..5abef8a3b7758e 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -2120,7 +2120,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev, /* check for initial state */ new_slave->link = BOND_LINK_NOCHANGE; if (bond->params.miimon) { - if (netif_carrier_ok(slave_dev)) { + if (netif_running(slave_dev) && netif_carrier_ok(slave_dev)) { if (bond->params.updelay) { bond_set_slave_link_state(new_slave, BOND_LINK_BACK, @@ -2665,7 +2665,8 @@ static int bond_miimon_inspect(struct bonding *bond) bond_for_each_slave_rcu(bond, slave, iter) { bond_propose_link_state(slave, BOND_LINK_NOCHANGE); - link_state = netif_carrier_ok(slave->dev); + link_state = netif_running(slave->dev) && + netif_carrier_ok(slave->dev); switch (slave->link) { case BOND_LINK_UP: diff --git a/drivers/net/bonding/bond_options.c b/drivers/net/bonding/bond_options.c index 495a87f2ea7c8b..384499c869b8da 100644 --- a/drivers/net/bonding/bond_options.c +++ b/drivers/net/bonding/bond_options.c @@ -225,13 +225,6 @@ static const struct bond_opt_value bond_ad_actor_sys_prio_tbl[] = { { NULL, -1, 0}, }; -static const struct bond_opt_value bond_actor_port_prio_tbl[] = { - { "minval", 0, BOND_VALFLAG_MIN}, - { "maxval", 65535, BOND_VALFLAG_MAX}, - { "default", 255, BOND_VALFLAG_DEFAULT}, - { NULL, -1, 0}, -}; - static const struct bond_opt_value bond_ad_user_port_key_tbl[] = { { "minval", 0, BOND_VALFLAG_MIN | BOND_VALFLAG_DEFAULT}, { "maxval", 1023, BOND_VALFLAG_MAX}, @@ -497,7 +490,7 @@ static const struct bond_option bond_opts[BOND_OPT_LAST] = { .id = BOND_OPT_ACTOR_PORT_PRIO, .name = "actor_port_prio", .unsuppmodes = BOND_MODE_ALL_EX(BIT(BOND_MODE_8023AD)), - .values = bond_actor_port_prio_tbl, + .flags = BOND_OPTFLAG_RAWVAL, .set = bond_option_actor_port_prio_set, }, [BOND_OPT_AD_ACTOR_SYSTEM] = { diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c index 2f846381d5a762..eb767edc4c135b 100644 --- a/drivers/net/dsa/b53/b53_common.c +++ b/drivers/net/dsa/b53/b53_common.c @@ -371,11 +371,11 @@ static void b53_set_forwarding(struct b53_device *dev, int enable) * frames should be flooded or not. */ b53_read8(dev, B53_CTRL_PAGE, B53_IP_MULTICAST_CTRL, &mgmt); - mgmt |= B53_UC_FWD_EN | B53_MC_FWD_EN | B53_IPMC_FWD_EN; + mgmt |= B53_UC_FWD_EN | B53_MC_FWD_EN | B53_IP_MC; b53_write8(dev, B53_CTRL_PAGE, B53_IP_MULTICAST_CTRL, mgmt); } else { b53_read8(dev, B53_CTRL_PAGE, B53_IP_MULTICAST_CTRL, &mgmt); - mgmt |= B53_IP_MCAST_25; + mgmt |= B53_IP_MC; b53_write8(dev, B53_CTRL_PAGE, B53_IP_MULTICAST_CTRL, mgmt); } } @@ -1372,6 +1372,10 @@ static void b53_force_port_config(struct b53_device *dev, int port, else reg &= ~PORT_OVERRIDE_FULL_DUPLEX; + reg &= ~(0x3 << GMII_PO_SPEED_S); + if (is5301x(dev) || is58xx(dev)) + reg &= ~PORT_OVERRIDE_SPEED_2000M; + switch (speed) { case 2000: reg |= PORT_OVERRIDE_SPEED_2000M; @@ -1390,6 +1394,11 @@ static void b53_force_port_config(struct b53_device *dev, int port, return; } + if (is5325(dev)) + reg &= ~PORT_OVERRIDE_LP_FLOW_25; + else + reg &= ~(PORT_OVERRIDE_RX_FLOW | PORT_OVERRIDE_TX_FLOW); + if (rx_pause) { if (is5325(dev)) reg |= PORT_OVERRIDE_LP_FLOW_25; @@ -1593,8 +1602,11 @@ static void b53_phylink_mac_link_down(struct phylink_config *config, struct b53_device *dev = dp->ds->priv; int port = dp->index; - if (mode == MLO_AN_PHY) + if (mode == MLO_AN_PHY) { + if (is63xx(dev) && in_range(port, B53_63XX_RGMII0, 4)) + b53_force_link(dev, port, false); return; + } if (mode == MLO_AN_FIXED) { b53_force_link(dev, port, false); @@ -1622,6 +1634,13 @@ static void b53_phylink_mac_link_up(struct phylink_config *config, if (mode == MLO_AN_PHY) { /* Re-negotiate EEE if it was enabled already */ p->eee_enabled = b53_eee_init(ds, port, phydev); + + if (is63xx(dev) && in_range(port, B53_63XX_RGMII0, 4)) { + b53_force_port_config(dev, port, speed, duplex, + tx_pause, rx_pause); + b53_force_link(dev, port, true); + } + return; } @@ -2018,7 +2037,7 @@ static int b53_arl_search_wait(struct b53_device *dev) do { b53_read8(dev, B53_ARLIO_PAGE, offset, ®); if (!(reg & ARL_SRCH_STDN)) - return 0; + return -ENOENT; if (reg & ARL_SRCH_VLID) return 0; @@ -2068,13 +2087,16 @@ static int b53_fdb_copy(int port, const struct b53_arl_entry *ent, int b53_fdb_dump(struct dsa_switch *ds, int port, dsa_fdb_dump_cb_t *cb, void *data) { + unsigned int count = 0, results_per_hit = 1; struct b53_device *priv = ds->priv; struct b53_arl_entry results[2]; - unsigned int count = 0; u8 offset; int ret; u8 reg; + if (priv->num_arl_bins > 2) + results_per_hit = 2; + mutex_lock(&priv->arl_mutex); if (is5325(priv) || is5365(priv)) @@ -2096,7 +2118,7 @@ int b53_fdb_dump(struct dsa_switch *ds, int port, if (ret) break; - if (priv->num_arl_bins > 2) { + if (results_per_hit == 2) { b53_arl_search_rd(priv, 1, &results[1]); ret = b53_fdb_copy(port, &results[1], cb, data); if (ret) @@ -2106,7 +2128,7 @@ int b53_fdb_dump(struct dsa_switch *ds, int port, break; } - } while (count++ < b53_max_arl_entries(priv) / 2); + } while (count++ < b53_max_arl_entries(priv) / results_per_hit); mutex_unlock(&priv->arl_mutex); diff --git a/drivers/net/dsa/b53/b53_regs.h b/drivers/net/dsa/b53/b53_regs.h index 309fe0e46dadf4..8ce1ce72e93856 100644 --- a/drivers/net/dsa/b53/b53_regs.h +++ b/drivers/net/dsa/b53/b53_regs.h @@ -111,8 +111,7 @@ /* IP Multicast control (8 bit) */ #define B53_IP_MULTICAST_CTRL 0x21 -#define B53_IP_MCAST_25 BIT(0) -#define B53_IPMC_FWD_EN BIT(1) +#define B53_IP_MC BIT(0) #define B53_UC_FWD_EN BIT(6) #define B53_MC_FWD_EN BIT(7) diff --git a/drivers/net/dsa/hirschmann/hellcreek_ptp.c b/drivers/net/dsa/hirschmann/hellcreek_ptp.c index bfe21f9f7dcd36..cb23bea9c21b81 100644 --- a/drivers/net/dsa/hirschmann/hellcreek_ptp.c +++ b/drivers/net/dsa/hirschmann/hellcreek_ptp.c @@ -376,8 +376,18 @@ static int hellcreek_led_setup(struct hellcreek *hellcreek) hellcreek_set_brightness(hellcreek, STATUS_OUT_IS_GM, 1); /* Register both leds */ - led_classdev_register(hellcreek->dev, &hellcreek->led_sync_good); - led_classdev_register(hellcreek->dev, &hellcreek->led_is_gm); + ret = led_classdev_register(hellcreek->dev, &hellcreek->led_sync_good); + if (ret) { + dev_err(hellcreek->dev, "Failed to register sync_good LED\n"); + goto out; + } + + ret = led_classdev_register(hellcreek->dev, &hellcreek->led_is_gm); + if (ret) { + dev_err(hellcreek->dev, "Failed to register is_gm LED\n"); + led_classdev_unregister(&hellcreek->led_sync_good); + goto out; + } ret = 0; diff --git a/drivers/net/dsa/microchip/ksz9477.c b/drivers/net/dsa/microchip/ksz9477.c index d747ea1c41a793..5df8f153d511bc 100644 --- a/drivers/net/dsa/microchip/ksz9477.c +++ b/drivers/net/dsa/microchip/ksz9477.c @@ -1355,9 +1355,15 @@ void ksz9477_config_cpu_port(struct dsa_switch *ds) } } +#define RESV_MCAST_CNT 8 + +static u8 reserved_mcast_map[RESV_MCAST_CNT] = { 0, 1, 3, 16, 32, 33, 2, 17 }; + int ksz9477_enable_stp_addr(struct ksz_device *dev) { + u8 i, ports, update; const u32 *masks; + bool override; u32 data; int ret; @@ -1366,23 +1372,87 @@ int ksz9477_enable_stp_addr(struct ksz_device *dev) /* Enable Reserved multicast table */ ksz_cfg(dev, REG_SW_LUE_CTRL_0, SW_RESV_MCAST_ENABLE, true); - /* Set the Override bit for forwarding BPDU packet to CPU */ - ret = ksz_write32(dev, REG_SW_ALU_VAL_B, - ALU_V_OVERRIDE | BIT(dev->cpu_port)); - if (ret < 0) - return ret; + /* The reserved multicast address table has 8 entries. Each entry has + * a default value of which port to forward. It is assumed the host + * port is the last port in most of the switches, but that is not the + * case for KSZ9477 or maybe KSZ9897. For LAN937X family the default + * port is port 5, the first RGMII port. It is okay for LAN9370, a + * 5-port switch, but may not be correct for the other 8-port + * versions. It is necessary to update the whole table to forward to + * the right ports. + * Furthermore PTP messages can use a reserved multicast address and + * the host will not receive them if this table is not correct. + */ + for (i = 0; i < RESV_MCAST_CNT; i++) { + data = reserved_mcast_map[i] << + dev->info->shifts[ALU_STAT_INDEX]; + data |= ALU_STAT_START | + masks[ALU_STAT_DIRECT] | + masks[ALU_RESV_MCAST_ADDR] | + masks[ALU_STAT_READ]; + ret = ksz_write32(dev, REG_SW_ALU_STAT_CTRL__4, data); + if (ret < 0) + return ret; - data = ALU_STAT_START | ALU_RESV_MCAST_ADDR | masks[ALU_STAT_WRITE]; + /* wait to be finished */ + ret = ksz9477_wait_alu_sta_ready(dev); + if (ret < 0) + return ret; - ret = ksz_write32(dev, REG_SW_ALU_STAT_CTRL__4, data); - if (ret < 0) - return ret; + ret = ksz_read32(dev, REG_SW_ALU_VAL_B, &data); + if (ret < 0) + return ret; - /* wait to be finished */ - ret = ksz9477_wait_alu_sta_ready(dev); - if (ret < 0) { - dev_err(dev->dev, "Failed to update Reserved Multicast table\n"); - return ret; + override = false; + ports = data & dev->port_mask; + switch (i) { + case 0: + case 6: + /* Change the host port. */ + update = BIT(dev->cpu_port); + override = true; + break; + case 2: + /* Change the host port. */ + update = BIT(dev->cpu_port); + break; + case 4: + case 5: + case 7: + /* Skip the host port. */ + update = dev->port_mask & ~BIT(dev->cpu_port); + break; + default: + update = ports; + break; + } + if (update != ports || override) { + data &= ~dev->port_mask; + data |= update; + /* Set Override bit to receive frame even when port is + * closed. + */ + if (override) + data |= ALU_V_OVERRIDE; + ret = ksz_write32(dev, REG_SW_ALU_VAL_B, data); + if (ret < 0) + return ret; + + data = reserved_mcast_map[i] << + dev->info->shifts[ALU_STAT_INDEX]; + data |= ALU_STAT_START | + masks[ALU_STAT_DIRECT] | + masks[ALU_RESV_MCAST_ADDR] | + masks[ALU_STAT_WRITE]; + ret = ksz_write32(dev, REG_SW_ALU_STAT_CTRL__4, data); + if (ret < 0) + return ret; + + /* wait to be finished */ + ret = ksz9477_wait_alu_sta_ready(dev); + if (ret < 0) + return ret; + } } return 0; diff --git a/drivers/net/dsa/microchip/ksz9477_reg.h b/drivers/net/dsa/microchip/ksz9477_reg.h index ff579920078ee3..61ea11e3338e1b 100644 --- a/drivers/net/dsa/microchip/ksz9477_reg.h +++ b/drivers/net/dsa/microchip/ksz9477_reg.h @@ -2,7 +2,7 @@ /* * Microchip KSZ9477 register definitions * - * Copyright (C) 2017-2024 Microchip Technology Inc. + * Copyright (C) 2017-2025 Microchip Technology Inc. */ #ifndef __KSZ9477_REGS_H @@ -397,7 +397,6 @@ #define ALU_RESV_MCAST_INDEX_M (BIT(6) - 1) #define ALU_STAT_START BIT(7) -#define ALU_RESV_MCAST_ADDR BIT(1) #define REG_SW_ALU_VAL_A 0x0420 diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c index a962055bfdbd8f..933ae8dc633783 100644 --- a/drivers/net/dsa/microchip/ksz_common.c +++ b/drivers/net/dsa/microchip/ksz_common.c @@ -808,6 +808,8 @@ static const u16 ksz9477_regs[] = { static const u32 ksz9477_masks[] = { [ALU_STAT_WRITE] = 0, [ALU_STAT_READ] = 1, + [ALU_STAT_DIRECT] = 0, + [ALU_RESV_MCAST_ADDR] = BIT(1), [P_MII_TX_FLOW_CTRL] = BIT(5), [P_MII_RX_FLOW_CTRL] = BIT(3), }; @@ -835,6 +837,8 @@ static const u8 ksz9477_xmii_ctrl1[] = { static const u32 lan937x_masks[] = { [ALU_STAT_WRITE] = 1, [ALU_STAT_READ] = 2, + [ALU_STAT_DIRECT] = BIT(3), + [ALU_RESV_MCAST_ADDR] = BIT(2), [P_MII_TX_FLOW_CTRL] = BIT(5), [P_MII_RX_FLOW_CTRL] = BIT(3), }; diff --git a/drivers/net/dsa/microchip/ksz_common.h b/drivers/net/dsa/microchip/ksz_common.h index a1eb39771bb995..c65188cd3c0a0e 100644 --- a/drivers/net/dsa/microchip/ksz_common.h +++ b/drivers/net/dsa/microchip/ksz_common.h @@ -294,6 +294,8 @@ enum ksz_masks { DYNAMIC_MAC_TABLE_TIMESTAMP, ALU_STAT_WRITE, ALU_STAT_READ, + ALU_STAT_DIRECT, + ALU_RESV_MCAST_ADDR, P_MII_TX_FLOW_CTRL, P_MII_RX_FLOW_CTRL, }; diff --git a/drivers/net/dsa/microchip/lan937x_main.c b/drivers/net/dsa/microchip/lan937x_main.c index b1ae3b9de3d16b..5a1496fff4452a 100644 --- a/drivers/net/dsa/microchip/lan937x_main.c +++ b/drivers/net/dsa/microchip/lan937x_main.c @@ -540,6 +540,7 @@ static void lan937x_set_tune_adj(struct ksz_device *dev, int port, ksz_pread16(dev, port, reg, &data16); /* Update tune Adjust */ + data16 &= ~PORT_TUNE_ADJ; data16 |= FIELD_PREP(PORT_TUNE_ADJ, val); ksz_pwrite16(dev, port, reg, data16); diff --git a/drivers/net/ethernet/airoha/airoha_ppe.c b/drivers/net/ethernet/airoha/airoha_ppe.c index 691361b2540755..c0e17035db18ed 100644 --- a/drivers/net/ethernet/airoha/airoha_ppe.c +++ b/drivers/net/ethernet/airoha/airoha_ppe.c @@ -282,7 +282,7 @@ static int airoha_ppe_foe_entry_prepare(struct airoha_eth *eth, if (!airoha_is_valid_gdm_port(eth, port)) return -EINVAL; - if (dsa_port >= 0) + if (dsa_port >= 0 || eth->ports[1]) pse_port = port->id == 4 ? FE_PSE_PORT_GDM4 : port->id; else diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index 3fc33b1b4dfb14..a625e7c311dd7e 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -12439,7 +12439,7 @@ static int bnxt_try_recover_fw(struct bnxt *bp) return -ENODEV; } -static void bnxt_clear_reservations(struct bnxt *bp, bool fw_reset) +void bnxt_clear_reservations(struct bnxt *bp, bool fw_reset) { struct bnxt_hw_resc *hw_resc = &bp->hw_resc; @@ -16892,6 +16892,10 @@ static void bnxt_shutdown(struct pci_dev *pdev) if (netif_running(dev)) netif_close(dev); + if (bnxt_hwrm_func_drv_unrgtr(bp)) { + pcie_flr(pdev); + goto shutdown_exit; + } bnxt_ptp_clear(bp); bnxt_clear_int_mode(bp); pci_disable_device(pdev); diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h index 741b2d854789b6..3613a172483a16 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h @@ -2149,7 +2149,7 @@ struct bnxt_bs_trace_info { static inline void bnxt_bs_trace_check_wrap(struct bnxt_bs_trace_info *bs_trace, u32 offset) { - if (!bs_trace->wrapped && + if (!bs_trace->wrapped && bs_trace->magic_byte && *bs_trace->magic_byte != BNXT_TRACE_BUF_MAGIC_BYTE) bs_trace->wrapped = 1; bs_trace->last_offset = offset; @@ -2941,6 +2941,7 @@ void bnxt_report_link(struct bnxt *bp); int bnxt_update_link(struct bnxt *bp, bool chng_link_state); int bnxt_hwrm_set_pause(struct bnxt *); int bnxt_hwrm_set_link_setting(struct bnxt *, bool, bool); +void bnxt_clear_reservations(struct bnxt *bp, bool fw_reset); int bnxt_cancel_reservations(struct bnxt *bp, bool fw_reset); int bnxt_hwrm_alloc_wol_fltr(struct bnxt *bp); int bnxt_hwrm_free_wol_fltr(struct bnxt *bp); diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_coredump.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_coredump.c index 0181ab1f2dfdcf..ccb8b509662ddc 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_coredump.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_coredump.c @@ -333,13 +333,14 @@ static void bnxt_fill_drv_seg_record(struct bnxt *bp, u32 offset = 0; int rc = 0; + record->max_entries = cpu_to_le32(ctxm->max_entries); + record->entry_size = cpu_to_le32(ctxm->entry_size); + rc = bnxt_dbg_hwrm_log_buffer_flush(bp, type, 0, &offset); if (rc) return; bnxt_bs_trace_check_wrap(bs_trace, offset); - record->max_entries = cpu_to_le32(ctxm->max_entries); - record->entry_size = cpu_to_le32(ctxm->entry_size); record->offset = cpu_to_le32(bs_trace->last_offset); record->wrapped = bs_trace->wrapped; } diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c index 02961d93ed35d6..67ca02d84c9793 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c @@ -461,7 +461,7 @@ static int bnxt_dl_reload_down(struct devlink *dl, bool netns_change, rtnl_unlock(); break; } - bnxt_cancel_reservations(bp, false); + bnxt_clear_reservations(bp, false); bnxt_free_ctx_mem(bp, false); break; } diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c index db81cf6d5289b2..0abaa2bbe3577e 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c @@ -1051,9 +1051,9 @@ static void bnxt_ptp_free(struct bnxt *bp) if (ptp->ptp_clock) { ptp_clock_unregister(ptp->ptp_clock); ptp->ptp_clock = NULL; - kfree(ptp->ptp_info.pin_config); - ptp->ptp_info.pin_config = NULL; } + kfree(ptp->ptp_info.pin_config); + ptp->ptp_info.pin_config = NULL; } int bnxt_ptp_init(struct bnxt *bp) diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index cb004fd1625273..5bb31c8fab3913 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -1296,7 +1296,8 @@ static void be_xmit_flush(struct be_adapter *adapter, struct be_tx_obj *txo) (adapter->bmc_filt_mask & BMC_FILT_MULTICAST) static bool be_send_pkt_to_bmc(struct be_adapter *adapter, - struct sk_buff **skb) + struct sk_buff **skb, + struct be_wrb_params *wrb_params) { struct ethhdr *eh = (struct ethhdr *)(*skb)->data; bool os2bmc = false; @@ -1360,7 +1361,7 @@ static bool be_send_pkt_to_bmc(struct be_adapter *adapter, * to BMC, asic expects the vlan to be inline in the packet. */ if (os2bmc) - *skb = be_insert_vlan_in_pkt(adapter, *skb, NULL); + *skb = be_insert_vlan_in_pkt(adapter, *skb, wrb_params); return os2bmc; } @@ -1387,7 +1388,7 @@ static netdev_tx_t be_xmit(struct sk_buff *skb, struct net_device *netdev) /* if os2bmc is enabled and if the pkt is destined to bmc, * enqueue the pkt a 2nd time with mgmt bit set. */ - if (be_send_pkt_to_bmc(adapter, &skb)) { + if (be_send_pkt_to_bmc(adapter, &skb, &wrb_params)) { BE_WRB_F_SET(wrb_params.features, OS2BMC, 1); wrb_cnt = be_xmit_enqueue(adapter, txo, skb, &wrb_params); if (unlikely(!wrb_cnt)) diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c index 1edcfaee6819e0..3222359ac15b77 100644 --- a/drivers/net/ethernet/freescale/fec_main.c +++ b/drivers/net/ethernet/freescale/fec_main.c @@ -1835,6 +1835,8 @@ fec_enet_rx_queue(struct net_device *ndev, u16 queue_id, int budget) ndev->stats.rx_packets++; pkt_len = fec16_to_cpu(bdp->cbd_datlen); ndev->stats.rx_bytes += pkt_len; + if (fep->quirks & FEC_QUIRK_HAS_RACC) + ndev->stats.rx_bytes -= 2; index = fec_enet_get_bd_index(bdp, &rxq->bd); page = rxq->rx_skb_info[index].page; diff --git a/drivers/net/ethernet/google/gve/gve_ptp.c b/drivers/net/ethernet/google/gve/gve_ptp.c index e96247c9d68d29..a384a9ed4914ef 100644 --- a/drivers/net/ethernet/google/gve/gve_ptp.c +++ b/drivers/net/ethernet/google/gve/gve_ptp.c @@ -26,6 +26,19 @@ int gve_clock_nic_ts_read(struct gve_priv *priv) return 0; } +static int gve_ptp_gettimex64(struct ptp_clock_info *info, + struct timespec64 *ts, + struct ptp_system_timestamp *sts) +{ + return -EOPNOTSUPP; +} + +static int gve_ptp_settime64(struct ptp_clock_info *info, + const struct timespec64 *ts) +{ + return -EOPNOTSUPP; +} + static long gve_ptp_do_aux_work(struct ptp_clock_info *info) { const struct gve_ptp *ptp = container_of(info, struct gve_ptp, info); @@ -47,6 +60,8 @@ static long gve_ptp_do_aux_work(struct ptp_clock_info *info) static const struct ptp_clock_info gve_ptp_caps = { .owner = THIS_MODULE, .name = "gve clock", + .gettimex64 = gve_ptp_gettimex64, + .settime64 = gve_ptp_settime64, .do_aux_work = gve_ptp_do_aux_work, }; diff --git a/drivers/net/ethernet/intel/Kconfig b/drivers/net/ethernet/intel/Kconfig index a563a94e27802a..122ee23497e6a5 100644 --- a/drivers/net/ethernet/intel/Kconfig +++ b/drivers/net/ethernet/intel/Kconfig @@ -146,7 +146,7 @@ config IXGBE tristate "Intel(R) 10GbE PCI Express adapters support" depends on PCI depends on PTP_1588_CLOCK_OPTIONAL - select LIBIE_FWLOG + select LIBIE_FWLOG if DEBUG_FS select MDIO select NET_DEVLINK select PLDMFW @@ -298,7 +298,7 @@ config ICE select DIMLIB select LIBIE select LIBIE_ADMINQ - select LIBIE_FWLOG + select LIBIE_FWLOG if DEBUG_FS select NET_DEVLINK select PACKING select PLDMFW diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c index fb0f6365a6d6f1..8ec0f7d0fcebdd 100644 --- a/drivers/net/ethernet/intel/ice/ice_ptp.c +++ b/drivers/net/ethernet/intel/ice/ice_ptp.c @@ -3246,7 +3246,7 @@ void ice_ptp_init(struct ice_pf *pf) err = ice_ptp_init_port(pf, &ptp->port); if (err) - goto err_exit; + goto err_clean_pf; /* Start the PHY timestamping block */ ice_ptp_reset_phy_timestamping(pf); @@ -3263,13 +3263,19 @@ void ice_ptp_init(struct ice_pf *pf) dev_info(ice_pf_to_dev(pf), "PTP init successful\n"); return; +err_clean_pf: + mutex_destroy(&ptp->port.ps_lock); + ice_ptp_cleanup_pf(pf); err_exit: /* If we registered a PTP clock, release it */ if (pf->ptp.clock) { ptp_clock_unregister(ptp->clock); pf->ptp.clock = NULL; } - ptp->state = ICE_PTP_ERROR; + /* Keep ICE_PTP_UNINIT state to avoid ambiguity at driver unload + * and to avoid duplicated resources release. + */ + ptp->state = ICE_PTP_UNINIT; dev_err(ice_pf_to_dev(pf), "PTP failed %d\n", err); } @@ -3282,9 +3288,19 @@ void ice_ptp_init(struct ice_pf *pf) */ void ice_ptp_release(struct ice_pf *pf) { - if (pf->ptp.state != ICE_PTP_READY) + if (pf->ptp.state == ICE_PTP_UNINIT) return; + if (pf->ptp.state != ICE_PTP_READY) { + mutex_destroy(&pf->ptp.port.ps_lock); + ice_ptp_cleanup_pf(pf); + if (pf->ptp.clock) { + ptp_clock_unregister(pf->ptp.clock); + pf->ptp.clock = NULL; + } + return; + } + pf->ptp.state = ICE_PTP_UNINIT; /* Disable timestamping for both Tx and Rx */ diff --git a/drivers/net/ethernet/intel/idpf/idpf_main.c b/drivers/net/ethernet/intel/idpf/idpf_main.c index 8c46481d2e1f4a..8cf4ff6975722e 100644 --- a/drivers/net/ethernet/intel/idpf/idpf_main.c +++ b/drivers/net/ethernet/intel/idpf/idpf_main.c @@ -63,6 +63,8 @@ static void idpf_remove(struct pci_dev *pdev) destroy_workqueue(adapter->vc_event_wq); for (i = 0; i < adapter->max_vports; i++) { + if (!adapter->vport_config[i]) + continue; kfree(adapter->vport_config[i]->user_config.q_coalesce); kfree(adapter->vport_config[i]); adapter->vport_config[i] = NULL; diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h index 14d2752701238b..dce4936708eb44 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h @@ -821,9 +821,7 @@ struct ixgbe_adapter { #ifdef CONFIG_IXGBE_HWMON struct hwmon_buff *ixgbe_hwmon_buff; #endif /* CONFIG_IXGBE_HWMON */ -#ifdef CONFIG_DEBUG_FS struct dentry *ixgbe_dbg_adapter; -#endif /*CONFIG_DEBUG_FS*/ u8 default_up; /* Bitmask indicating in use pools */ diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c index aff17c37ddde07..902d6abaa3ec17 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c +++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c @@ -1516,10 +1516,8 @@ int otx2_pool_init(struct otx2_nic *pfvf, u16 pool_id, pool->xdp_cnt = numptrs; pool->xdp = devm_kcalloc(pfvf->dev, numptrs, sizeof(struct xdp_buff *), GFP_KERNEL); - if (IS_ERR(pool->xdp)) { - netdev_err(pfvf->netdev, "Creation of xsk pool failed\n"); - return PTR_ERR(pool->xdp); - } + if (!pool->xdp) + return -ENOMEM; } return 0; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/cq.c b/drivers/net/ethernet/mellanox/mlx5/core/cq.c index e9f319a9bdd6be..60f7ab1d72e788 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/cq.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/cq.c @@ -66,8 +66,8 @@ void mlx5_cq_tasklet_cb(struct tasklet_struct *t) tasklet_schedule(&ctx->task); } -static void mlx5_add_cq_to_tasklet(struct mlx5_core_cq *cq, - struct mlx5_eqe *eqe) +void mlx5_add_cq_to_tasklet(struct mlx5_core_cq *cq, + struct mlx5_eqe *eqe) { unsigned long flags; struct mlx5_eq_tasklet *tasklet_ctx = cq->tasklet_ctx.priv; @@ -95,7 +95,15 @@ static void mlx5_add_cq_to_tasklet(struct mlx5_core_cq *cq, if (schedule_tasklet) tasklet_schedule(&tasklet_ctx->task); } +EXPORT_SYMBOL(mlx5_add_cq_to_tasklet); +static void mlx5_core_cq_dummy_cb(struct mlx5_core_cq *cq, struct mlx5_eqe *eqe) +{ + mlx5_core_err(cq->eq->core.dev, + "CQ default completion callback, CQ #%u\n", cq->cqn); +} + +#define MLX5_CQ_INIT_CMD_SN cpu_to_be32(2 << 28) /* Callers must verify outbox status in case of err */ int mlx5_create_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq, u32 *in, int inlen, u32 *out, int outlen) @@ -121,10 +129,19 @@ int mlx5_create_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq, cq->arm_sn = 0; cq->eq = eq; cq->uid = MLX5_GET(create_cq_in, in, uid); + + /* Kernel CQs must set the arm_db address prior to calling + * this function, allowing for the proper value to be + * initialized. User CQs are responsible for their own + * initialization since they do not use the arm_db field. + */ + if (cq->arm_db) + *cq->arm_db = MLX5_CQ_INIT_CMD_SN; + refcount_set(&cq->refcount, 1); init_completion(&cq->free); if (!cq->comp) - cq->comp = mlx5_add_cq_to_tasklet; + cq->comp = mlx5_core_cq_dummy_cb; /* assuming CQ will be deleted before the EQ */ cq->tasklet_ctx.priv = &eq->tasklet_ctx; INIT_LIST_HEAD(&cq->tasklet_ctx.list); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c index fceea83abbd76b..887adf4807d164 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c @@ -541,7 +541,7 @@ static int mlx5_devlink_num_doorbells_validate(struct devlink *devlink, u32 id, max_num_channels = mlx5e_get_max_num_channels(mdev); if (val32 > max_num_channels) { NL_SET_ERR_MSG_FMT_MOD(extack, - "Requested num_doorbells (%u) exceeds maximum number of channels (%u)", + "Requested num_doorbells (%u) exceeds max number of channels (%u)", val32, max_num_channels); return -EINVAL; } diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h index 14e3207b14e745..a163f81f07c13d 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h @@ -634,7 +634,10 @@ struct mlx5e_dma_info { struct mlx5e_shampo_hd { struct mlx5e_frag_page *pages; u32 hd_per_wq; + u32 hd_per_page; u16 hd_per_wqe; + u8 log_hd_per_page; + u8 log_hd_entry_size; unsigned long *bitmap; u16 pi; u16 ci; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c index 0a4fb8c922684d..35d9530037a655 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c @@ -804,7 +804,8 @@ static int mlx5e_xfrm_add_state(struct net_device *dev, goto err_xfrm; } - if (mlx5_eswitch_block_mode(priv->mdev)) + err = mlx5_eswitch_block_mode(priv->mdev); + if (err) goto unblock_ipsec; if (x->props.mode == XFRM_MODE_TUNNEL && diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c index d166c0d5189e19..9b93da4d52f64b 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c @@ -595,32 +595,55 @@ static int mlx5e_dcbnl_ieee_setmaxrate(struct net_device *netdev, struct mlx5_core_dev *mdev = priv->mdev; u8 max_bw_value[IEEE_8021QAZ_MAX_TCS]; u8 max_bw_unit[IEEE_8021QAZ_MAX_TCS]; - __u64 upper_limit_mbps = roundup(255 * MLX5E_100MB, MLX5E_1GB); + __u64 upper_limit_mbps; + __u64 upper_limit_gbps; int i; + struct { + int scale; + const char *units_str; + } units[] = { + [MLX5_100_MBPS_UNIT] = { + .scale = 100, + .units_str = "Mbps", + }, + [MLX5_GBPS_UNIT] = { + .scale = 1, + .units_str = "Gbps", + }, + }; memset(max_bw_value, 0, sizeof(max_bw_value)); memset(max_bw_unit, 0, sizeof(max_bw_unit)); + upper_limit_mbps = 255 * MLX5E_100MB; + upper_limit_gbps = 255 * MLX5E_1GB; for (i = 0; i <= mlx5_max_tc(mdev); i++) { if (!maxrate->tc_maxrate[i]) { max_bw_unit[i] = MLX5_BW_NO_LIMIT; continue; } - if (maxrate->tc_maxrate[i] < upper_limit_mbps) { + if (maxrate->tc_maxrate[i] <= upper_limit_mbps) { max_bw_value[i] = div_u64(maxrate->tc_maxrate[i], MLX5E_100MB); max_bw_value[i] = max_bw_value[i] ? max_bw_value[i] : 1; max_bw_unit[i] = MLX5_100_MBPS_UNIT; - } else { + } else if (max_bw_value[i] <= upper_limit_gbps) { max_bw_value[i] = div_u64(maxrate->tc_maxrate[i], MLX5E_1GB); max_bw_unit[i] = MLX5_GBPS_UNIT; + } else { + netdev_err(netdev, + "tc_%d maxrate %llu Kbps exceeds limit %llu\n", + i, maxrate->tc_maxrate[i], + upper_limit_gbps); + return -EINVAL; } } for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) { - netdev_dbg(netdev, "%s: tc_%d <=> max_bw %d Gbps\n", - __func__, i, max_bw_value[i]); + netdev_dbg(netdev, "%s: tc_%d <=> max_bw %u %s\n", __func__, i, + max_bw_value[i] * units[max_bw_unit[i]].scale, + units[max_bw_unit[i]].units_str); } return mlx5_modify_port_ets_rate_limit(mdev, max_bw_value, max_bw_unit); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c index 53e5ae252eac58..893e1380a7c973 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c @@ -2125,14 +2125,12 @@ static int mlx5e_get_module_eeprom_by_page(struct net_device *netdev, if (!size_read) return i; - if (size_read == -EINVAL) - return -EINVAL; if (size_read < 0) { NL_SET_ERR_MSG_FMT_MOD( extack, "Query module eeprom by page failed, read %u bytes, err %d", i, size_read); - return i; + return size_read; } i += size_read; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c index 9c46511e7b4376..5e17eae81f4b3c 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c @@ -791,8 +791,9 @@ static int mlx5_rq_shampo_alloc(struct mlx5_core_dev *mdev, int node) { void *wqc = MLX5_ADDR_OF(rqc, rqp->rqc, wq); + u8 log_hd_per_page, log_hd_entry_size; + u16 hd_per_wq, hd_per_wqe; u32 hd_pool_size; - u16 hd_per_wq; int wq_size; int err; @@ -815,11 +816,24 @@ static int mlx5_rq_shampo_alloc(struct mlx5_core_dev *mdev, if (err) goto err_umr_mkey; - rq->mpwqe.shampo->hd_per_wqe = - mlx5e_shampo_hd_per_wqe(mdev, params, rqp); + hd_per_wqe = mlx5e_shampo_hd_per_wqe(mdev, params, rqp); wq_size = BIT(MLX5_GET(wq, wqc, log_wq_sz)); - hd_pool_size = (rq->mpwqe.shampo->hd_per_wqe * wq_size) / - MLX5E_SHAMPO_WQ_HEADER_PER_PAGE; + + BUILD_BUG_ON(MLX5E_SHAMPO_LOG_MAX_HEADER_ENTRY_SIZE > PAGE_SHIFT); + if (hd_per_wqe >= MLX5E_SHAMPO_WQ_HEADER_PER_PAGE) { + log_hd_per_page = MLX5E_SHAMPO_LOG_WQ_HEADER_PER_PAGE; + log_hd_entry_size = MLX5E_SHAMPO_LOG_MAX_HEADER_ENTRY_SIZE; + } else { + log_hd_per_page = order_base_2(hd_per_wqe); + log_hd_entry_size = order_base_2(PAGE_SIZE / hd_per_wqe); + } + + rq->mpwqe.shampo->hd_per_wqe = hd_per_wqe; + rq->mpwqe.shampo->hd_per_page = BIT(log_hd_per_page); + rq->mpwqe.shampo->log_hd_per_page = log_hd_per_page; + rq->mpwqe.shampo->log_hd_entry_size = log_hd_entry_size; + + hd_pool_size = (hd_per_wqe * wq_size) >> log_hd_per_page; if (netif_rxq_has_unreadable_mp(rq->netdev, rq->ix)) { /* Separate page pool for shampo headers */ @@ -2205,7 +2219,6 @@ static int mlx5e_alloc_cq_common(struct mlx5_core_dev *mdev, mcq->set_ci_db = cq->wq_ctrl.db.db; mcq->arm_db = cq->wq_ctrl.db.db + 1; *mcq->set_ci_db = 0; - *mcq->arm_db = 0; mcq->vector = param->eq_ix; mcq->comp = mlx5e_completion_event; mcq->event = mlx5e_cq_error_event; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c index 26621a2972ec2b..687cf123211d75 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c @@ -648,17 +648,20 @@ static void build_ksm_umr(struct mlx5e_icosq *sq, struct mlx5e_umr_wqe *umr_wqe, umr_wqe->hdr.uctrl.mkey_mask = cpu_to_be64(MLX5_MKEY_MASK_FREE); } -static struct mlx5e_frag_page *mlx5e_shampo_hd_to_frag_page(struct mlx5e_rq *rq, int header_index) +static struct mlx5e_frag_page *mlx5e_shampo_hd_to_frag_page(struct mlx5e_rq *rq, + int header_index) { - BUILD_BUG_ON(MLX5E_SHAMPO_LOG_MAX_HEADER_ENTRY_SIZE > PAGE_SHIFT); + struct mlx5e_shampo_hd *shampo = rq->mpwqe.shampo; - return &rq->mpwqe.shampo->pages[header_index >> MLX5E_SHAMPO_LOG_WQ_HEADER_PER_PAGE]; + return &shampo->pages[header_index >> shampo->log_hd_per_page]; } -static u64 mlx5e_shampo_hd_offset(int header_index) +static u64 mlx5e_shampo_hd_offset(struct mlx5e_rq *rq, int header_index) { - return (header_index & (MLX5E_SHAMPO_WQ_HEADER_PER_PAGE - 1)) << - MLX5E_SHAMPO_LOG_MAX_HEADER_ENTRY_SIZE; + struct mlx5e_shampo_hd *shampo = rq->mpwqe.shampo; + u32 hd_per_page = shampo->hd_per_page; + + return (header_index & (hd_per_page - 1)) << shampo->log_hd_entry_size; } static void mlx5e_free_rx_shampo_hd_entry(struct mlx5e_rq *rq, u16 header_index); @@ -671,7 +674,7 @@ static int mlx5e_build_shampo_hd_umr(struct mlx5e_rq *rq, u16 pi, header_offset, err, wqe_bbs; u32 lkey = rq->mdev->mlx5e_res.hw_objs.mkey; struct mlx5e_umr_wqe *umr_wqe; - int headroom, i = 0; + int headroom, i; headroom = rq->buff.headroom; wqe_bbs = MLX5E_KSM_UMR_WQEBBS(ksm_entries); @@ -679,25 +682,24 @@ static int mlx5e_build_shampo_hd_umr(struct mlx5e_rq *rq, umr_wqe = mlx5_wq_cyc_get_wqe(&sq->wq, pi); build_ksm_umr(sq, umr_wqe, shampo->mkey_be, index, ksm_entries); - WARN_ON_ONCE(ksm_entries & (MLX5E_SHAMPO_WQ_HEADER_PER_PAGE - 1)); - while (i < ksm_entries) { - struct mlx5e_frag_page *frag_page = mlx5e_shampo_hd_to_frag_page(rq, index); + for (i = 0; i < ksm_entries; i++, index++) { + struct mlx5e_frag_page *frag_page; u64 addr; - err = mlx5e_page_alloc_fragmented(rq->hd_page_pool, frag_page); - if (unlikely(err)) - goto err_unmap; + frag_page = mlx5e_shampo_hd_to_frag_page(rq, index); + header_offset = mlx5e_shampo_hd_offset(rq, index); + if (!header_offset) { + err = mlx5e_page_alloc_fragmented(rq->hd_page_pool, + frag_page); + if (err) + goto err_unmap; + } addr = page_pool_get_dma_addr_netmem(frag_page->netmem); - - for (int j = 0; j < MLX5E_SHAMPO_WQ_HEADER_PER_PAGE; j++) { - header_offset = mlx5e_shampo_hd_offset(index++); - - umr_wqe->inline_ksms[i++] = (struct mlx5_ksm) { - .key = cpu_to_be32(lkey), - .va = cpu_to_be64(addr + header_offset + headroom), - }; - } + umr_wqe->inline_ksms[i] = (struct mlx5_ksm) { + .key = cpu_to_be32(lkey), + .va = cpu_to_be64(addr + header_offset + headroom), + }; } sq->db.wqe_info[pi] = (struct mlx5e_icosq_wqe_info) { @@ -713,9 +715,9 @@ static int mlx5e_build_shampo_hd_umr(struct mlx5e_rq *rq, return 0; err_unmap: - while (--i) { + while (--i >= 0) { --index; - header_offset = mlx5e_shampo_hd_offset(index); + header_offset = mlx5e_shampo_hd_offset(rq, index); if (!header_offset) { struct mlx5e_frag_page *frag_page = mlx5e_shampo_hd_to_frag_page(rq, index); @@ -735,12 +737,11 @@ static int mlx5e_alloc_rx_hd_mpwqe(struct mlx5e_rq *rq) struct mlx5e_icosq *sq = rq->icosq; int i, err, max_ksm_entries, len; - max_ksm_entries = ALIGN_DOWN(MLX5E_MAX_KSM_PER_WQE(rq->mdev), - MLX5E_SHAMPO_WQ_HEADER_PER_PAGE); + max_ksm_entries = MLX5E_MAX_KSM_PER_WQE(rq->mdev); ksm_entries = bitmap_find_window(shampo->bitmap, shampo->hd_per_wqe, shampo->hd_per_wq, shampo->pi); - ksm_entries = ALIGN_DOWN(ksm_entries, MLX5E_SHAMPO_WQ_HEADER_PER_PAGE); + ksm_entries = ALIGN_DOWN(ksm_entries, shampo->hd_per_page); if (!ksm_entries) return 0; @@ -858,7 +859,7 @@ mlx5e_free_rx_shampo_hd_entry(struct mlx5e_rq *rq, u16 header_index) { struct mlx5e_shampo_hd *shampo = rq->mpwqe.shampo; - if (((header_index + 1) & (MLX5E_SHAMPO_WQ_HEADER_PER_PAGE - 1)) == 0) { + if (((header_index + 1) & (shampo->hd_per_page - 1)) == 0) { struct mlx5e_frag_page *frag_page = mlx5e_shampo_hd_to_frag_page(rq, header_index); mlx5e_page_release_fragmented(rq->hd_page_pool, frag_page); @@ -1225,9 +1226,10 @@ static unsigned int mlx5e_lro_update_hdr(struct sk_buff *skb, static void *mlx5e_shampo_get_packet_hd(struct mlx5e_rq *rq, u16 header_index) { struct mlx5e_frag_page *frag_page = mlx5e_shampo_hd_to_frag_page(rq, header_index); - u16 head_offset = mlx5e_shampo_hd_offset(header_index) + rq->buff.headroom; + u16 head_offset = mlx5e_shampo_hd_offset(rq, header_index); + void *addr = netmem_address(frag_page->netmem); - return netmem_address(frag_page->netmem) + head_offset; + return addr + head_offset + rq->buff.headroom; } static void mlx5e_shampo_update_ipv4_udp_hdr(struct mlx5e_rq *rq, struct iphdr *ipv4) @@ -2267,7 +2269,8 @@ mlx5e_skb_from_cqe_shampo(struct mlx5e_rq *rq, struct mlx5e_mpw_info *wi, struct mlx5_cqe64 *cqe, u16 header_index) { struct mlx5e_frag_page *frag_page = mlx5e_shampo_hd_to_frag_page(rq, header_index); - u16 head_offset = mlx5e_shampo_hd_offset(header_index); + u16 head_offset = mlx5e_shampo_hd_offset(rq, header_index); + struct mlx5e_shampo_hd *shampo = rq->mpwqe.shampo; u16 head_size = cqe->shampo.header_size; u16 rx_headroom = rq->buff.headroom; struct sk_buff *skb = NULL; @@ -2283,7 +2286,7 @@ mlx5e_skb_from_cqe_shampo(struct mlx5e_rq *rq, struct mlx5e_mpw_info *wi, data = hdr + rx_headroom; frag_size = MLX5_SKB_FRAG_SZ(rx_headroom + head_size); - if (likely(frag_size <= BIT(MLX5E_SHAMPO_LOG_MAX_HEADER_ENTRY_SIZE))) { + if (likely(frag_size <= BIT(shampo->log_hd_entry_size))) { /* build SKB around header */ dma_sync_single_range_for_cpu(rq->pdev, dma_addr, 0, frag_size, rq->buff.map_dir); net_prefetchw(hdr); @@ -2356,7 +2359,10 @@ mlx5e_hw_gro_skb_has_enough_space(struct sk_buff *skb, u16 data_bcnt) { int nr_frags = skb_shinfo(skb)->nr_frags; - return PAGE_SIZE * nr_frags + data_bcnt <= GRO_LEGACY_MAX_SIZE; + if (PAGE_SIZE >= GRO_LEGACY_MAX_SIZE) + return skb->len + data_bcnt <= GRO_LEGACY_MAX_SIZE; + else + return PAGE_SIZE * nr_frags + data_bcnt <= GRO_LEGACY_MAX_SIZE; } static void mlx5e_handle_rx_cqe_mpwrq_shampo(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fpga/conn.c b/drivers/net/ethernet/mellanox/mlx5/core/fpga/conn.c index cb1319974f83f9..ccef64fb40b666 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/fpga/conn.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/fpga/conn.c @@ -421,6 +421,13 @@ static int mlx5_fpga_conn_create_cq(struct mlx5_fpga_conn *conn, int cq_size) __be64 *pas; u32 i; + conn->cq.mcq.cqe_sz = 64; + conn->cq.mcq.set_ci_db = conn->cq.wq_ctrl.db.db; + conn->cq.mcq.arm_db = conn->cq.wq_ctrl.db.db + 1; + *conn->cq.mcq.set_ci_db = 0; + conn->cq.mcq.vector = 0; + conn->cq.mcq.comp = mlx5_fpga_conn_cq_complete; + cq_size = roundup_pow_of_two(cq_size); MLX5_SET(cqc, temp_cqc, log_cq_size, ilog2(cq_size)); @@ -468,15 +475,7 @@ static int mlx5_fpga_conn_create_cq(struct mlx5_fpga_conn *conn, int cq_size) if (err) goto err_cqwq; - conn->cq.mcq.cqe_sz = 64; - conn->cq.mcq.set_ci_db = conn->cq.wq_ctrl.db.db; - conn->cq.mcq.arm_db = conn->cq.wq_ctrl.db.db + 1; - *conn->cq.mcq.set_ci_db = 0; - *conn->cq.mcq.arm_db = 0; - conn->cq.mcq.vector = 0; - conn->cq.mcq.comp = mlx5_fpga_conn_cq_complete; tasklet_setup(&conn->cq.tasklet, mlx5_fpga_conn_cq_tasklet); - mlx5_fpga_dbg(fdev, "Created CQ #0x%x\n", conn->cq.mcq.cqn); goto out; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c b/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c index e18a850c615c66..aa3b5878e3dadf 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c @@ -324,10 +324,8 @@ struct mlx5_irq *mlx5_irq_alloc(struct mlx5_irq_pool *pool, int i, free_irq(irq->map.virq, &irq->nh); err_req_irq: #ifdef CONFIG_RFS_ACCEL - if (i && rmap && *rmap) { - free_irq_cpu_rmap(*rmap); - *rmap = NULL; - } + if (i && rmap && *rmap) + irq_cpu_rmap_remove(*rmap, irq->map.virq); err_irq_rmap: #endif if (i && pci_msix_can_alloc_dyn(dev->pdev)) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/send.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/send.c index 24ef7d66fa8aa2..7510c46e58a570 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/send.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/send.c @@ -873,12 +873,6 @@ static int hws_send_ring_open_sq(struct mlx5hws_context *ctx, return err; } -static void hws_cq_complete(struct mlx5_core_cq *mcq, - struct mlx5_eqe *eqe) -{ - pr_err("CQ completion CQ: #%u\n", mcq->cqn); -} - static int hws_send_ring_alloc_cq(struct mlx5_core_dev *mdev, int numa_node, struct mlx5hws_send_engine *queue, @@ -901,7 +895,6 @@ static int hws_send_ring_alloc_cq(struct mlx5_core_dev *mdev, mcq->cqe_sz = 64; mcq->set_ci_db = cq->wq_ctrl.db.db; mcq->arm_db = cq->wq_ctrl.db.db + 1; - mcq->comp = hws_cq_complete; for (i = 0; i < mlx5_cqwq_get_size(&cq->wq); i++) { cqe = mlx5_cqwq_get_wqe(&cq->wq, i); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/sws/dr_send.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/sws/dr_send.c index 077a77fde670ef..d034372fa04768 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/steering/sws/dr_send.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/sws/dr_send.c @@ -1049,12 +1049,6 @@ static int dr_prepare_qp_to_rts(struct mlx5dr_domain *dmn) return 0; } -static void dr_cq_complete(struct mlx5_core_cq *mcq, - struct mlx5_eqe *eqe) -{ - pr_err("CQ completion CQ: #%u\n", mcq->cqn); -} - static struct mlx5dr_cq *dr_create_cq(struct mlx5_core_dev *mdev, struct mlx5_uars_page *uar, size_t ncqe) @@ -1089,6 +1083,13 @@ static struct mlx5dr_cq *dr_create_cq(struct mlx5_core_dev *mdev, cqe->op_own = MLX5_CQE_INVALID << 4 | MLX5_CQE_OWNER_MASK; } + cq->mcq.cqe_sz = 64; + cq->mcq.set_ci_db = cq->wq_ctrl.db.db; + cq->mcq.arm_db = cq->wq_ctrl.db.db + 1; + *cq->mcq.set_ci_db = 0; + cq->mcq.vector = 0; + cq->mdev = mdev; + inlen = MLX5_ST_SZ_BYTES(create_cq_in) + sizeof(u64) * cq->wq_ctrl.buf.npages; in = kvzalloc(inlen, GFP_KERNEL); @@ -1112,27 +1113,12 @@ static struct mlx5dr_cq *dr_create_cq(struct mlx5_core_dev *mdev, pas = (__be64 *)MLX5_ADDR_OF(create_cq_in, in, pas); mlx5_fill_page_frag_array(&cq->wq_ctrl.buf, pas); - cq->mcq.comp = dr_cq_complete; - err = mlx5_core_create_cq(mdev, &cq->mcq, in, inlen, out, sizeof(out)); kvfree(in); if (err) goto err_cqwq; - cq->mcq.cqe_sz = 64; - cq->mcq.set_ci_db = cq->wq_ctrl.db.db; - cq->mcq.arm_db = cq->wq_ctrl.db.db + 1; - *cq->mcq.set_ci_db = 0; - - /* set no-zero value, in order to avoid the HW to run db-recovery on - * CQ that used in polling mode. - */ - *cq->mcq.arm_db = cpu_to_be32(2 << 28); - - cq->mcq.vector = 0; - cq->mdev = mdev; - return cq; err_cqwq: diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_linecards.c b/drivers/net/ethernet/mellanox/mlxsw/core_linecards.c index b032d5a4b3b84c..10f5bc4892fc75 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/core_linecards.c +++ b/drivers/net/ethernet/mellanox/mlxsw/core_linecards.c @@ -601,6 +601,8 @@ int mlxsw_linecard_devlink_info_get(struct mlxsw_linecard *linecard, err = devlink_info_version_fixed_put(req, DEVLINK_INFO_VERSION_GENERIC_FW_PSID, info->psid); + if (err) + goto unlock; sprintf(buf, "%u.%u.%u", info->fw_major, info->fw_minor, info->fw_sub_minor); diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c index 6a4a81c63451c6..353fd9ca89a68a 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c @@ -830,8 +830,10 @@ int mlxsw_sp_flower_stats(struct mlxsw_sp *mlxsw_sp, return -EINVAL; rule = mlxsw_sp_acl_rule_lookup(mlxsw_sp, ruleset, f->cookie); - if (!rule) - return -EINVAL; + if (!rule) { + err = -EINVAL; + goto err_rule_get_stats; + } err = mlxsw_sp_acl_rule_get_stats(mlxsw_sp, rule, &packets, &bytes, &drops, &lastuse, &used_hw_stats); diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_ethtool.c b/drivers/net/ethernet/microchip/lan966x/lan966x_ethtool.c index 2474dfd330f46e..fe4e6140528405 100644 --- a/drivers/net/ethernet/microchip/lan966x/lan966x_ethtool.c +++ b/drivers/net/ethernet/microchip/lan966x/lan966x_ethtool.c @@ -294,7 +294,7 @@ static void lan966x_stats_update(struct lan966x *lan966x) { int i, j; - mutex_lock(&lan966x->stats_lock); + spin_lock(&lan966x->stats_lock); for (i = 0; i < lan966x->num_phys_ports; i++) { uint idx = i * lan966x->num_stats; @@ -310,7 +310,7 @@ static void lan966x_stats_update(struct lan966x *lan966x) } } - mutex_unlock(&lan966x->stats_lock); + spin_unlock(&lan966x->stats_lock); } static int lan966x_get_sset_count(struct net_device *dev, int sset) @@ -365,7 +365,7 @@ static void lan966x_get_eth_mac_stats(struct net_device *dev, idx = port->chip_port * lan966x->num_stats; - mutex_lock(&lan966x->stats_lock); + spin_lock(&lan966x->stats_lock); mac_stats->FramesTransmittedOK = lan966x->stats[idx + SYS_COUNT_TX_UC] + @@ -416,7 +416,7 @@ static void lan966x_get_eth_mac_stats(struct net_device *dev, lan966x->stats[idx + SYS_COUNT_RX_LONG] + lan966x->stats[idx + SYS_COUNT_RX_PMAC_LONG]; - mutex_unlock(&lan966x->stats_lock); + spin_unlock(&lan966x->stats_lock); } static const struct ethtool_rmon_hist_range lan966x_rmon_ranges[] = { @@ -442,7 +442,7 @@ static void lan966x_get_eth_rmon_stats(struct net_device *dev, idx = port->chip_port * lan966x->num_stats; - mutex_lock(&lan966x->stats_lock); + spin_lock(&lan966x->stats_lock); rmon_stats->undersize_pkts = lan966x->stats[idx + SYS_COUNT_RX_SHORT] + @@ -500,7 +500,7 @@ static void lan966x_get_eth_rmon_stats(struct net_device *dev, lan966x->stats[idx + SYS_COUNT_TX_SZ_1024_1526] + lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_1024_1526]; - mutex_unlock(&lan966x->stats_lock); + spin_unlock(&lan966x->stats_lock); *ranges = lan966x_rmon_ranges; } @@ -603,7 +603,7 @@ void lan966x_stats_get(struct net_device *dev, idx = port->chip_port * lan966x->num_stats; - mutex_lock(&lan966x->stats_lock); + spin_lock(&lan966x->stats_lock); stats->rx_bytes = lan966x->stats[idx + SYS_COUNT_RX_OCT] + lan966x->stats[idx + SYS_COUNT_RX_PMAC_OCT]; @@ -685,7 +685,7 @@ void lan966x_stats_get(struct net_device *dev, stats->collisions = lan966x->stats[idx + SYS_COUNT_TX_COL]; - mutex_unlock(&lan966x->stats_lock); + spin_unlock(&lan966x->stats_lock); } int lan966x_stats_init(struct lan966x *lan966x) @@ -701,7 +701,7 @@ int lan966x_stats_init(struct lan966x *lan966x) return -ENOMEM; /* Init stats worker */ - mutex_init(&lan966x->stats_lock); + spin_lock_init(&lan966x->stats_lock); snprintf(queue_name, sizeof(queue_name), "%s-stats", dev_name(lan966x->dev)); lan966x->stats_queue = create_singlethread_workqueue(queue_name); diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_main.c b/drivers/net/ethernet/microchip/lan966x/lan966x_main.c index 7001584f1b7a62..47752d3fde0b10 100644 --- a/drivers/net/ethernet/microchip/lan966x/lan966x_main.c +++ b/drivers/net/ethernet/microchip/lan966x/lan966x_main.c @@ -1261,7 +1261,6 @@ static int lan966x_probe(struct platform_device *pdev) cancel_delayed_work_sync(&lan966x->stats_work); destroy_workqueue(lan966x->stats_queue); - mutex_destroy(&lan966x->stats_lock); debugfs_remove_recursive(lan966x->debugfs_root); @@ -1279,7 +1278,6 @@ static void lan966x_remove(struct platform_device *pdev) cancel_delayed_work_sync(&lan966x->stats_work); destroy_workqueue(lan966x->stats_queue); - mutex_destroy(&lan966x->stats_lock); lan966x_mac_purge_entries(lan966x); lan966x_mdb_deinit(lan966x); diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_main.h b/drivers/net/ethernet/microchip/lan966x/lan966x_main.h index 4f75f068836933..eea286c29474f2 100644 --- a/drivers/net/ethernet/microchip/lan966x/lan966x_main.h +++ b/drivers/net/ethernet/microchip/lan966x/lan966x_main.h @@ -295,8 +295,8 @@ struct lan966x { const struct lan966x_stat_layout *stats_layout; u32 num_stats; - /* workqueue for reading stats */ - struct mutex stats_lock; + /* lock for reading stats */ + spinlock_t stats_lock; u64 *stats; struct delayed_work stats_work; struct workqueue_struct *stats_queue; diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_vcap_impl.c b/drivers/net/ethernet/microchip/lan966x/lan966x_vcap_impl.c index a1471e38d11898..2a37fc1ba4bcda 100644 --- a/drivers/net/ethernet/microchip/lan966x/lan966x_vcap_impl.c +++ b/drivers/net/ethernet/microchip/lan966x/lan966x_vcap_impl.c @@ -403,11 +403,11 @@ static void lan966x_es0_read_esdx_counter(struct lan966x *lan966x, u32 counter; id = id & 0xff; /* counter limit */ - mutex_lock(&lan966x->stats_lock); + spin_lock(&lan966x->stats_lock); lan_wr(SYS_STAT_CFG_STAT_VIEW_SET(id), lan966x, SYS_STAT_CFG); counter = lan_rd(lan966x, SYS_CNT(LAN966X_STAT_ESDX_GRN_PKTS)) + lan_rd(lan966x, SYS_CNT(LAN966X_STAT_ESDX_YEL_PKTS)); - mutex_unlock(&lan966x->stats_lock); + spin_unlock(&lan966x->stats_lock); if (counter) admin->cache.counter = counter; } @@ -417,14 +417,14 @@ static void lan966x_es0_write_esdx_counter(struct lan966x *lan966x, { id = id & 0xff; /* counter limit */ - mutex_lock(&lan966x->stats_lock); + spin_lock(&lan966x->stats_lock); lan_wr(SYS_STAT_CFG_STAT_VIEW_SET(id), lan966x, SYS_STAT_CFG); lan_wr(0, lan966x, SYS_CNT(LAN966X_STAT_ESDX_GRN_BYTES)); lan_wr(admin->cache.counter, lan966x, SYS_CNT(LAN966X_STAT_ESDX_GRN_PKTS)); lan_wr(0, lan966x, SYS_CNT(LAN966X_STAT_ESDX_YEL_BYTES)); lan_wr(0, lan966x, SYS_CNT(LAN966X_STAT_ESDX_YEL_PKTS)); - mutex_unlock(&lan966x->stats_lock); + spin_unlock(&lan966x->stats_lock); } static void lan966x_vcap_cache_write(struct net_device *dev, diff --git a/drivers/net/ethernet/pensando/ionic/ionic_txrx.c b/drivers/net/ethernet/pensando/ionic/ionic_txrx.c index d10b58ebf6034a..301ebee2fdc50b 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_txrx.c +++ b/drivers/net/ethernet/pensando/ionic/ionic_txrx.c @@ -29,6 +29,10 @@ static void ionic_tx_clean(struct ionic_queue *q, static inline void ionic_txq_post(struct ionic_queue *q, bool ring_dbell) { + /* Ensure TX descriptor writes reach memory before NIC reads them. + * Prevents device from fetching stale descriptors. + */ + dma_wmb(); ionic_q_post(q, ring_dbell); } @@ -1444,19 +1448,6 @@ static int ionic_tx_tso(struct net_device *netdev, struct ionic_queue *q, bool encap; int err; - desc_info = &q->tx_info[q->head_idx]; - - if (unlikely(ionic_tx_map_skb(q, skb, desc_info))) - return -EIO; - - len = skb->len; - mss = skb_shinfo(skb)->gso_size; - outer_csum = (skb_shinfo(skb)->gso_type & (SKB_GSO_GRE | - SKB_GSO_GRE_CSUM | - SKB_GSO_IPXIP4 | - SKB_GSO_IPXIP6 | - SKB_GSO_UDP_TUNNEL | - SKB_GSO_UDP_TUNNEL_CSUM)); has_vlan = !!skb_vlan_tag_present(skb); vlan_tci = skb_vlan_tag_get(skb); encap = skb->encapsulation; @@ -1470,12 +1461,21 @@ static int ionic_tx_tso(struct net_device *netdev, struct ionic_queue *q, err = ionic_tx_tcp_inner_pseudo_csum(skb); else err = ionic_tx_tcp_pseudo_csum(skb); - if (unlikely(err)) { - /* clean up mapping from ionic_tx_map_skb */ - ionic_tx_desc_unmap_bufs(q, desc_info); + if (unlikely(err)) return err; - } + desc_info = &q->tx_info[q->head_idx]; + if (unlikely(ionic_tx_map_skb(q, skb, desc_info))) + return -EIO; + + len = skb->len; + mss = skb_shinfo(skb)->gso_size; + outer_csum = (skb_shinfo(skb)->gso_type & (SKB_GSO_GRE | + SKB_GSO_GRE_CSUM | + SKB_GSO_IPXIP4 | + SKB_GSO_IPXIP6 | + SKB_GSO_UDP_TUNNEL | + SKB_GSO_UDP_TUNNEL_CSUM)); if (encap) hdrlen = skb_inner_tcp_all_headers(skb); else diff --git a/drivers/net/ethernet/qlogic/qede/qede_fp.c b/drivers/net/ethernet/qlogic/qede/qede_fp.c index 847fa62c80df82..e338bfc8b7b2f2 100644 --- a/drivers/net/ethernet/qlogic/qede/qede_fp.c +++ b/drivers/net/ethernet/qlogic/qede/qede_fp.c @@ -4,6 +4,7 @@ * Copyright (c) 2019-2020 Marvell International Ltd. */ +#include #include #include #include @@ -960,7 +961,7 @@ static inline void qede_tpa_cont(struct qede_dev *edev, { int i; - for (i = 0; cqe->len_list[i]; i++) + for (i = 0; cqe->len_list[i] && i < ARRAY_SIZE(cqe->len_list); i++) qede_fill_frag_skb(edev, rxq, cqe->tpa_agg_index, le16_to_cpu(cqe->len_list[i])); @@ -985,7 +986,7 @@ static int qede_tpa_end(struct qede_dev *edev, dma_unmap_page(rxq->dev, tpa_info->buffer.mapping, PAGE_SIZE, rxq->data_direction); - for (i = 0; cqe->len_list[i]; i++) + for (i = 0; cqe->len_list[i] && i < ARRAY_SIZE(cqe->len_list); i++) qede_fill_frag_skb(edev, rxq, cqe->tpa_agg_index, le16_to_cpu(cqe->len_list[i])); if (unlikely(i > 1)) diff --git a/drivers/net/ethernet/spacemit/k1_emac.c b/drivers/net/ethernet/spacemit/k1_emac.c index e1c5faff3b71c7..220eb5ce75833d 100644 --- a/drivers/net/ethernet/spacemit/k1_emac.c +++ b/drivers/net/ethernet/spacemit/k1_emac.c @@ -1441,6 +1441,9 @@ static int emac_set_pauseparam(struct net_device *dev, struct emac_priv *priv = netdev_priv(dev); u8 fc = 0; + if (!netif_running(dev)) + return -ENETDOWN; + priv->flow_control_autoneg = pause->autoneg; if (pause->autoneg) { diff --git a/drivers/net/ethernet/ti/am65-cpsw-qos.c b/drivers/net/ethernet/ti/am65-cpsw-qos.c index fa96db7c1a1305..66e8b224827b66 100644 --- a/drivers/net/ethernet/ti/am65-cpsw-qos.c +++ b/drivers/net/ethernet/ti/am65-cpsw-qos.c @@ -276,9 +276,31 @@ static int am65_cpsw_iet_set_verify_timeout_count(struct am65_cpsw_port *port) /* The number of wireside clocks contained in the verify * timeout counter. The default is 0x1312d0 * (10ms at 125Mhz in 1G mode). + * The frequency of the clock depends on the link speed + * and the PHY interface. */ - val = 125 * HZ_PER_MHZ; /* assuming 125MHz wireside clock */ + switch (port->slave.phy_if) { + case PHY_INTERFACE_MODE_RGMII: + case PHY_INTERFACE_MODE_RGMII_ID: + case PHY_INTERFACE_MODE_RGMII_RXID: + case PHY_INTERFACE_MODE_RGMII_TXID: + if (port->qos.link_speed == SPEED_1000) + val = 125 * HZ_PER_MHZ; /* 125 MHz at 1000Mbps*/ + else if (port->qos.link_speed == SPEED_100) + val = 25 * HZ_PER_MHZ; /* 25 MHz at 100Mbps*/ + else + val = (25 * HZ_PER_MHZ) / 10; /* 2.5 MHz at 10Mbps*/ + break; + + case PHY_INTERFACE_MODE_QSGMII: + case PHY_INTERFACE_MODE_SGMII: + val = 125 * HZ_PER_MHZ; /* 125 MHz */ + break; + default: + netdev_err(port->ndev, "selected mode does not supported IET\n"); + return -EOPNOTSUPP; + } val /= MILLIHZ_PER_HZ; /* count per ms timeout */ val *= verify_time_ms; /* count for timeout ms */ @@ -295,20 +317,21 @@ static int am65_cpsw_iet_verify_wait(struct am65_cpsw_port *port) u32 ctrl, status; int try; - try = 20; - do { - /* Reset the verify state machine by writing 1 - * to LINKFAIL - */ - ctrl = readl(port->port_base + AM65_CPSW_PN_REG_IET_CTRL); - ctrl |= AM65_CPSW_PN_IET_MAC_LINKFAIL; - writel(ctrl, port->port_base + AM65_CPSW_PN_REG_IET_CTRL); + try = 3; - /* Clear MAC_LINKFAIL bit to start Verify. */ - ctrl = readl(port->port_base + AM65_CPSW_PN_REG_IET_CTRL); - ctrl &= ~AM65_CPSW_PN_IET_MAC_LINKFAIL; - writel(ctrl, port->port_base + AM65_CPSW_PN_REG_IET_CTRL); + /* Reset the verify state machine by writing 1 + * to LINKFAIL + */ + ctrl = readl(port->port_base + AM65_CPSW_PN_REG_IET_CTRL); + ctrl |= AM65_CPSW_PN_IET_MAC_LINKFAIL; + writel(ctrl, port->port_base + AM65_CPSW_PN_REG_IET_CTRL); + /* Clear MAC_LINKFAIL bit to start Verify. */ + ctrl = readl(port->port_base + AM65_CPSW_PN_REG_IET_CTRL); + ctrl &= ~AM65_CPSW_PN_IET_MAC_LINKFAIL; + writel(ctrl, port->port_base + AM65_CPSW_PN_REG_IET_CTRL); + + do { msleep(port->qos.iet.verify_time_ms); status = readl(port->port_base + AM65_CPSW_PN_REG_IET_STATUS); @@ -330,7 +353,7 @@ static int am65_cpsw_iet_verify_wait(struct am65_cpsw_port *port) netdev_dbg(port->ndev, "MAC Merge verify error\n"); return -ENODEV; } - } while (try-- > 0); + } while (--try > 0); netdev_dbg(port->ndev, "MAC Merge verify timeout\n"); return -ETIMEDOUT; diff --git a/drivers/net/ethernet/ti/icssg/icssg_config.c b/drivers/net/ethernet/ti/icssg/icssg_config.c index da53eb04b0a43d..3f8237c17d099e 100644 --- a/drivers/net/ethernet/ti/icssg/icssg_config.c +++ b/drivers/net/ethernet/ti/icssg/icssg_config.c @@ -66,6 +66,9 @@ #define FDB_GEN_CFG1 0x60 #define SMEM_VLAN_OFFSET 8 #define SMEM_VLAN_OFFSET_MASK GENMASK(25, 8) +#define FDB_HASH_SIZE_MASK GENMASK(6, 3) +#define FDB_HASH_SIZE_SHIFT 3 +#define FDB_HASH_SIZE 3 #define FDB_GEN_CFG2 0x64 #define FDB_VLAN_EN BIT(6) @@ -463,6 +466,8 @@ void icssg_init_emac_mode(struct prueth *prueth) /* Set VLAN TABLE address base */ regmap_update_bits(prueth->miig_rt, FDB_GEN_CFG1, SMEM_VLAN_OFFSET_MASK, addr << SMEM_VLAN_OFFSET); + regmap_update_bits(prueth->miig_rt, FDB_GEN_CFG1, FDB_HASH_SIZE_MASK, + FDB_HASH_SIZE << FDB_HASH_SIZE_SHIFT); /* Set enable VLAN aware mode, and FDBs for all PRUs */ regmap_write(prueth->miig_rt, FDB_GEN_CFG2, (FDB_PRU0_EN | FDB_PRU1_EN | FDB_HOST_EN)); prueth->vlan_tbl = (struct prueth_vlan_tbl __force *)(prueth->shram.va + @@ -484,6 +489,8 @@ void icssg_init_fw_offload_mode(struct prueth *prueth) /* Set VLAN TABLE address base */ regmap_update_bits(prueth->miig_rt, FDB_GEN_CFG1, SMEM_VLAN_OFFSET_MASK, addr << SMEM_VLAN_OFFSET); + regmap_update_bits(prueth->miig_rt, FDB_GEN_CFG1, FDB_HASH_SIZE_MASK, + FDB_HASH_SIZE << FDB_HASH_SIZE_SHIFT); /* Set enable VLAN aware mode, and FDBs for all PRUs */ regmap_write(prueth->miig_rt, FDB_GEN_CFG2, FDB_EN_ALL); prueth->vlan_tbl = (struct prueth_vlan_tbl __force *)(prueth->shram.va + diff --git a/drivers/net/ethernet/ti/netcp_core.c b/drivers/net/ethernet/ti/netcp_core.c index 857820657bac51..5ee13db568f08f 100644 --- a/drivers/net/ethernet/ti/netcp_core.c +++ b/drivers/net/ethernet/ti/netcp_core.c @@ -1338,10 +1338,10 @@ int netcp_txpipe_open(struct netcp_tx_pipe *tx_pipe) tx_pipe->dma_channel = knav_dma_open_channel(dev, tx_pipe->dma_chan_name, &config); - if (IS_ERR(tx_pipe->dma_channel)) { + if (!tx_pipe->dma_channel) { dev_err(dev, "failed opening tx chan(%s)\n", tx_pipe->dma_chan_name); - ret = PTR_ERR(tx_pipe->dma_channel); + ret = -EINVAL; goto err; } @@ -1359,7 +1359,7 @@ int netcp_txpipe_open(struct netcp_tx_pipe *tx_pipe) return 0; err: - if (!IS_ERR_OR_NULL(tx_pipe->dma_channel)) + if (tx_pipe->dma_channel) knav_dma_close_channel(tx_pipe->dma_channel); tx_pipe->dma_channel = NULL; return ret; @@ -1678,10 +1678,10 @@ static int netcp_setup_navigator_resources(struct net_device *ndev) netcp->rx_channel = knav_dma_open_channel(netcp->netcp_device->device, netcp->dma_chan_name, &config); - if (IS_ERR(netcp->rx_channel)) { + if (!netcp->rx_channel) { dev_err(netcp->ndev_dev, "failed opening rx chan(%s\n", netcp->dma_chan_name); - ret = PTR_ERR(netcp->rx_channel); + ret = -EINVAL; goto fail; } diff --git a/drivers/net/ethernet/toshiba/ps3_gelic_net.c b/drivers/net/ethernet/toshiba/ps3_gelic_net.c index 5ee8e8980393c3..591866fc9055d6 100644 --- a/drivers/net/ethernet/toshiba/ps3_gelic_net.c +++ b/drivers/net/ethernet/toshiba/ps3_gelic_net.c @@ -260,6 +260,7 @@ void gelic_card_down(struct gelic_card *card) if (atomic_dec_if_positive(&card->users) == 0) { pr_debug("%s: real do\n", __func__); napi_disable(&card->napi); + timer_delete_sync(&card->rx_oom_timer); /* * Disable irq. Wireless interrupts will * be disabled later if any @@ -970,7 +971,8 @@ static void gelic_net_pass_skb_up(struct gelic_descr *descr, * gelic_card_decode_one_descr - processes an rx descriptor * @card: card structure * - * returns 1 if a packet has been sent to the stack, otherwise 0 + * returns 1 if a packet has been sent to the stack, -ENOMEM on skb alloc + * failure, otherwise 0 * * processes an rx descriptor by iommu-unmapping the data buffer and passing * the packet up to the stack @@ -981,16 +983,18 @@ static int gelic_card_decode_one_descr(struct gelic_card *card) struct gelic_descr_chain *chain = &card->rx_chain; struct gelic_descr *descr = chain->head; struct net_device *netdev = NULL; - int dmac_chain_ended; + int dmac_chain_ended = 0; + int prepare_rx_ret; status = gelic_descr_get_status(descr); if (status == GELIC_DESCR_DMA_CARDOWNED) return 0; - if (status == GELIC_DESCR_DMA_NOT_IN_USE) { + if (status == GELIC_DESCR_DMA_NOT_IN_USE || !descr->skb) { dev_dbg(ctodev(card), "dormant descr? %p\n", descr); - return 0; + dmac_chain_ended = 1; + goto refill; } /* netdevice select */ @@ -1048,9 +1052,10 @@ static int gelic_card_decode_one_descr(struct gelic_card *card) refill: /* is the current descriptor terminated with next_descr == NULL? */ - dmac_chain_ended = - be32_to_cpu(descr->hw_regs.dmac_cmd_status) & - GELIC_DESCR_RX_DMA_CHAIN_END; + if (!dmac_chain_ended) + dmac_chain_ended = + be32_to_cpu(descr->hw_regs.dmac_cmd_status) & + GELIC_DESCR_RX_DMA_CHAIN_END; /* * So that always DMAC can see the end * of the descriptor chain to avoid @@ -1062,10 +1067,11 @@ static int gelic_card_decode_one_descr(struct gelic_card *card) gelic_descr_set_status(descr, GELIC_DESCR_DMA_NOT_IN_USE); /* - * this call can fail, but for now, just leave this - * descriptor without skb + * this call can fail, propagate the error */ - gelic_descr_prepare_rx(card, descr); + prepare_rx_ret = gelic_descr_prepare_rx(card, descr); + if (prepare_rx_ret) + return prepare_rx_ret; chain->tail = descr; chain->head = descr->next; @@ -1087,6 +1093,13 @@ static int gelic_card_decode_one_descr(struct gelic_card *card) return 1; } +static void gelic_rx_oom_timer(struct timer_list *t) +{ + struct gelic_card *card = timer_container_of(card, t, rx_oom_timer); + + napi_schedule(&card->napi); +} + /** * gelic_net_poll - NAPI poll function called by the stack to return packets * @napi: napi structure @@ -1099,14 +1112,22 @@ static int gelic_net_poll(struct napi_struct *napi, int budget) { struct gelic_card *card = container_of(napi, struct gelic_card, napi); int packets_done = 0; + int work_result = 0; while (packets_done < budget) { - if (!gelic_card_decode_one_descr(card)) + work_result = gelic_card_decode_one_descr(card); + if (work_result != 1) break; packets_done++; } + if (work_result == -ENOMEM) { + napi_complete_done(napi, packets_done); + mod_timer(&card->rx_oom_timer, jiffies + 1); + return packets_done; + } + if (packets_done < budget) { napi_complete_done(napi, packets_done); gelic_card_rx_irq_on(card); @@ -1576,6 +1597,8 @@ static struct gelic_card *gelic_alloc_card_net(struct net_device **netdev) mutex_init(&card->updown_lock); atomic_set(&card->users, 0); + timer_setup(&card->rx_oom_timer, gelic_rx_oom_timer, 0); + return card; } diff --git a/drivers/net/ethernet/toshiba/ps3_gelic_net.h b/drivers/net/ethernet/toshiba/ps3_gelic_net.h index f7d7931e51b77d..c10f1984a5a114 100644 --- a/drivers/net/ethernet/toshiba/ps3_gelic_net.h +++ b/drivers/net/ethernet/toshiba/ps3_gelic_net.h @@ -268,6 +268,7 @@ struct gelic_vlan_id { struct gelic_card { struct napi_struct napi; struct net_device *netdev[GELIC_PORT_MAX]; + struct timer_list rx_oom_timer; /* * hypervisor requires irq_status should be * 8 bytes aligned, but u64 member is diff --git a/drivers/net/ethernet/wangxun/libwx/wx_hw.c b/drivers/net/ethernet/wangxun/libwx/wx_hw.c index 1e2713f0c9212f..b37d6cfbfbe943 100644 --- a/drivers/net/ethernet/wangxun/libwx/wx_hw.c +++ b/drivers/net/ethernet/wangxun/libwx/wx_hw.c @@ -2427,7 +2427,8 @@ int wx_sw_init(struct wx *wx) wx->oem_svid = pdev->subsystem_vendor; wx->oem_ssid = pdev->subsystem_device; wx->bus.device = PCI_SLOT(pdev->devfn); - wx->bus.func = PCI_FUNC(pdev->devfn); + wx->bus.func = FIELD_GET(WX_CFG_PORT_ST_LANID, + rd32(wx, WX_CFG_PORT_ST)); if (wx->oem_svid == PCI_VENDOR_ID_WANGXUN || pdev->is_virtfn) { diff --git a/drivers/net/ethernet/wangxun/libwx/wx_type.h b/drivers/net/ethernet/wangxun/libwx/wx_type.h index d89b9b8a0a2ce0..2f8319e031820c 100644 --- a/drivers/net/ethernet/wangxun/libwx/wx_type.h +++ b/drivers/net/ethernet/wangxun/libwx/wx_type.h @@ -97,6 +97,8 @@ #define WX_CFG_PORT_CTL_DRV_LOAD BIT(3) #define WX_CFG_PORT_CTL_QINQ BIT(2) #define WX_CFG_PORT_CTL_D_VLAN BIT(0) /* double vlan*/ +#define WX_CFG_PORT_ST 0x14404 +#define WX_CFG_PORT_ST_LANID GENMASK(9, 8) #define WX_CFG_TAG_TPID(_i) (0x14430 + ((_i) * 4)) #define WX_CFG_PORT_CTL_NUM_VT_MASK GENMASK(13, 12) /* number of TVs */ @@ -557,8 +559,6 @@ enum WX_MSCA_CMD_value { #define TXD_USE_COUNT(S) DIV_ROUND_UP((S), WX_MAX_DATA_PER_TXD) #define DESC_NEEDED (MAX_SKB_FRAGS + 4) -#define WX_CFG_PORT_ST 0x14404 - /******************* Receive Descriptor bit definitions **********************/ #define WX_RXD_STAT_DD BIT(0) /* Done */ #define WX_RXD_STAT_EOP BIT(1) /* End of Packet */ diff --git a/drivers/net/mdio/mdio-airoha.c b/drivers/net/mdio/mdio-airoha.c index 1dc9939c8d7d41..52e7475121eafc 100644 --- a/drivers/net/mdio/mdio-airoha.c +++ b/drivers/net/mdio/mdio-airoha.c @@ -219,6 +219,8 @@ static int airoha_mdio_probe(struct platform_device *pdev) priv = bus->priv; priv->base_addr = addr; priv->regmap = device_node_to_regmap(dev->parent->of_node); + if (IS_ERR(priv->regmap)) + return PTR_ERR(priv->regmap); priv->clk = devm_clk_get_enabled(dev, NULL); if (IS_ERR(priv->clk)) diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c index 5d8d0214786c7b..bb6e03a929565b 100644 --- a/drivers/net/netconsole.c +++ b/drivers/net/netconsole.c @@ -936,6 +936,7 @@ static ssize_t userdatum_value_store(struct config_item *item, const char *buf, if (count > MAX_EXTRADATA_VALUE_LEN) return -EMSGSIZE; + mutex_lock(&netconsole_subsys.su_mutex); mutex_lock(&dynamic_netconsole_mutex); ret = strscpy(udm->value, buf, sizeof(udm->value)); @@ -949,6 +950,7 @@ static ssize_t userdatum_value_store(struct config_item *item, const char *buf, ret = count; out_unlock: mutex_unlock(&dynamic_netconsole_mutex); + mutex_unlock(&netconsole_subsys.su_mutex); return ret; } @@ -974,6 +976,7 @@ static ssize_t sysdata_msgid_enabled_store(struct config_item *item, if (ret) return ret; + mutex_lock(&netconsole_subsys.su_mutex); mutex_lock(&dynamic_netconsole_mutex); curr = !!(nt->sysdata_fields & SYSDATA_MSGID); if (msgid_enabled == curr) @@ -994,6 +997,7 @@ static ssize_t sysdata_msgid_enabled_store(struct config_item *item, ret = strnlen(buf, count); unlock: mutex_unlock(&dynamic_netconsole_mutex); + mutex_unlock(&netconsole_subsys.su_mutex); return ret; } @@ -1008,6 +1012,7 @@ static ssize_t sysdata_release_enabled_store(struct config_item *item, if (ret) return ret; + mutex_lock(&netconsole_subsys.su_mutex); mutex_lock(&dynamic_netconsole_mutex); curr = !!(nt->sysdata_fields & SYSDATA_RELEASE); if (release_enabled == curr) @@ -1028,6 +1033,7 @@ static ssize_t sysdata_release_enabled_store(struct config_item *item, ret = strnlen(buf, count); unlock: mutex_unlock(&dynamic_netconsole_mutex); + mutex_unlock(&netconsole_subsys.su_mutex); return ret; } @@ -1042,6 +1048,7 @@ static ssize_t sysdata_taskname_enabled_store(struct config_item *item, if (ret) return ret; + mutex_lock(&netconsole_subsys.su_mutex); mutex_lock(&dynamic_netconsole_mutex); curr = !!(nt->sysdata_fields & SYSDATA_TASKNAME); if (taskname_enabled == curr) @@ -1062,6 +1069,7 @@ static ssize_t sysdata_taskname_enabled_store(struct config_item *item, ret = strnlen(buf, count); unlock: mutex_unlock(&dynamic_netconsole_mutex); + mutex_unlock(&netconsole_subsys.su_mutex); return ret; } @@ -1077,6 +1085,7 @@ static ssize_t sysdata_cpu_nr_enabled_store(struct config_item *item, if (ret) return ret; + mutex_lock(&netconsole_subsys.su_mutex); mutex_lock(&dynamic_netconsole_mutex); curr = !!(nt->sysdata_fields & SYSDATA_CPU_NR); if (cpu_nr_enabled == curr) @@ -1105,6 +1114,7 @@ static ssize_t sysdata_cpu_nr_enabled_store(struct config_item *item, ret = strnlen(buf, count); unlock: mutex_unlock(&dynamic_netconsole_mutex); + mutex_unlock(&netconsole_subsys.su_mutex); return ret; } diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c index cad6ed3aa10b64..4354241137d50d 100644 --- a/drivers/net/phy/mdio_bus.c +++ b/drivers/net/phy/mdio_bus.c @@ -73,8 +73,11 @@ int mdiobus_register_device(struct mdio_device *mdiodev) return err; err = mdiobus_register_reset(mdiodev); - if (err) + if (err) { + gpiod_put(mdiodev->reset_gpio); + mdiodev->reset_gpio = NULL; return err; + } /* Assert the reset signal */ mdio_device_reset(mdiodev, 1); diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c index 604b5de0c15817..01c87c9b77020e 100644 --- a/drivers/net/phy/micrel.c +++ b/drivers/net/phy/micrel.c @@ -466,6 +466,12 @@ struct lan8842_priv { u16 rev; }; +struct lanphy_reg_data { + int page; + u16 addr; + u16 val; +}; + static const struct kszphy_type lan8814_type = { .led_mode_reg = ~LAN8814_LED_CTRL_1, .cable_diag_reg = LAN8814_CABLE_DIAG, @@ -2835,6 +2841,13 @@ static int ksz886x_cable_test_get_status(struct phy_device *phydev, */ #define LAN8814_PAGE_PCS_DIGITAL 2 +/** + * LAN8814_PAGE_EEE - Selects Extended Page 3. + * + * This page contains EEE registers + */ +#define LAN8814_PAGE_EEE 3 + /** * LAN8814_PAGE_COMMON_REGS - Selects Extended Page 4. * @@ -2853,6 +2866,13 @@ static int ksz886x_cable_test_get_status(struct phy_device *phydev, */ #define LAN8814_PAGE_PORT_REGS 5 +/** + * LAN8814_PAGE_POWER_REGS - Selects Extended Page 28. + * + * This page contains analog control registers and power mode registers. + */ +#define LAN8814_PAGE_POWER_REGS 28 + /** * LAN8814_PAGE_SYSTEM_CTRL - Selects Extended Page 31. * @@ -4360,12 +4380,6 @@ static int lan8814_config_init(struct phy_device *phydev) { struct kszphy_priv *lan8814 = phydev->priv; - /* Reset the PHY */ - lanphy_modify_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, - LAN8814_QSGMII_SOFT_RESET, - LAN8814_QSGMII_SOFT_RESET_BIT, - LAN8814_QSGMII_SOFT_RESET_BIT); - /* Disable ANEG with QSGMII PCS Host side */ lanphy_modify_page_reg(phydev, LAN8814_PAGE_PORT_REGS, LAN8814_QSGMII_PCS1G_ANEG_CONFIG, @@ -4451,6 +4465,12 @@ static int lan8814_probe(struct phy_device *phydev) addr, sizeof(struct lan8814_shared_priv)); if (phy_package_init_once(phydev)) { + /* Reset the PHY */ + lanphy_modify_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, + LAN8814_QSGMII_SOFT_RESET, + LAN8814_QSGMII_SOFT_RESET_BIT, + LAN8814_QSGMII_SOFT_RESET_BIT); + err = lan8814_release_coma_mode(phydev); if (err) return err; @@ -5884,6 +5904,144 @@ static int lan8842_probe(struct phy_device *phydev) return 0; } +#define LAN8814_POWER_MGMT_MODE_3_ANEG_MDI 0x13 +#define LAN8814_POWER_MGMT_MODE_4_ANEG_MDIX 0x14 +#define LAN8814_POWER_MGMT_MODE_5_10BT_MDI 0x15 +#define LAN8814_POWER_MGMT_MODE_6_10BT_MDIX 0x16 +#define LAN8814_POWER_MGMT_MODE_7_100BT_TRAIN 0x17 +#define LAN8814_POWER_MGMT_MODE_8_100BT_MDI 0x18 +#define LAN8814_POWER_MGMT_MODE_9_100BT_EEE_MDI_TX 0x19 +#define LAN8814_POWER_MGMT_MODE_10_100BT_EEE_MDI_RX 0x1a +#define LAN8814_POWER_MGMT_MODE_11_100BT_MDIX 0x1b +#define LAN8814_POWER_MGMT_MODE_12_100BT_EEE_MDIX_TX 0x1c +#define LAN8814_POWER_MGMT_MODE_13_100BT_EEE_MDIX_RX 0x1d +#define LAN8814_POWER_MGMT_MODE_14_100BTX_EEE_TX_RX 0x1e + +#define LAN8814_POWER_MGMT_DLLPD_D BIT(0) +#define LAN8814_POWER_MGMT_ADCPD_D BIT(1) +#define LAN8814_POWER_MGMT_PGAPD_D BIT(2) +#define LAN8814_POWER_MGMT_TXPD_D BIT(3) +#define LAN8814_POWER_MGMT_DLLPD_C BIT(4) +#define LAN8814_POWER_MGMT_ADCPD_C BIT(5) +#define LAN8814_POWER_MGMT_PGAPD_C BIT(6) +#define LAN8814_POWER_MGMT_TXPD_C BIT(7) +#define LAN8814_POWER_MGMT_DLLPD_B BIT(8) +#define LAN8814_POWER_MGMT_ADCPD_B BIT(9) +#define LAN8814_POWER_MGMT_PGAPD_B BIT(10) +#define LAN8814_POWER_MGMT_TXPD_B BIT(11) +#define LAN8814_POWER_MGMT_DLLPD_A BIT(12) +#define LAN8814_POWER_MGMT_ADCPD_A BIT(13) +#define LAN8814_POWER_MGMT_PGAPD_A BIT(14) +#define LAN8814_POWER_MGMT_TXPD_A BIT(15) + +#define LAN8814_POWER_MGMT_C_D (LAN8814_POWER_MGMT_DLLPD_D | \ + LAN8814_POWER_MGMT_ADCPD_D | \ + LAN8814_POWER_MGMT_PGAPD_D | \ + LAN8814_POWER_MGMT_DLLPD_C | \ + LAN8814_POWER_MGMT_ADCPD_C | \ + LAN8814_POWER_MGMT_PGAPD_C) + +#define LAN8814_POWER_MGMT_B_C_D (LAN8814_POWER_MGMT_C_D | \ + LAN8814_POWER_MGMT_DLLPD_B | \ + LAN8814_POWER_MGMT_ADCPD_B | \ + LAN8814_POWER_MGMT_PGAPD_B) + +#define LAN8814_POWER_MGMT_VAL1 (LAN8814_POWER_MGMT_C_D | \ + LAN8814_POWER_MGMT_ADCPD_B | \ + LAN8814_POWER_MGMT_PGAPD_B | \ + LAN8814_POWER_MGMT_ADCPD_A | \ + LAN8814_POWER_MGMT_PGAPD_A) + +#define LAN8814_POWER_MGMT_VAL2 LAN8814_POWER_MGMT_C_D + +#define LAN8814_POWER_MGMT_VAL3 (LAN8814_POWER_MGMT_C_D | \ + LAN8814_POWER_MGMT_DLLPD_B | \ + LAN8814_POWER_MGMT_ADCPD_B | \ + LAN8814_POWER_MGMT_PGAPD_A) + +#define LAN8814_POWER_MGMT_VAL4 (LAN8814_POWER_MGMT_B_C_D | \ + LAN8814_POWER_MGMT_ADCPD_A | \ + LAN8814_POWER_MGMT_PGAPD_A) + +#define LAN8814_POWER_MGMT_VAL5 LAN8814_POWER_MGMT_B_C_D + +#define LAN8814_EEE_WAKE_TX_TIMER 0x0e +#define LAN8814_EEE_WAKE_TX_TIMER_MAX_VAL 0x1f + +static const struct lanphy_reg_data short_center_tap_errata[] = { + { LAN8814_PAGE_POWER_REGS, + LAN8814_POWER_MGMT_MODE_3_ANEG_MDI, + LAN8814_POWER_MGMT_VAL1 }, + { LAN8814_PAGE_POWER_REGS, + LAN8814_POWER_MGMT_MODE_4_ANEG_MDIX, + LAN8814_POWER_MGMT_VAL1 }, + { LAN8814_PAGE_POWER_REGS, + LAN8814_POWER_MGMT_MODE_5_10BT_MDI, + LAN8814_POWER_MGMT_VAL1 }, + { LAN8814_PAGE_POWER_REGS, + LAN8814_POWER_MGMT_MODE_6_10BT_MDIX, + LAN8814_POWER_MGMT_VAL1 }, + { LAN8814_PAGE_POWER_REGS, + LAN8814_POWER_MGMT_MODE_7_100BT_TRAIN, + LAN8814_POWER_MGMT_VAL2 }, + { LAN8814_PAGE_POWER_REGS, + LAN8814_POWER_MGMT_MODE_8_100BT_MDI, + LAN8814_POWER_MGMT_VAL3 }, + { LAN8814_PAGE_POWER_REGS, + LAN8814_POWER_MGMT_MODE_9_100BT_EEE_MDI_TX, + LAN8814_POWER_MGMT_VAL3 }, + { LAN8814_PAGE_POWER_REGS, + LAN8814_POWER_MGMT_MODE_10_100BT_EEE_MDI_RX, + LAN8814_POWER_MGMT_VAL4 }, + { LAN8814_PAGE_POWER_REGS, + LAN8814_POWER_MGMT_MODE_11_100BT_MDIX, + LAN8814_POWER_MGMT_VAL5 }, + { LAN8814_PAGE_POWER_REGS, + LAN8814_POWER_MGMT_MODE_12_100BT_EEE_MDIX_TX, + LAN8814_POWER_MGMT_VAL5 }, + { LAN8814_PAGE_POWER_REGS, + LAN8814_POWER_MGMT_MODE_13_100BT_EEE_MDIX_RX, + LAN8814_POWER_MGMT_VAL4 }, + { LAN8814_PAGE_POWER_REGS, + LAN8814_POWER_MGMT_MODE_14_100BTX_EEE_TX_RX, + LAN8814_POWER_MGMT_VAL4 }, +}; + +static const struct lanphy_reg_data waketx_timer_errata[] = { + { LAN8814_PAGE_EEE, + LAN8814_EEE_WAKE_TX_TIMER, + LAN8814_EEE_WAKE_TX_TIMER_MAX_VAL }, +}; + +static int lanphy_write_reg_data(struct phy_device *phydev, + const struct lanphy_reg_data *data, + size_t num) +{ + int ret = 0; + + while (num--) { + ret = lanphy_write_page_reg(phydev, data->page, data->addr, + data->val); + if (ret) + break; + } + + return ret; +} + +static int lan8842_erratas(struct phy_device *phydev) +{ + int ret; + + ret = lanphy_write_reg_data(phydev, short_center_tap_errata, + ARRAY_SIZE(short_center_tap_errata)); + if (ret) + return ret; + + return lanphy_write_reg_data(phydev, waketx_timer_errata, + ARRAY_SIZE(waketx_timer_errata)); +} + static int lan8842_config_init(struct phy_device *phydev) { int ret; @@ -5896,6 +6054,11 @@ static int lan8842_config_init(struct phy_device *phydev) if (ret < 0) return ret; + /* Apply the erratas for this device */ + ret = lan8842_erratas(phydev); + if (ret < 0) + return ret; + /* Even if the GPIOs are set to control the LEDs the behaviour of the * LEDs is wrong, they are not blinking when there is traffic. * To fix this it is required to set extended LED mode diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c index 9d7799ea1c1730..9182443082158b 100644 --- a/drivers/net/phy/phylink.c +++ b/drivers/net/phy/phylink.c @@ -637,6 +637,9 @@ static int phylink_validate(struct phylink *pl, unsigned long *supported, static void phylink_fill_fixedlink_supported(unsigned long *supported) { + linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT, supported); + linkmode_set_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, supported); + linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, supported); linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT, supported); linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT, supported); linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT, supported); diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index 11352d85475ae2..3a4985b582cb12 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c @@ -192,6 +192,12 @@ static int qmimux_rx_fixup(struct usbnet *dev, struct sk_buff *skb) if (!skbn) return 0; + /* Raw IP packets don't have a MAC header, but other subsystems + * (like xfrm) may still access MAC header offsets, so they must + * be initialized. + */ + skb_reset_mac_header(skbn); + switch (skb->data[offset + qmimux_hdr_sz] & 0xf0) { case 0x40: skbn->protocol = htons(ETH_P_IP); diff --git a/drivers/net/veth.c b/drivers/net/veth.c index a3046142cb8e26..35dd89aff4a944 100644 --- a/drivers/net/veth.c +++ b/drivers/net/veth.c @@ -392,14 +392,12 @@ static netdev_tx_t veth_xmit(struct sk_buff *skb, struct net_device *dev) } /* Restore Eth hdr pulled by dev_forward_skb/eth_type_trans */ __skb_push(skb, ETH_HLEN); - /* Depend on prior success packets started NAPI consumer via - * __veth_xdp_flush(). Cancel TXQ stop if consumer stopped, - * paired with empty check in veth_poll(). - */ netif_tx_stop_queue(txq); - smp_mb__after_atomic(); - if (unlikely(__ptr_ring_empty(&rq->xdp_ring))) - netif_tx_wake_queue(txq); + /* Makes sure NAPI peer consumer runs. Consumer is responsible + * for starting txq again, until then ndo_start_xmit (this + * function) will not be invoked by the netstack again. + */ + __veth_xdp_flush(rq); break; case NET_RX_DROP: /* same as NET_XMIT_DROP */ drop: @@ -900,17 +898,9 @@ static int veth_xdp_rcv(struct veth_rq *rq, int budget, struct veth_xdp_tx_bq *bq, struct veth_stats *stats) { - struct veth_priv *priv = netdev_priv(rq->dev); - int queue_idx = rq->xdp_rxq.queue_index; - struct netdev_queue *peer_txq; - struct net_device *peer_dev; int i, done = 0, n_xdpf = 0; void *xdpf[VETH_XDP_BATCH]; - /* NAPI functions as RCU section */ - peer_dev = rcu_dereference_check(priv->peer, rcu_read_lock_bh_held()); - peer_txq = peer_dev ? netdev_get_tx_queue(peer_dev, queue_idx) : NULL; - for (i = 0; i < budget; i++) { void *ptr = __ptr_ring_consume(&rq->xdp_ring); @@ -959,9 +949,6 @@ static int veth_xdp_rcv(struct veth_rq *rq, int budget, rq->stats.vs.xdp_packets += done; u64_stats_update_end(&rq->stats.syncp); - if (peer_txq && unlikely(netif_tx_queue_stopped(peer_txq))) - netif_tx_wake_queue(peer_txq); - return done; } @@ -969,12 +956,20 @@ static int veth_poll(struct napi_struct *napi, int budget) { struct veth_rq *rq = container_of(napi, struct veth_rq, xdp_napi); + struct veth_priv *priv = netdev_priv(rq->dev); + int queue_idx = rq->xdp_rxq.queue_index; + struct netdev_queue *peer_txq; struct veth_stats stats = {}; + struct net_device *peer_dev; struct veth_xdp_tx_bq bq; int done; bq.count = 0; + /* NAPI functions as RCU section */ + peer_dev = rcu_dereference_check(priv->peer, rcu_read_lock_bh_held()); + peer_txq = peer_dev ? netdev_get_tx_queue(peer_dev, queue_idx) : NULL; + xdp_set_return_frame_no_direct(); done = veth_xdp_rcv(rq, budget, &bq, &stats); @@ -996,6 +991,13 @@ static int veth_poll(struct napi_struct *napi, int budget) veth_xdp_flush(rq, &bq); xdp_clear_return_frame_no_direct(); + /* Release backpressure per NAPI poll */ + smp_rmb(); /* Paired with netif_tx_stop_queue set_bit */ + if (peer_txq && netif_tx_queue_stopped(peer_txq)) { + txq_trans_cond_update(peer_txq); + netif_tx_wake_queue(peer_txq); + } + return done; } diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 8e8a179aaa4915..0369dda5ed6068 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -910,17 +910,6 @@ static struct sk_buff *page_to_skb(struct virtnet_info *vi, goto ok; } - /* - * Verify that we can indeed put this data into a skb. - * This is here to handle cases when the device erroneously - * tries to receive more than is possible. This is usually - * the case of a broken device. - */ - if (unlikely(len > MAX_SKB_FRAGS * PAGE_SIZE)) { - net_dbg_ratelimited("%s: too much data\n", skb->dev->name); - dev_kfree_skb(skb); - return NULL; - } BUG_ON(offset >= PAGE_SIZE); while (len) { unsigned int frag_size = min((unsigned)PAGE_SIZE - offset, len); @@ -2112,9 +2101,19 @@ static struct sk_buff *receive_big(struct net_device *dev, struct virtnet_rq_stats *stats) { struct page *page = buf; - struct sk_buff *skb = - page_to_skb(vi, rq, page, 0, len, PAGE_SIZE, 0); + struct sk_buff *skb; + /* Make sure that len does not exceed the size allocated in + * add_recvbuf_big. + */ + if (unlikely(len > (vi->big_packets_num_skbfrags + 1) * PAGE_SIZE)) { + pr_debug("%s: rx error: len %u exceeds allocated size %lu\n", + dev->name, len, + (vi->big_packets_num_skbfrags + 1) * PAGE_SIZE); + goto err; + } + + skb = page_to_skb(vi, rq, page, 0, len, PAGE_SIZE, 0); u64_stats_add(&stats->bytes, len - vi->hdr_len); if (unlikely(!skb)) goto err; @@ -2539,6 +2538,13 @@ static struct sk_buff *receive_mergeable(struct net_device *dev, return NULL; } +static inline u32 +virtio_net_hash_value(const struct virtio_net_hdr_v1_hash *hdr_hash) +{ + return __le16_to_cpu(hdr_hash->hash_value_lo) | + (__le16_to_cpu(hdr_hash->hash_value_hi) << 16); +} + static void virtio_skb_set_hash(const struct virtio_net_hdr_v1_hash *hdr_hash, struct sk_buff *skb) { @@ -2565,7 +2571,7 @@ static void virtio_skb_set_hash(const struct virtio_net_hdr_v1_hash *hdr_hash, default: rss_hash_type = PKT_HASH_TYPE_NONE; } - skb_set_hash(skb, __le32_to_cpu(hdr_hash->hash_value), rss_hash_type); + skb_set_hash(skb, virtio_net_hash_value(hdr_hash), rss_hash_type); } static void virtnet_receive_done(struct virtnet_info *vi, struct receive_queue *rq, @@ -2625,22 +2631,28 @@ static void receive_buf(struct virtnet_info *vi, struct receive_queue *rq, return; } - /* 1. Save the flags early, as the XDP program might overwrite them. + /* About the flags below: + * 1. Save the flags early, as the XDP program might overwrite them. * These flags ensure packets marked as VIRTIO_NET_HDR_F_DATA_VALID * stay valid after XDP processing. * 2. XDP doesn't work with partially checksummed packets (refer to * virtnet_xdp_set()), so packets marked as * VIRTIO_NET_HDR_F_NEEDS_CSUM get dropped during XDP processing. */ - flags = ((struct virtio_net_common_hdr *)buf)->hdr.flags; - if (vi->mergeable_rx_bufs) + if (vi->mergeable_rx_bufs) { + flags = ((struct virtio_net_common_hdr *)buf)->hdr.flags; skb = receive_mergeable(dev, vi, rq, buf, ctx, len, xdp_xmit, stats); - else if (vi->big_packets) + } else if (vi->big_packets) { + void *p = page_address((struct page *)buf); + + flags = ((struct virtio_net_common_hdr *)p)->hdr.flags; skb = receive_big(dev, vi, rq, buf, len, stats); - else + } else { + flags = ((struct virtio_net_common_hdr *)buf)->hdr.flags; skb = receive_small(dev, vi, rq, buf, ctx, len, xdp_xmit, stats); + } if (unlikely(!skb)) return; @@ -3311,6 +3323,10 @@ static int xmit_skb(struct send_queue *sq, struct sk_buff *skb, bool orphan) pr_debug("%s: xmit %p %pM\n", vi->dev->name, skb, dest); + /* Make sure it's safe to cast between formats */ + BUILD_BUG_ON(__alignof__(*hdr) != __alignof__(hdr->hash_hdr)); + BUILD_BUG_ON(__alignof__(*hdr) != __alignof__(hdr->hash_hdr.hdr)); + can_push = vi->any_header_sg && !((unsigned long)skb->data & (__alignof__(*hdr) - 1)) && !skb_header_cloned(skb) && skb_headroom(skb) >= hdr_len; @@ -6750,7 +6766,7 @@ static int virtnet_xdp_rx_hash(const struct xdp_md *_ctx, u32 *hash, hash_report = VIRTIO_NET_HASH_REPORT_NONE; *rss_type = virtnet_xdp_rss_type[hash_report]; - *hash = __le32_to_cpu(hdr_hash->hash_value); + *hash = virtio_net_hash_value(hdr_hash); return 0; } diff --git a/drivers/net/wan/framer/pef2256/pef2256.c b/drivers/net/wan/framer/pef2256/pef2256.c index c5501826db1eb9..c058cc79137dd4 100644 --- a/drivers/net/wan/framer/pef2256/pef2256.c +++ b/drivers/net/wan/framer/pef2256/pef2256.c @@ -648,7 +648,8 @@ static int pef2256_add_audio_devices(struct pef2256 *pef2256) audio_devs[i].id = i; } - ret = mfd_add_devices(pef2256->dev, 0, audio_devs, count, NULL, 0, NULL); + ret = devm_mfd_add_devices(pef2256->dev, 0, audio_devs, count, + NULL, 0, NULL); kfree(audio_devs); return ret; } @@ -822,8 +823,8 @@ static int pef2256_probe(struct platform_device *pdev) platform_set_drvdata(pdev, pef2256); - ret = mfd_add_devices(pef2256->dev, 0, pef2256_devs, - ARRAY_SIZE(pef2256_devs), NULL, 0, NULL); + ret = devm_mfd_add_devices(pef2256->dev, 0, pef2256_devs, + ARRAY_SIZE(pef2256_devs), NULL, 0, NULL); if (ret) { dev_err(pef2256->dev, "add devices failed (%d)\n", ret); return ret; diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index b3b00d324075bd..b4aad6604d6d9d 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c @@ -1764,32 +1764,33 @@ void ath10k_wmi_put_wmi_channel(struct ath10k *ar, struct wmi_channel *ch, int ath10k_wmi_wait_for_service_ready(struct ath10k *ar) { - unsigned long timeout = jiffies + WMI_SERVICE_READY_TIMEOUT_HZ; unsigned long time_left, i; - /* Sometimes the PCI HIF doesn't receive interrupt - * for the service ready message even if the buffer - * was completed. PCIe sniffer shows that it's - * because the corresponding CE ring doesn't fires - * it. Workaround here by polling CE rings. Since - * the message could arrive at any time, continue - * polling until timeout. - */ - do { + time_left = wait_for_completion_timeout(&ar->wmi.service_ready, + WMI_SERVICE_READY_TIMEOUT_HZ); + if (!time_left) { + /* Sometimes the PCI HIF doesn't receive interrupt + * for the service ready message even if the buffer + * was completed. PCIe sniffer shows that it's + * because the corresponding CE ring doesn't fires + * it. Workaround here by polling CE rings once. + */ + ath10k_warn(ar, "failed to receive service ready completion, polling..\n"); + for (i = 0; i < CE_COUNT; i++) ath10k_hif_send_complete_check(ar, i, 1); - /* The 100 ms granularity is a tradeoff considering scheduler - * overhead and response latency - */ time_left = wait_for_completion_timeout(&ar->wmi.service_ready, - msecs_to_jiffies(100)); - if (time_left) - return 0; - } while (time_before(jiffies, timeout)); + WMI_SERVICE_READY_TIMEOUT_HZ); + if (!time_left) { + ath10k_warn(ar, "polling timed out\n"); + return -ETIMEDOUT; + } + + ath10k_warn(ar, "service ready completion received, continuing normally\n"); + } - ath10k_warn(ar, "failed to receive service ready completion\n"); - return -ETIMEDOUT; + return 0; } int ath10k_wmi_wait_for_unified_ready(struct ath10k *ar) diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c index 0491e3fd6b5e16..e3b444333deed1 100644 --- a/drivers/net/wireless/ath/ath11k/wmi.c +++ b/drivers/net/wireless/ath/ath11k/wmi.c @@ -5961,6 +5961,9 @@ static int wmi_process_mgmt_tx_comp(struct ath11k *ar, dma_unmap_single(ar->ab->dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE); info = IEEE80211_SKB_CB(msdu); + memset(&info->status, 0, sizeof(info->status)); + info->status.rates[0].idx = -1; + if ((!(info->flags & IEEE80211_TX_CTL_NO_ACK)) && !tx_compl_param->status) { info->flags |= IEEE80211_TX_STAT_ACK; diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index eacab798630aa5..db351c92201817 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -4064,68 +4064,12 @@ static int ath12k_mac_fils_discovery(struct ath12k_link_vif *arvif, return ret; } -static void ath12k_mac_vif_setup_ps(struct ath12k_link_vif *arvif) -{ - struct ath12k *ar = arvif->ar; - struct ieee80211_vif *vif = arvif->ahvif->vif; - struct ieee80211_conf *conf = &ath12k_ar_to_hw(ar)->conf; - enum wmi_sta_powersave_param param; - struct ieee80211_bss_conf *info; - enum wmi_sta_ps_mode psmode; - int ret; - int timeout; - bool enable_ps; - - lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy); - - if (vif->type != NL80211_IFTYPE_STATION) - return; - - enable_ps = arvif->ahvif->ps; - if (enable_ps) { - psmode = WMI_STA_PS_MODE_ENABLED; - param = WMI_STA_PS_PARAM_INACTIVITY_TIME; - - timeout = conf->dynamic_ps_timeout; - if (timeout == 0) { - info = ath12k_mac_get_link_bss_conf(arvif); - if (!info) { - ath12k_warn(ar->ab, "unable to access bss link conf in setup ps for vif %pM link %u\n", - vif->addr, arvif->link_id); - return; - } - - /* firmware doesn't like 0 */ - timeout = ieee80211_tu_to_usec(info->beacon_int) / 1000; - } - - ret = ath12k_wmi_set_sta_ps_param(ar, arvif->vdev_id, param, - timeout); - if (ret) { - ath12k_warn(ar->ab, "failed to set inactivity time for vdev %d: %i\n", - arvif->vdev_id, ret); - return; - } - } else { - psmode = WMI_STA_PS_MODE_DISABLED; - } - - ath12k_dbg(ar->ab, ATH12K_DBG_MAC, "mac vdev %d psmode %s\n", - arvif->vdev_id, psmode ? "enable" : "disable"); - - ret = ath12k_wmi_pdev_set_ps_mode(ar, arvif->vdev_id, psmode); - if (ret) - ath12k_warn(ar->ab, "failed to set sta power save mode %d for vdev %d: %d\n", - psmode, arvif->vdev_id, ret); -} - static void ath12k_mac_op_vif_cfg_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u64 changed) { struct ath12k_vif *ahvif = ath12k_vif_to_ahvif(vif); unsigned long links = ahvif->links_map; - struct ieee80211_vif_cfg *vif_cfg; struct ieee80211_bss_conf *info; struct ath12k_link_vif *arvif; struct ieee80211_sta *sta; @@ -4189,24 +4133,61 @@ static void ath12k_mac_op_vif_cfg_changed(struct ieee80211_hw *hw, } } } +} - if (changed & BSS_CHANGED_PS) { - links = ahvif->links_map; - vif_cfg = &vif->cfg; +static void ath12k_mac_vif_setup_ps(struct ath12k_link_vif *arvif) +{ + struct ath12k *ar = arvif->ar; + struct ieee80211_vif *vif = arvif->ahvif->vif; + struct ieee80211_conf *conf = &ath12k_ar_to_hw(ar)->conf; + enum wmi_sta_powersave_param param; + struct ieee80211_bss_conf *info; + enum wmi_sta_ps_mode psmode; + int ret; + int timeout; + bool enable_ps; - for_each_set_bit(link_id, &links, IEEE80211_MLD_MAX_NUM_LINKS) { - arvif = wiphy_dereference(hw->wiphy, ahvif->link[link_id]); - if (!arvif || !arvif->ar) - continue; + lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy); - ar = arvif->ar; + if (vif->type != NL80211_IFTYPE_STATION) + return; + + enable_ps = arvif->ahvif->ps; + if (enable_ps) { + psmode = WMI_STA_PS_MODE_ENABLED; + param = WMI_STA_PS_PARAM_INACTIVITY_TIME; - if (ar->ab->hw_params->supports_sta_ps) { - ahvif->ps = vif_cfg->ps; - ath12k_mac_vif_setup_ps(arvif); + timeout = conf->dynamic_ps_timeout; + if (timeout == 0) { + info = ath12k_mac_get_link_bss_conf(arvif); + if (!info) { + ath12k_warn(ar->ab, "unable to access bss link conf in setup ps for vif %pM link %u\n", + vif->addr, arvif->link_id); + return; } + + /* firmware doesn't like 0 */ + timeout = ieee80211_tu_to_usec(info->beacon_int) / 1000; } + + ret = ath12k_wmi_set_sta_ps_param(ar, arvif->vdev_id, param, + timeout); + if (ret) { + ath12k_warn(ar->ab, "failed to set inactivity time for vdev %d: %i\n", + arvif->vdev_id, ret); + return; + } + } else { + psmode = WMI_STA_PS_MODE_DISABLED; } + + ath12k_dbg(ar->ab, ATH12K_DBG_MAC, "mac vdev %d psmode %s\n", + arvif->vdev_id, psmode ? "enable" : "disable"); + + ret = ath12k_wmi_pdev_set_ps_mode(ar, arvif->vdev_id, psmode); + if (ret) + ath12k_warn(ar->ab, "failed to set sta power save mode %d for vdev %d: %d\n", + psmode, arvif->vdev_id, ret); } static bool ath12k_mac_supports_tpc(struct ath12k *ar, struct ath12k_vif *ahvif, @@ -4228,6 +4209,7 @@ static void ath12k_mac_bss_info_changed(struct ath12k *ar, { struct ath12k_vif *ahvif = arvif->ahvif; struct ieee80211_vif *vif = ath12k_ahvif_to_vif(ahvif); + struct ieee80211_vif_cfg *vif_cfg = &vif->cfg; struct cfg80211_chan_def def; u32 param_id, param_value; enum nl80211_band band; @@ -4514,6 +4496,12 @@ static void ath12k_mac_bss_info_changed(struct ath12k *ar, } ath12k_mac_fils_discovery(arvif, info); + + if (changed & BSS_CHANGED_PS && + ar->ab->hw_params->supports_sta_ps) { + ahvif->ps = vif_cfg->ps; + ath12k_mac_vif_setup_ps(arvif); + } } static struct ath12k_vif_cache *ath12k_ahvif_get_link_cache(struct ath12k_vif *ahvif, diff --git a/drivers/net/wireless/intel/iwlwifi/mld/link.c b/drivers/net/wireless/intel/iwlwifi/mld/link.c index 60d814bf5779a8..f6f52d297a72c8 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/link.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/link.c @@ -708,18 +708,13 @@ static int iwl_mld_get_chan_load_from_element(struct iwl_mld *mld, struct ieee80211_bss_conf *link_conf) { - struct ieee80211_vif *vif = link_conf->vif; const struct cfg80211_bss_ies *ies; const struct element *bss_load_elem = NULL; const struct ieee80211_bss_load_elem *bss_load; guard(rcu)(); - if (ieee80211_vif_link_active(vif, link_conf->link_id)) - ies = rcu_dereference(link_conf->bss->beacon_ies); - else - ies = rcu_dereference(link_conf->bss->ies); - + ies = rcu_dereference(link_conf->bss->beacon_ies); if (ies) bss_load_elem = cfg80211_find_elem(WLAN_EID_QBSS_LOAD, ies->data, ies->len); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c index 9c9e0e1c6e1d4c..867807abde6643 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c @@ -938,19 +938,12 @@ u8 iwl_mvm_mac_ctxt_get_lowest_rate(struct iwl_mvm *mvm, u16 iwl_mvm_mac_ctxt_get_beacon_flags(const struct iwl_fw *fw, u8 rate_idx) { + u16 flags = iwl_mvm_mac80211_idx_to_hwrate(fw, rate_idx); bool is_new_rate = iwl_fw_lookup_cmd_ver(fw, BEACON_TEMPLATE_CMD, 0) > 10; - u16 flags, cck_flag; - - if (is_new_rate) { - flags = iwl_mvm_mac80211_idx_to_hwrate(fw, rate_idx); - cck_flag = IWL_MAC_BEACON_CCK; - } else { - cck_flag = IWL_MAC_BEACON_CCK_V1; - flags = iwl_fw_rate_idx_to_plcp(rate_idx); - } if (rate_idx <= IWL_LAST_CCK_RATE) - flags |= cck_flag; + flags |= is_new_rate ? IWL_MAC_BEACON_CCK + : IWL_MAC_BEACON_CCK_V1; return flags; } diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c b/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c index 0c9c2492d8a759..0b12ee8ad6180b 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c @@ -463,7 +463,7 @@ static int iwl_mvm_aux_roc_te_handle_notif(struct iwl_mvm *mvm, if (!aux_roc_te) /* Not a Aux ROC time event */ return -EINVAL; - iwl_mvm_te_check_trigger(mvm, notif, te_data); + iwl_mvm_te_check_trigger(mvm, notif, aux_roc_te); IWL_DEBUG_TE(mvm, "Aux ROC time event notification - UID = 0x%x action %d (error = %d)\n", @@ -475,14 +475,14 @@ static int iwl_mvm_aux_roc_te_handle_notif(struct iwl_mvm *mvm, /* End TE, notify mac80211 */ ieee80211_remain_on_channel_expired(mvm->hw); iwl_mvm_roc_finished(mvm); /* flush aux queue */ - list_del(&te_data->list); /* remove from list */ - te_data->running = false; - te_data->vif = NULL; - te_data->uid = 0; - te_data->id = TE_MAX; + list_del(&aux_roc_te->list); /* remove from list */ + aux_roc_te->running = false; + aux_roc_te->vif = NULL; + aux_roc_te->uid = 0; + aux_roc_te->id = TE_MAX; } else if (le32_to_cpu(notif->action) == TE_V2_NOTIF_HOST_EVENT_START) { set_bit(IWL_MVM_STATUS_ROC_AUX_RUNNING, &mvm->status); - te_data->running = true; + aux_roc_te->running = true; ieee80211_ready_on_channel(mvm->hw); /* Start TE */ } else { IWL_DEBUG_TE(mvm, diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c index 22602c32faa5b6..fa995e235d9b43 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c @@ -159,9 +159,15 @@ int iwl_mvm_legacy_rate_to_mac80211_idx(u32 rate_n_flags, u8 iwl_mvm_mac80211_idx_to_hwrate(const struct iwl_fw *fw, int rate_idx) { - return (rate_idx >= IWL_FIRST_OFDM_RATE ? - rate_idx - IWL_FIRST_OFDM_RATE : - rate_idx); + if (iwl_fw_lookup_cmd_ver(fw, TX_CMD, 0) > 8) + /* In the new rate legacy rates are indexed: + * 0 - 3 for CCK and 0 - 7 for OFDM. + */ + return (rate_idx >= IWL_FIRST_OFDM_RATE ? + rate_idx - IWL_FIRST_OFDM_RATE : + rate_idx); + + return iwl_fw_rate_idx_to_plcp(rate_idx); } u8 iwl_mvm_mac80211_ac_to_ucode_ac(enum ieee80211_ac_numbers ac) diff --git a/drivers/net/wireless/marvell/mwl8k.c b/drivers/net/wireless/marvell/mwl8k.c index 891e125ad30b53..54d6d00ecdf1e4 100644 --- a/drivers/net/wireless/marvell/mwl8k.c +++ b/drivers/net/wireless/marvell/mwl8k.c @@ -2966,6 +2966,51 @@ mwl8k_cmd_rf_antenna(struct ieee80211_hw *hw, int antenna, int mask) /* * CMD_SET_BEACON. */ + +static bool mwl8k_beacon_has_ds_params(const u8 *buf, int len) +{ + const struct ieee80211_mgmt *mgmt = (const void *)buf; + int ies_len; + + if (len <= offsetof(struct ieee80211_mgmt, u.beacon.variable)) + return false; + + ies_len = len - offsetof(struct ieee80211_mgmt, u.beacon.variable); + + return cfg80211_find_ie(WLAN_EID_DS_PARAMS, mgmt->u.beacon.variable, + ies_len) != NULL; +} + +static void mwl8k_beacon_copy_inject_ds_params(struct ieee80211_hw *hw, + u8 *buf_dst, const u8 *buf_src, + int src_len) +{ + const struct ieee80211_mgmt *mgmt = (const void *)buf_src; + static const u8 before_ds_params[] = { + WLAN_EID_SSID, + WLAN_EID_SUPP_RATES, + }; + const u8 *ies; + int hdr_len, left, offs, pos; + + ies = mgmt->u.beacon.variable; + hdr_len = offsetof(struct ieee80211_mgmt, u.beacon.variable); + + offs = ieee80211_ie_split(ies, src_len - hdr_len, before_ds_params, + ARRAY_SIZE(before_ds_params), 0); + + pos = hdr_len + offs; + left = src_len - pos; + + memcpy(buf_dst, buf_src, pos); + + /* Inject a DSSS Parameter Set after SSID + Supp Rates */ + buf_dst[pos + 0] = WLAN_EID_DS_PARAMS; + buf_dst[pos + 1] = 1; + buf_dst[pos + 2] = hw->conf.chandef.chan->hw_value; + + memcpy(buf_dst + pos + 3, buf_src + pos, left); +} struct mwl8k_cmd_set_beacon { struct mwl8k_cmd_pkt_hdr header; __le16 beacon_len; @@ -2975,17 +3020,33 @@ struct mwl8k_cmd_set_beacon { static int mwl8k_cmd_set_beacon(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u8 *beacon, int len) { + bool ds_params_present = mwl8k_beacon_has_ds_params(beacon, len); struct mwl8k_cmd_set_beacon *cmd; - int rc; + int rc, final_len = len; - cmd = kzalloc(sizeof(*cmd) + len, GFP_KERNEL); + if (!ds_params_present) { + /* + * mwl8k firmware requires a DS Params IE with the current + * channel in AP beacons. If mac80211/hostapd does not + * include it, inject one here. IE ID + length + channel + * number = 3 bytes. + */ + final_len += 3; + } + + cmd = kzalloc(sizeof(*cmd) + final_len, GFP_KERNEL); if (cmd == NULL) return -ENOMEM; cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_BEACON); - cmd->header.length = cpu_to_le16(sizeof(*cmd) + len); - cmd->beacon_len = cpu_to_le16(len); - memcpy(cmd->beacon, beacon, len); + cmd->header.length = cpu_to_le16(sizeof(*cmd) + final_len); + cmd->beacon_len = cpu_to_le16(final_len); + + if (ds_params_present) + memcpy(cmd->beacon, beacon, len); + else + mwl8k_beacon_copy_inject_ds_params(hw, cmd->beacon, beacon, + len); rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header); kfree(cmd); diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c index ab904a7def1b44..080c4f8a655a86 100644 --- a/drivers/net/wireless/realtek/rtw89/fw.c +++ b/drivers/net/wireless/realtek/rtw89/fw.c @@ -7694,6 +7694,13 @@ int rtw89_hw_scan_add_chan_list_ax(struct rtw89_dev *rtwdev, INIT_LIST_HEAD(&list); list_for_each_entry_safe(ch_info, tmp, &scan_info->chan_list, list) { + /* The operating channel (tx_null == true) should + * not be last in the list, to avoid breaking + * RTL8851BU and RTL8832BU. + */ + if (list_len + 1 == RTW89_SCAN_LIST_LIMIT_AX && ch_info->tx_null) + break; + list_move_tail(&ch_info->list, &list); list_len++; diff --git a/drivers/net/wireless/virtual/mac80211_hwsim.c b/drivers/net/wireless/virtual/mac80211_hwsim.c index 9f856042a67af1..5903d82e1ab1e8 100644 --- a/drivers/net/wireless/virtual/mac80211_hwsim.c +++ b/drivers/net/wireless/virtual/mac80211_hwsim.c @@ -2003,8 +2003,14 @@ static void mac80211_hwsim_tx(struct ieee80211_hw *hw, struct ieee80211_sta *sta = control->sta; struct ieee80211_bss_conf *bss_conf; + /* This can happen in case of monitor injection */ + if (!vif) { + ieee80211_free_txskb(hw, skb); + return; + } + if (link != IEEE80211_LINK_UNSPECIFIED) { - bss_conf = rcu_dereference(txi->control.vif->link_conf[link]); + bss_conf = rcu_dereference(vif->link_conf[link]); if (sta) link_sta = rcu_dereference(sta->link[link]); } else { @@ -2065,13 +2071,13 @@ static void mac80211_hwsim_tx(struct ieee80211_hw *hw, return; } - if (txi->control.vif) - hwsim_check_magic(txi->control.vif); + if (vif) + hwsim_check_magic(vif); if (control->sta) hwsim_check_sta_magic(control->sta); if (ieee80211_hw_check(hw, SUPPORTS_RC_TABLE)) - ieee80211_get_tx_rates(txi->control.vif, control->sta, skb, + ieee80211_get_tx_rates(vif, control->sta, skb, txi->control.rates, ARRAY_SIZE(txi->control.rates)); @@ -6698,14 +6704,15 @@ static struct genl_family hwsim_genl_family __ro_after_init = { .n_mcgrps = ARRAY_SIZE(hwsim_mcgrps), }; -static void remove_user_radios(u32 portid) +static void remove_user_radios(u32 portid, int netgroup) { struct mac80211_hwsim_data *entry, *tmp; LIST_HEAD(list); spin_lock_bh(&hwsim_radio_lock); list_for_each_entry_safe(entry, tmp, &hwsim_radios, list) { - if (entry->destroy_on_close && entry->portid == portid) { + if (entry->destroy_on_close && entry->portid == portid && + entry->netgroup == netgroup) { list_move(&entry->list, &list); rhashtable_remove_fast(&hwsim_radios_rht, &entry->rht, hwsim_rht_params); @@ -6730,7 +6737,7 @@ static int mac80211_hwsim_netlink_notify(struct notifier_block *nb, if (state != NETLINK_URELEASE) return NOTIFY_DONE; - remove_user_radios(notify->portid); + remove_user_radios(notify->portid, hwsim_net_get_netgroup(notify->net)); if (notify->portid == hwsim_net_get_wmediumd(notify->net)) { printk(KERN_INFO "mac80211_hwsim: wmediumd released netlink" diff --git a/drivers/net/wireless/zydas/zd1211rw/zd_usb.c b/drivers/net/wireless/zydas/zd1211rw/zd_usb.c index 2faa0de2a36ec5..8ee15a15f4ca2d 100644 --- a/drivers/net/wireless/zydas/zd1211rw/zd_usb.c +++ b/drivers/net/wireless/zydas/zd1211rw/zd_usb.c @@ -791,6 +791,7 @@ static int __zd_usb_enable_rx(struct zd_usb *usb) if (urbs) { for (i = 0; i < RX_URBS_COUNT; i++) free_rx_urb(urbs[i]); + kfree(urbs); } return r; } diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index fa4181d7de7362..f1f719351f3f2c 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -4901,7 +4901,6 @@ void nvme_remove_admin_tag_set(struct nvme_ctrl *ctrl) */ nvme_stop_keep_alive(ctrl); blk_mq_destroy_queue(ctrl->admin_q); - blk_put_queue(ctrl->admin_q); if (ctrl->ops->flags & NVME_F_FABRICS) { blk_mq_destroy_queue(ctrl->fabrics_q); blk_put_queue(ctrl->fabrics_q); @@ -5045,6 +5044,8 @@ static void nvme_free_ctrl(struct device *dev) container_of(dev, struct nvme_ctrl, ctrl_device); struct nvme_subsystem *subsys = ctrl->subsys; + if (ctrl->admin_q) + blk_put_queue(ctrl->admin_q); if (!subsys || ctrl->instance != subsys->instance) ida_free(&nvme_instance_ida, ctrl->instance); nvme_free_cels(ctrl); diff --git a/drivers/nvme/host/fc.c b/drivers/nvme/host/fc.c index 03987f497a5b55..2c903729b0b909 100644 --- a/drivers/nvme/host/fc.c +++ b/drivers/nvme/host/fc.c @@ -2355,17 +2355,11 @@ nvme_fc_ctrl_free(struct kref *ref) container_of(ref, struct nvme_fc_ctrl, ref); unsigned long flags; - if (ctrl->ctrl.tagset) - nvme_remove_io_tag_set(&ctrl->ctrl); - /* remove from rport list */ spin_lock_irqsave(&ctrl->rport->lock, flags); list_del(&ctrl->ctrl_list); spin_unlock_irqrestore(&ctrl->rport->lock, flags); - nvme_unquiesce_admin_queue(&ctrl->ctrl); - nvme_remove_admin_tag_set(&ctrl->ctrl); - kfree(ctrl->queues); put_device(ctrl->dev); @@ -3259,13 +3253,20 @@ nvme_fc_delete_ctrl(struct nvme_ctrl *nctrl) { struct nvme_fc_ctrl *ctrl = to_fc_ctrl(nctrl); - cancel_work_sync(&ctrl->ioerr_work); cancel_delayed_work_sync(&ctrl->connect_work); + /* * kill the association on the link side. this will block * waiting for io to terminate */ nvme_fc_delete_association(ctrl); + cancel_work_sync(&ctrl->ioerr_work); + + if (ctrl->ctrl.tagset) + nvme_remove_io_tag_set(&ctrl->ctrl); + + nvme_unquiesce_admin_queue(&ctrl->ctrl); + nvme_remove_admin_tag_set(&ctrl->ctrl); } static void diff --git a/drivers/nvme/host/multipath.c b/drivers/nvme/host/multipath.c index 543e17aead12ba..e35eccacee8c8a 100644 --- a/drivers/nvme/host/multipath.c +++ b/drivers/nvme/host/multipath.c @@ -793,7 +793,7 @@ static void nvme_mpath_set_live(struct nvme_ns *ns) return; } nvme_add_ns_head_cdev(head); - kblockd_schedule_work(&head->partition_scan_work); + queue_work(nvme_wq, &head->partition_scan_work); } nvme_mpath_add_sysfs_link(ns->head); diff --git a/drivers/nvme/target/auth.c b/drivers/nvme/target/auth.c index ceba21684e82c5..300d5e032f6d43 100644 --- a/drivers/nvme/target/auth.c +++ b/drivers/nvme/target/auth.c @@ -298,7 +298,7 @@ int nvmet_auth_host_hash(struct nvmet_req *req, u8 *response, const char *hash_name; u8 *challenge = req->sq->dhchap_c1; struct nvme_dhchap_key *transformed_key; - u8 buf[4], sc_c = ctrl->concat ? 1 : 0; + u8 buf[4]; int ret; hash_name = nvme_auth_hmac_name(ctrl->shash_id); @@ -367,7 +367,7 @@ int nvmet_auth_host_hash(struct nvmet_req *req, u8 *response, ret = crypto_shash_update(shash, buf, 2); if (ret) goto out; - *buf = sc_c; + *buf = req->sq->sc_c; ret = crypto_shash_update(shash, buf, 1); if (ret) goto out; diff --git a/drivers/nvme/target/fabrics-cmd-auth.c b/drivers/nvme/target/fabrics-cmd-auth.c index bf01ec414c55f7..5946681cb0e322 100644 --- a/drivers/nvme/target/fabrics-cmd-auth.c +++ b/drivers/nvme/target/fabrics-cmd-auth.c @@ -43,6 +43,7 @@ static u8 nvmet_auth_negotiate(struct nvmet_req *req, void *d) data->auth_protocol[0].dhchap.halen, data->auth_protocol[0].dhchap.dhlen); req->sq->dhchap_tid = le16_to_cpu(data->t_id); + req->sq->sc_c = data->sc_c; if (data->sc_c != NVME_AUTH_SECP_NOSC) { if (!IS_ENABLED(CONFIG_NVME_TARGET_TCP_TLS)) return NVME_AUTH_DHCHAP_FAILURE_CONCAT_MISMATCH; diff --git a/drivers/nvme/target/nvmet.h b/drivers/nvme/target/nvmet.h index 51df72f5e89b72..f3b09f4099f086 100644 --- a/drivers/nvme/target/nvmet.h +++ b/drivers/nvme/target/nvmet.h @@ -159,6 +159,7 @@ struct nvmet_sq { bool authenticated; struct delayed_work auth_expired_work; u16 dhchap_tid; + u8 sc_c; u8 dhchap_status; u8 dhchap_step; u8 *dhchap_c1; diff --git a/drivers/of/property.c b/drivers/of/property.c index c1feb631e3831d..4e3524227720a5 100644 --- a/drivers/of/property.c +++ b/drivers/of/property.c @@ -147,6 +147,39 @@ static void *of_find_property_value_of_size(const struct device_node *np, return prop->value; } +/** + * of_property_read_u8_index - Find and read a u8 from a multi-value property. + * + * @np: device node from which the property value is to be read. + * @propname: name of the property to be searched. + * @index: index of the u8 in the list of values + * @out_value: pointer to return value, modified only if no error. + * + * Search for a property in a device node and read nth 8-bit value from + * it. + * + * Return: 0 on success, -EINVAL if the property does not exist, + * -ENODATA if property does not have a value, and -EOVERFLOW if the + * property data isn't large enough. + * + * The out_value is modified only if a valid u8 value can be decoded. + */ +int of_property_read_u8_index(const struct device_node *np, + const char *propname, + u32 index, u8 *out_value) +{ + const u8 *val = of_find_property_value_of_size(np, propname, + ((index + 1) * sizeof(*out_value)), + 0, NULL); + + if (IS_ERR(val)) + return PTR_ERR(val); + + *out_value = val[index]; + return 0; +} +EXPORT_SYMBOL_GPL(of_property_read_u8_index); + /** * of_property_read_u16_index - Find and read a u16 from a multi-value property. * diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 4492b809094b57..36f8c0985430a4 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -958,6 +958,7 @@ void pci_save_aspm_l1ss_state(struct pci_dev *dev); void pci_restore_aspm_l1ss_state(struct pci_dev *dev); #ifdef CONFIG_PCIEASPM +void pcie_aspm_remove_cap(struct pci_dev *pdev, u32 lnkcap); void pcie_aspm_init_link_state(struct pci_dev *pdev); void pcie_aspm_exit_link_state(struct pci_dev *pdev); void pcie_aspm_pm_state_change(struct pci_dev *pdev, bool locked); @@ -965,6 +966,7 @@ void pcie_aspm_powersave_config_link(struct pci_dev *pdev); void pci_configure_ltr(struct pci_dev *pdev); void pci_bridge_reconfigure_ltr(struct pci_dev *pdev); #else +static inline void pcie_aspm_remove_cap(struct pci_dev *pdev, u32 lnkcap) { } static inline void pcie_aspm_init_link_state(struct pci_dev *pdev) { } static inline void pcie_aspm_exit_link_state(struct pci_dev *pdev) { } static inline void pcie_aspm_pm_state_change(struct pci_dev *pdev, bool locked) { } diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c index 79b96515847376..cedea47a3547f4 100644 --- a/drivers/pci/pcie/aspm.c +++ b/drivers/pci/pcie/aspm.c @@ -814,7 +814,6 @@ static void pcie_aspm_override_default_link_state(struct pcie_link_state *link) static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist) { struct pci_dev *child = link->downstream, *parent = link->pdev; - u32 parent_lnkcap, child_lnkcap; u16 parent_lnkctl, child_lnkctl; struct pci_bus *linkbus = parent->subordinate; @@ -829,9 +828,8 @@ static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist) * If ASPM not supported, don't mess with the clocks and link, * bail out now. */ - pcie_capability_read_dword(parent, PCI_EXP_LNKCAP, &parent_lnkcap); - pcie_capability_read_dword(child, PCI_EXP_LNKCAP, &child_lnkcap); - if (!(parent_lnkcap & child_lnkcap & PCI_EXP_LNKCAP_ASPMS)) + if (!(parent->aspm_l0s_support && child->aspm_l0s_support) && + !(parent->aspm_l1_support && child->aspm_l1_support)) return; /* Configure common clock before checking latencies */ @@ -843,8 +841,6 @@ static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist) * read-only Link Capabilities may change depending on common clock * configuration (PCIe r5.0, sec 7.5.3.6). */ - pcie_capability_read_dword(parent, PCI_EXP_LNKCAP, &parent_lnkcap); - pcie_capability_read_dword(child, PCI_EXP_LNKCAP, &child_lnkcap); pcie_capability_read_word(parent, PCI_EXP_LNKCTL, &parent_lnkctl); pcie_capability_read_word(child, PCI_EXP_LNKCTL, &child_lnkctl); @@ -864,7 +860,7 @@ static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist) * given link unless components on both sides of the link each * support L0s. */ - if (parent_lnkcap & child_lnkcap & PCI_EXP_LNKCAP_ASPM_L0S) + if (parent->aspm_l0s_support && child->aspm_l0s_support) link->aspm_support |= PCIE_LINK_STATE_L0S; if (child_lnkctl & PCI_EXP_LNKCTL_ASPM_L0S) @@ -873,7 +869,7 @@ static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist) link->aspm_enabled |= PCIE_LINK_STATE_L0S_DW; /* Setup L1 state */ - if (parent_lnkcap & child_lnkcap & PCI_EXP_LNKCAP_ASPM_L1) + if (parent->aspm_l1_support && child->aspm_l1_support) link->aspm_support |= PCIE_LINK_STATE_L1; if (parent_lnkctl & child_lnkctl & PCI_EXP_LNKCTL_ASPM_L1) @@ -1530,6 +1526,19 @@ int pci_enable_link_state_locked(struct pci_dev *pdev, int state) } EXPORT_SYMBOL(pci_enable_link_state_locked); +void pcie_aspm_remove_cap(struct pci_dev *pdev, u32 lnkcap) +{ + if (lnkcap & PCI_EXP_LNKCAP_ASPM_L0S) + pdev->aspm_l0s_support = 0; + if (lnkcap & PCI_EXP_LNKCAP_ASPM_L1) + pdev->aspm_l1_support = 0; + + pci_info(pdev, "ASPM: Link Capabilities%s%s treated as unsupported to avoid device defect\n", + lnkcap & PCI_EXP_LNKCAP_ASPM_L0S ? " L0s" : "", + lnkcap & PCI_EXP_LNKCAP_ASPM_L1 ? " L1" : ""); + +} + static int pcie_aspm_set_policy(const char *val, const struct kernel_param *kp) { diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 0ce98e18b5a876..9cd032dff31e57 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -1656,6 +1656,13 @@ void set_pcie_port_type(struct pci_dev *pdev) if (reg32 & PCI_EXP_LNKCAP_DLLLARC) pdev->link_active_reporting = 1; +#ifdef CONFIG_PCIEASPM + if (reg32 & PCI_EXP_LNKCAP_ASPM_L0S) + pdev->aspm_l0s_support = 1; + if (reg32 & PCI_EXP_LNKCAP_ASPM_L1) + pdev->aspm_l1_support = 1; +#endif + parent = pci_upstream_bridge(pdev); if (!parent) return; diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 214ed060ca1b3d..b9c252aa6fe08a 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -2494,28 +2494,27 @@ DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, */ static void quirk_disable_aspm_l0s(struct pci_dev *dev) { - pci_info(dev, "Disabling L0s\n"); - pci_disable_link_state(dev, PCIE_LINK_STATE_L0S); -} -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10a7, quirk_disable_aspm_l0s); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10a9, quirk_disable_aspm_l0s); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10b6, quirk_disable_aspm_l0s); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10c6, quirk_disable_aspm_l0s); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10c7, quirk_disable_aspm_l0s); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10c8, quirk_disable_aspm_l0s); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10d6, quirk_disable_aspm_l0s); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10db, quirk_disable_aspm_l0s); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10dd, quirk_disable_aspm_l0s); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10e1, quirk_disable_aspm_l0s); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10ec, quirk_disable_aspm_l0s); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10f1, quirk_disable_aspm_l0s); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10f4, quirk_disable_aspm_l0s); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1508, quirk_disable_aspm_l0s); + pcie_aspm_remove_cap(dev, PCI_EXP_LNKCAP_ASPM_L0S); +} +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10a7, quirk_disable_aspm_l0s); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10a9, quirk_disable_aspm_l0s); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10b6, quirk_disable_aspm_l0s); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10c6, quirk_disable_aspm_l0s); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10c7, quirk_disable_aspm_l0s); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10c8, quirk_disable_aspm_l0s); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10d6, quirk_disable_aspm_l0s); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10db, quirk_disable_aspm_l0s); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10dd, quirk_disable_aspm_l0s); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10e1, quirk_disable_aspm_l0s); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10ec, quirk_disable_aspm_l0s); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10f1, quirk_disable_aspm_l0s); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10f4, quirk_disable_aspm_l0s); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1508, quirk_disable_aspm_l0s); static void quirk_disable_aspm_l0s_l1(struct pci_dev *dev) { - pci_info(dev, "Disabling ASPM L0s/L1\n"); - pci_disable_link_state(dev, PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1); + pcie_aspm_remove_cap(dev, + PCI_EXP_LNKCAP_ASPM_L0S | PCI_EXP_LNKCAP_ASPM_L1); } /* @@ -2523,7 +2522,10 @@ static void quirk_disable_aspm_l0s_l1(struct pci_dev *dev) * upstream PCIe root port when ASPM is enabled. At least L0s mode is affected; * disable both L0s and L1 for now to be safe. */ -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ASMEDIA, 0x1080, quirk_disable_aspm_l0s_l1); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ASMEDIA, 0x1080, quirk_disable_aspm_l0s_l1); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_FREESCALE, 0x0451, quirk_disable_aspm_l0s_l1); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_PASEMI, 0xa002, quirk_disable_aspm_l0s_l1); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_HUAWEI, 0x1105, quirk_disable_aspm_l0s_l1); /* * Some Pericom PCIe-to-PCI bridges in reverse mode need the PCIe Retrain diff --git a/drivers/perf/riscv_pmu_sbi.c b/drivers/perf/riscv_pmu_sbi.c index e255c1b069ec18..7dd282da67cef9 100644 --- a/drivers/perf/riscv_pmu_sbi.c +++ b/drivers/perf/riscv_pmu_sbi.c @@ -1109,7 +1109,7 @@ static irqreturn_t pmu_sbi_ovf_handler(int irq, void *dev) /* compute hardware counter index */ hidx = info->csr - CSR_CYCLE; - /* check if the corresponding bit is set in sscountovf or overflow mask in shmem */ + /* check if the corresponding bit is set in scountovf or overflow mask in shmem */ if (!(overflow & BIT(hidx))) continue; diff --git a/drivers/pinctrl/cirrus/pinctrl-cs42l43.c b/drivers/pinctrl/cirrus/pinctrl-cs42l43.c index 68abb6d6cecd8c..a8f82104a3842e 100644 --- a/drivers/pinctrl/cirrus/pinctrl-cs42l43.c +++ b/drivers/pinctrl/cirrus/pinctrl-cs42l43.c @@ -532,6 +532,11 @@ static int cs42l43_gpio_add_pin_ranges(struct gpio_chip *chip) return ret; } +static void cs42l43_fwnode_put(void *data) +{ + fwnode_handle_put(data); +} + static int cs42l43_pin_probe(struct platform_device *pdev) { struct cs42l43 *cs42l43 = dev_get_drvdata(pdev->dev.parent); @@ -563,10 +568,20 @@ static int cs42l43_pin_probe(struct platform_device *pdev) priv->gpio_chip.ngpio = CS42L43_NUM_GPIOS; if (is_of_node(fwnode)) { - fwnode = fwnode_get_named_child_node(fwnode, "pinctrl"); - - if (fwnode && !fwnode->dev) - fwnode->dev = priv->dev; + struct fwnode_handle *child; + + child = fwnode_get_named_child_node(fwnode, "pinctrl"); + if (child) { + ret = devm_add_action_or_reset(&pdev->dev, + cs42l43_fwnode_put, child); + if (ret) { + fwnode_handle_put(child); + return ret; + } + if (!child->dev) + child->dev = priv->dev; + fwnode = child; + } } priv->gpio_chip.fwnode = fwnode; diff --git a/drivers/pinctrl/mediatek/pinctrl-mt8189.c b/drivers/pinctrl/mediatek/pinctrl-mt8189.c index 7028aff55ae586..f6a3e584588b0e 100644 --- a/drivers/pinctrl/mediatek/pinctrl-mt8189.c +++ b/drivers/pinctrl/mediatek/pinctrl-mt8189.c @@ -1642,9 +1642,7 @@ static const struct mtk_pin_reg_calc mt8189_reg_cals[PINCTRL_PIN_REG_MAX] = { }; static const char * const mt8189_pinctrl_register_base_names[] = { - "gpio_base", "iocfg_bm0_base", "iocfg_bm1_base", "iocfg_bm2_base", "iocfg_lm_base", - "iocfg_lt0_base", "iocfg_lt1_base", "iocfg_rb0_base", "iocfg_rb1_base", - "iocfg_rt_base" + "base", "lm", "rb0", "rb1", "bm0", "bm1", "bm2", "lt0", "lt1", "rt", }; static const struct mtk_eint_hw mt8189_eint_hw = { diff --git a/drivers/pinctrl/mediatek/pinctrl-mt8196.c b/drivers/pinctrl/mediatek/pinctrl-mt8196.c index 82a73929c7a0fc..dec957c1724b01 100644 --- a/drivers/pinctrl/mediatek/pinctrl-mt8196.c +++ b/drivers/pinctrl/mediatek/pinctrl-mt8196.c @@ -1801,10 +1801,8 @@ static const struct mtk_pin_reg_calc mt8196_reg_cals[PINCTRL_PIN_REG_MAX] = { }; static const char * const mt8196_pinctrl_register_base_names[] = { - "iocfg0", "iocfg_rt", "iocfg_rm1", "iocfg_rm2", - "iocfg_rb", "iocfg_bm1", "iocfg_bm2", "iocfg_bm3", - "iocfg_lt", "iocfg_lm1", "iocfg_lm2", "iocfg_lb1", - "iocfg_lb2", "iocfg_tm1", "iocfg_tm2", "iocfg_tm3", + "base", "rt", "rm1", "rm2", "rb", "bm1", "bm2", "bm3", + "lt", "lm1", "lm2", "lb1", "lb2", "tm1", "tm2", "tm3", }; static const struct mtk_eint_hw mt8196_eint_hw = { diff --git a/drivers/pinctrl/nxp/pinctrl-s32cc.c b/drivers/pinctrl/nxp/pinctrl-s32cc.c index 501eb296c76050..35511f83d05603 100644 --- a/drivers/pinctrl/nxp/pinctrl-s32cc.c +++ b/drivers/pinctrl/nxp/pinctrl-s32cc.c @@ -392,6 +392,7 @@ static int s32_pmx_gpio_request_enable(struct pinctrl_dev *pctldev, gpio_pin->pin_id = offset; gpio_pin->config = config; + INIT_LIST_HEAD(&gpio_pin->list); spin_lock_irqsave(&ipctl->gpio_configs_lock, flags); list_add(&gpio_pin->list, &ipctl->gpio_configs); @@ -951,7 +952,7 @@ int s32_pinctrl_probe(struct platform_device *pdev, spin_lock_init(&ipctl->gpio_configs_lock); s32_pinctrl_desc = - devm_kmalloc(&pdev->dev, sizeof(*s32_pinctrl_desc), GFP_KERNEL); + devm_kzalloc(&pdev->dev, sizeof(*s32_pinctrl_desc), GFP_KERNEL); if (!s32_pinctrl_desc) return -ENOMEM; diff --git a/drivers/pinctrl/qcom/pinctrl-msm.c b/drivers/pinctrl/qcom/pinctrl-msm.c index 67525d542c5b7b..e99871b90ab9c7 100644 --- a/drivers/pinctrl/qcom/pinctrl-msm.c +++ b/drivers/pinctrl/qcom/pinctrl-msm.c @@ -189,7 +189,7 @@ static int msm_pinmux_set_mux(struct pinctrl_dev *pctldev, */ if (d && i != gpio_func && !test_and_set_bit(d->hwirq, pctrl->disabled_for_mux)) - disable_irq(irq); + disable_irq_nosync(irq); raw_spin_lock_irqsave(&pctrl->lock, flags); diff --git a/drivers/pinctrl/realtek/Kconfig b/drivers/pinctrl/realtek/Kconfig index 0fc6bd4fcb7ece..400c9e5b16ada5 100644 --- a/drivers/pinctrl/realtek/Kconfig +++ b/drivers/pinctrl/realtek/Kconfig @@ -6,6 +6,7 @@ config PINCTRL_RTD default y select PINMUX select GENERIC_PINCONF + select REGMAP_MMIO config PINCTRL_RTD1619B tristate "Realtek DHC 1619B pin controller driver" diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index 46e62feeda3c9a..c883a28e091639 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig @@ -432,7 +432,7 @@ config WIRELESS_HOTKEY depends on INPUT help This driver provides supports for the wireless buttons found on some AMD, - HP, & Xioami laptops. + HP, & Xiaomi laptops. On such systems the driver should load automatically (via ACPI alias). To compile this driver as a module, choose M here: the module will @@ -545,6 +545,7 @@ config MSI_WMI config MSI_WMI_PLATFORM tristate "MSI WMI Platform features" depends on ACPI_WMI + depends on DMI depends on HWMON help Say Y here if you want to have support for WMI-based platform features diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c index 13eb22b35aa8f8..d848afc91f87dd 100644 --- a/drivers/platform/x86/acer-wmi.c +++ b/drivers/platform/x86/acer-wmi.c @@ -102,6 +102,7 @@ MODULE_ALIAS("wmi:676AA15E-6A47-4D9F-A2CC-1E6D18D14026"); enum acer_wmi_event_ids { WMID_HOTKEY_EVENT = 0x1, + WMID_BACKLIGHT_EVENT = 0x4, WMID_ACCEL_OR_KBD_DOCK_EVENT = 0x5, WMID_GAMING_TURBO_KEY_EVENT = 0x7, WMID_AC_EVENT = 0x8, @@ -2369,6 +2370,9 @@ static void acer_wmi_notify(union acpi_object *obj, void *context) sparse_keymap_report_event(acer_wmi_input_dev, scancode, 1, true); } break; + case WMID_BACKLIGHT_EVENT: + /* Already handled by acpi-video */ + break; case WMID_ACCEL_OR_KBD_DOCK_EVENT: acer_gsensor_event(); acer_kbd_dock_event(&return_value); diff --git a/drivers/platform/x86/amd/pmc/pmc-quirks.c b/drivers/platform/x86/amd/pmc/pmc-quirks.c index d63aaad7ef5998..404e62ad293a98 100644 --- a/drivers/platform/x86/amd/pmc/pmc-quirks.c +++ b/drivers/platform/x86/amd/pmc/pmc-quirks.c @@ -122,6 +122,14 @@ static const struct dmi_system_id fwbug_list[] = { DMI_MATCH(DMI_PRODUCT_NAME, "21A1"), } }, + { + .ident = "ROG Xbox Ally RC73YA", + .driver_data = &quirk_spurious_8042, + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_BOARD_NAME, "RC73YA"), + } + }, /* https://bugzilla.kernel.org/show_bug.cgi?id=218024 */ { .ident = "V14 G4 AMN", @@ -204,6 +212,23 @@ static const struct dmi_system_id fwbug_list[] = { DMI_MATCH(DMI_PRODUCT_NAME, "82ND"), } }, + /* https://gitlab.freedesktop.org/drm/amd/-/issues/4618 */ + { + .ident = "Lenovo Legion Go 2", + .driver_data = &quirk_s2idle_bug, + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "83N0"), + } + }, + { + .ident = "Lenovo Legion Go 2", + .driver_data = &quirk_s2idle_bug, + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "83N1"), + } + }, /* https://gitlab.freedesktop.org/drm/amd/-/issues/2684 */ { .ident = "HP Laptop 15s-eq2xxx", diff --git a/drivers/platform/x86/amd/pmc/pmc.c b/drivers/platform/x86/amd/pmc/pmc.c index bd318fd02ccf4a..cae3fcafd4d7bb 100644 --- a/drivers/platform/x86/amd/pmc/pmc.c +++ b/drivers/platform/x86/amd/pmc/pmc.c @@ -106,6 +106,7 @@ static void amd_pmc_get_ip_info(struct amd_pmc_dev *dev) switch (dev->cpu_id) { case AMD_CPU_ID_PCO: case AMD_CPU_ID_RN: + case AMD_CPU_ID_VG: case AMD_CPU_ID_YC: case AMD_CPU_ID_CB: dev->num_ips = 12; @@ -517,6 +518,7 @@ static int amd_pmc_get_os_hint(struct amd_pmc_dev *dev) case AMD_CPU_ID_PCO: return MSG_OS_HINT_PCO; case AMD_CPU_ID_RN: + case AMD_CPU_ID_VG: case AMD_CPU_ID_YC: case AMD_CPU_ID_CB: case AMD_CPU_ID_PS: @@ -717,6 +719,7 @@ static const struct pci_device_id pmc_pci_ids[] = { { PCI_DEVICE(PCI_VENDOR_ID_AMD, AMD_CPU_ID_RV) }, { PCI_DEVICE(PCI_VENDOR_ID_AMD, AMD_CPU_ID_SP) }, { PCI_DEVICE(PCI_VENDOR_ID_AMD, AMD_CPU_ID_SHP) }, + { PCI_DEVICE(PCI_VENDOR_ID_AMD, AMD_CPU_ID_VG) }, { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M20H_ROOT) }, { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M60H_ROOT) }, { } diff --git a/drivers/platform/x86/amd/pmc/pmc.h b/drivers/platform/x86/amd/pmc/pmc.h index 62f3e51020fdf1..fe3f53eb59558e 100644 --- a/drivers/platform/x86/amd/pmc/pmc.h +++ b/drivers/platform/x86/amd/pmc/pmc.h @@ -156,6 +156,7 @@ void amd_mp2_stb_deinit(struct amd_pmc_dev *dev); #define AMD_CPU_ID_RN 0x1630 #define AMD_CPU_ID_PCO AMD_CPU_ID_RV #define AMD_CPU_ID_CZN AMD_CPU_ID_RN +#define AMD_CPU_ID_VG 0x1645 #define AMD_CPU_ID_YC 0x14B5 #define AMD_CPU_ID_CB 0x14D8 #define AMD_CPU_ID_PS 0x14E8 diff --git a/drivers/platform/x86/dell/alienware-wmi-wmax.c b/drivers/platform/x86/dell/alienware-wmi-wmax.c index f417dcc9af355d..fadf7aac6779f7 100644 --- a/drivers/platform/x86/dell/alienware-wmi-wmax.c +++ b/drivers/platform/x86/dell/alienware-wmi-wmax.c @@ -90,34 +90,34 @@ static struct awcc_quirks empty_quirks; static const struct dmi_system_id awcc_dmi_table[] __initconst = { { - .ident = "Alienware Area-51m", + .ident = "Alienware 16 Aurora", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Alienware"), - DMI_MATCH(DMI_PRODUCT_NAME, "Alienware Area-51m"), + DMI_MATCH(DMI_PRODUCT_NAME, "Alienware 16 Aurora"), }, - .driver_data = &generic_quirks, + .driver_data = &g_series_quirks, }, { - .ident = "Alienware Area-51m R2", + .ident = "Alienware Area-51m", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Alienware"), - DMI_MATCH(DMI_PRODUCT_NAME, "Alienware Area-51m R2"), + DMI_MATCH(DMI_PRODUCT_NAME, "Alienware Area-51m"), }, .driver_data = &generic_quirks, }, { - .ident = "Alienware m15 R5", + .ident = "Alienware m15", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Alienware"), - DMI_MATCH(DMI_PRODUCT_NAME, "Alienware m15 R5"), + DMI_MATCH(DMI_PRODUCT_NAME, "Alienware m15"), }, .driver_data = &generic_quirks, }, { - .ident = "Alienware m15 R7", + .ident = "Alienware m16 R1 AMD", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Alienware"), - DMI_MATCH(DMI_PRODUCT_NAME, "Alienware m15 R7"), + DMI_MATCH(DMI_PRODUCT_NAME, "Alienware m16 R1 AMD"), }, .driver_data = &generic_quirks, }, @@ -129,14 +129,6 @@ static const struct dmi_system_id awcc_dmi_table[] __initconst = { }, .driver_data = &g_series_quirks, }, - { - .ident = "Alienware m16 R1 AMD", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Alienware"), - DMI_MATCH(DMI_PRODUCT_NAME, "Alienware m16 R1 AMD"), - }, - .driver_data = &generic_quirks, - }, { .ident = "Alienware m16 R2", .matches = { @@ -146,114 +138,66 @@ static const struct dmi_system_id awcc_dmi_table[] __initconst = { .driver_data = &generic_quirks, }, { - .ident = "Alienware m17 R5", + .ident = "Alienware m17", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Alienware"), - DMI_MATCH(DMI_PRODUCT_NAME, "Alienware m17 R5 AMD"), + DMI_MATCH(DMI_PRODUCT_NAME, "Alienware m17"), }, .driver_data = &generic_quirks, }, { - .ident = "Alienware m18 R2", + .ident = "Alienware m18", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Alienware"), - DMI_MATCH(DMI_PRODUCT_NAME, "Alienware m18 R2"), + DMI_MATCH(DMI_PRODUCT_NAME, "Alienware m18"), }, .driver_data = &generic_quirks, }, { - .ident = "Alienware x15 R1", + .ident = "Alienware x15", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Alienware"), - DMI_MATCH(DMI_PRODUCT_NAME, "Alienware x15 R1"), + DMI_MATCH(DMI_PRODUCT_NAME, "Alienware x15"), }, .driver_data = &generic_quirks, }, { - .ident = "Alienware x15 R2", + .ident = "Alienware x17", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Alienware"), - DMI_MATCH(DMI_PRODUCT_NAME, "Alienware x15 R2"), + DMI_MATCH(DMI_PRODUCT_NAME, "Alienware x17"), }, .driver_data = &generic_quirks, }, { - .ident = "Alienware x17 R2", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Alienware"), - DMI_MATCH(DMI_PRODUCT_NAME, "Alienware x17 R2"), - }, - .driver_data = &generic_quirks, - }, - { - .ident = "Dell Inc. G15 5510", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "Dell G15 5510"), - }, - .driver_data = &g_series_quirks, - }, - { - .ident = "Dell Inc. G15 5511", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "Dell G15 5511"), - }, - .driver_data = &g_series_quirks, - }, - { - .ident = "Dell Inc. G15 5515", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "Dell G15 5515"), - }, - .driver_data = &g_series_quirks, - }, - { - .ident = "Dell Inc. G15 5530", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "Dell G15 5530"), - }, - .driver_data = &g_series_quirks, - }, - { - .ident = "Dell Inc. G16 7630", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "Dell G16 7630"), - }, - .driver_data = &g_series_quirks, - }, - { - .ident = "Dell Inc. G3 3500", + .ident = "Dell Inc. G15", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "G3 3500"), + DMI_MATCH(DMI_PRODUCT_NAME, "Dell G15"), }, .driver_data = &g_series_quirks, }, { - .ident = "Dell Inc. G3 3590", + .ident = "Dell Inc. G16", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "G3 3590"), + DMI_MATCH(DMI_PRODUCT_NAME, "Dell G16"), }, .driver_data = &g_series_quirks, }, { - .ident = "Dell Inc. G5 5500", + .ident = "Dell Inc. G3", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "G5 5500"), + DMI_MATCH(DMI_PRODUCT_NAME, "G3"), }, .driver_data = &g_series_quirks, }, { - .ident = "Dell Inc. G5 5505", + .ident = "Dell Inc. G5", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "G5 5505"), + DMI_MATCH(DMI_PRODUCT_NAME, "G5"), }, .driver_data = &g_series_quirks, }, diff --git a/drivers/platform/x86/dell/dell-wmi-base.c b/drivers/platform/x86/dell/dell-wmi-base.c index 841a5414d28a68..28076929d6af5b 100644 --- a/drivers/platform/x86/dell/dell-wmi-base.c +++ b/drivers/platform/x86/dell/dell-wmi-base.c @@ -365,6 +365,13 @@ static const struct key_entry dell_wmi_keymap_type_0012[] = { /* Backlight brightness change event */ { KE_IGNORE, 0x0003, { KEY_RESERVED } }, + /* + * Electronic privacy screen toggled, extended data gives state, + * separate entries for on/off see handling in dell_wmi_process_key(). + */ + { KE_KEY, 0x000c, { KEY_EPRIVACY_SCREEN_OFF } }, + { KE_KEY, 0x000c, { KEY_EPRIVACY_SCREEN_ON } }, + /* Ultra-performance mode switch request */ { KE_IGNORE, 0x000d, { KEY_RESERVED } }, @@ -435,6 +442,11 @@ static int dell_wmi_process_key(struct wmi_device *wdev, int type, int code, u16 "Dell tablet mode switch", SW_TABLET_MODE, !buffer[0]); return 1; + } else if (type == 0x0012 && code == 0x000c && remaining > 0) { + /* Eprivacy toggle, switch to "on" key entry for on events */ + if (buffer[0] == 2) + key++; + used = 1; } else if (type == 0x0012 && code == 0x000d && remaining > 0) { value = (buffer[2] == 2); used = 1; diff --git a/drivers/platform/x86/hp/hp-wmi.c b/drivers/platform/x86/hp/hp-wmi.c index 8b3533d6ba091a..ad9d9f97960f2b 100644 --- a/drivers/platform/x86/hp/hp-wmi.c +++ b/drivers/platform/x86/hp/hp-wmi.c @@ -92,9 +92,11 @@ static const char * const victus_thermal_profile_boards[] = { "8A25" }; -/* DMI Board names of Victus 16-r1000 and Victus 16-s1000 laptops */ +/* DMI Board names of Victus 16-r and Victus 16-s laptops */ static const char * const victus_s_thermal_profile_boards[] = { - "8C99", "8C9C" + "8BBE", "8BD4", "8BD5", + "8C78", "8C99", "8C9C", + "8D41", }; enum hp_wmi_radio { diff --git a/drivers/platform/x86/huawei-wmi.c b/drivers/platform/x86/huawei-wmi.c index c3772df34679f5..8a4c54089ace31 100644 --- a/drivers/platform/x86/huawei-wmi.c +++ b/drivers/platform/x86/huawei-wmi.c @@ -81,6 +81,10 @@ static const struct key_entry huawei_wmi_keymap[] = { { KE_KEY, 0x289, { KEY_WLAN } }, // Huawei |M| key { KE_KEY, 0x28a, { KEY_CONFIG } }, + // HONOR YOYO key + { KE_KEY, 0x28b, { KEY_NOTIFICATION_CENTER } }, + // HONOR print screen + { KE_KEY, 0x28e, { KEY_PRINT } }, // Keyboard backlit { KE_IGNORE, 0x293, { KEY_KBDILLUMTOGGLE } }, { KE_IGNORE, 0x294, { KEY_KBDILLUMUP } }, diff --git a/drivers/platform/x86/intel/hid.c b/drivers/platform/x86/intel/hid.c index f25a427cccdace..9c07a7faf18fee 100644 --- a/drivers/platform/x86/intel/hid.c +++ b/drivers/platform/x86/intel/hid.c @@ -55,6 +55,7 @@ static const struct acpi_device_id intel_hid_ids[] = { { "INTC10CB" }, { "INTC10CC" }, { "INTC10F1" }, + { "INTC10F2" }, { } }; MODULE_DEVICE_TABLE(acpi, intel_hid_ids); diff --git a/drivers/platform/x86/intel/int3472/clk_and_regulator.c b/drivers/platform/x86/intel/int3472/clk_and_regulator.c index 476ec24d37020a..9e052b164a1ab8 100644 --- a/drivers/platform/x86/intel/int3472/clk_and_regulator.c +++ b/drivers/platform/x86/intel/int3472/clk_and_regulator.c @@ -245,15 +245,12 @@ int skl_int3472_register_regulator(struct int3472_discrete_device *int3472, if (IS_ERR(regulator->rdev)) return PTR_ERR(regulator->rdev); - int3472->regulators[int3472->n_regulator_gpios].ena_gpio = gpio; int3472->n_regulator_gpios++; return 0; } void skl_int3472_unregister_regulator(struct int3472_discrete_device *int3472) { - for (int i = 0; i < int3472->n_regulator_gpios; i++) { + for (int i = 0; i < int3472->n_regulator_gpios; i++) regulator_unregister(int3472->regulators[i].rdev); - gpiod_put(int3472->regulators[i].ena_gpio); - } } diff --git a/drivers/platform/x86/intel/int3472/led.c b/drivers/platform/x86/intel/int3472/led.c index f1d6d7b0cb75a3..b1d84b96811244 100644 --- a/drivers/platform/x86/intel/int3472/led.c +++ b/drivers/platform/x86/intel/int3472/led.c @@ -43,7 +43,7 @@ int skl_int3472_register_pled(struct int3472_discrete_device *int3472, struct gp int3472->pled.lookup.provider = int3472->pled.name; int3472->pled.lookup.dev_id = int3472->sensor_name; - int3472->pled.lookup.con_id = "privacy-led"; + int3472->pled.lookup.con_id = "privacy"; led_add_lookup(&int3472->pled.lookup); return 0; diff --git a/drivers/platform/x86/intel/speed_select_if/isst_if_mmio.c b/drivers/platform/x86/intel/speed_select_if/isst_if_mmio.c index 3f4343147dadb0..950ede5eab7694 100644 --- a/drivers/platform/x86/intel/speed_select_if/isst_if_mmio.c +++ b/drivers/platform/x86/intel/speed_select_if/isst_if_mmio.c @@ -108,11 +108,11 @@ static int isst_if_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ret = pci_read_config_dword(pdev, 0xD0, &mmio_base); if (ret) - return ret; + return pcibios_err_to_errno(ret); ret = pci_read_config_dword(pdev, 0xFC, &pcu_base); if (ret) - return ret; + return pcibios_err_to_errno(ret); pcu_base &= GENMASK(10, 0); base_addr = (u64)mmio_base << 23 | (u64) pcu_base << 12; diff --git a/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-common.h b/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-common.h index 70ae11519837ee..0abe850ef54eaa 100644 --- a/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-common.h +++ b/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-common.h @@ -40,7 +40,7 @@ * @agent_type_mask: Bit mask of all hardware agents for this domain * @uncore_attr_group: Attribute group storage * @max_freq_khz_kobj_attr: Storage for kobject attribute max_freq_khz - * @mix_freq_khz_kobj_attr: Storage for kobject attribute min_freq_khz + * @min_freq_khz_kobj_attr: Storage for kobject attribute min_freq_khz * @initial_max_freq_khz_kobj_attr: Storage for kobject attribute initial_max_freq_khz * @initial_min_freq_khz_kobj_attr: Storage for kobject attribute initial_min_freq_khz * @current_freq_khz_kobj_attr: Storage for kobject attribute current_freq_khz @@ -48,13 +48,14 @@ * @fabric_cluster_id_kobj_attr: Storage for kobject attribute fabric_cluster_id * @package_id_kobj_attr: Storage for kobject attribute package_id * @elc_low_threshold_percent_kobj_attr: - Storage for kobject attribute elc_low_threshold_percent + * Storage for kobject attribute elc_low_threshold_percent * @elc_high_threshold_percent_kobj_attr: - Storage for kobject attribute elc_high_threshold_percent + * Storage for kobject attribute elc_high_threshold_percent * @elc_high_threshold_enable_kobj_attr: - Storage for kobject attribute elc_high_threshold_enable + * Storage for kobject attribute elc_high_threshold_enable * @elc_floor_freq_khz_kobj_attr: Storage for kobject attribute elc_floor_freq_khz * @agent_types_kobj_attr: Storage for kobject attribute agent_type + * @die_id_kobj_attr: Attribute storage for die_id information * @uncore_attrs: Attribute storage for group creation * * This structure is used to encapsulate all data related to uncore sysfs diff --git a/drivers/platform/x86/intel/uncore-frequency/uncore-frequency.c b/drivers/platform/x86/intel/uncore-frequency/uncore-frequency.c index 2a6897035150c4..0dfc552b280246 100644 --- a/drivers/platform/x86/intel/uncore-frequency/uncore-frequency.c +++ b/drivers/platform/x86/intel/uncore-frequency/uncore-frequency.c @@ -256,6 +256,10 @@ static const struct x86_cpu_id intel_uncore_cpu_ids[] = { X86_MATCH_VFM(INTEL_ARROWLAKE, NULL), X86_MATCH_VFM(INTEL_ARROWLAKE_H, NULL), X86_MATCH_VFM(INTEL_LUNARLAKE_M, NULL), + X86_MATCH_VFM(INTEL_PANTHERLAKE_L, NULL), + X86_MATCH_VFM(INTEL_WILDCATLAKE_L, NULL), + X86_MATCH_VFM(INTEL_NOVALAKE, NULL), + X86_MATCH_VFM(INTEL_NOVALAKE_L, NULL), {} }; MODULE_DEVICE_TABLE(x86cpu, intel_uncore_cpu_ids); diff --git a/drivers/platform/x86/msi-wmi-platform.c b/drivers/platform/x86/msi-wmi-platform.c index dc5e9878cb6822..e912fcc12d1243 100644 --- a/drivers/platform/x86/msi-wmi-platform.c +++ b/drivers/platform/x86/msi-wmi-platform.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -28,7 +29,7 @@ #define DRIVER_NAME "msi-wmi-platform" -#define MSI_PLATFORM_GUID "ABBC0F6E-8EA1-11d1-00A0-C90629100000" +#define MSI_PLATFORM_GUID "ABBC0F6E-8EA1-11D1-00A0-C90629100000" #define MSI_WMI_PLATFORM_INTERFACE_VERSION 2 @@ -448,7 +449,45 @@ static struct wmi_driver msi_wmi_platform_driver = { .probe = msi_wmi_platform_probe, .no_singleton = true, }; -module_wmi_driver(msi_wmi_platform_driver); + +/* + * MSI reused the WMI GUID from the WMI-ACPI sample code provided by Microsoft, + * so other manufacturers might use it as well for their WMI-ACPI implementations. + */ +static const struct dmi_system_id msi_wmi_platform_whitelist[] __initconst = { + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "MICRO-STAR INT"), + }, + }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"), + }, + }, + { } +}; + +static int __init msi_wmi_platform_module_init(void) +{ + if (!dmi_check_system(msi_wmi_platform_whitelist)) { + if (!force) + return -ENODEV; + + pr_warn("Ignoring DMI whitelist\n"); + } + + return wmi_driver_register(&msi_wmi_platform_driver); +} + +static void __exit msi_wmi_platform_module_exit(void) +{ + wmi_driver_unregister(&msi_wmi_platform_driver); +} + +module_init(msi_wmi_platform_module_init); +module_exit(msi_wmi_platform_module_exit); + MODULE_AUTHOR("Armin Wolf "); MODULE_DESCRIPTION("MSI WMI platform features"); diff --git a/drivers/pmdomain/arm/scmi_pm_domain.c b/drivers/pmdomain/arm/scmi_pm_domain.c index 8fe1c0a501c9ba..b5e2ffd5ea64c0 100644 --- a/drivers/pmdomain/arm/scmi_pm_domain.c +++ b/drivers/pmdomain/arm/scmi_pm_domain.c @@ -41,7 +41,7 @@ static int scmi_pd_power_off(struct generic_pm_domain *domain) static int scmi_pm_domain_probe(struct scmi_device *sdev) { - int num_domains, i; + int num_domains, i, ret; struct device *dev = &sdev->dev; struct device_node *np = dev->of_node; struct scmi_pm_domain *scmi_pd; @@ -108,9 +108,18 @@ static int scmi_pm_domain_probe(struct scmi_device *sdev) scmi_pd_data->domains = domains; scmi_pd_data->num_domains = num_domains; + ret = of_genpd_add_provider_onecell(np, scmi_pd_data); + if (ret) + goto err_rm_genpds; + dev_set_drvdata(dev, scmi_pd_data); - return of_genpd_add_provider_onecell(np, scmi_pd_data); + return 0; +err_rm_genpds: + for (i = num_domains - 1; i >= 0; i--) + pm_genpd_remove(domains[i]); + + return ret; } static void scmi_pm_domain_remove(struct scmi_device *sdev) diff --git a/drivers/pmdomain/imx/gpc.c b/drivers/pmdomain/imx/gpc.c index 33991f3c6b5564..a34b260274f7bd 100644 --- a/drivers/pmdomain/imx/gpc.c +++ b/drivers/pmdomain/imx/gpc.c @@ -536,6 +536,8 @@ static void imx_gpc_remove(struct platform_device *pdev) return; } } + + of_node_put(pgc_node); } static struct platform_driver imx_gpc_driver = { diff --git a/drivers/pmdomain/samsung/exynos-pm-domains.c b/drivers/pmdomain/samsung/exynos-pm-domains.c index 5d478bb37ad68a..5c3aa898308793 100644 --- a/drivers/pmdomain/samsung/exynos-pm-domains.c +++ b/drivers/pmdomain/samsung/exynos-pm-domains.c @@ -92,13 +92,14 @@ static const struct of_device_id exynos_pm_domain_of_match[] = { { }, }; -static const char *exynos_get_domain_name(struct device_node *node) +static const char *exynos_get_domain_name(struct device *dev, + struct device_node *node) { const char *name; if (of_property_read_string(node, "label", &name) < 0) name = kbasename(node->full_name); - return kstrdup_const(name, GFP_KERNEL); + return devm_kstrdup_const(dev, name, GFP_KERNEL); } static int exynos_pd_probe(struct platform_device *pdev) @@ -115,20 +116,27 @@ static int exynos_pd_probe(struct platform_device *pdev) if (!pd) return -ENOMEM; - pd->pd.name = exynos_get_domain_name(np); + pd->pd.name = exynos_get_domain_name(dev, np); if (!pd->pd.name) return -ENOMEM; pd->base = of_iomap(np, 0); - if (!pd->base) { - kfree_const(pd->pd.name); + if (!pd->base) return -ENODEV; - } pd->pd.power_off = exynos_pd_power_off; pd->pd.power_on = exynos_pd_power_on; pd->local_pwr_cfg = pm_domain_cfg->local_pwr_cfg; + /* + * Some Samsung platforms with bootloaders turning on the splash-screen + * and handing it over to the kernel, requires the power-domains to be + * reset during boot. + */ + if (IS_ENABLED(CONFIG_ARM) && + of_device_is_compatible(np, "samsung,exynos4210-pd")) + exynos_pd_power_off(&pd->pd); + on = readl_relaxed(pd->base + 0x4) & pd->local_pwr_cfg; pm_genpd_init(&pd->pd, NULL, !on); @@ -147,15 +155,6 @@ static int exynos_pd_probe(struct platform_device *pdev) parent.np, child.np); } - /* - * Some Samsung platforms with bootloaders turning on the splash-screen - * and handing it over to the kernel, requires the power-domains to be - * reset during boot. As a temporary hack to manage this, let's enforce - * a sync_state. - */ - if (!ret) - of_genpd_sync_state(np); - pm_runtime_enable(dev); return ret; } diff --git a/drivers/ptp/ptp_chardev.c b/drivers/ptp/ptp_chardev.c index 8106eb617c8c4f..c61cf9edac48b8 100644 --- a/drivers/ptp/ptp_chardev.c +++ b/drivers/ptp/ptp_chardev.c @@ -561,10 +561,14 @@ long ptp_ioctl(struct posix_clock_context *pccontext, unsigned int cmd, return ptp_mask_en_single(pccontext->private_clkdata, argptr); case PTP_SYS_OFFSET_PRECISE_CYCLES: + if (!ptp->has_cycles) + return -EOPNOTSUPP; return ptp_sys_offset_precise(ptp, argptr, ptp->info->getcrosscycles); case PTP_SYS_OFFSET_EXTENDED_CYCLES: + if (!ptp->has_cycles) + return -EOPNOTSUPP; return ptp_sys_offset_extended(ptp, argptr, ptp->info->getcyclesx64); default: diff --git a/drivers/pwm/pwm-adp5585.c b/drivers/pwm/pwm-adp5585.c index dc2860979e24e8..806f8d79b0d7b3 100644 --- a/drivers/pwm/pwm-adp5585.c +++ b/drivers/pwm/pwm-adp5585.c @@ -190,13 +190,13 @@ static int adp5585_pwm_probe(struct platform_device *pdev) return 0; } -static const struct adp5585_pwm_chip adp5589_pwm_chip_info = { +static const struct adp5585_pwm_chip adp5585_pwm_chip_info = { .pwm_cfg = ADP5585_PWM_CFG, .pwm_offt_low = ADP5585_PWM_OFFT_LOW, .pwm_ont_low = ADP5585_PWM_ONT_LOW, }; -static const struct adp5585_pwm_chip adp5585_pwm_chip_info = { +static const struct adp5585_pwm_chip adp5589_pwm_chip_info = { .pwm_cfg = ADP5589_PWM_CFG, .pwm_offt_low = ADP5589_PWM_OFFT_LOW, .pwm_ont_low = ADP5589_PWM_ONT_LOW, diff --git a/drivers/regulator/arizona-micsupp.c b/drivers/regulator/arizona-micsupp.c index e250e5f3fcbcb3..be7208bc7409b6 100644 --- a/drivers/regulator/arizona-micsupp.c +++ b/drivers/regulator/arizona-micsupp.c @@ -48,7 +48,6 @@ static void arizona_micsupp_check_cp(struct work_struct *work) struct arizona_micsupp *micsupp = container_of(work, struct arizona_micsupp, check_cp_work); struct snd_soc_dapm_context *dapm = *micsupp->dapm; - struct snd_soc_component *component; const struct regulator_desc *desc = micsupp->desc; unsigned int val; int ret; @@ -61,14 +60,11 @@ static void arizona_micsupp_check_cp(struct work_struct *work) } if (dapm) { - component = snd_soc_dapm_to_component(dapm); - if ((val & (desc->enable_mask | desc->bypass_mask)) == desc->enable_mask) - snd_soc_component_force_enable_pin(component, - "MICSUPP"); + snd_soc_dapm_force_enable_pin(dapm, "MICSUPP"); else - snd_soc_component_disable_pin(component, "MICSUPP"); + snd_soc_dapm_disable_pin(dapm, "MICSUPP"); snd_soc_dapm_sync(dapm); } diff --git a/drivers/regulator/fixed.c b/drivers/regulator/fixed.c index 1cb647ed70c62d..a2d16e9abfb58d 100644 --- a/drivers/regulator/fixed.c +++ b/drivers/regulator/fixed.c @@ -334,6 +334,7 @@ static int reg_fixed_voltage_probe(struct platform_device *pdev) ret = dev_err_probe(&pdev->dev, PTR_ERR(drvdata->dev), "Failed to register regulator: %ld\n", PTR_ERR(drvdata->dev)); + gpiod_put(cfg.ena_gpiod); return ret; } diff --git a/drivers/reset/reset-imx8mp-audiomix.c b/drivers/reset/reset-imx8mp-audiomix.c index 6b357adfe646c7..eceb37ff5dc5b5 100644 --- a/drivers/reset/reset-imx8mp-audiomix.c +++ b/drivers/reset/reset-imx8mp-audiomix.c @@ -14,8 +14,8 @@ #include #define IMX8MP_AUDIOMIX_EARC_RESET_OFFSET 0x200 -#define IMX8MP_AUDIOMIX_EARC_RESET_MASK BIT(1) -#define IMX8MP_AUDIOMIX_EARC_PHY_RESET_MASK BIT(2) +#define IMX8MP_AUDIOMIX_EARC_RESET_MASK BIT(0) +#define IMX8MP_AUDIOMIX_EARC_PHY_RESET_MASK BIT(1) #define IMX8MP_AUDIOMIX_DSP_RUNSTALL_OFFSET 0x108 #define IMX8MP_AUDIOMIX_DSP_RUNSTALL_MASK BIT(5) diff --git a/drivers/rtc/rtc-cpcap.c b/drivers/rtc/rtc-cpcap.c index 8b6b35716f539e..c170345ac076ca 100644 --- a/drivers/rtc/rtc-cpcap.c +++ b/drivers/rtc/rtc-cpcap.c @@ -268,7 +268,6 @@ static int cpcap_rtc_probe(struct platform_device *pdev) return err; rtc->alarm_irq = platform_get_irq(pdev, 0); - rtc->alarm_enabled = true; err = devm_request_threaded_irq(dev, rtc->alarm_irq, NULL, cpcap_rtc_alarm_irq, IRQF_TRIGGER_NONE | IRQF_ONESHOT, diff --git a/drivers/rtc/rtc-rx8025.c b/drivers/rtc/rtc-rx8025.c index aabe62c283a150..7e9f7cb90c2887 100644 --- a/drivers/rtc/rtc-rx8025.c +++ b/drivers/rtc/rtc-rx8025.c @@ -316,7 +316,7 @@ static int rx8025_init_client(struct i2c_client *client) return hour_reg; rx8025->is_24 = (hour_reg & RX8035_BIT_HOUR_1224); } else { - rx8025->is_24 = (ctrl[1] & RX8025_BIT_CTRL1_1224); + rx8025->is_24 = (ctrl[0] & RX8025_BIT_CTRL1_1224); } out: return err; diff --git a/drivers/rtc/rtc-tps6586x.c b/drivers/rtc/rtc-tps6586x.c index 76ecf7b798f0de..54c8429b16bfcc 100644 --- a/drivers/rtc/rtc-tps6586x.c +++ b/drivers/rtc/rtc-tps6586x.c @@ -258,7 +258,6 @@ static int tps6586x_rtc_probe(struct platform_device *pdev) irq_set_status_flags(rtc->irq, IRQ_NOAUTOEN); - rtc->irq_en = true; ret = devm_request_threaded_irq(&pdev->dev, rtc->irq, NULL, tps6586x_rtc_irq, IRQF_ONESHOT, diff --git a/drivers/s390/net/ctcm_mpc.c b/drivers/s390/net/ctcm_mpc.c index 0aeafa772fb1e8..407b7c51665855 100644 --- a/drivers/s390/net/ctcm_mpc.c +++ b/drivers/s390/net/ctcm_mpc.c @@ -701,7 +701,6 @@ static void mpc_rcvd_sweep_req(struct mpcg_info *mpcginfo) grp->sweep_req_pend_num--; ctcmpc_send_sweep_resp(ch); - kfree(mpcginfo); return; } diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index 4c62c597c7be93..b3af9b78fa123b 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -2208,9 +2208,17 @@ sg_remove_sfp_usercontext(struct work_struct *work) write_lock_irqsave(&sfp->rq_list_lock, iflags); while (!list_empty(&sfp->rq_list)) { srp = list_first_entry(&sfp->rq_list, Sg_request, entry); - sg_finish_rem_req(srp); list_del(&srp->entry); + write_unlock_irqrestore(&sfp->rq_list_lock, iflags); + + sg_finish_rem_req(srp); + /* + * sg_rq_end_io() uses srp->parentfp. Hence, only clear + * srp->parentfp after blk_mq_free_request() has been called. + */ srp->parentfp = NULL; + + write_lock_irqsave(&sfp->rq_list_lock, iflags); } write_unlock_irqrestore(&sfp->rq_list_lock, iflags); diff --git a/drivers/soc/ti/knav_dma.c b/drivers/soc/ti/knav_dma.c index a25ebe6cd5030d..553ae7ee20f166 100644 --- a/drivers/soc/ti/knav_dma.c +++ b/drivers/soc/ti/knav_dma.c @@ -402,7 +402,7 @@ static int of_channel_match_helper(struct device_node *np, const char *name, * @name: slave channel name * @config: dma configuration parameters * - * Returns pointer to appropriate DMA channel on success or error. + * Return: Pointer to appropriate DMA channel on success or NULL on error. */ void *knav_dma_open_channel(struct device *dev, const char *name, struct knav_dma_cfg *config) @@ -414,13 +414,13 @@ void *knav_dma_open_channel(struct device *dev, const char *name, if (!kdev) { pr_err("keystone-navigator-dma driver not registered\n"); - return (void *)-EINVAL; + return NULL; } chan_num = of_channel_match_helper(dev->of_node, name, &instance); if (chan_num < 0) { dev_err(kdev->dev, "No DMA instance with name %s\n", name); - return (void *)-EINVAL; + return NULL; } dev_dbg(kdev->dev, "initializing %s channel %d from DMA %s\n", @@ -431,7 +431,7 @@ void *knav_dma_open_channel(struct device *dev, const char *name, if (config->direction != DMA_MEM_TO_DEV && config->direction != DMA_DEV_TO_MEM) { dev_err(kdev->dev, "bad direction\n"); - return (void *)-EINVAL; + return NULL; } /* Look for correct dma instance */ @@ -443,7 +443,7 @@ void *knav_dma_open_channel(struct device *dev, const char *name, } if (!dma) { dev_err(kdev->dev, "No DMA instance with name %s\n", instance); - return (void *)-EINVAL; + return NULL; } /* Look for correct dma channel from dma instance */ @@ -463,14 +463,14 @@ void *knav_dma_open_channel(struct device *dev, const char *name, if (!chan) { dev_err(kdev->dev, "channel %d is not in DMA %s\n", chan_num, instance); - return (void *)-EINVAL; + return NULL; } if (atomic_read(&chan->ref_count) >= 1) { if (!check_config(chan, config)) { dev_err(kdev->dev, "channel %d config miss-match\n", chan_num); - return (void *)-EINVAL; + return NULL; } } diff --git a/drivers/soundwire/qcom.c b/drivers/soundwire/qcom.c index 5b3078220189be..17afc5aa8b44e0 100644 --- a/drivers/soundwire/qcom.c +++ b/drivers/soundwire/qcom.c @@ -31,6 +31,7 @@ #define SWRM_VERSION_1_5_1 0x01050001 #define SWRM_VERSION_1_7_0 0x01070000 #define SWRM_VERSION_2_0_0 0x02000000 +#define SWRM_VERSION_3_1_0 0x03010000 #define SWRM_COMP_HW_VERSION 0x00 #define SWRM_COMP_CFG_ADDR 0x04 #define SWRM_COMP_CFG_IRQ_LEVEL_OR_PULSE_MSK BIT(1) @@ -40,6 +41,9 @@ #define SWRM_COMP_PARAMS_RD_FIFO_DEPTH GENMASK(19, 15) #define SWRM_COMP_PARAMS_DOUT_PORTS_MASK GENMASK(4, 0) #define SWRM_COMP_PARAMS_DIN_PORTS_MASK GENMASK(9, 5) +#define SWRM_V3_COMP_PARAMS_WR_FIFO_DEPTH GENMASK(17, 10) +#define SWRM_V3_COMP_PARAMS_RD_FIFO_DEPTH GENMASK(23, 18) + #define SWRM_COMP_MASTER_ID 0x104 #define SWRM_V1_3_INTERRUPT_STATUS 0x200 #define SWRM_V2_0_INTERRUPT_STATUS 0x5000 @@ -99,14 +103,15 @@ #define SWRM_MCP_SLV_STATUS 0x1090 #define SWRM_MCP_SLV_STATUS_MASK GENMASK(1, 0) #define SWRM_MCP_SLV_STATUS_SZ 2 -#define SWRM_DP_PORT_CTRL_BANK(n, m) (0x1124 + 0x100 * (n - 1) + 0x40 * m) -#define SWRM_DP_PORT_CTRL_2_BANK(n, m) (0x1128 + 0x100 * (n - 1) + 0x40 * m) -#define SWRM_DP_BLOCK_CTRL_1(n) (0x112C + 0x100 * (n - 1)) -#define SWRM_DP_BLOCK_CTRL2_BANK(n, m) (0x1130 + 0x100 * (n - 1) + 0x40 * m) -#define SWRM_DP_PORT_HCTRL_BANK(n, m) (0x1134 + 0x100 * (n - 1) + 0x40 * m) -#define SWRM_DP_BLOCK_CTRL3_BANK(n, m) (0x1138 + 0x100 * (n - 1) + 0x40 * m) -#define SWRM_DP_SAMPLECTRL2_BANK(n, m) (0x113C + 0x100 * (n - 1) + 0x40 * m) -#define SWRM_DIN_DPn_PCM_PORT_CTRL(n) (0x1054 + 0x100 * (n - 1)) + +#define SWRM_DPn_PORT_CTRL_BANK(offset, n, m) (offset + 0x100 * (n - 1) + 0x40 * m) +#define SWRM_DPn_PORT_CTRL_2_BANK(offset, n, m) (offset + 0x100 * (n - 1) + 0x40 * m) +#define SWRM_DPn_BLOCK_CTRL_1(offset, n) (offset + 0x100 * (n - 1)) +#define SWRM_DPn_BLOCK_CTRL2_BANK(offset, n, m) (offset + 0x100 * (n - 1) + 0x40 * m) +#define SWRM_DPn_PORT_HCTRL_BANK(offset, n, m) (offset + 0x100 * (n - 1) + 0x40 * m) +#define SWRM_DPn_BLOCK_CTRL3_BANK(offset, n, m) (offset + 0x100 * (n - 1) + 0x40 * m) +#define SWRM_DPn_SAMPLECTRL2_BANK(offset, n, m) (offset + 0x100 * (n - 1) + 0x40 * m) + #define SWR_V1_3_MSTR_MAX_REG_ADDR 0x1740 #define SWR_V2_0_MSTR_MAX_REG_ADDR 0x50ac @@ -128,7 +133,6 @@ #define MAX_FREQ_NUM 1 #define TIMEOUT_MS 100 #define QCOM_SWRM_MAX_RD_LEN 0x1 -#define QCOM_SDW_MAX_PORTS 14 #define DEFAULT_CLK_FREQ 9600000 #define SWRM_MAX_DAIS 0xF #define SWR_INVALID_PARAM 0xFF @@ -172,6 +176,13 @@ enum { SWRM_REG_CMD_FIFO_RD_CMD, SWRM_REG_CMD_FIFO_STATUS, SWRM_REG_CMD_FIFO_RD_FIFO_ADDR, + SWRM_OFFSET_DP_PORT_CTRL_BANK, + SWRM_OFFSET_DP_PORT_CTRL_2_BANK, + SWRM_OFFSET_DP_BLOCK_CTRL_1, + SWRM_OFFSET_DP_BLOCK_CTRL2_BANK, + SWRM_OFFSET_DP_PORT_HCTRL_BANK, + SWRM_OFFSET_DP_BLOCK_CTRL3_BANK, + SWRM_OFFSET_DP_SAMPLECTRL2_BANK, }; struct qcom_swrm_ctrl { @@ -195,6 +206,7 @@ struct qcom_swrm_ctrl { int wake_irq; int num_din_ports; int num_dout_ports; + int nports; int cols_index; int rows_index; unsigned long port_mask; @@ -202,14 +214,13 @@ struct qcom_swrm_ctrl { u8 rcmd_id; u8 wcmd_id; /* Port numbers are 1 - 14 */ - struct qcom_swrm_port_config pconfig[QCOM_SDW_MAX_PORTS + 1]; + struct qcom_swrm_port_config *pconfig; struct sdw_stream_runtime *sruntime[SWRM_MAX_DAIS]; enum sdw_slave_status status[SDW_MAX_DEVICES + 1]; int (*reg_read)(struct qcom_swrm_ctrl *ctrl, int reg, u32 *val); int (*reg_write)(struct qcom_swrm_ctrl *ctrl, int reg, int val); u32 slave_status; u32 wr_fifo_depth; - u32 rd_fifo_depth; bool clock_stop_not_supported; }; @@ -231,6 +242,13 @@ static const unsigned int swrm_v1_3_reg_layout[] = { [SWRM_REG_CMD_FIFO_RD_CMD] = SWRM_V1_3_CMD_FIFO_RD_CMD, [SWRM_REG_CMD_FIFO_STATUS] = SWRM_V1_3_CMD_FIFO_STATUS, [SWRM_REG_CMD_FIFO_RD_FIFO_ADDR] = SWRM_V1_3_CMD_FIFO_RD_FIFO_ADDR, + [SWRM_OFFSET_DP_PORT_CTRL_BANK] = 0x1124, + [SWRM_OFFSET_DP_PORT_CTRL_2_BANK] = 0x1128, + [SWRM_OFFSET_DP_BLOCK_CTRL_1] = 0x112c, + [SWRM_OFFSET_DP_BLOCK_CTRL2_BANK] = 0x1130, + [SWRM_OFFSET_DP_PORT_HCTRL_BANK] = 0x1134, + [SWRM_OFFSET_DP_BLOCK_CTRL3_BANK] = 0x1138, + [SWRM_OFFSET_DP_SAMPLECTRL2_BANK] = 0x113c, }; static const struct qcom_swrm_data swrm_v1_3_data = { @@ -265,6 +283,13 @@ static const unsigned int swrm_v2_0_reg_layout[] = { [SWRM_REG_CMD_FIFO_RD_CMD] = SWRM_V2_0_CMD_FIFO_RD_CMD, [SWRM_REG_CMD_FIFO_STATUS] = SWRM_V2_0_CMD_FIFO_STATUS, [SWRM_REG_CMD_FIFO_RD_FIFO_ADDR] = SWRM_V2_0_CMD_FIFO_RD_FIFO_ADDR, + [SWRM_OFFSET_DP_PORT_CTRL_BANK] = 0x1124, + [SWRM_OFFSET_DP_PORT_CTRL_2_BANK] = 0x1128, + [SWRM_OFFSET_DP_BLOCK_CTRL_1] = 0x112c, + [SWRM_OFFSET_DP_BLOCK_CTRL2_BANK] = 0x1130, + [SWRM_OFFSET_DP_PORT_HCTRL_BANK] = 0x1134, + [SWRM_OFFSET_DP_BLOCK_CTRL3_BANK] = 0x1138, + [SWRM_OFFSET_DP_SAMPLECTRL2_BANK] = 0x113c, }; static const struct qcom_swrm_data swrm_v2_0_data = { @@ -275,6 +300,32 @@ static const struct qcom_swrm_data swrm_v2_0_data = { .reg_layout = swrm_v2_0_reg_layout, }; +static const unsigned int swrm_v3_0_reg_layout[] = { + [SWRM_REG_FRAME_GEN_ENABLED] = SWRM_V2_0_LINK_STATUS, + [SWRM_REG_INTERRUPT_STATUS] = SWRM_V2_0_INTERRUPT_STATUS, + [SWRM_REG_INTERRUPT_MASK_ADDR] = 0, /* Not present */ + [SWRM_REG_INTERRUPT_CLEAR] = SWRM_V2_0_INTERRUPT_CLEAR, + [SWRM_REG_INTERRUPT_CPU_EN] = SWRM_V2_0_INTERRUPT_CPU_EN, + [SWRM_REG_CMD_FIFO_WR_CMD] = SWRM_V2_0_CMD_FIFO_WR_CMD, + [SWRM_REG_CMD_FIFO_RD_CMD] = SWRM_V2_0_CMD_FIFO_RD_CMD, + [SWRM_REG_CMD_FIFO_STATUS] = SWRM_V2_0_CMD_FIFO_STATUS, + [SWRM_REG_CMD_FIFO_RD_FIFO_ADDR] = SWRM_V2_0_CMD_FIFO_RD_FIFO_ADDR, + [SWRM_OFFSET_DP_PORT_CTRL_BANK] = 0x1224, + [SWRM_OFFSET_DP_PORT_CTRL_2_BANK] = 0x1228, + [SWRM_OFFSET_DP_BLOCK_CTRL_1] = 0x122c, + [SWRM_OFFSET_DP_BLOCK_CTRL2_BANK] = 0x1230, + [SWRM_OFFSET_DP_PORT_HCTRL_BANK] = 0x1234, + [SWRM_OFFSET_DP_BLOCK_CTRL3_BANK] = 0x1238, + [SWRM_OFFSET_DP_SAMPLECTRL2_BANK] = 0x123c, +}; + +static const struct qcom_swrm_data swrm_v3_0_data = { + .default_rows = 50, + .default_cols = 16, + .sw_clk_gate_required = true, + .max_reg = SWR_V2_0_MSTR_MAX_REG_ADDR, + .reg_layout = swrm_v3_0_reg_layout, +}; #define to_qcom_sdw(b) container_of(b, struct qcom_swrm_ctrl, bus) static int qcom_swrm_ahb_reg_read(struct qcom_swrm_ctrl *ctrl, int reg, @@ -898,8 +949,11 @@ static int qcom_swrm_init(struct qcom_swrm_ctrl *ctrl) swrm_wait_for_frame_gen_enabled(ctrl); ctrl->slave_status = 0; ctrl->reg_read(ctrl, SWRM_COMP_PARAMS, &val); - ctrl->rd_fifo_depth = FIELD_GET(SWRM_COMP_PARAMS_RD_FIFO_DEPTH, val); - ctrl->wr_fifo_depth = FIELD_GET(SWRM_COMP_PARAMS_WR_FIFO_DEPTH, val); + + if (ctrl->version >= SWRM_VERSION_3_1_0) + ctrl->wr_fifo_depth = FIELD_GET(SWRM_V3_COMP_PARAMS_WR_FIFO_DEPTH, val); + else + ctrl->wr_fifo_depth = FIELD_GET(SWRM_COMP_PARAMS_WR_FIFO_DEPTH, val); return 0; } @@ -966,10 +1020,10 @@ static int qcom_swrm_port_params(struct sdw_bus *bus, unsigned int bank) { struct qcom_swrm_ctrl *ctrl = to_qcom_sdw(bus); + u32 offset = ctrl->reg_layout[SWRM_OFFSET_DP_BLOCK_CTRL_1]; - return ctrl->reg_write(ctrl, SWRM_DP_BLOCK_CTRL_1(p_params->num), - p_params->bps - 1); - + return ctrl->reg_write(ctrl, SWRM_DPn_BLOCK_CTRL_1(offset, p_params->num), + p_params->bps - 1); } static int qcom_swrm_transport_params(struct sdw_bus *bus, @@ -979,9 +1033,11 @@ static int qcom_swrm_transport_params(struct sdw_bus *bus, struct qcom_swrm_ctrl *ctrl = to_qcom_sdw(bus); struct qcom_swrm_port_config *pcfg; u32 value; - int reg = SWRM_DP_PORT_CTRL_BANK((params->port_num), bank); + int reg, offset = ctrl->reg_layout[SWRM_OFFSET_DP_PORT_CTRL_BANK]; int ret; + reg = SWRM_DPn_PORT_CTRL_BANK(offset, params->port_num, bank); + pcfg = &ctrl->pconfig[params->port_num]; value = pcfg->off1 << SWRM_DP_PORT_CTRL_OFFSET1_SHFT; @@ -993,15 +1049,19 @@ static int qcom_swrm_transport_params(struct sdw_bus *bus, goto err; if (pcfg->si > 0xff) { + offset = ctrl->reg_layout[SWRM_OFFSET_DP_SAMPLECTRL2_BANK]; value = (pcfg->si >> 8) & 0xff; - reg = SWRM_DP_SAMPLECTRL2_BANK(params->port_num, bank); + reg = SWRM_DPn_SAMPLECTRL2_BANK(offset, params->port_num, bank); + ret = ctrl->reg_write(ctrl, reg, value); if (ret) goto err; } if (pcfg->lane_control != SWR_INVALID_PARAM) { - reg = SWRM_DP_PORT_CTRL_2_BANK(params->port_num, bank); + offset = ctrl->reg_layout[SWRM_OFFSET_DP_PORT_CTRL_2_BANK]; + reg = SWRM_DPn_PORT_CTRL_2_BANK(offset, params->port_num, bank); + value = pcfg->lane_control; ret = ctrl->reg_write(ctrl, reg, value); if (ret) @@ -1009,20 +1069,23 @@ static int qcom_swrm_transport_params(struct sdw_bus *bus, } if (pcfg->blk_group_count != SWR_INVALID_PARAM) { - reg = SWRM_DP_BLOCK_CTRL2_BANK(params->port_num, bank); + offset = ctrl->reg_layout[SWRM_OFFSET_DP_BLOCK_CTRL2_BANK]; + + reg = SWRM_DPn_BLOCK_CTRL2_BANK(offset, params->port_num, bank); + value = pcfg->blk_group_count; ret = ctrl->reg_write(ctrl, reg, value); if (ret) goto err; } - if (pcfg->hstart != SWR_INVALID_PARAM - && pcfg->hstop != SWR_INVALID_PARAM) { - reg = SWRM_DP_PORT_HCTRL_BANK(params->port_num, bank); + offset = ctrl->reg_layout[SWRM_OFFSET_DP_PORT_HCTRL_BANK]; + reg = SWRM_DPn_PORT_HCTRL_BANK(offset, params->port_num, bank); + + if (pcfg->hstart != SWR_INVALID_PARAM && pcfg->hstop != SWR_INVALID_PARAM) { value = (pcfg->hstop << 4) | pcfg->hstart; ret = ctrl->reg_write(ctrl, reg, value); } else { - reg = SWRM_DP_PORT_HCTRL_BANK(params->port_num, bank); value = (SWR_HSTOP_MAX_VAL << 4) | SWR_HSTART_MIN_VAL; ret = ctrl->reg_write(ctrl, reg, value); } @@ -1031,7 +1094,8 @@ static int qcom_swrm_transport_params(struct sdw_bus *bus, goto err; if (pcfg->bp_mode != SWR_INVALID_PARAM) { - reg = SWRM_DP_BLOCK_CTRL3_BANK(params->port_num, bank); + offset = ctrl->reg_layout[SWRM_OFFSET_DP_BLOCK_CTRL3_BANK]; + reg = SWRM_DPn_BLOCK_CTRL3_BANK(offset, params->port_num, bank); ret = ctrl->reg_write(ctrl, reg, pcfg->bp_mode); } @@ -1043,9 +1107,12 @@ static int qcom_swrm_port_enable(struct sdw_bus *bus, struct sdw_enable_ch *enable_ch, unsigned int bank) { - u32 reg = SWRM_DP_PORT_CTRL_BANK(enable_ch->port_num, bank); + u32 reg; struct qcom_swrm_ctrl *ctrl = to_qcom_sdw(bus); u32 val; + u32 offset = ctrl->reg_layout[SWRM_OFFSET_DP_PORT_CTRL_BANK]; + + reg = SWRM_DPn_PORT_CTRL_BANK(offset, enable_ch->port_num, bank); ctrl->reg_read(ctrl, reg, &val); @@ -1155,7 +1222,6 @@ static int qcom_swrm_stream_alloc_ports(struct qcom_swrm_ctrl *ctrl, struct snd_pcm_hw_params *params, int direction) { - struct sdw_port_config pconfig[QCOM_SDW_MAX_PORTS]; struct sdw_stream_config sconfig; struct sdw_master_runtime *m_rt; struct sdw_slave_runtime *s_rt; @@ -1164,6 +1230,10 @@ static int qcom_swrm_stream_alloc_ports(struct qcom_swrm_ctrl *ctrl, unsigned long *port_mask; int maxport, pn, nports = 0, ret = 0; unsigned int m_port; + struct sdw_port_config *pconfig __free(kfree) = kcalloc(ctrl->nports, + sizeof(*pconfig), GFP_KERNEL); + if (!pconfig) + return -ENOMEM; if (direction == SNDRV_PCM_STREAM_CAPTURE) sconfig.direction = SDW_DATA_DIR_TX; @@ -1188,8 +1258,7 @@ static int qcom_swrm_stream_alloc_ports(struct qcom_swrm_ctrl *ctrl, continue; port_mask = &ctrl->port_mask; - maxport = ctrl->num_dout_ports + ctrl->num_din_ports; - + maxport = ctrl->nports; list_for_each_entry(s_rt, &m_rt->slave_rt_list, m_rt_node) { slave = s_rt->slave; @@ -1349,17 +1418,8 @@ static int qcom_swrm_register_dais(struct qcom_swrm_ctrl *ctrl) static int qcom_swrm_get_port_config(struct qcom_swrm_ctrl *ctrl) { struct device_node *np = ctrl->dev->of_node; - u8 off1[QCOM_SDW_MAX_PORTS]; - u8 off2[QCOM_SDW_MAX_PORTS]; - u16 si[QCOM_SDW_MAX_PORTS]; - u8 bp_mode[QCOM_SDW_MAX_PORTS] = { 0, }; - u8 hstart[QCOM_SDW_MAX_PORTS]; - u8 hstop[QCOM_SDW_MAX_PORTS]; - u8 word_length[QCOM_SDW_MAX_PORTS]; - u8 blk_group_count[QCOM_SDW_MAX_PORTS]; - u8 lane_control[QCOM_SDW_MAX_PORTS]; - int i, ret, nports, val; - bool si_16 = false; + struct qcom_swrm_port_config *pcfg; + int i, ret, val; ctrl->reg_read(ctrl, SWRM_COMP_PARAMS, &val); @@ -1367,88 +1427,78 @@ static int qcom_swrm_get_port_config(struct qcom_swrm_ctrl *ctrl) ctrl->num_din_ports = FIELD_GET(SWRM_COMP_PARAMS_DIN_PORTS_MASK, val); ret = of_property_read_u32(np, "qcom,din-ports", &val); - if (ret) - return ret; - - if (val > ctrl->num_din_ports) - return -EINVAL; + if (!ret) { /* only if present */ + if (val != ctrl->num_din_ports) { + dev_err(ctrl->dev, "din-ports (%d) mismatch with controller (%d)", + val, ctrl->num_din_ports); + } - ctrl->num_din_ports = val; + ctrl->num_din_ports = val; + } ret = of_property_read_u32(np, "qcom,dout-ports", &val); - if (ret) - return ret; + if (!ret) { /* only if present */ + if (val != ctrl->num_dout_ports) { + dev_err(ctrl->dev, "dout-ports (%d) mismatch with controller (%d)", + val, ctrl->num_dout_ports); + } - if (val > ctrl->num_dout_ports) - return -EINVAL; + ctrl->num_dout_ports = val; + } - ctrl->num_dout_ports = val; + ctrl->nports = ctrl->num_dout_ports + ctrl->num_din_ports; - nports = ctrl->num_dout_ports + ctrl->num_din_ports; - if (nports > QCOM_SDW_MAX_PORTS) - return -EINVAL; + ctrl->pconfig = devm_kcalloc(ctrl->dev, ctrl->nports + 1, + sizeof(*ctrl->pconfig), GFP_KERNEL); + if (!ctrl->pconfig) + return -ENOMEM; - /* Valid port numbers are from 1-14, so mask out port 0 explicitly */ set_bit(0, &ctrl->port_mask); + /* Valid port numbers are from 1, so mask out port 0 explicitly */ + for (i = 0; i < ctrl->nports; i++) { + pcfg = &ctrl->pconfig[i + 1]; - ret = of_property_read_u8_array(np, "qcom,ports-offset1", - off1, nports); - if (ret) - return ret; - - ret = of_property_read_u8_array(np, "qcom,ports-offset2", - off2, nports); - if (ret) - return ret; - - ret = of_property_read_u8_array(np, "qcom,ports-sinterval-low", - (u8 *)si, nports); - if (ret) { - ret = of_property_read_u16_array(np, "qcom,ports-sinterval", - si, nports); + ret = of_property_read_u8_index(np, "qcom,ports-offset1", i, &pcfg->off1); if (ret) return ret; - si_16 = true; - } - ret = of_property_read_u8_array(np, "qcom,ports-block-pack-mode", - bp_mode, nports); - if (ret) { - if (ctrl->version <= SWRM_VERSION_1_3_0) - memset(bp_mode, SWR_INVALID_PARAM, QCOM_SDW_MAX_PORTS); - else + ret = of_property_read_u8_index(np, "qcom,ports-offset2", i, &pcfg->off2); + if (ret) return ret; - } - memset(hstart, SWR_INVALID_PARAM, QCOM_SDW_MAX_PORTS); - of_property_read_u8_array(np, "qcom,ports-hstart", hstart, nports); + ret = of_property_read_u8_index(np, "qcom,ports-sinterval-low", i, (u8 *)&pcfg->si); + if (ret) { + ret = of_property_read_u16_index(np, "qcom,ports-sinterval", i, &pcfg->si); + if (ret) + return ret; + } + + ret = of_property_read_u8_index(np, "qcom,ports-block-pack-mode", + i, &pcfg->bp_mode); + if (ret) { + if (ctrl->version <= SWRM_VERSION_1_3_0) + pcfg->bp_mode = SWR_INVALID_PARAM; + else + return ret; + } + + /* Optional properties */ + pcfg->hstart = SWR_INVALID_PARAM; + pcfg->hstop = SWR_INVALID_PARAM; + pcfg->word_length = SWR_INVALID_PARAM; + pcfg->blk_group_count = SWR_INVALID_PARAM; + pcfg->lane_control = SWR_INVALID_PARAM; - memset(hstop, SWR_INVALID_PARAM, QCOM_SDW_MAX_PORTS); - of_property_read_u8_array(np, "qcom,ports-hstop", hstop, nports); + of_property_read_u8_index(np, "qcom,ports-hstart", i, &pcfg->hstart); - memset(word_length, SWR_INVALID_PARAM, QCOM_SDW_MAX_PORTS); - of_property_read_u8_array(np, "qcom,ports-word-length", word_length, nports); + of_property_read_u8_index(np, "qcom,ports-hstop", i, &pcfg->hstop); - memset(blk_group_count, SWR_INVALID_PARAM, QCOM_SDW_MAX_PORTS); - of_property_read_u8_array(np, "qcom,ports-block-group-count", blk_group_count, nports); + of_property_read_u8_index(np, "qcom,ports-word-length", i, &pcfg->word_length); - memset(lane_control, SWR_INVALID_PARAM, QCOM_SDW_MAX_PORTS); - of_property_read_u8_array(np, "qcom,ports-lane-control", lane_control, nports); + of_property_read_u8_index(np, "qcom,ports-block-group-count", + i, &pcfg->blk_group_count); - for (i = 0; i < nports; i++) { - /* Valid port number range is from 1-14 */ - if (si_16) - ctrl->pconfig[i + 1].si = si[i]; - else - ctrl->pconfig[i + 1].si = ((u8 *)si)[i]; - ctrl->pconfig[i + 1].off1 = off1[i]; - ctrl->pconfig[i + 1].off2 = off2[i]; - ctrl->pconfig[i + 1].bp_mode = bp_mode[i]; - ctrl->pconfig[i + 1].hstart = hstart[i]; - ctrl->pconfig[i + 1].hstop = hstop[i]; - ctrl->pconfig[i + 1].word_length = word_length[i]; - ctrl->pconfig[i + 1].blk_group_count = blk_group_count[i]; - ctrl->pconfig[i + 1].lane_control = lane_control[i]; + of_property_read_u8_index(np, "qcom,ports-lane-control", i, &pcfg->lane_control); } return 0; @@ -1769,6 +1819,7 @@ static const struct of_device_id qcom_swrm_of_match[] = { { .compatible = "qcom,soundwire-v1.6.0", .data = &swrm_v1_6_data }, { .compatible = "qcom,soundwire-v1.7.0", .data = &swrm_v1_5_data }, { .compatible = "qcom,soundwire-v2.0.0", .data = &swrm_v2_0_data }, + { .compatible = "qcom,soundwire-v3.1.0", .data = &swrm_v3_0_data }, {/* sentinel */}, }; diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c index 155ddeb8fcd460..bbf1fd4fe1e925 100644 --- a/drivers/spi/spi-imx.c +++ b/drivers/spi/spi-imx.c @@ -519,9 +519,15 @@ static void mx51_ecspi_trigger(struct spi_imx_data *spi_imx) { u32 reg; - reg = readl(spi_imx->base + MX51_ECSPI_CTRL); - reg |= MX51_ECSPI_CTRL_XCH; - writel(reg, spi_imx->base + MX51_ECSPI_CTRL); + if (spi_imx->usedma) { + reg = readl(spi_imx->base + MX51_ECSPI_DMA); + reg |= MX51_ECSPI_DMA_TEDEN | MX51_ECSPI_DMA_RXDEN; + writel(reg, spi_imx->base + MX51_ECSPI_DMA); + } else { + reg = readl(spi_imx->base + MX51_ECSPI_CTRL); + reg |= MX51_ECSPI_CTRL_XCH; + writel(reg, spi_imx->base + MX51_ECSPI_CTRL); + } } static void mx51_ecspi_disable(struct spi_imx_data *spi_imx) @@ -759,7 +765,6 @@ static void mx51_setup_wml(struct spi_imx_data *spi_imx) writel(MX51_ECSPI_DMA_RX_WML(spi_imx->wml - 1) | MX51_ECSPI_DMA_TX_WML(tx_wml) | MX51_ECSPI_DMA_RXT_WML(spi_imx->wml) | - MX51_ECSPI_DMA_TEDEN | MX51_ECSPI_DMA_RXDEN | MX51_ECSPI_DMA_RXTDEN, spi_imx->base + MX51_ECSPI_DMA); } @@ -1520,6 +1525,8 @@ static int spi_imx_dma_transfer(struct spi_imx_data *spi_imx, reinit_completion(&spi_imx->dma_tx_completion); dma_async_issue_pending(controller->dma_tx); + spi_imx->devtype_data->trigger(spi_imx); + transfer_timeout = spi_imx_calculate_timeout(spi_imx, transfer->len); /* Wait SDMA to finish the data transfer.*/ diff --git a/drivers/spi/spi-xilinx.c b/drivers/spi/spi-xilinx.c index d59cc8a1848466..c86dc56f38b456 100644 --- a/drivers/spi/spi-xilinx.c +++ b/drivers/spi/spi-xilinx.c @@ -300,7 +300,7 @@ static int xilinx_spi_txrx_bufs(struct spi_device *spi, struct spi_transfer *t) /* Read out all the data from the Rx FIFO */ rx_words = n_words; - stalled = 10; + stalled = 32; while (rx_words) { if (rx_words == n_words && !(stalled--) && !(sr & XSPI_SR_TX_EMPTY_MASK) && diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 2e0647a0689029..e25df9990f82de 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -2851,6 +2851,18 @@ static acpi_status acpi_register_spi_device(struct spi_controller *ctlr, acpi_set_modalias(adev, acpi_device_hid(adev), spi->modalias, sizeof(spi->modalias)); + /* + * This gets re-tried in spi_probe() for -EPROBE_DEFER handling in case + * the GPIO controller does not have a driver yet. This needs to be done + * here too, because this call sets the GPIO direction and/or bias. + * Setting these needs to be done even if there is no driver, in which + * case spi_probe() will never get called. + * TODO: ideally the setup of the GPIO should be handled in a generic + * manner in the ACPI/gpiolib core code. + */ + if (spi->irq < 0) + spi->irq = acpi_dev_gpio_irq_get(adev, 0); + acpi_device_set_enumerated(adev); adev->power.flags.ignore_parent = true; diff --git a/drivers/staging/greybus/audio_codec.c b/drivers/staging/greybus/audio_codec.c index 2f05e761fb9ad3..444c53b4e08dd3 100644 --- a/drivers/staging/greybus/audio_codec.c +++ b/drivers/staging/greybus/audio_codec.c @@ -807,6 +807,7 @@ int gbaudio_register_module(struct gbaudio_module_info *module) { int ret; struct snd_soc_component *comp; + struct snd_soc_dapm_context *dapm; struct gbaudio_jack *jack = NULL; if (!gbcodec) { @@ -815,6 +816,7 @@ int gbaudio_register_module(struct gbaudio_module_info *module) } comp = gbcodec->component; + dapm = snd_soc_component_to_dapm(comp); mutex_lock(&gbcodec->register_mutex); @@ -833,18 +835,18 @@ int gbaudio_register_module(struct gbaudio_module_info *module) } if (module->dapm_widgets) - snd_soc_dapm_new_controls(&comp->dapm, module->dapm_widgets, + snd_soc_dapm_new_controls(dapm, module->dapm_widgets, module->num_dapm_widgets); if (module->controls) snd_soc_add_component_controls(comp, module->controls, module->num_controls); if (module->dapm_routes) - snd_soc_dapm_add_routes(&comp->dapm, module->dapm_routes, + snd_soc_dapm_add_routes(dapm, module->dapm_routes, module->num_dapm_routes); /* card already instantiated, create widgets here only */ if (comp->card->instantiated) { - gbaudio_dapm_link_component_dai_widgets(comp->card, &comp->dapm); + gbaudio_dapm_link_component_dai_widgets(comp->card, dapm); #ifdef CONFIG_SND_JACK /* * register jack devices for this module @@ -966,9 +968,11 @@ void gbaudio_unregister_module(struct gbaudio_module_info *module) #endif if (module->dapm_routes) { + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(comp); + dev_dbg(comp->dev, "Removing %d routes\n", module->num_dapm_routes); - snd_soc_dapm_del_routes(&comp->dapm, module->dapm_routes, + snd_soc_dapm_del_routes(dapm, module->dapm_routes, module->num_dapm_routes); } if (module->controls) { @@ -979,9 +983,11 @@ void gbaudio_unregister_module(struct gbaudio_module_info *module) module->num_controls); } if (module->dapm_widgets) { + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(comp); + dev_dbg(comp->dev, "Removing %d widgets\n", module->num_dapm_widgets); - gbaudio_dapm_free_controls(&comp->dapm, module->dapm_widgets, + gbaudio_dapm_free_controls(dapm, module->dapm_widgets, module->num_dapm_widgets); } diff --git a/drivers/staging/greybus/audio_helper.c b/drivers/staging/greybus/audio_helper.c index 97ce5b9ad7fd32..b4873c6d6bed08 100644 --- a/drivers/staging/greybus/audio_helper.c +++ b/drivers/staging/greybus/audio_helper.c @@ -115,12 +115,13 @@ int gbaudio_dapm_free_controls(struct snd_soc_dapm_context *dapm, { int i; struct snd_soc_dapm_widget *w, *tmp_w; + struct snd_soc_card *card = snd_soc_dapm_to_card(dapm); - mutex_lock(&dapm->card->dapm_mutex); + mutex_lock(&card->dapm_mutex); for (i = 0; i < num; i++) { /* below logic can be optimized to identify widget pointer */ w = NULL; - list_for_each_entry(tmp_w, &dapm->card->widgets, list) { + list_for_each_entry(tmp_w, &card->widgets, list) { if (tmp_w->dapm == dapm && !strcmp(tmp_w->name, widget->name)) { w = tmp_w; @@ -128,7 +129,7 @@ int gbaudio_dapm_free_controls(struct snd_soc_dapm_context *dapm, } } if (!w) { - dev_err(dapm->dev, "%s: widget not found\n", + dev_err(card->dev, "%s: widget not found\n", widget->name); widget++; continue; @@ -136,7 +137,7 @@ int gbaudio_dapm_free_controls(struct snd_soc_dapm_context *dapm, widget++; gbaudio_dapm_free_widget(w); } - mutex_unlock(&dapm->card->dapm_mutex); + mutex_unlock(&card->dapm_mutex); return 0; } diff --git a/drivers/staging/greybus/audio_topology.c b/drivers/staging/greybus/audio_topology.c index 13b790f81d4421..76146f91cddcc2 100644 --- a/drivers/staging/greybus/audio_topology.c +++ b/drivers/staging/greybus/audio_topology.c @@ -380,7 +380,7 @@ static int gbcodec_mixer_dapm_ctl_get(struct snd_kcontrol *kcontrol, struct gbaudio_module_info *module; struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol); struct snd_soc_dapm_widget *widget = wlist->widgets[0]; - struct device *codec_dev = widget->dapm->dev; + struct device *codec_dev = snd_soc_dapm_to_dev(widget->dapm); struct gbaudio_codec_info *gb = dev_get_drvdata(codec_dev); struct gb_bundle *bundle; @@ -393,7 +393,7 @@ static int gbcodec_mixer_dapm_ctl_get(struct snd_kcontrol *kcontrol, bundle = to_gb_bundle(module->dev); if (data->vcount == 2) - dev_warn(widget->dapm->dev, + dev_warn(codec_dev, "GB: Control '%s' is stereo, which is not supported\n", kcontrol->id.name); @@ -429,7 +429,7 @@ static int gbcodec_mixer_dapm_ctl_put(struct snd_kcontrol *kcontrol, struct gbaudio_module_info *module; struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol); struct snd_soc_dapm_widget *widget = wlist->widgets[0]; - struct device *codec_dev = widget->dapm->dev; + struct device *codec_dev = snd_soc_dapm_to_dev(widget->dapm); struct gbaudio_codec_info *gb = dev_get_drvdata(codec_dev); struct gb_bundle *bundle; @@ -443,7 +443,7 @@ static int gbcodec_mixer_dapm_ctl_put(struct snd_kcontrol *kcontrol, bundle = to_gb_bundle(module->dev); if (data->vcount == 2) - dev_warn(widget->dapm->dev, + dev_warn(codec_dev, "GB: Control '%s' is stereo, which is not supported\n", kcontrol->id.name); @@ -712,7 +712,7 @@ static int gbcodec_enum_dapm_ctl_get(struct snd_kcontrol *kcontrol, struct snd_soc_dapm_widget *widget = wlist->widgets[0]; struct gbaudio_module_info *module; struct gb_audio_ctl_elem_value gbvalue; - struct device *codec_dev = widget->dapm->dev; + struct device *codec_dev = snd_soc_dapm_to_dev(widget->dapm); struct gbaudio_codec_info *gb = dev_get_drvdata(codec_dev); struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; struct gb_bundle *bundle; @@ -759,7 +759,7 @@ static int gbcodec_enum_dapm_ctl_put(struct snd_kcontrol *kcontrol, struct snd_soc_dapm_widget *widget = wlist->widgets[0]; struct gb_audio_ctl_elem_value gbvalue; struct gbaudio_module_info *module; - struct device *codec_dev = widget->dapm->dev; + struct device *codec_dev = snd_soc_dapm_to_dev(widget->dapm); struct gbaudio_codec_info *gb = dev_get_drvdata(codec_dev); struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; struct gb_bundle *bundle; @@ -924,7 +924,7 @@ static int gbaudio_widget_event(struct snd_soc_dapm_widget *w, { int wid; int ret; - struct device *codec_dev = w->dapm->dev; + struct device *codec_dev = snd_soc_dapm_to_dev(w->dapm); struct gbaudio_codec_info *gbcodec = dev_get_drvdata(codec_dev); struct gbaudio_module_info *module; struct gb_bundle *bundle; diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c index c7b7da6297418f..01a8e349dc4d1a 100644 --- a/drivers/target/loopback/tcm_loop.c +++ b/drivers/target/loopback/tcm_loop.c @@ -894,6 +894,9 @@ static ssize_t tcm_loop_tpg_address_show(struct config_item *item, struct tcm_loop_tpg, tl_se_tpg); struct tcm_loop_hba *tl_hba = tl_tpg->tl_hba; + if (!tl_hba->sh) + return -ENODEV; + return snprintf(page, PAGE_SIZE, "%d:0:%d\n", tl_hba->sh->host_no, tl_tpg->tl_tpgt); } diff --git a/drivers/ufs/core/ufs-sysfs.c b/drivers/ufs/core/ufs-sysfs.c index c040afc6668e8c..0086816b27cd90 100644 --- a/drivers/ufs/core/ufs-sysfs.c +++ b/drivers/ufs/core/ufs-sysfs.c @@ -1949,7 +1949,7 @@ static umode_t ufs_sysfs_hid_is_visible(struct kobject *kobj, return hba->dev_info.hid_sup ? attr->mode : 0; } -const struct attribute_group ufs_sysfs_hid_group = { +static const struct attribute_group ufs_sysfs_hid_group = { .name = "hid", .attrs = ufs_sysfs_hid, .is_visible = ufs_sysfs_hid_is_visible, diff --git a/drivers/ufs/core/ufs-sysfs.h b/drivers/ufs/core/ufs-sysfs.h index 6efb82a082fdd3..8d94af3b807719 100644 --- a/drivers/ufs/core/ufs-sysfs.h +++ b/drivers/ufs/core/ufs-sysfs.h @@ -14,6 +14,5 @@ void ufs_sysfs_remove_nodes(struct device *dev); extern const struct attribute_group ufs_sysfs_unit_descriptor_group; extern const struct attribute_group ufs_sysfs_lun_attributes_group; -extern const struct attribute_group ufs_sysfs_hid_group; #endif diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c index 9ca27de4767a18..d6a060a7246186 100644 --- a/drivers/ufs/core/ufshcd.c +++ b/drivers/ufs/core/ufshcd.c @@ -5066,7 +5066,8 @@ static int ufshcd_link_startup(struct ufs_hba *hba) * If UFS device isn't active then we will have to issue link startup * 2 times to make sure the device state move to active. */ - if (!ufshcd_is_ufs_dev_active(hba)) + if (!(hba->quirks & UFSHCD_QUIRK_PERFORM_LINK_STARTUP_ONCE) && + !ufshcd_is_ufs_dev_active(hba)) link_startup_again = true; link_startup: @@ -5131,12 +5132,8 @@ static int ufshcd_link_startup(struct ufs_hba *hba) ufshcd_readl(hba, REG_UIC_ERROR_CODE_PHY_ADAPTER_LAYER); ret = ufshcd_make_hba_operational(hba); out: - if (ret) { + if (ret) dev_err(hba->dev, "link startup failed %d\n", ret); - ufshcd_print_host_state(hba); - ufshcd_print_pwr_info(hba); - ufshcd_print_evt_hist(hba); - } return ret; } @@ -8503,8 +8500,6 @@ static int ufs_get_device_desc(struct ufs_hba *hba) DEVICE_DESC_PARAM_EXT_UFS_FEATURE_SUP) & UFS_DEV_HID_SUPPORT; - sysfs_update_group(&hba->dev->kobj, &ufs_sysfs_hid_group); - model_index = desc_buf[DEVICE_DESC_PARAM_PRDCT_NAME]; err = ufshcd_read_string_desc(hba, model_index, @@ -10661,7 +10656,7 @@ static int ufshcd_add_scsi_host(struct ufs_hba *hba) * @mmio_base: base register address * @irq: Interrupt line of device * - * Return: 0 on success, non-zero value on failure. + * Return: 0 on success; < 0 on failure. */ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq) { @@ -10891,8 +10886,8 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq) if (err) goto out_disable; - async_schedule(ufshcd_async_scan, hba); ufs_sysfs_add_nodes(hba->dev); + async_schedule(ufshcd_async_scan, hba); device_enable_async_suspend(dev); ufshcd_pm_qos_init(hba); @@ -10902,7 +10897,7 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq) hba->is_irq_enabled = false; ufshcd_hba_exit(hba); out_error: - return err; + return err > 0 ? -EIO : err; } EXPORT_SYMBOL_GPL(ufshcd_init); diff --git a/drivers/ufs/host/ufs-qcom.c b/drivers/ufs/host/ufs-qcom.c index 3e83dc51d53857..eba0e66174834d 100644 --- a/drivers/ufs/host/ufs-qcom.c +++ b/drivers/ufs/host/ufs-qcom.c @@ -740,8 +740,21 @@ static int ufs_qcom_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op, /* reset the connected UFS device during power down */ - if (ufs_qcom_is_link_off(hba) && host->device_reset) + if (ufs_qcom_is_link_off(hba) && host->device_reset) { ufs_qcom_device_reset_ctrl(hba, true); + /* + * After sending the SSU command, asserting the rst_n + * line causes the device firmware to wake up and + * execute its reset routine. + * + * During this process, the device may draw current + * beyond the permissible limit for low-power mode (LPM). + * A 10ms delay, based on experimental observations, + * allows the UFS device to complete its hardware reset + * before transitioning the power rail to LPM. + */ + usleep_range(10000, 11000); + } return ufs_qcom_ice_suspend(host); } diff --git a/drivers/ufs/host/ufshcd-pci.c b/drivers/ufs/host/ufshcd-pci.c index b87e037773955f..5f65dfad1a71a3 100644 --- a/drivers/ufs/host/ufshcd-pci.c +++ b/drivers/ufs/host/ufshcd-pci.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -31,6 +32,7 @@ struct intel_host { u32 dsm_fns; u32 active_ltr; u32 idle_ltr; + int saved_spm_lvl; struct dentry *debugfs_root; struct gpio_desc *reset_gpio; }; @@ -347,6 +349,7 @@ static int ufs_intel_common_init(struct ufs_hba *hba) host = devm_kzalloc(hba->dev, sizeof(*host), GFP_KERNEL); if (!host) return -ENOMEM; + host->saved_spm_lvl = -1; ufshcd_set_variant(hba, host); intel_dsm_init(host, hba->dev); if (INTEL_DSM_SUPPORTED(host, RESET)) { @@ -425,7 +428,8 @@ static int ufs_intel_lkf_init(struct ufs_hba *hba) static int ufs_intel_adl_init(struct ufs_hba *hba) { hba->nop_out_timeout = 200; - hba->quirks |= UFSHCD_QUIRK_BROKEN_AUTO_HIBERN8; + hba->quirks |= UFSHCD_QUIRK_BROKEN_AUTO_HIBERN8 | + UFSHCD_QUIRK_PERFORM_LINK_STARTUP_ONCE; hba->caps |= UFSHCD_CAP_WB_EN; return ufs_intel_common_init(hba); } @@ -538,6 +542,66 @@ static int ufshcd_pci_restore(struct device *dev) return ufshcd_system_resume(dev); } + +static int ufs_intel_suspend_prepare(struct device *dev) +{ + struct ufs_hba *hba = dev_get_drvdata(dev); + struct intel_host *host = ufshcd_get_variant(hba); + int err; + + /* + * Only s2idle (S0ix) retains link state. Force power-off + * (UFS_PM_LVL_5) for any other case. + */ + if (pm_suspend_target_state != PM_SUSPEND_TO_IDLE && hba->spm_lvl < UFS_PM_LVL_5) { + host->saved_spm_lvl = hba->spm_lvl; + hba->spm_lvl = UFS_PM_LVL_5; + } + + err = ufshcd_suspend_prepare(dev); + + if (err < 0 && host->saved_spm_lvl != -1) { + hba->spm_lvl = host->saved_spm_lvl; + host->saved_spm_lvl = -1; + } + + return err; +} + +static void ufs_intel_resume_complete(struct device *dev) +{ + struct ufs_hba *hba = dev_get_drvdata(dev); + struct intel_host *host = ufshcd_get_variant(hba); + + ufshcd_resume_complete(dev); + + if (host->saved_spm_lvl != -1) { + hba->spm_lvl = host->saved_spm_lvl; + host->saved_spm_lvl = -1; + } +} + +static int ufshcd_pci_suspend_prepare(struct device *dev) +{ + struct ufs_hba *hba = dev_get_drvdata(dev); + + if (!strcmp(hba->vops->name, "intel-pci")) + return ufs_intel_suspend_prepare(dev); + + return ufshcd_suspend_prepare(dev); +} + +static void ufshcd_pci_resume_complete(struct device *dev) +{ + struct ufs_hba *hba = dev_get_drvdata(dev); + + if (!strcmp(hba->vops->name, "intel-pci")) { + ufs_intel_resume_complete(dev); + return; + } + + ufshcd_resume_complete(dev); +} #endif /** @@ -611,8 +675,8 @@ static const struct dev_pm_ops ufshcd_pci_pm_ops = { .thaw = ufshcd_system_resume, .poweroff = ufshcd_system_suspend, .restore = ufshcd_pci_restore, - .prepare = ufshcd_suspend_prepare, - .complete = ufshcd_resume_complete, + .prepare = ufshcd_pci_suspend_prepare, + .complete = ufshcd_pci_resume_complete, #endif }; diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.c b/drivers/vdpa/mlx5/net/mlx5_vnet.c index 82034efb74fc7c..a7936bd1aabe17 100644 --- a/drivers/vdpa/mlx5/net/mlx5_vnet.c +++ b/drivers/vdpa/mlx5/net/mlx5_vnet.c @@ -573,6 +573,8 @@ static int cq_create(struct mlx5_vdpa_net *ndev, u16 idx, u32 num_ent) vcq->mcq.set_ci_db = vcq->db.db; vcq->mcq.arm_db = vcq->db.db + 1; vcq->mcq.cqe_sz = 64; + vcq->mcq.comp = mlx5_vdpa_cq_comp; + vcq->cqe = num_ent; err = cq_frag_buf_alloc(ndev, &vcq->buf, num_ent); if (err) @@ -612,10 +614,6 @@ static int cq_create(struct mlx5_vdpa_net *ndev, u16 idx, u32 num_ent) if (err) goto err_vec; - vcq->mcq.comp = mlx5_vdpa_cq_comp; - vcq->cqe = num_ent; - vcq->mcq.set_ci_db = vcq->db.db; - vcq->mcq.arm_db = vcq->db.db + 1; mlx5_cq_arm(&mvq->cq.mcq, MLX5_CQ_DB_REQ_NOT, uar_page, mvq->cq.mcq.cons_index); kfree(in); return 0; diff --git a/fs/afs/cell.c b/fs/afs/cell.c index f31359922e98d9..d9b6fa1088b7b3 100644 --- a/fs/afs/cell.c +++ b/fs/afs/cell.c @@ -229,7 +229,7 @@ static struct afs_cell *afs_alloc_cell(struct afs_net *net, * @name: The name of the cell. * @namesz: The strlen of the cell name. * @vllist: A colon/comma separated list of numeric IP addresses or NULL. - * @excl: T if an error should be given if the cell name already exists. + * @reason: The reason we're doing the lookup * @trace: The reason to be logged if the lookup is successful. * * Look up a cell record by name and query the DNS for VL server addresses if @@ -239,7 +239,8 @@ static struct afs_cell *afs_alloc_cell(struct afs_net *net, */ struct afs_cell *afs_lookup_cell(struct afs_net *net, const char *name, unsigned int namesz, - const char *vllist, bool excl, + const char *vllist, + enum afs_lookup_cell_for reason, enum afs_cell_trace trace) { struct afs_cell *cell, *candidate, *cursor; @@ -247,12 +248,18 @@ struct afs_cell *afs_lookup_cell(struct afs_net *net, enum afs_cell_state state; int ret, n; - _enter("%s,%s", name, vllist); + _enter("%s,%s,%u", name, vllist, reason); - if (!excl) { + if (reason != AFS_LOOKUP_CELL_PRELOAD) { cell = afs_find_cell(net, name, namesz, trace); - if (!IS_ERR(cell)) + if (!IS_ERR(cell)) { + if (reason == AFS_LOOKUP_CELL_DYNROOT) + goto no_wait; + if (cell->state == AFS_CELL_SETTING_UP || + cell->state == AFS_CELL_UNLOOKED) + goto lookup_cell; goto wait_for_cell; + } } /* Assume we're probably going to create a cell and preallocate and @@ -298,26 +305,69 @@ struct afs_cell *afs_lookup_cell(struct afs_net *net, rb_insert_color(&cell->net_node, &net->cells); up_write(&net->cells_lock); - afs_queue_cell(cell, afs_cell_trace_queue_new); +lookup_cell: + if (reason != AFS_LOOKUP_CELL_PRELOAD && + reason != AFS_LOOKUP_CELL_ROOTCELL) { + set_bit(AFS_CELL_FL_DO_LOOKUP, &cell->flags); + afs_queue_cell(cell, afs_cell_trace_queue_new); + } wait_for_cell: - _debug("wait_for_cell"); state = smp_load_acquire(&cell->state); /* vs error */ - if (state != AFS_CELL_ACTIVE && - state != AFS_CELL_DEAD) { + switch (state) { + case AFS_CELL_ACTIVE: + case AFS_CELL_DEAD: + break; + case AFS_CELL_UNLOOKED: + default: + if (reason == AFS_LOOKUP_CELL_PRELOAD || + reason == AFS_LOOKUP_CELL_ROOTCELL) + break; + _debug("wait_for_cell"); afs_see_cell(cell, afs_cell_trace_wait); wait_var_event(&cell->state, ({ state = smp_load_acquire(&cell->state); /* vs error */ state == AFS_CELL_ACTIVE || state == AFS_CELL_DEAD; })); + _debug("waited_for_cell %d %d", cell->state, cell->error); } +no_wait: /* Check the state obtained from the wait check. */ + state = smp_load_acquire(&cell->state); /* vs error */ if (state == AFS_CELL_DEAD) { ret = cell->error; goto error; } + if (state == AFS_CELL_ACTIVE) { + switch (cell->dns_status) { + case DNS_LOOKUP_NOT_DONE: + if (cell->dns_source == DNS_RECORD_FROM_CONFIG) { + ret = 0; + break; + } + fallthrough; + default: + ret = -EIO; + goto error; + case DNS_LOOKUP_GOOD: + case DNS_LOOKUP_GOOD_WITH_BAD: + ret = 0; + break; + case DNS_LOOKUP_GOT_NOT_FOUND: + ret = -ENOENT; + goto error; + case DNS_LOOKUP_BAD: + ret = -EREMOTEIO; + goto error; + case DNS_LOOKUP_GOT_LOCAL_FAILURE: + case DNS_LOOKUP_GOT_TEMP_FAILURE: + case DNS_LOOKUP_GOT_NS_FAILURE: + ret = -EDESTADDRREQ; + goto error; + } + } _leave(" = %p [cell]", cell); return cell; @@ -325,7 +375,7 @@ struct afs_cell *afs_lookup_cell(struct afs_net *net, cell_already_exists: _debug("cell exists"); cell = cursor; - if (excl) { + if (reason == AFS_LOOKUP_CELL_PRELOAD) { ret = -EEXIST; } else { afs_use_cell(cursor, trace); @@ -384,7 +434,8 @@ int afs_cell_init(struct afs_net *net, const char *rootcell) return -EINVAL; /* allocate a cell record for the root/workstation cell */ - new_root = afs_lookup_cell(net, rootcell, len, vllist, false, + new_root = afs_lookup_cell(net, rootcell, len, vllist, + AFS_LOOKUP_CELL_ROOTCELL, afs_cell_trace_use_lookup_ws); if (IS_ERR(new_root)) { _leave(" = %ld", PTR_ERR(new_root)); @@ -777,6 +828,7 @@ static bool afs_manage_cell(struct afs_cell *cell) switch (cell->state) { case AFS_CELL_SETTING_UP: goto set_up_cell; + case AFS_CELL_UNLOOKED: case AFS_CELL_ACTIVE: goto cell_is_active; case AFS_CELL_REMOVING: @@ -797,7 +849,7 @@ static bool afs_manage_cell(struct afs_cell *cell) goto remove_cell; } - afs_set_cell_state(cell, AFS_CELL_ACTIVE); + afs_set_cell_state(cell, AFS_CELL_UNLOOKED); cell_is_active: if (afs_has_cell_expired(cell, &next_manage)) @@ -807,6 +859,8 @@ static bool afs_manage_cell(struct afs_cell *cell) ret = afs_update_cell(cell); if (ret < 0) cell->error = ret; + if (cell->state == AFS_CELL_UNLOOKED) + afs_set_cell_state(cell, AFS_CELL_ACTIVE); } if (next_manage < TIME64_MAX && cell->net->live) { diff --git a/fs/afs/dynroot.c b/fs/afs/dynroot.c index 8c6130789fde3a..dc9d29e3739e71 100644 --- a/fs/afs/dynroot.c +++ b/fs/afs/dynroot.c @@ -108,7 +108,8 @@ static struct dentry *afs_dynroot_lookup_cell(struct inode *dir, struct dentry * dotted = true; } - cell = afs_lookup_cell(net, name, len, NULL, false, + cell = afs_lookup_cell(net, name, len, NULL, + AFS_LOOKUP_CELL_DYNROOT, afs_cell_trace_use_lookup_dynroot); if (IS_ERR(cell)) { ret = PTR_ERR(cell); diff --git a/fs/afs/internal.h b/fs/afs/internal.h index a45ae5c2ef8a85..b92f96f567671a 100644 --- a/fs/afs/internal.h +++ b/fs/afs/internal.h @@ -343,6 +343,7 @@ extern const char afs_init_sysname[]; enum afs_cell_state { AFS_CELL_SETTING_UP, + AFS_CELL_UNLOOKED, AFS_CELL_ACTIVE, AFS_CELL_REMOVING, AFS_CELL_DEAD, @@ -1049,9 +1050,18 @@ static inline bool afs_cb_is_broken(unsigned int cb_break, extern int afs_cell_init(struct afs_net *, const char *); extern struct afs_cell *afs_find_cell(struct afs_net *, const char *, unsigned, enum afs_cell_trace); +enum afs_lookup_cell_for { + AFS_LOOKUP_CELL_DYNROOT, + AFS_LOOKUP_CELL_MOUNTPOINT, + AFS_LOOKUP_CELL_DIRECT_MOUNT, + AFS_LOOKUP_CELL_PRELOAD, + AFS_LOOKUP_CELL_ROOTCELL, + AFS_LOOKUP_CELL_ALIAS_CHECK, +}; struct afs_cell *afs_lookup_cell(struct afs_net *net, const char *name, unsigned int namesz, - const char *vllist, bool excl, + const char *vllist, + enum afs_lookup_cell_for reason, enum afs_cell_trace trace); extern struct afs_cell *afs_use_cell(struct afs_cell *, enum afs_cell_trace); void afs_unuse_cell(struct afs_cell *cell, enum afs_cell_trace reason); diff --git a/fs/afs/mntpt.c b/fs/afs/mntpt.c index 1ad048e6e16457..57c204a3c04e52 100644 --- a/fs/afs/mntpt.c +++ b/fs/afs/mntpt.c @@ -107,7 +107,8 @@ static int afs_mntpt_set_params(struct fs_context *fc, struct dentry *mntpt) if (size > AFS_MAXCELLNAME) return -ENAMETOOLONG; - cell = afs_lookup_cell(ctx->net, p, size, NULL, false, + cell = afs_lookup_cell(ctx->net, p, size, NULL, + AFS_LOOKUP_CELL_MOUNTPOINT, afs_cell_trace_use_lookup_mntpt); if (IS_ERR(cell)) { pr_err("kAFS: unable to lookup cell '%pd'\n", mntpt); diff --git a/fs/afs/proc.c b/fs/afs/proc.c index 40e879c8ca773f..44520549b509a1 100644 --- a/fs/afs/proc.c +++ b/fs/afs/proc.c @@ -122,7 +122,8 @@ static int afs_proc_cells_write(struct file *file, char *buf, size_t size) if (strcmp(buf, "add") == 0) { struct afs_cell *cell; - cell = afs_lookup_cell(net, name, strlen(name), args, true, + cell = afs_lookup_cell(net, name, strlen(name), args, + AFS_LOOKUP_CELL_PRELOAD, afs_cell_trace_use_lookup_add); if (IS_ERR(cell)) { ret = PTR_ERR(cell); diff --git a/fs/afs/super.c b/fs/afs/super.c index da407f2d6f0d1d..d672b7ab57ae2c 100644 --- a/fs/afs/super.c +++ b/fs/afs/super.c @@ -290,7 +290,7 @@ static int afs_parse_source(struct fs_context *fc, struct fs_parameter *param) /* lookup the cell record */ if (cellname) { cell = afs_lookup_cell(ctx->net, cellname, cellnamesz, - NULL, false, + NULL, AFS_LOOKUP_CELL_DIRECT_MOUNT, afs_cell_trace_use_lookup_mount); if (IS_ERR(cell)) { pr_err("kAFS: unable to lookup cell '%*.*s'\n", diff --git a/fs/afs/vl_alias.c b/fs/afs/vl_alias.c index 709b4cdb723eea..fc9676abd2527a 100644 --- a/fs/afs/vl_alias.c +++ b/fs/afs/vl_alias.c @@ -269,7 +269,8 @@ static int yfs_check_canonical_cell_name(struct afs_cell *cell, struct key *key) if (!name_len || name_len > AFS_MAXCELLNAME) master = ERR_PTR(-EOPNOTSUPP); else - master = afs_lookup_cell(cell->net, cell_name, name_len, NULL, false, + master = afs_lookup_cell(cell->net, cell_name, name_len, NULL, + AFS_LOOKUP_CELL_ALIAS_CHECK, afs_cell_trace_use_lookup_canonical); kfree(cell_name); if (IS_ERR(master)) diff --git a/fs/bfs/inode.c b/fs/bfs/inode.c index 1d41ce477df58b..984b365df04608 100644 --- a/fs/bfs/inode.c +++ b/fs/bfs/inode.c @@ -61,7 +61,19 @@ struct inode *bfs_iget(struct super_block *sb, unsigned long ino) off = (ino - BFS_ROOT_INO) % BFS_INODES_PER_BLOCK; di = (struct bfs_inode *)bh->b_data + off; - inode->i_mode = 0x0000FFFF & le32_to_cpu(di->i_mode); + /* + * https://martin.hinner.info/fs/bfs/bfs-structure.html explains that + * BFS in SCO UnixWare environment used only lower 9 bits of di->i_mode + * value. This means that, although bfs_write_inode() saves whole + * inode->i_mode bits (which include S_IFMT bits and S_IS{UID,GID,VTX} + * bits), middle 7 bits of di->i_mode value can be garbage when these + * bits were not saved by bfs_write_inode(). + * Since we can't tell whether middle 7 bits are garbage, use only + * lower 12 bits (i.e. tolerate S_IS{UID,GID,VTX} bits possibly being + * garbage) and reconstruct S_IFMT bits for Linux environment from + * di->i_vtype value. + */ + inode->i_mode = 0x00000FFF & le32_to_cpu(di->i_mode); if (le32_to_cpu(di->i_vtype) == BFS_VDIR) { inode->i_mode |= S_IFDIR; inode->i_op = &bfs_dir_inops; @@ -71,6 +83,11 @@ struct inode *bfs_iget(struct super_block *sb, unsigned long ino) inode->i_op = &bfs_file_inops; inode->i_fop = &bfs_file_operations; inode->i_mapping->a_ops = &bfs_aops; + } else { + brelse(bh); + printf("Unknown vtype=%u %s:%08lx\n", + le32_to_cpu(di->i_vtype), inode->i_sb->s_id, ino); + goto error; } BFS_I(inode)->i_sblock = le32_to_cpu(di->i_sblock); diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c index a839f960cd4a00..a8b1d79e4af074 100644 --- a/fs/binfmt_misc.c +++ b/fs/binfmt_misc.c @@ -837,8 +837,10 @@ static ssize_t bm_register_write(struct file *file, const char __user *buffer, inode_unlock(d_inode(root)); if (err) { - if (f) + if (f) { + exe_file_allow_write_access(f); filp_close(f, NULL); + } kfree(e); return err; } diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 755ec6dfd51cbf..23273d0e6f2245 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c @@ -2228,6 +2228,14 @@ static noinline_for_stack void write_one_eb(struct extent_buffer *eb, wbc_account_cgroup_owner(wbc, folio, range_len); folio_unlock(folio); } + /* + * If the fs is already in error status, do not submit any writeback + * but immediately finish it. + */ + if (unlikely(BTRFS_FS_ERROR(fs_info))) { + btrfs_bio_end_io(bbio, errno_to_blk_status(BTRFS_FS_ERROR(fs_info))); + return; + } btrfs_submit_bbio(bbio, 0); } diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 7efd1f8a19121f..fa82def46e3952 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -2854,12 +2854,22 @@ static int btrfs_fallocate_update_isize(struct inode *inode, { struct btrfs_trans_handle *trans; struct btrfs_root *root = BTRFS_I(inode)->root; + u64 range_start; + u64 range_end; int ret; int ret2; if (mode & FALLOC_FL_KEEP_SIZE || end <= i_size_read(inode)) return 0; + range_start = round_down(i_size_read(inode), root->fs_info->sectorsize); + range_end = round_up(end, root->fs_info->sectorsize); + + ret = btrfs_inode_set_file_extent_range(BTRFS_I(inode), range_start, + range_end - range_start); + if (ret) + return ret; + trans = btrfs_start_transaction(root, 1); if (IS_ERR(trans)) return PTR_ERR(trans); diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 3b1b3a0553eea0..6282911e536f08 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -177,8 +177,10 @@ static int data_reloc_print_warning_inode(u64 inum, u64 offset, u64 num_bytes, return ret; } ret = paths_from_inode(inum, ipath); - if (ret < 0) + if (ret < 0) { + btrfs_put_root(local_root); goto err; + } /* * We deliberately ignore the bit ipath might have been too small to @@ -6873,7 +6875,6 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir, BTRFS_I(inode)->dir_index = 0ULL; inode_inc_iversion(inode); inode_set_ctime_current(inode); - set_bit(BTRFS_INODE_COPY_EVERYTHING, &BTRFS_I(inode)->runtime_flags); ret = btrfs_add_link(trans, BTRFS_I(dir), BTRFS_I(inode), &fname.disk_name, 1, index); diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c index 1175b8192cd7de..31ad8580322a6e 100644 --- a/fs/btrfs/qgroup.c +++ b/fs/btrfs/qgroup.c @@ -1539,8 +1539,10 @@ int btrfs_add_qgroup_relation(struct btrfs_trans_handle *trans, u64 src, u64 dst ASSERT(prealloc); /* Check the level of src and dst first */ - if (btrfs_qgroup_level(src) >= btrfs_qgroup_level(dst)) + if (btrfs_qgroup_level(src) >= btrfs_qgroup_level(dst)) { + kfree(prealloc); return -EINVAL; + } mutex_lock(&fs_info->qgroup_ioctl_lock); if (!fs_info->quota_root) { diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c index 651b11884f82b2..ba20d9286a340c 100644 --- a/fs/btrfs/scrub.c +++ b/fs/btrfs/scrub.c @@ -2203,6 +2203,7 @@ static int scrub_raid56_parity_stripe(struct scrub_ctx *sctx, ret = btrfs_map_block(fs_info, BTRFS_MAP_WRITE, full_stripe_start, &length, &bioc, NULL, NULL); if (ret < 0) { + bio_put(bio); btrfs_put_bioc(bioc); btrfs_bio_counter_dec(fs_info); goto out; @@ -2212,6 +2213,7 @@ static int scrub_raid56_parity_stripe(struct scrub_ctx *sctx, btrfs_put_bioc(bioc); if (!rbio) { ret = -ENOMEM; + bio_put(bio); btrfs_bio_counter_dec(fs_info); goto out; } diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index 621e0df097e376..30f3c3b849c143 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c @@ -7122,7 +7122,7 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans, * a power failure unless the log was synced as part of an fsync * against any other unrelated inode. */ - if (inode_only != LOG_INODE_EXISTS) + if (!ctx->logging_new_name && inode_only != LOG_INODE_EXISTS) inode->last_log_commit = inode->last_sub_trans; spin_unlock(&inode->lock); @@ -7910,6 +7910,9 @@ void btrfs_log_new_name(struct btrfs_trans_handle *trans, bool log_pinned = false; int ret; + /* The inode has a new name (ref/extref), so make sure we log it. */ + set_bit(BTRFS_INODE_COPY_EVERYTHING, &inode->runtime_flags); + btrfs_init_log_ctx(&ctx, inode); ctx.logging_new_name = true; diff --git a/fs/btrfs/zoned.c b/fs/btrfs/zoned.c index 0ea0df18a8e43b..d1db7fa1fe583a 100644 --- a/fs/btrfs/zoned.c +++ b/fs/btrfs/zoned.c @@ -1317,6 +1317,7 @@ static int btrfs_load_zone_info(struct btrfs_fs_info *fs_info, int zone_idx, if (!btrfs_dev_is_sequential(device, info->physical)) { up_read(&dev_replace->rwsem); info->alloc_offset = WP_CONVENTIONAL; + info->capacity = device->zone_info->zone_size; return 0; } @@ -1522,6 +1523,8 @@ static int btrfs_load_block_group_raid0(struct btrfs_block_group *bg, u64 last_alloc) { struct btrfs_fs_info *fs_info = bg->fs_info; + u64 stripe_nr = 0, stripe_offset = 0; + u32 stripe_index = 0; if ((map->type & BTRFS_BLOCK_GROUP_DATA) && !fs_info->stripe_root) { btrfs_err(fs_info, "zoned: data %s needs raid-stripe-tree", @@ -1529,28 +1532,26 @@ static int btrfs_load_block_group_raid0(struct btrfs_block_group *bg, return -EINVAL; } + if (last_alloc) { + u32 factor = map->num_stripes; + + stripe_nr = last_alloc >> BTRFS_STRIPE_LEN_SHIFT; + stripe_offset = last_alloc & BTRFS_STRIPE_LEN_MASK; + stripe_nr = div_u64_rem(stripe_nr, factor, &stripe_index); + } + for (int i = 0; i < map->num_stripes; i++) { if (zone_info[i].alloc_offset == WP_MISSING_DEV) continue; if (zone_info[i].alloc_offset == WP_CONVENTIONAL) { - u64 stripe_nr, full_stripe_nr; - u64 stripe_offset; - int stripe_index; - stripe_nr = div64_u64(last_alloc, map->stripe_size); - stripe_offset = stripe_nr * map->stripe_size; - full_stripe_nr = div_u64(stripe_nr, map->num_stripes); - div_u64_rem(stripe_nr, map->num_stripes, &stripe_index); - - zone_info[i].alloc_offset = - full_stripe_nr * map->stripe_size; + zone_info[i].alloc_offset = btrfs_stripe_nr_to_offset(stripe_nr); if (stripe_index > i) - zone_info[i].alloc_offset += map->stripe_size; + zone_info[i].alloc_offset += BTRFS_STRIPE_LEN; else if (stripe_index == i) - zone_info[i].alloc_offset += - (last_alloc - stripe_offset); + zone_info[i].alloc_offset += stripe_offset; } if (test_bit(0, active) != test_bit(i, active)) { @@ -1574,6 +1575,8 @@ static int btrfs_load_block_group_raid10(struct btrfs_block_group *bg, u64 last_alloc) { struct btrfs_fs_info *fs_info = bg->fs_info; + u64 stripe_nr = 0, stripe_offset = 0; + u32 stripe_index = 0; if ((map->type & BTRFS_BLOCK_GROUP_DATA) && !fs_info->stripe_root) { btrfs_err(fs_info, "zoned: data %s needs raid-stripe-tree", @@ -1581,6 +1584,14 @@ static int btrfs_load_block_group_raid10(struct btrfs_block_group *bg, return -EINVAL; } + if (last_alloc) { + u32 factor = map->num_stripes / map->sub_stripes; + + stripe_nr = last_alloc >> BTRFS_STRIPE_LEN_SHIFT; + stripe_offset = last_alloc & BTRFS_STRIPE_LEN_MASK; + stripe_nr = div_u64_rem(stripe_nr, factor, &stripe_index); + } + for (int i = 0; i < map->num_stripes; i++) { if (zone_info[i].alloc_offset == WP_MISSING_DEV) continue; @@ -1594,26 +1605,12 @@ static int btrfs_load_block_group_raid10(struct btrfs_block_group *bg, } if (zone_info[i].alloc_offset == WP_CONVENTIONAL) { - u64 stripe_nr, full_stripe_nr; - u64 stripe_offset; - int stripe_index; - - stripe_nr = div64_u64(last_alloc, map->stripe_size); - stripe_offset = stripe_nr * map->stripe_size; - full_stripe_nr = div_u64(stripe_nr, - map->num_stripes / map->sub_stripes); - div_u64_rem(stripe_nr, - (map->num_stripes / map->sub_stripes), - &stripe_index); - - zone_info[i].alloc_offset = - full_stripe_nr * map->stripe_size; + zone_info[i].alloc_offset = btrfs_stripe_nr_to_offset(stripe_nr); if (stripe_index > (i / map->sub_stripes)) - zone_info[i].alloc_offset += map->stripe_size; + zone_info[i].alloc_offset += BTRFS_STRIPE_LEN; else if (stripe_index == (i / map->sub_stripes)) - zone_info[i].alloc_offset += - (last_alloc - stripe_offset); + zone_info[i].alloc_offset += stripe_offset; } if ((i % map->sub_stripes) == 0) { @@ -1683,8 +1680,6 @@ int btrfs_load_block_group_zone_info(struct btrfs_block_group *cache, bool new) set_bit(BLOCK_GROUP_FLAG_SEQUENTIAL_ZONE, &cache->runtime_flags); if (num_conventional > 0) { - /* Zone capacity is always zone size in emulation */ - cache->zone_capacity = cache->length; ret = calculate_alloc_pointer(cache, &last_alloc, new); if (ret) { btrfs_err(fs_info, @@ -1693,6 +1688,7 @@ int btrfs_load_block_group_zone_info(struct btrfs_block_group *cache, bool new) goto out; } else if (map->num_stripes == num_conventional) { cache->alloc_offset = last_alloc; + cache->zone_capacity = cache->length; set_bit(BLOCK_GROUP_FLAG_ZONE_IS_ACTIVE, &cache->runtime_flags); goto out; } diff --git a/fs/crypto/inline_crypt.c b/fs/crypto/inline_crypt.c index 5dee7c498bc8c5..ed6e926226b51d 100644 --- a/fs/crypto/inline_crypt.c +++ b/fs/crypto/inline_crypt.c @@ -333,8 +333,7 @@ static bool bh_get_inode_and_lblk_num(const struct buffer_head *bh, inode = mapping->host; *inode_ret = inode; - *lblk_num_ret = ((u64)folio->index << (PAGE_SHIFT - inode->i_blkbits)) + - (bh_offset(bh) >> inode->i_blkbits); + *lblk_num_ret = (folio_pos(folio) + bh_offset(bh)) >> inode->i_blkbits; return true; } diff --git a/fs/efivarfs/super.c b/fs/efivarfs/super.c index 1f4d8ce5666700..6de97565d5f787 100644 --- a/fs/efivarfs/super.c +++ b/fs/efivarfs/super.c @@ -533,6 +533,7 @@ static struct file_system_type efivarfs_type = { .init_fs_context = efivarfs_init_fs_context, .kill_sb = efivarfs_kill_sb, .parameters = efivarfs_parameters, + .fs_flags = FS_POWER_FREEZE, }; static __init int efivarfs_init(void) diff --git a/fs/erofs/decompressor_zstd.c b/fs/erofs/decompressor_zstd.c index b4bfe14229f9f6..e38d93bb21048f 100644 --- a/fs/erofs/decompressor_zstd.c +++ b/fs/erofs/decompressor_zstd.c @@ -172,7 +172,6 @@ static int z_erofs_zstd_decompress(struct z_erofs_decompress_req *rq, dctx.bounce = strm->bounce; do { - dctx.avail_out = out_buf.size - out_buf.pos; dctx.inbuf_sz = in_buf.size; dctx.inbuf_pos = in_buf.pos; err = z_erofs_stream_switch_bufs(&dctx, &out_buf.dst, @@ -188,14 +187,18 @@ static int z_erofs_zstd_decompress(struct z_erofs_decompress_req *rq, in_buf.pos = dctx.inbuf_pos; zerr = zstd_decompress_stream(stream, &out_buf, &in_buf); - if (zstd_is_error(zerr) || (!zerr && rq->outputsize)) { + dctx.avail_out = out_buf.size - out_buf.pos; + if (zstd_is_error(zerr) || + ((rq->outputsize + dctx.avail_out) && (!zerr || (zerr > 0 && + !(rq->inputsize + in_buf.size - in_buf.pos))))) { erofs_err(sb, "failed to decompress in[%u] out[%u]: %s", rq->inputsize, rq->outputsize, - zerr ? zstd_get_error_name(zerr) : "unexpected end of stream"); + zstd_is_error(zerr) ? zstd_get_error_name(zerr) : + "unexpected end of stream"); err = -EFSCORRUPTED; break; } - } while (rq->outputsize || out_buf.pos < out_buf.size); + } while (rq->outputsize + dctx.avail_out); if (dctx.kout) kunmap_local(dctx.kout); diff --git a/fs/exfat/super.c b/fs/exfat/super.c index 7f9592856bf788..74d451f732c732 100644 --- a/fs/exfat/super.c +++ b/fs/exfat/super.c @@ -433,7 +433,10 @@ static int exfat_read_boot_sector(struct super_block *sb) struct exfat_sb_info *sbi = EXFAT_SB(sb); /* set block size to read super block */ - sb_min_blocksize(sb, 512); + if (!sb_min_blocksize(sb, 512)) { + exfat_err(sb, "unable to set blocksize"); + return -EINVAL; + } /* read boot sector */ sbi->boot_bh = sb_bread(sb, 0); diff --git a/fs/fat/inode.c b/fs/fat/inode.c index 9648ed09781683..9cfe20a3daaf68 100644 --- a/fs/fat/inode.c +++ b/fs/fat/inode.c @@ -1595,8 +1595,12 @@ int fat_fill_super(struct super_block *sb, struct fs_context *fc, setup(sb); /* flavour-specific stuff that needs options */ + error = -EINVAL; + if (!sb_min_blocksize(sb, 512)) { + fat_msg(sb, KERN_ERR, "unable to set blocksize"); + goto out_fail; + } error = -EIO; - sb_min_blocksize(sb, 512); bh = sb_bread(sb, 0); if (bh == NULL) { fat_msg(sb, KERN_ERR, "unable to read boot sector"); diff --git a/fs/fuse/virtio_fs.c b/fs/fuse/virtio_fs.c index 6bc7c97b017db5..b2f6486fe1d565 100644 --- a/fs/fuse/virtio_fs.c +++ b/fs/fuse/virtio_fs.c @@ -373,7 +373,7 @@ static int virtio_fs_add_queues_sysfs(struct virtio_fs *fs) sprintf(buff, "%d", i); fsvq->kobj = kobject_create_and_add(buff, fs->mqs_kobj); - if (!fs->mqs_kobj) { + if (!fsvq->kobj) { ret = -ENOMEM; goto out_del; } diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c index 1e1acf5775ab5f..86455eebbf6cfa 100644 --- a/fs/hostfs/hostfs_kern.c +++ b/fs/hostfs/hostfs_kern.c @@ -979,7 +979,7 @@ static int hostfs_parse_param(struct fs_context *fc, struct fs_parameter *param) { struct hostfs_fs_info *fsi = fc->s_fs_info; struct fs_parse_result result; - char *host_root; + char *host_root, *tmp_root; int opt; opt = fs_parse(fc, hostfs_param_specs, param, &result); @@ -990,11 +990,13 @@ static int hostfs_parse_param(struct fs_context *fc, struct fs_parameter *param) case Opt_hostfs: host_root = param->string; if (!*host_root) - host_root = ""; - fsi->host_root_path = - kasprintf(GFP_KERNEL, "%s/%s", root_ino, host_root); - if (fsi->host_root_path == NULL) + break; + tmp_root = kasprintf(GFP_KERNEL, "%s%s", + fsi->host_root_path, host_root); + if (!tmp_root) return -ENOMEM; + kfree(fsi->host_root_path); + fsi->host_root_path = tmp_root; break; } @@ -1004,17 +1006,17 @@ static int hostfs_parse_param(struct fs_context *fc, struct fs_parameter *param) static int hostfs_parse_monolithic(struct fs_context *fc, void *data) { struct hostfs_fs_info *fsi = fc->s_fs_info; - char *host_root = (char *)data; + char *tmp_root, *host_root = (char *)data; /* NULL is printed as '(null)' by printf(): avoid that. */ if (host_root == NULL) - host_root = ""; + return 0; - fsi->host_root_path = - kasprintf(GFP_KERNEL, "%s/%s", root_ino, host_root); - if (fsi->host_root_path == NULL) + tmp_root = kasprintf(GFP_KERNEL, "%s%s", fsi->host_root_path, host_root); + if (!tmp_root) return -ENOMEM; - + kfree(fsi->host_root_path); + fsi->host_root_path = tmp_root; return 0; } @@ -1049,6 +1051,11 @@ static int hostfs_init_fs_context(struct fs_context *fc) if (!fsi) return -ENOMEM; + fsi->host_root_path = kasprintf(GFP_KERNEL, "%s/", root_ino); + if (!fsi->host_root_path) { + kfree(fsi); + return -ENOMEM; + } fc->s_fs_info = fsi; fc->ops = &hostfs_context_ops; return 0; diff --git a/fs/inode.c b/fs/inode.c index ec9339024ac36e..cff1d3af0d5772 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -1967,6 +1967,18 @@ void iput(struct inode *inode) } EXPORT_SYMBOL(iput); +/** + * iput_not_last - put an inode assuming this is not the last reference + * @inode: inode to put + */ +void iput_not_last(struct inode *inode) +{ + VFS_BUG_ON_INODE(atomic_read(&inode->i_count) < 2, inode); + + WARN_ON(atomic_sub_return(1, &inode->i_count) == 0); +} +EXPORT_SYMBOL(iput_not_last); + #ifdef CONFIG_BLOCK /** * bmap - find a block number in a file diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c index 6f0e6b19383c87..ad3143d4066bf6 100644 --- a/fs/isofs/inode.c +++ b/fs/isofs/inode.c @@ -610,6 +610,11 @@ static int isofs_fill_super(struct super_block *s, struct fs_context *fc) goto out_freesbi; } opt->blocksize = sb_min_blocksize(s, opt->blocksize); + if (!opt->blocksize) { + printk(KERN_ERR + "ISOFS: unable to set blocksize\n"); + goto out_freesbi; + } sbi->s_high_sierra = 0; /* default is iso9660 */ sbi->s_session = opt->session; diff --git a/fs/namespace.c b/fs/namespace.c index d82910f33dc483..2bad25709b2c03 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -132,16 +132,6 @@ EXPORT_SYMBOL_GPL(fs_kobj); */ __cacheline_aligned_in_smp DEFINE_SEQLOCK(mount_lock); -static inline struct mnt_namespace *node_to_mnt_ns(const struct rb_node *node) -{ - struct ns_common *ns; - - if (!node) - return NULL; - ns = rb_entry(node, struct ns_common, ns_tree_node); - return container_of(ns, struct mnt_namespace, ns); -} - static void mnt_ns_release(struct mnt_namespace *ns) { /* keep alive for {list,stat}mount() */ @@ -151,7 +141,8 @@ static void mnt_ns_release(struct mnt_namespace *ns) kfree(ns); } } -DEFINE_FREE(mnt_ns_release, struct mnt_namespace *, if (_T) mnt_ns_release(_T)) +DEFINE_FREE(mnt_ns_release, struct mnt_namespace *, + if (!IS_ERR(_T)) mnt_ns_release(_T)) static void mnt_ns_release_rcu(struct rcu_head *rcu) { @@ -5454,11 +5445,11 @@ static int statmount_string(struct kstatmount *s, u64 flag) ret = statmount_sb_source(s, seq); break; case STATMOUNT_MNT_UIDMAP: - sm->mnt_uidmap = start; + offp = &sm->mnt_uidmap; ret = statmount_mnt_uidmap(s, seq); break; case STATMOUNT_MNT_GIDMAP: - sm->mnt_gidmap = start; + offp = &sm->mnt_gidmap; ret = statmount_mnt_gidmap(s, seq); break; default: @@ -5736,7 +5727,7 @@ static int copy_mnt_id_req(const struct mnt_id_req __user *req, ret = copy_struct_from_user(kreq, sizeof(*kreq), req, usize); if (ret) return ret; - if (kreq->spare != 0) + if (kreq->mnt_ns_fd != 0 && kreq->mnt_ns_id) return -EINVAL; /* The first valid unique mount id is MNT_UNIQUE_ID_OFFSET + 1. */ if (kreq->mnt_id <= MNT_UNIQUE_ID_OFFSET) @@ -5753,16 +5744,12 @@ static struct mnt_namespace *grab_requested_mnt_ns(const struct mnt_id_req *kreq { struct mnt_namespace *mnt_ns; - if (kreq->mnt_ns_id && kreq->spare) - return ERR_PTR(-EINVAL); - - if (kreq->mnt_ns_id) - return lookup_mnt_ns(kreq->mnt_ns_id); - - if (kreq->spare) { + if (kreq->mnt_ns_id) { + mnt_ns = lookup_mnt_ns(kreq->mnt_ns_id); + } else if (kreq->mnt_ns_fd) { struct ns_common *ns; - CLASS(fd, f)(kreq->spare); + CLASS(fd, f)(kreq->mnt_ns_fd); if (fd_empty(f)) return ERR_PTR(-EBADF); @@ -5777,6 +5764,8 @@ static struct mnt_namespace *grab_requested_mnt_ns(const struct mnt_id_req *kreq } else { mnt_ns = current->nsproxy->mnt_ns; } + if (!mnt_ns) + return ERR_PTR(-ENOENT); refcount_inc(&mnt_ns->passive); return mnt_ns; @@ -5801,8 +5790,8 @@ SYSCALL_DEFINE4(statmount, const struct mnt_id_req __user *, req, return ret; ns = grab_requested_mnt_ns(&kreq); - if (!ns) - return -ENOENT; + if (IS_ERR(ns)) + return PTR_ERR(ns); if (kreq.mnt_ns_id && (ns != current->nsproxy->mnt_ns) && !ns_capable_noaudit(ns->user_ns, CAP_SYS_ADMIN)) @@ -5912,8 +5901,8 @@ static void __free_klistmount_free(const struct klistmount *kls) static inline int prepare_klistmount(struct klistmount *kls, struct mnt_id_req *kreq, size_t nr_mnt_ids) { - u64 last_mnt_id = kreq->param; + struct mnt_namespace *ns; /* The first valid unique mount id is MNT_UNIQUE_ID_OFFSET + 1. */ if (last_mnt_id != 0 && last_mnt_id <= MNT_UNIQUE_ID_OFFSET) @@ -5927,9 +5916,10 @@ static inline int prepare_klistmount(struct klistmount *kls, struct mnt_id_req * if (!kls->kmnt_ids) return -ENOMEM; - kls->ns = grab_requested_mnt_ns(kreq); - if (!kls->ns) - return -ENOENT; + ns = grab_requested_mnt_ns(kreq); + if (IS_ERR(ns)) + return PTR_ERR(ns); + kls->ns = ns; kls->mnt_parent_id = kreq->mnt_id; return 0; diff --git a/fs/nfs/client.c b/fs/nfs/client.c index 4e3dcc157a83c8..54699299d5b168 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c @@ -338,6 +338,14 @@ static struct nfs_client *nfs_match_client(const struct nfs_client_initdata *dat /* Match the xprt security policy */ if (clp->cl_xprtsec.policy != data->xprtsec.policy) continue; + if (clp->cl_xprtsec.policy == RPC_XPRTSEC_TLS_X509) { + if (clp->cl_xprtsec.cert_serial != + data->xprtsec.cert_serial) + continue; + if (clp->cl_xprtsec.privkey_serial != + data->xprtsec.privkey_serial) + continue; + } refcount_inc(&clp->cl_count); return clp; diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 46d9c65d50f83f..ea9f6ca8f30fa2 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -2268,11 +2268,12 @@ int nfs_atomic_open_v23(struct inode *dir, struct dentry *dentry, return -ENAMETOOLONG; if (open_flags & O_CREAT) { - file->f_mode |= FMODE_CREATED; error = nfs_do_create(dir, dentry, mode, open_flags); - if (error) + if (!error) { + file->f_mode |= FMODE_CREATED; + return finish_open(file, dentry, NULL); + } else if (error != -EEXIST || open_flags & O_EXCL) return error; - return finish_open(file, dentry, NULL); } if (d_in_lookup(dentry)) { /* The only flags nfs_lookup considers are diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 18b57c7c2f97b4..13ad70fc00d84b 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -718,6 +718,8 @@ nfs_setattr(struct mnt_idmap *idmap, struct dentry *dentry, struct nfs_fattr *fattr; loff_t oldsize = i_size_read(inode); int error = 0; + kuid_t task_uid = current_fsuid(); + kuid_t owner_uid = inode->i_uid; nfs_inc_stats(inode, NFSIOS_VFSSETATTR); @@ -739,9 +741,11 @@ nfs_setattr(struct mnt_idmap *idmap, struct dentry *dentry, if (nfs_have_delegated_mtime(inode) && attr->ia_valid & ATTR_MTIME) { spin_lock(&inode->i_lock); if (attr->ia_valid & ATTR_MTIME_SET) { - nfs_set_timestamps_to_ts(inode, attr); - attr->ia_valid &= ~(ATTR_MTIME|ATTR_MTIME_SET| + if (uid_eq(task_uid, owner_uid)) { + nfs_set_timestamps_to_ts(inode, attr); + attr->ia_valid &= ~(ATTR_MTIME|ATTR_MTIME_SET| ATTR_ATIME|ATTR_ATIME_SET); + } } else { nfs_update_timestamps(inode, attr->ia_valid); attr->ia_valid &= ~(ATTR_MTIME|ATTR_ATIME); @@ -751,10 +755,12 @@ nfs_setattr(struct mnt_idmap *idmap, struct dentry *dentry, attr->ia_valid & ATTR_ATIME && !(attr->ia_valid & ATTR_MTIME)) { if (attr->ia_valid & ATTR_ATIME_SET) { - spin_lock(&inode->i_lock); - nfs_set_timestamps_to_ts(inode, attr); - spin_unlock(&inode->i_lock); - attr->ia_valid &= ~(ATTR_ATIME|ATTR_ATIME_SET); + if (uid_eq(task_uid, owner_uid)) { + spin_lock(&inode->i_lock); + nfs_set_timestamps_to_ts(inode, attr); + spin_unlock(&inode->i_lock); + attr->ia_valid &= ~(ATTR_ATIME|ATTR_ATIME_SET); + } } else { nfs_update_delegated_atime(inode); attr->ia_valid &= ~ATTR_ATIME; diff --git a/fs/nfs/localio.c b/fs/nfs/localio.c index 2c0455e91571b8..656976b4f42ce6 100644 --- a/fs/nfs/localio.c +++ b/fs/nfs/localio.c @@ -42,10 +42,9 @@ struct nfs_local_kiocb { /* Begin mostly DIO-specific members */ size_t end_len; short int end_iter_index; - short int n_iters; + atomic_t n_iters; bool iter_is_dio_aligned[NFSLOCAL_MAX_IOS]; - loff_t offset[NFSLOCAL_MAX_IOS] ____cacheline_aligned; - struct iov_iter iters[NFSLOCAL_MAX_IOS]; + struct iov_iter iters[NFSLOCAL_MAX_IOS] ____cacheline_aligned; /* End mostly DIO-specific members */ }; @@ -314,7 +313,9 @@ nfs_local_iocb_alloc(struct nfs_pgio_header *hdr, init_sync_kiocb(&iocb->kiocb, file); iocb->hdr = hdr; + iocb->kiocb.ki_pos = hdr->args.offset; iocb->kiocb.ki_flags &= ~IOCB_APPEND; + iocb->kiocb.ki_complete = NULL; iocb->aio_complete_work = NULL; iocb->end_iter_index = -1; @@ -388,13 +389,24 @@ static bool nfs_iov_iter_aligned_bvec(const struct iov_iter *i, return true; } +static void +nfs_local_iter_setup(struct iov_iter *iter, int rw, struct bio_vec *bvec, + unsigned int nvecs, unsigned long total, + size_t start, size_t len) +{ + iov_iter_bvec(iter, rw, bvec, nvecs, total); + if (start) + iov_iter_advance(iter, start); + iov_iter_truncate(iter, len); +} + /* * Setup as many as 3 iov_iter based on extents described by @local_dio. * Returns the number of iov_iter that were setup. */ static int nfs_local_iters_setup_dio(struct nfs_local_kiocb *iocb, int rw, - unsigned int nvecs, size_t len, + unsigned int nvecs, unsigned long total, struct nfs_local_dio *local_dio) { int n_iters = 0; @@ -402,39 +414,17 @@ nfs_local_iters_setup_dio(struct nfs_local_kiocb *iocb, int rw, /* Setup misaligned start? */ if (local_dio->start_len) { - iov_iter_bvec(&iters[n_iters], rw, iocb->bvec, nvecs, len); - iters[n_iters].count = local_dio->start_len; - iocb->offset[n_iters] = iocb->hdr->args.offset; - iocb->iter_is_dio_aligned[n_iters] = false; + nfs_local_iter_setup(&iters[n_iters], rw, iocb->bvec, + nvecs, total, 0, local_dio->start_len); ++n_iters; } - /* Setup misaligned end? - * If so, the end is purposely setup to be issued using buffered IO - * before the middle (which will use DIO, if DIO-aligned, with AIO). - * This creates problems if/when the end results in a partial write. - * So must save index and length of end to handle this corner case. - */ - if (local_dio->end_len) { - iov_iter_bvec(&iters[n_iters], rw, iocb->bvec, nvecs, len); - iocb->offset[n_iters] = local_dio->end_offset; - iov_iter_advance(&iters[n_iters], - local_dio->start_len + local_dio->middle_len); - iocb->iter_is_dio_aligned[n_iters] = false; - /* Save index and length of end */ - iocb->end_iter_index = n_iters; - iocb->end_len = local_dio->end_len; - ++n_iters; - } - - /* Setup DIO-aligned middle to be issued last, to allow for - * DIO with AIO completion (see nfs_local_call_{read,write}). + /* + * Setup DIO-aligned middle, if there is no misaligned end (below) + * then AIO completion is used, see nfs_local_call_{read,write} */ - iov_iter_bvec(&iters[n_iters], rw, iocb->bvec, nvecs, len); - if (local_dio->start_len) - iov_iter_advance(&iters[n_iters], local_dio->start_len); - iters[n_iters].count -= local_dio->end_len; - iocb->offset[n_iters] = local_dio->middle_offset; + nfs_local_iter_setup(&iters[n_iters], rw, iocb->bvec, nvecs, + total, local_dio->start_len, local_dio->middle_len); iocb->iter_is_dio_aligned[n_iters] = nfs_iov_iter_aligned_bvec(&iters[n_iters], @@ -442,12 +432,22 @@ nfs_local_iters_setup_dio(struct nfs_local_kiocb *iocb, int rw, if (unlikely(!iocb->iter_is_dio_aligned[n_iters])) { trace_nfs_local_dio_misaligned(iocb->hdr->inode, - iocb->hdr->args.offset, len, local_dio); + local_dio->start_len, local_dio->middle_len, local_dio); return 0; /* no DIO-aligned IO possible */ } + iocb->end_iter_index = n_iters; ++n_iters; - iocb->n_iters = n_iters; + /* Setup misaligned end? */ + if (local_dio->end_len) { + nfs_local_iter_setup(&iters[n_iters], rw, iocb->bvec, + nvecs, total, local_dio->start_len + + local_dio->middle_len, local_dio->end_len); + iocb->end_iter_index = n_iters; + ++n_iters; + } + + atomic_set(&iocb->n_iters, n_iters); return n_iters; } @@ -473,18 +473,26 @@ nfs_local_iters_init(struct nfs_local_kiocb *iocb, int rw) } len = hdr->args.count - total; + /* + * For each iocb, iocb->n_iters is always at least 1 and we always + * end io after first nfs_local_pgio_done call unless misaligned DIO. + */ + atomic_set(&iocb->n_iters, 1); + if (test_bit(NFS_IOHDR_ODIRECT, &hdr->flags)) { struct nfs_local_dio local_dio; if (nfs_is_local_dio_possible(iocb, rw, len, &local_dio) && - nfs_local_iters_setup_dio(iocb, rw, v, len, &local_dio) != 0) + nfs_local_iters_setup_dio(iocb, rw, v, len, &local_dio) != 0) { + /* Ensure DIO WRITE's IO on stable storage upon completion */ + if (rw == ITER_SOURCE) + iocb->kiocb.ki_flags |= IOCB_DSYNC|IOCB_SYNC; return; /* is DIO-aligned */ + } } /* Use buffered IO */ - iocb->offset[0] = hdr->args.offset; iov_iter_bvec(&iocb->iters[0], rw, iocb->bvec, v, len); - iocb->n_iters = 1; } static void @@ -504,9 +512,11 @@ nfs_local_pgio_init(struct nfs_pgio_header *hdr, hdr->task.tk_start = ktime_get(); } -static void -nfs_local_pgio_done(struct nfs_pgio_header *hdr, long status) +static bool +nfs_local_pgio_done(struct nfs_local_kiocb *iocb, long status, bool force) { + struct nfs_pgio_header *hdr = iocb->hdr; + /* Must handle partial completions */ if (status >= 0) { hdr->res.count += status; @@ -517,6 +527,12 @@ nfs_local_pgio_done(struct nfs_pgio_header *hdr, long status) hdr->res.op_status = nfs_localio_errno_to_nfs4_stat(status); hdr->task.tk_status = status; } + + if (force) + return true; + + BUG_ON(atomic_read(&iocb->n_iters) <= 0); + return atomic_dec_and_test(&iocb->n_iters); } static void @@ -547,11 +563,11 @@ static inline void nfs_local_pgio_aio_complete(struct nfs_local_kiocb *iocb) queue_work(nfsiod_workqueue, &iocb->work); } -static void -nfs_local_read_done(struct nfs_local_kiocb *iocb, long status) +static void nfs_local_read_done(struct nfs_local_kiocb *iocb) { struct nfs_pgio_header *hdr = iocb->hdr; struct file *filp = iocb->kiocb.ki_filp; + long status = hdr->task.tk_status; if ((iocb->kiocb.ki_flags & IOCB_DIRECT) && status == -EINVAL) { /* Underlying FS will return -EINVAL if misaligned DIO is attempted. */ @@ -564,20 +580,27 @@ nfs_local_read_done(struct nfs_local_kiocb *iocb, long status) */ hdr->res.replen = 0; - if (hdr->res.count != hdr->args.count || - hdr->args.offset + hdr->res.count >= i_size_read(file_inode(filp))) + /* nfs_readpage_result() handles short read */ + + if (hdr->args.offset + hdr->res.count >= i_size_read(file_inode(filp))) hdr->res.eof = true; dprintk("%s: read %ld bytes eof %d.\n", __func__, status > 0 ? status : 0, hdr->res.eof); } +static inline void nfs_local_read_iocb_done(struct nfs_local_kiocb *iocb) +{ + nfs_local_read_done(iocb); + nfs_local_pgio_release(iocb); +} + static void nfs_local_read_aio_complete_work(struct work_struct *work) { struct nfs_local_kiocb *iocb = container_of(work, struct nfs_local_kiocb, work); - nfs_local_pgio_release(iocb); + nfs_local_read_iocb_done(iocb); } static void nfs_local_read_aio_complete(struct kiocb *kiocb, long ret) @@ -585,8 +608,10 @@ static void nfs_local_read_aio_complete(struct kiocb *kiocb, long ret) struct nfs_local_kiocb *iocb = container_of(kiocb, struct nfs_local_kiocb, kiocb); - nfs_local_pgio_done(iocb->hdr, ret); - nfs_local_read_done(iocb, ret); + /* AIO completion of DIO read should always be last to complete */ + if (unlikely(!nfs_local_pgio_done(iocb, ret, false))) + return; + nfs_local_pgio_aio_complete(iocb); /* Calls nfs_local_read_aio_complete_work */ } @@ -596,32 +621,36 @@ static void nfs_local_call_read(struct work_struct *work) container_of(work, struct nfs_local_kiocb, work); struct file *filp = iocb->kiocb.ki_filp; const struct cred *save_cred; + bool force_done = false; ssize_t status; + int n_iters; save_cred = override_creds(filp->f_cred); - for (int i = 0; i < iocb->n_iters ; i++) { + n_iters = atomic_read(&iocb->n_iters); + for (int i = 0; i < n_iters ; i++) { if (iocb->iter_is_dio_aligned[i]) { iocb->kiocb.ki_flags |= IOCB_DIRECT; - iocb->kiocb.ki_complete = nfs_local_read_aio_complete; - iocb->aio_complete_work = nfs_local_read_aio_complete_work; - } + /* Only use AIO completion if DIO-aligned segment is last */ + if (i == iocb->end_iter_index) { + iocb->kiocb.ki_complete = nfs_local_read_aio_complete; + iocb->aio_complete_work = nfs_local_read_aio_complete_work; + } + } else + iocb->kiocb.ki_flags &= ~IOCB_DIRECT; - iocb->kiocb.ki_pos = iocb->offset[i]; status = filp->f_op->read_iter(&iocb->kiocb, &iocb->iters[i]); if (status != -EIOCBQUEUED) { - nfs_local_pgio_done(iocb->hdr, status); - if (iocb->hdr->task.tk_status) + if (unlikely(status >= 0 && status < iocb->iters[i].count)) + force_done = true; /* Partial read */ + if (nfs_local_pgio_done(iocb, status, force_done)) { + nfs_local_read_iocb_done(iocb); break; + } } } revert_creds(save_cred); - - if (status != -EIOCBQUEUED) { - nfs_local_read_done(iocb, status); - nfs_local_pgio_release(iocb); - } } static int @@ -736,11 +765,10 @@ static void nfs_local_vfs_getattr(struct nfs_local_kiocb *iocb) fattr->du.nfs3.used = stat.blocks << 9; } -static void -nfs_local_write_done(struct nfs_local_kiocb *iocb, long status) +static void nfs_local_write_done(struct nfs_local_kiocb *iocb) { struct nfs_pgio_header *hdr = iocb->hdr; - struct inode *inode = hdr->inode; + long status = hdr->task.tk_status; dprintk("%s: wrote %ld bytes.\n", __func__, status > 0 ? status : 0); @@ -759,10 +787,17 @@ nfs_local_write_done(struct nfs_local_kiocb *iocb, long status) nfs_set_pgio_error(hdr, -ENOSPC, hdr->args.offset); status = -ENOSPC; /* record -ENOSPC in terms of nfs_local_pgio_done */ - nfs_local_pgio_done(hdr, status); + (void) nfs_local_pgio_done(iocb, status, true); } if (hdr->task.tk_status < 0) - nfs_reset_boot_verifier(inode); + nfs_reset_boot_verifier(hdr->inode); +} + +static inline void nfs_local_write_iocb_done(struct nfs_local_kiocb *iocb) +{ + nfs_local_write_done(iocb); + nfs_local_vfs_getattr(iocb); + nfs_local_pgio_release(iocb); } static void nfs_local_write_aio_complete_work(struct work_struct *work) @@ -770,8 +805,7 @@ static void nfs_local_write_aio_complete_work(struct work_struct *work) struct nfs_local_kiocb *iocb = container_of(work, struct nfs_local_kiocb, work); - nfs_local_vfs_getattr(iocb); - nfs_local_pgio_release(iocb); + nfs_local_write_iocb_done(iocb); } static void nfs_local_write_aio_complete(struct kiocb *kiocb, long ret) @@ -779,8 +813,10 @@ static void nfs_local_write_aio_complete(struct kiocb *kiocb, long ret) struct nfs_local_kiocb *iocb = container_of(kiocb, struct nfs_local_kiocb, kiocb); - nfs_local_pgio_done(iocb->hdr, ret); - nfs_local_write_done(iocb, ret); + /* AIO completion of DIO write should always be last to complete */ + if (unlikely(!nfs_local_pgio_done(iocb, ret, false))) + return; + nfs_local_pgio_aio_complete(iocb); /* Calls nfs_local_write_aio_complete_work */ } @@ -791,63 +827,40 @@ static void nfs_local_call_write(struct work_struct *work) struct file *filp = iocb->kiocb.ki_filp; unsigned long old_flags = current->flags; const struct cred *save_cred; + bool force_done = false; ssize_t status; + int n_iters; current->flags |= PF_LOCAL_THROTTLE | PF_MEMALLOC_NOIO; save_cred = override_creds(filp->f_cred); file_start_write(filp); - for (int i = 0; i < iocb->n_iters ; i++) { + n_iters = atomic_read(&iocb->n_iters); + for (int i = 0; i < n_iters ; i++) { if (iocb->iter_is_dio_aligned[i]) { iocb->kiocb.ki_flags |= IOCB_DIRECT; - iocb->kiocb.ki_complete = nfs_local_write_aio_complete; - iocb->aio_complete_work = nfs_local_write_aio_complete_work; - } -retry: - iocb->kiocb.ki_pos = iocb->offset[i]; + /* Only use AIO completion if DIO-aligned segment is last */ + if (i == iocb->end_iter_index) { + iocb->kiocb.ki_complete = nfs_local_write_aio_complete; + iocb->aio_complete_work = nfs_local_write_aio_complete_work; + } + } else + iocb->kiocb.ki_flags &= ~IOCB_DIRECT; + status = filp->f_op->write_iter(&iocb->kiocb, &iocb->iters[i]); if (status != -EIOCBQUEUED) { - if (unlikely(status >= 0 && status < iocb->iters[i].count)) { - /* partial write */ - if (i == iocb->end_iter_index) { - /* Must not account partial end, otherwise, due - * to end being issued before middle: the partial - * write accounting in nfs_local_write_done() - * would incorrectly advance hdr->args.offset - */ - status = 0; - } else { - /* Partial write at start or buffered middle, - * exit early. - */ - nfs_local_pgio_done(iocb->hdr, status); - break; - } - } else if (unlikely(status == -ENOTBLK && - (iocb->kiocb.ki_flags & IOCB_DIRECT))) { - /* VFS will return -ENOTBLK if DIO WRITE fails to - * invalidate the page cache. Retry using buffered IO. - */ - iocb->kiocb.ki_flags &= ~IOCB_DIRECT; - iocb->kiocb.ki_complete = NULL; - iocb->aio_complete_work = NULL; - goto retry; - } - nfs_local_pgio_done(iocb->hdr, status); - if (iocb->hdr->task.tk_status) + if (unlikely(status >= 0 && status < iocb->iters[i].count)) + force_done = true; /* Partial write */ + if (nfs_local_pgio_done(iocb, status, force_done)) { + nfs_local_write_iocb_done(iocb); break; + } } } file_end_write(filp); revert_creds(save_cred); current->flags = old_flags; - - if (status != -EIOCBQUEUED) { - nfs_local_write_done(iocb, status); - nfs_local_vfs_getattr(iocb); - nfs_local_pgio_release(iocb); - } } static int diff --git a/fs/nfs/nfs3client.c b/fs/nfs/nfs3client.c index 0d7310c1ee0c0c..5d97c1d38bb62d 100644 --- a/fs/nfs/nfs3client.c +++ b/fs/nfs/nfs3client.c @@ -2,6 +2,7 @@ #include #include #include +#include #include "internal.h" #include "nfs3_fs.h" #include "netns.h" @@ -98,7 +99,11 @@ struct nfs_client *nfs3_set_ds_client(struct nfs_server *mds_srv, .net = mds_clp->cl_net, .timeparms = &ds_timeout, .cred = mds_srv->cred, - .xprtsec = mds_clp->cl_xprtsec, + .xprtsec = { + .policy = RPC_XPRTSEC_NONE, + .cert_serial = TLS_NO_CERT, + .privkey_serial = TLS_NO_PRIVKEY, + }, .connect_timeout = connect_timeout, .reconnect_timeout = connect_timeout, }; @@ -111,9 +116,14 @@ struct nfs_client *nfs3_set_ds_client(struct nfs_server *mds_srv, cl_init.hostname = buf; switch (ds_proto) { + case XPRT_TRANSPORT_TCP_TLS: + if (mds_clp->cl_xprtsec.policy != RPC_XPRTSEC_NONE) + cl_init.xprtsec = mds_clp->cl_xprtsec; + else + ds_proto = XPRT_TRANSPORT_TCP; + fallthrough; case XPRT_TRANSPORT_RDMA: case XPRT_TRANSPORT_TCP: - case XPRT_TRANSPORT_TCP_TLS: if (mds_clp->cl_nconnect > 1) cl_init.nconnect = mds_clp->cl_nconnect; } diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c index 5998d6bd8a4f4e..3a4baed993c96f 100644 --- a/fs/nfs/nfs4client.c +++ b/fs/nfs/nfs4client.c @@ -11,6 +11,7 @@ #include #include #include +#include #include "internal.h" #include "callback.h" #include "delegation.h" @@ -983,7 +984,11 @@ struct nfs_client *nfs4_set_ds_client(struct nfs_server *mds_srv, .net = mds_clp->cl_net, .timeparms = &ds_timeout, .cred = mds_srv->cred, - .xprtsec = mds_srv->nfs_client->cl_xprtsec, + .xprtsec = { + .policy = RPC_XPRTSEC_NONE, + .cert_serial = TLS_NO_CERT, + .privkey_serial = TLS_NO_PRIVKEY, + }, }; char buf[INET6_ADDRSTRLEN + 1]; @@ -992,9 +997,14 @@ struct nfs_client *nfs4_set_ds_client(struct nfs_server *mds_srv, cl_init.hostname = buf; switch (ds_proto) { + case XPRT_TRANSPORT_TCP_TLS: + if (mds_srv->nfs_client->cl_xprtsec.policy != RPC_XPRTSEC_NONE) + cl_init.xprtsec = mds_srv->nfs_client->cl_xprtsec; + else + ds_proto = XPRT_TRANSPORT_TCP; + fallthrough; case XPRT_TRANSPORT_RDMA: case XPRT_TRANSPORT_TCP: - case XPRT_TRANSPORT_TCP_TLS: if (mds_clp->cl_nconnect > 1) { cl_init.nconnect = mds_clp->cl_nconnect; cl_init.max_connect = NFS_MAX_TRANSPORTS; diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 411776718494bf..93c6ce04332b89 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -4715,16 +4715,19 @@ static int _nfs4_proc_lookupp(struct inode *inode, }; unsigned short task_flags = 0; - if (NFS_SERVER(inode)->flags & NFS_MOUNT_SOFTREVAL) + if (server->flags & NFS_MOUNT_SOFTREVAL) task_flags |= RPC_TASK_TIMEOUT; + if (server->caps & NFS_CAP_MOVEABLE) + task_flags |= RPC_TASK_MOVEABLE; args.bitmask = nfs4_bitmask(server, fattr->label); nfs_fattr_init(fattr); + nfs4_init_sequence(&args.seq_args, &res.seq_res, 0, 0); dprintk("NFS call lookupp ino=0x%lx\n", inode->i_ino); - status = nfs4_call_sync(clnt, server, &msg, &args.seq_args, - &res.seq_res, task_flags); + status = nfs4_do_call_sync(clnt, server, &msg, &args.seq_args, + &res.seq_res, task_flags); dprintk("NFS reply lookupp: %d\n", status); return status; } diff --git a/fs/nfs/pnfs_nfs.c b/fs/nfs/pnfs_nfs.c index 7b32afb2978271..9976cc16b6890b 100644 --- a/fs/nfs/pnfs_nfs.c +++ b/fs/nfs/pnfs_nfs.c @@ -809,8 +809,11 @@ static int _nfs4_pnfs_v3_ds_connect(struct nfs_server *mds_srv, unsigned int retrans) { struct nfs_client *clp = ERR_PTR(-EIO); + struct nfs_client *mds_clp = mds_srv->nfs_client; + enum xprtsec_policies xprtsec_policy = mds_clp->cl_xprtsec.policy; struct nfs4_pnfs_ds_addr *da; unsigned long connect_timeout = timeo * (retrans + 1) * HZ / 10; + int ds_proto; int status = 0; dprintk("--> %s DS %s\n", __func__, ds->ds_remotestr); @@ -834,27 +837,28 @@ static int _nfs4_pnfs_v3_ds_connect(struct nfs_server *mds_srv, .xprtsec = clp->cl_xprtsec, }; - if (da->da_transport != clp->cl_proto && - clp->cl_proto != XPRT_TRANSPORT_TCP_TLS) - continue; - if (da->da_transport == XPRT_TRANSPORT_TCP && - mds_srv->nfs_client->cl_proto == XPRT_TRANSPORT_TCP_TLS) + if (xprt_args.ident == XPRT_TRANSPORT_TCP && + clp->cl_proto == XPRT_TRANSPORT_TCP_TLS) xprt_args.ident = XPRT_TRANSPORT_TCP_TLS; - if (da->da_addr.ss_family != clp->cl_addr.ss_family) + if (xprt_args.ident != clp->cl_proto) + continue; + if (xprt_args.dstaddr->sa_family != + clp->cl_addr.ss_family) continue; /* Add this address as an alias */ rpc_clnt_add_xprt(clp->cl_rpcclient, &xprt_args, - rpc_clnt_test_and_add_xprt, NULL); + rpc_clnt_test_and_add_xprt, NULL); continue; } - if (da->da_transport == XPRT_TRANSPORT_TCP && - mds_srv->nfs_client->cl_proto == XPRT_TRANSPORT_TCP_TLS) - da->da_transport = XPRT_TRANSPORT_TCP_TLS; - clp = get_v3_ds_connect(mds_srv, - &da->da_addr, - da->da_addrlen, da->da_transport, - timeo, retrans); + + ds_proto = da->da_transport; + if (ds_proto == XPRT_TRANSPORT_TCP && + xprtsec_policy != RPC_XPRTSEC_NONE) + ds_proto = XPRT_TRANSPORT_TCP_TLS; + + clp = get_v3_ds_connect(mds_srv, &da->da_addr, da->da_addrlen, + ds_proto, timeo, retrans); if (IS_ERR(clp)) continue; clp->cl_rpcclient->cl_softerr = 0; @@ -880,7 +884,10 @@ static int _nfs4_pnfs_v4_ds_connect(struct nfs_server *mds_srv, u32 minor_version) { struct nfs_client *clp = ERR_PTR(-EIO); + struct nfs_client *mds_clp = mds_srv->nfs_client; + enum xprtsec_policies xprtsec_policy = mds_clp->cl_xprtsec.policy; struct nfs4_pnfs_ds_addr *da; + int ds_proto; int status = 0; dprintk("--> %s DS %s\n", __func__, ds->ds_remotestr); @@ -908,12 +915,8 @@ static int _nfs4_pnfs_v4_ds_connect(struct nfs_server *mds_srv, .data = &xprtdata, }; - if (da->da_transport != clp->cl_proto && - clp->cl_proto != XPRT_TRANSPORT_TCP_TLS) - continue; - if (da->da_transport == XPRT_TRANSPORT_TCP && - mds_srv->nfs_client->cl_proto == - XPRT_TRANSPORT_TCP_TLS) { + if (xprt_args.ident == XPRT_TRANSPORT_TCP && + clp->cl_proto == XPRT_TRANSPORT_TCP_TLS) { struct sockaddr *addr = (struct sockaddr *)&da->da_addr; struct sockaddr_in *sin = @@ -944,7 +947,10 @@ static int _nfs4_pnfs_v4_ds_connect(struct nfs_server *mds_srv, xprt_args.ident = XPRT_TRANSPORT_TCP_TLS; xprt_args.servername = servername; } - if (da->da_addr.ss_family != clp->cl_addr.ss_family) + if (xprt_args.ident != clp->cl_proto) + continue; + if (xprt_args.dstaddr->sa_family != + clp->cl_addr.ss_family) continue; /** @@ -958,15 +964,14 @@ static int _nfs4_pnfs_v4_ds_connect(struct nfs_server *mds_srv, if (xprtdata.cred) put_cred(xprtdata.cred); } else { - if (da->da_transport == XPRT_TRANSPORT_TCP && - mds_srv->nfs_client->cl_proto == - XPRT_TRANSPORT_TCP_TLS) - da->da_transport = XPRT_TRANSPORT_TCP_TLS; - clp = nfs4_set_ds_client(mds_srv, - &da->da_addr, - da->da_addrlen, - da->da_transport, timeo, - retrans, minor_version); + ds_proto = da->da_transport; + if (ds_proto == XPRT_TRANSPORT_TCP && + xprtsec_policy != RPC_XPRTSEC_NONE) + ds_proto = XPRT_TRANSPORT_TCP_TLS; + + clp = nfs4_set_ds_client(mds_srv, &da->da_addr, + da->da_addrlen, ds_proto, + timeo, retrans, minor_version); if (IS_ERR(clp)) continue; @@ -977,7 +982,6 @@ static int _nfs4_pnfs_v4_ds_connect(struct nfs_server *mds_srv, clp = ERR_PTR(-EIO); continue; } - } } diff --git a/fs/nfs/sysfs.c b/fs/nfs/sysfs.c index 545148d42dcc98..ea6e6168092b29 100644 --- a/fs/nfs/sysfs.c +++ b/fs/nfs/sysfs.c @@ -189,6 +189,7 @@ static struct nfs_netns_client *nfs_netns_client_alloc(struct kobject *parent, return p; kobject_put(&p->kobject); + kobject_put(&p->nfs_net_kobj); } return NULL; } diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index c1b54322c41278..8a696050021741 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -1542,7 +1542,8 @@ static void nfs4_free_ol_stateid(struct nfs4_stid *stid) release_all_access(stp); if (stp->st_stateowner) nfs4_put_stateowner(stp->st_stateowner); - WARN_ON(!list_empty(&stid->sc_cp_list)); + if (!list_empty(&stid->sc_cp_list)) + nfs4_free_cpntf_statelist(stid->sc_client->net, stid); kmem_cache_free(stateid_slab, stid); } @@ -3486,7 +3487,20 @@ nfsd4_store_cache_entry(struct nfsd4_compoundres *resp) struct nfsd4_slot *slot = resp->cstate.slot; unsigned int base; - dprintk("--> %s slot %p\n", __func__, slot); + /* + * RFC 5661 Section 2.10.6.1.2: + * + * Any time SEQUENCE ... returns an error ... [t]he replier MUST NOT + * modify the reply cache entry for the slot whenever an error is + * returned from SEQUENCE ... + * + * Because nfsd4_store_cache_entry is called only by + * nfsd4_sequence_done(), nfsd4_store_cache_entry() is called only + * when a SEQUENCE operation was part of the COMPOUND. + * nfs41_check_op_ordering() ensures SEQUENCE is the first op. + */ + if (resp->opcnt == 1 && resp->cstate.status != nfs_ok) + return; slot->sl_flags |= NFSD4_SLOT_INITIALIZED; slot->sl_opcnt = resp->opcnt; @@ -4349,6 +4363,36 @@ static bool replay_matches_cache(struct svc_rqst *rqstp, return true; } +/* + * Note that the response is constructed here both for the case + * of a new SEQUENCE request and for a replayed SEQUENCE request. + * We do not cache SEQUENCE responses as SEQUENCE is idempotent. + */ +static void nfsd4_construct_sequence_response(struct nfsd4_session *session, + struct nfsd4_sequence *seq) +{ + struct nfs4_client *clp = session->se_client; + + seq->maxslots_response = max(session->se_target_maxslots, + seq->maxslots); + seq->target_maxslots = session->se_target_maxslots; + + switch (clp->cl_cb_state) { + case NFSD4_CB_DOWN: + seq->status_flags = SEQ4_STATUS_CB_PATH_DOWN; + break; + case NFSD4_CB_FAULT: + seq->status_flags = SEQ4_STATUS_BACKCHANNEL_FAULT; + break; + default: + seq->status_flags = 0; + } + if (!list_empty(&clp->cl_revoked)) + seq->status_flags |= SEQ4_STATUS_RECALLABLE_STATE_REVOKED; + if (atomic_read(&clp->cl_admin_revoked)) + seq->status_flags |= SEQ4_STATUS_ADMIN_STATE_REVOKED; +} + __be32 nfsd4_sequence(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, union nfsd4_op_u *u) @@ -4398,6 +4442,9 @@ nfsd4_sequence(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, dprintk("%s: slotid %d\n", __func__, seq->slotid); trace_nfsd_slot_seqid_sequence(clp, seq, slot); + + nfsd4_construct_sequence_response(session, seq); + status = check_slot_seqid(seq->seqid, slot->sl_seqid, slot->sl_flags); if (status == nfserr_replay_cache) { status = nfserr_seq_misordered; @@ -4495,23 +4542,6 @@ nfsd4_sequence(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, } out: - seq->maxslots = max(session->se_target_maxslots, seq->maxslots); - seq->target_maxslots = session->se_target_maxslots; - - switch (clp->cl_cb_state) { - case NFSD4_CB_DOWN: - seq->status_flags = SEQ4_STATUS_CB_PATH_DOWN; - break; - case NFSD4_CB_FAULT: - seq->status_flags = SEQ4_STATUS_BACKCHANNEL_FAULT; - break; - default: - seq->status_flags = 0; - } - if (!list_empty(&clp->cl_revoked)) - seq->status_flags |= SEQ4_STATUS_RECALLABLE_STATE_REVOKED; - if (atomic_read(&clp->cl_admin_revoked)) - seq->status_flags |= SEQ4_STATUS_ADMIN_STATE_REVOKED; trace_nfsd_seq4_status(rqstp, seq); out_no_session: if (conn) diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 6040a6145dad85..67bb9c0b9fcb18 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -5073,7 +5073,7 @@ nfsd4_encode_sequence(struct nfsd4_compoundres *resp, __be32 nfserr, return nfserr; /* Note slotid's are numbered from zero: */ /* sr_highest_slotid */ - nfserr = nfsd4_encode_slotid4(xdr, seq->maxslots - 1); + nfserr = nfsd4_encode_slotid4(xdr, seq->maxslots_response - 1); if (nfserr != nfs_ok) return nfserr; /* sr_target_highest_slotid */ @@ -5925,8 +5925,7 @@ nfsd4_encode_operation(struct nfsd4_compoundres *resp, struct nfsd4_op *op) */ warn_on_nonidempotent_op(op); xdr_truncate_encode(xdr, op_status_offset + XDR_UNIT); - } - if (so) { + } else if (so) { int len = xdr->buf->len - (op_status_offset + XDR_UNIT); so->so_replay.rp_status = op->status; diff --git a/fs/nfsd/nfsd.h b/fs/nfsd/nfsd.h index f19320018639eb..b752433c3c2c43 100644 --- a/fs/nfsd/nfsd.h +++ b/fs/nfsd/nfsd.h @@ -458,6 +458,7 @@ enum { #define NFSD4_2_SUPPORTED_ATTRS_WORD2 \ (NFSD4_1_SUPPORTED_ATTRS_WORD2 | \ FATTR4_WORD2_MODE_UMASK | \ + FATTR4_WORD2_CLONE_BLKSIZE | \ NFSD4_2_SECURITY_ATTRS | \ FATTR4_WORD2_XATTR_SUPPORT | \ FATTR4_WORD2_TIME_DELEG_ACCESS | \ diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c index 3eb724ec956606..ed85dd43da18e6 100644 --- a/fs/nfsd/nfsfh.c +++ b/fs/nfsd/nfsfh.c @@ -269,9 +269,6 @@ static __be32 nfsd_set_fh_dentry(struct svc_rqst *rqstp, struct net *net, dentry); } - fhp->fh_dentry = dentry; - fhp->fh_export = exp; - switch (fhp->fh_maxsize) { case NFS4_FHSIZE: if (dentry->d_sb->s_export_op->flags & EXPORT_OP_NOATOMIC_ATTR) @@ -293,6 +290,9 @@ static __be32 nfsd_set_fh_dentry(struct svc_rqst *rqstp, struct net *net, goto out; } + fhp->fh_dentry = dentry; + fhp->fh_export = exp; + return 0; out: exp_put(exp); diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h index ee0570cbdd9e88..1ce8e12ae3354c 100644 --- a/fs/nfsd/xdr4.h +++ b/fs/nfsd/xdr4.h @@ -574,8 +574,9 @@ struct nfsd4_sequence { struct nfs4_sessionid sessionid; /* request/response */ u32 seqid; /* request/response */ u32 slotid; /* request/response */ - u32 maxslots; /* request/response */ + u32 maxslots; /* request */ u32 cachethis; /* request */ + u32 maxslots_response; /* response */ u32 target_maxslots; /* response */ u32 status_flags; /* response */ }; diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c index f15ca6fc400d19..deee16bc9d4eb2 100644 --- a/fs/nilfs2/segment.c +++ b/fs/nilfs2/segment.c @@ -2768,7 +2768,12 @@ static void nilfs_segctor_destroy(struct nilfs_sc_info *sci) if (sci->sc_task) { wake_up(&sci->sc_wait_daemon); - kthread_stop(sci->sc_task); + if (kthread_stop(sci->sc_task)) { + spin_lock(&sci->sc_state_lock); + sci->sc_task = NULL; + timer_shutdown_sync(&sci->sc_timer); + spin_unlock(&sci->sc_state_lock); + } } spin_lock(&sci->sc_state_lock); diff --git a/fs/proc/generic.c b/fs/proc/generic.c index 1762811122735f..501889856461b5 100644 --- a/fs/proc/generic.c +++ b/fs/proc/generic.c @@ -698,6 +698,12 @@ void pde_put(struct proc_dir_entry *pde) } } +static void pde_erase(struct proc_dir_entry *pde, struct proc_dir_entry *parent) +{ + rb_erase(&pde->subdir_node, &parent->subdir); + RB_CLEAR_NODE(&pde->subdir_node); +} + /* * Remove a /proc entry and free it if it's not currently in use. */ @@ -720,7 +726,7 @@ void remove_proc_entry(const char *name, struct proc_dir_entry *parent) WARN(1, "removing permanent /proc entry '%s'", de->name); de = NULL; } else { - rb_erase(&de->subdir_node, &parent->subdir); + pde_erase(de, parent); if (S_ISDIR(de->mode)) parent->nlink--; } @@ -764,7 +770,7 @@ int remove_proc_subtree(const char *name, struct proc_dir_entry *parent) root->parent->name, root->name); return -EINVAL; } - rb_erase(&root->subdir_node, &parent->subdir); + pde_erase(root, parent); de = root; while (1) { @@ -776,7 +782,7 @@ int remove_proc_subtree(const char *name, struct proc_dir_entry *parent) next->parent->name, next->name); return -EINVAL; } - rb_erase(&next->subdir_node, &de->subdir); + pde_erase(next, de); de = next; continue; } diff --git a/fs/smb/client/cached_dir.c b/fs/smb/client/cached_dir.c index b8ac7b7faf611d..e3ea6fe7edb474 100644 --- a/fs/smb/client/cached_dir.c +++ b/fs/smb/client/cached_dir.c @@ -16,6 +16,7 @@ static struct cached_fid *init_cached_dir(const char *path); static void free_cached_dir(struct cached_fid *cfid); static void smb2_close_cached_fid(struct kref *ref); static void cfids_laundromat_worker(struct work_struct *work); +static void close_cached_dir_locked(struct cached_fid *cfid); struct cached_dir_dentry { struct list_head entry; @@ -388,11 +389,11 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon, * lease. Release one here, and the second below. */ cfid->has_lease = false; - kref_put(&cfid->refcount, smb2_close_cached_fid); + close_cached_dir_locked(cfid); } spin_unlock(&cfids->cfid_list_lock); - kref_put(&cfid->refcount, smb2_close_cached_fid); + close_cached_dir(cfid); } else { *ret_cfid = cfid; atomic_inc(&tcon->num_remote_opens); @@ -438,12 +439,14 @@ int open_cached_dir_by_dentry(struct cifs_tcon *tcon, static void smb2_close_cached_fid(struct kref *ref) +__releases(&cfid->cfids->cfid_list_lock) { struct cached_fid *cfid = container_of(ref, struct cached_fid, refcount); int rc; - spin_lock(&cfid->cfids->cfid_list_lock); + lockdep_assert_held(&cfid->cfids->cfid_list_lock); + if (cfid->on_list) { list_del(&cfid->entry); cfid->on_list = false; @@ -478,15 +481,49 @@ void drop_cached_dir_by_name(const unsigned int xid, struct cifs_tcon *tcon, spin_lock(&cfid->cfids->cfid_list_lock); if (cfid->has_lease) { cfid->has_lease = false; - kref_put(&cfid->refcount, smb2_close_cached_fid); + close_cached_dir_locked(cfid); } spin_unlock(&cfid->cfids->cfid_list_lock); close_cached_dir(cfid); } - +/** + * close_cached_dir - drop a reference of a cached dir + * + * The release function will be called with cfid_list_lock held to remove the + * cached dirs from the list before any other thread can take another @cfid + * ref. Must not be called with cfid_list_lock held; use + * close_cached_dir_locked() called instead. + * + * @cfid: cached dir + */ void close_cached_dir(struct cached_fid *cfid) { + lockdep_assert_not_held(&cfid->cfids->cfid_list_lock); + kref_put_lock(&cfid->refcount, smb2_close_cached_fid, &cfid->cfids->cfid_list_lock); +} + +/** + * close_cached_dir_locked - put a reference of a cached dir with + * cfid_list_lock held + * + * Calling close_cached_dir() with cfid_list_lock held has the potential effect + * of causing a deadlock if the invariant of refcount >= 2 is false. + * + * This function is used in paths that hold cfid_list_lock and expect at least + * two references. If that invariant is violated, WARNs and returns without + * dropping a reference; the final put must still go through + * close_cached_dir(). + * + * @cfid: cached dir + */ +static void close_cached_dir_locked(struct cached_fid *cfid) +{ + lockdep_assert_held(&cfid->cfids->cfid_list_lock); + + if (WARN_ON(kref_read(&cfid->refcount) < 2)) + return; + kref_put(&cfid->refcount, smb2_close_cached_fid); } @@ -596,7 +633,7 @@ cached_dir_offload_close(struct work_struct *work) WARN_ON(cfid->on_list); - kref_put(&cfid->refcount, smb2_close_cached_fid); + close_cached_dir(cfid); cifs_put_tcon(tcon, netfs_trace_tcon_ref_put_cached_close); } @@ -762,7 +799,7 @@ static void cfids_laundromat_worker(struct work_struct *work) * Drop the ref-count from above, either the lease-ref (if there * was one) or the extra one acquired. */ - kref_put(&cfid->refcount, smb2_close_cached_fid); + close_cached_dir(cfid); } queue_delayed_work(cfid_put_wq, &cfids->laundromat_work, dir_cache_timeout * HZ); diff --git a/fs/smb/client/cifssmb.c b/fs/smb/client/cifssmb.c index 7da194f29fefc8..dcc50a2bfa4b23 100644 --- a/fs/smb/client/cifssmb.c +++ b/fs/smb/client/cifssmb.c @@ -1363,6 +1363,14 @@ cifs_readv_callback(struct mid_q_entry *mid) if (rdata->result == -ENODATA) { rdata->result = 0; __set_bit(NETFS_SREQ_HIT_EOF, &rdata->subreq.flags); + trace_smb3_read_err(rdata->rreq->debug_id, + rdata->subreq.debug_index, + rdata->xid, + rdata->req->cfile->fid.persistent_fid, + tcon->tid, tcon->ses->Suid, + rdata->subreq.start + rdata->subreq.transferred, + rdata->subreq.len - rdata->subreq.transferred, + rdata->result); } else { size_t trans = rdata->subreq.transferred + rdata->got_bytes; if (trans < rdata->subreq.len && @@ -1374,6 +1382,13 @@ cifs_readv_callback(struct mid_q_entry *mid) } if (rdata->got_bytes) __set_bit(NETFS_SREQ_MADE_PROGRESS, &rdata->subreq.flags); + trace_smb3_read_done(rdata->rreq->debug_id, + rdata->subreq.debug_index, + rdata->xid, + rdata->req->cfile->fid.persistent_fid, + tcon->tid, tcon->ses->Suid, + rdata->subreq.start + rdata->subreq.transferred, + rdata->got_bytes); } trace_smb3_rw_credits(rreq_debug_id, subreq_debug_index, rdata->credits.value, @@ -1445,6 +1460,13 @@ cifs_async_readv(struct cifs_io_subrequest *rdata) rdata->iov[1].iov_base = (char *)smb + 4; rdata->iov[1].iov_len = get_rfc1002_length(smb); + trace_smb3_read_enter(rdata->rreq->debug_id, + rdata->subreq.debug_index, + rdata->xid, + rdata->req->cfile->fid.netfid, + tcon->tid, tcon->ses->Suid, + rdata->subreq.start, rdata->subreq.len); + rc = cifs_call_async(tcon->ses->server, &rqst, cifs_readv_receive, cifs_readv_callback, NULL, rdata, 0, NULL); diff --git a/fs/smb/client/fs_context.c b/fs/smb/client/fs_context.c index e60927b2a7c836..2a0d8b87bd8ea8 100644 --- a/fs/smb/client/fs_context.c +++ b/fs/smb/client/fs_context.c @@ -1435,12 +1435,14 @@ static int smb3_fs_context_parse_param(struct fs_context *fc, cifs_errorf(fc, "Unknown error parsing devname\n"); goto cifs_parse_mount_err; } + kfree(ctx->source); ctx->source = smb3_fs_context_fullpath(ctx, '/'); if (IS_ERR(ctx->source)) { ctx->source = NULL; cifs_errorf(fc, "OOM when copying UNC string\n"); goto cifs_parse_mount_err; } + kfree(fc->source); fc->source = kstrdup(ctx->source, GFP_KERNEL); if (fc->source == NULL) { cifs_errorf(fc, "OOM when copying UNC string\n"); @@ -1468,7 +1470,7 @@ static int smb3_fs_context_parse_param(struct fs_context *fc, break; } - if (strnlen(param->string, CIFS_MAX_USERNAME_LEN) > + if (strnlen(param->string, CIFS_MAX_USERNAME_LEN) == CIFS_MAX_USERNAME_LEN) { pr_warn("username too long\n"); goto cifs_parse_mount_err; @@ -1832,6 +1834,10 @@ static int smb3_fs_context_parse_param(struct fs_context *fc, ctx->password = NULL; kfree_sensitive(ctx->password2); ctx->password2 = NULL; + kfree(ctx->source); + ctx->source = NULL; + kfree(fc->source); + fc->source = NULL; return -EINVAL; } diff --git a/fs/smb/client/smb2inode.c b/fs/smb/client/smb2inode.c index 09e3fc81d7cbc7..69cb81fa0d3ab1 100644 --- a/fs/smb/client/smb2inode.c +++ b/fs/smb/client/smb2inode.c @@ -1294,6 +1294,8 @@ static int smb2_set_path_attr(const unsigned int xid, struct cifs_tcon *tcon, smb2_to_name = cifs_convert_path_to_utf16(to_name, cifs_sb); if (smb2_to_name == NULL) { rc = -ENOMEM; + if (cfile) + cifsFileInfo_put(cfile); goto smb2_rename_path; } in_iov.iov_base = smb2_to_name; diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c index b0739a2661bf95..8b4a4573e9c372 100644 --- a/fs/smb/client/smb2pdu.c +++ b/fs/smb/client/smb2pdu.c @@ -4054,9 +4054,12 @@ SMB2_change_notify(const unsigned int xid, struct cifs_tcon *tcon, smb_rsp = (struct smb2_change_notify_rsp *)rsp_iov.iov_base; - smb2_validate_iov(le16_to_cpu(smb_rsp->OutputBufferOffset), - le32_to_cpu(smb_rsp->OutputBufferLength), &rsp_iov, + rc = smb2_validate_iov(le16_to_cpu(smb_rsp->OutputBufferOffset), + le32_to_cpu(smb_rsp->OutputBufferLength), + &rsp_iov, sizeof(struct file_notify_information)); + if (rc) + goto cnotify_exit; *out_data = kmemdup((char *)smb_rsp + le16_to_cpu(smb_rsp->OutputBufferOffset), le32_to_cpu(smb_rsp->OutputBufferLength), GFP_KERNEL); diff --git a/fs/smb/client/smbdirect.c b/fs/smb/client/smbdirect.c index 85a4c55b61b851..c6c428c2e08ddb 100644 --- a/fs/smb/client/smbdirect.c +++ b/fs/smb/client/smbdirect.c @@ -290,6 +290,9 @@ static void smbd_disconnect_rdma_connection(struct smbdirect_socket *sc) break; case SMBDIRECT_SOCKET_CREATED: + sc->status = SMBDIRECT_SOCKET_DISCONNECTED; + break; + case SMBDIRECT_SOCKET_CONNECTED: sc->status = SMBDIRECT_SOCKET_ERROR; break; diff --git a/fs/smb/client/transport.c b/fs/smb/client/transport.c index 051cd9dbba13d8..915cedde5d6645 100644 --- a/fs/smb/client/transport.c +++ b/fs/smb/client/transport.c @@ -830,7 +830,7 @@ struct TCP_Server_Info *cifs_pick_channel(struct cifs_ses *ses) if (!server || server->terminate) continue; - if (CIFS_CHAN_NEEDS_RECONNECT(ses, i)) + if (CIFS_CHAN_NEEDS_RECONNECT(ses, cur)) continue; /* diff --git a/fs/smb/server/transport_rdma.c b/fs/smb/server/transport_rdma.c index 7d86553fcc7cdc..e2be9a49615461 100644 --- a/fs/smb/server/transport_rdma.c +++ b/fs/smb/server/transport_rdma.c @@ -334,6 +334,9 @@ smb_direct_disconnect_rdma_connection(struct smbdirect_socket *sc) break; case SMBDIRECT_SOCKET_CREATED: + sc->status = SMBDIRECT_SOCKET_DISCONNECTED; + break; + case SMBDIRECT_SOCKET_CONNECTED: sc->status = SMBDIRECT_SOCKET_ERROR; break; @@ -1883,6 +1886,7 @@ static int smb_direct_accept_client(struct smbdirect_socket *sc) static int smb_direct_prepare_negotiation(struct smbdirect_socket *sc) { struct smbdirect_recv_io *recvmsg; + bool recv_posted = false; int ret; WARN_ON_ONCE(sc->status != SMBDIRECT_SOCKET_CREATED); @@ -1899,6 +1903,7 @@ static int smb_direct_prepare_negotiation(struct smbdirect_socket *sc) pr_err("Can't post recv: %d\n", ret); goto out_err; } + recv_posted = true; ret = smb_direct_accept_client(sc); if (ret) { @@ -1908,7 +1913,14 @@ static int smb_direct_prepare_negotiation(struct smbdirect_socket *sc) return 0; out_err: - put_recvmsg(sc, recvmsg); + /* + * If the recv was never posted, return it to the free list. + * If it was posted, leave it alone so disconnect teardown can + * drain the QP and complete it (flush) and the completion path + * will unmap it exactly once. + */ + if (!recv_posted) + put_recvmsg(sc, recvmsg); return ret; } @@ -2606,7 +2618,7 @@ void ksmbd_rdma_destroy(void) } } -bool ksmbd_rdma_capable_netdev(struct net_device *netdev) +static bool ksmbd_find_rdma_capable_netdev(struct net_device *netdev) { struct smb_direct_device *smb_dev; int i; @@ -2648,6 +2660,28 @@ bool ksmbd_rdma_capable_netdev(struct net_device *netdev) return rdma_capable; } +bool ksmbd_rdma_capable_netdev(struct net_device *netdev) +{ + struct net_device *lower_dev; + struct list_head *iter; + + if (ksmbd_find_rdma_capable_netdev(netdev)) + return true; + + /* check if netdev is bridge or VLAN */ + if (netif_is_bridge_master(netdev) || + netdev->priv_flags & IFF_802_1Q_VLAN) + netdev_for_each_lower_dev(netdev, lower_dev, iter) + if (ksmbd_find_rdma_capable_netdev(lower_dev)) + return true; + + /* check if netdev is IPoIB safely without layer violation */ + if (netdev->type == ARPHRD_INFINIBAND) + return true; + + return false; +} + static const struct ksmbd_transport_ops ksmbd_smb_direct_transport_ops = { .prepare = smb_direct_prepare, .disconnect = smb_direct_disconnect, diff --git a/fs/smb/server/transport_tcp.c b/fs/smb/server/transport_tcp.c index 7a1e3dcc2cdee2..d2e391c29464e7 100644 --- a/fs/smb/server/transport_tcp.c +++ b/fs/smb/server/transport_tcp.c @@ -290,8 +290,11 @@ static int ksmbd_kthread_fn(void *p) } } up_read(&conn_list_lock); - if (ret == -EAGAIN) + if (ret == -EAGAIN) { + /* Per-IP limit hit: release the just-accepted socket. */ + sock_release(client_sk); continue; + } skip_max_ip_conns_limit: if (server_conf.max_connections && diff --git a/fs/super.c b/fs/super.c index 5bab94fb7e0358..277b84e5c27913 100644 --- a/fs/super.c +++ b/fs/super.c @@ -1183,11 +1183,14 @@ static inline bool get_active_super(struct super_block *sb) static const char *filesystems_freeze_ptr = "filesystems_freeze"; -static void filesystems_freeze_callback(struct super_block *sb, void *unused) +static void filesystems_freeze_callback(struct super_block *sb, void *freeze_all_ptr) { if (!sb->s_op->freeze_fs && !sb->s_op->freeze_super) return; + if (freeze_all_ptr && !(sb->s_type->fs_flags & FS_POWER_FREEZE)) + return; + if (!get_active_super(sb)) return; @@ -1201,9 +1204,13 @@ static void filesystems_freeze_callback(struct super_block *sb, void *unused) deactivate_super(sb); } -void filesystems_freeze(void) +void filesystems_freeze(bool freeze_all) { - __iterate_supers(filesystems_freeze_callback, NULL, + void *freeze_all_ptr = NULL; + + if (freeze_all) + freeze_all_ptr = &freeze_all; + __iterate_supers(filesystems_freeze_callback, freeze_all_ptr, SUPER_ITER_UNLOCKED | SUPER_ITER_REVERSE); } diff --git a/fs/xfs/scrub/symlink_repair.c b/fs/xfs/scrub/symlink_repair.c index 5902398185a898..df629892462fe1 100644 --- a/fs/xfs/scrub/symlink_repair.c +++ b/fs/xfs/scrub/symlink_repair.c @@ -184,7 +184,7 @@ xrep_symlink_salvage_inline( sc->ip->i_disk_size == 1 && old_target[0] == '?') return 0; - nr = min(XFS_SYMLINK_MAXLEN, xfs_inode_data_fork_size(ip)); + nr = min(XFS_SYMLINK_MAXLEN, ifp->if_bytes); memcpy(target_buf, ifp->if_data, nr); return nr; } diff --git a/fs/xfs/xfs_discard.c b/fs/xfs/xfs_discard.c index ee49f20875afa3..6917de8321915d 100644 --- a/fs/xfs/xfs_discard.c +++ b/fs/xfs/xfs_discard.c @@ -726,8 +726,10 @@ xfs_trim_rtgroup_extents( break; } - if (!tr.queued) + if (!tr.queued) { + kfree(tr.extents); break; + } /* * We hand the extent list to the discard function here so the diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index d3f6e3e42a1191..490e12cb99be9c 100644 --- a/fs/xfs/xfs_iomap.c +++ b/fs/xfs/xfs_iomap.c @@ -1091,6 +1091,29 @@ const struct iomap_ops xfs_zoned_direct_write_iomap_ops = { }; #endif /* CONFIG_XFS_RT */ +#ifdef DEBUG +static void +xfs_check_atomic_cow_conversion( + struct xfs_inode *ip, + xfs_fileoff_t offset_fsb, + xfs_filblks_t count_fsb, + const struct xfs_bmbt_irec *cmap) +{ + struct xfs_iext_cursor icur; + struct xfs_bmbt_irec cmap2 = { }; + + if (xfs_iext_lookup_extent(ip, ip->i_cowfp, offset_fsb, &icur, &cmap2)) + xfs_trim_extent(&cmap2, offset_fsb, count_fsb); + + ASSERT(cmap2.br_startoff == cmap->br_startoff); + ASSERT(cmap2.br_blockcount == cmap->br_blockcount); + ASSERT(cmap2.br_startblock == cmap->br_startblock); + ASSERT(cmap2.br_state == cmap->br_state); +} +#else +# define xfs_check_atomic_cow_conversion(...) ((void)0) +#endif + static int xfs_atomic_write_cow_iomap_begin( struct inode *inode, @@ -1102,9 +1125,10 @@ xfs_atomic_write_cow_iomap_begin( { struct xfs_inode *ip = XFS_I(inode); struct xfs_mount *mp = ip->i_mount; - const xfs_fileoff_t offset_fsb = XFS_B_TO_FSBT(mp, offset); - xfs_fileoff_t end_fsb = xfs_iomap_end_fsb(mp, offset, length); - xfs_filblks_t count_fsb = end_fsb - offset_fsb; + const xfs_fileoff_t offset_fsb = XFS_B_TO_FSBT(mp, offset); + const xfs_fileoff_t end_fsb = XFS_B_TO_FSB(mp, offset + length); + const xfs_filblks_t count_fsb = end_fsb - offset_fsb; + xfs_filblks_t hole_count_fsb; int nmaps = 1; xfs_filblks_t resaligned; struct xfs_bmbt_irec cmap; @@ -1130,7 +1154,7 @@ xfs_atomic_write_cow_iomap_begin( return -EAGAIN; trace_xfs_iomap_atomic_write_cow(ip, offset, length); - +retry: xfs_ilock(ip, XFS_ILOCK_EXCL); if (!ip->i_cowfp) { @@ -1141,14 +1165,22 @@ xfs_atomic_write_cow_iomap_begin( if (!xfs_iext_lookup_extent(ip, ip->i_cowfp, offset_fsb, &icur, &cmap)) cmap.br_startoff = end_fsb; if (cmap.br_startoff <= offset_fsb) { + if (isnullstartblock(cmap.br_startblock)) + goto convert_delay; + + /* + * cmap could extend outside the write range due to previous + * speculative preallocations. We must trim cmap to the write + * range because the cow fork treats written mappings to mean + * "write in progress". + */ xfs_trim_extent(&cmap, offset_fsb, count_fsb); goto found; } - end_fsb = cmap.br_startoff; - count_fsb = end_fsb - offset_fsb; + hole_count_fsb = cmap.br_startoff - offset_fsb; - resaligned = xfs_aligned_fsb_count(offset_fsb, count_fsb, + resaligned = xfs_aligned_fsb_count(offset_fsb, hole_count_fsb, xfs_get_cowextsz_hint(ip)); xfs_iunlock(ip, XFS_ILOCK_EXCL); @@ -1169,8 +1201,10 @@ xfs_atomic_write_cow_iomap_begin( if (!xfs_iext_lookup_extent(ip, ip->i_cowfp, offset_fsb, &icur, &cmap)) cmap.br_startoff = end_fsb; if (cmap.br_startoff <= offset_fsb) { - xfs_trim_extent(&cmap, offset_fsb, count_fsb); xfs_trans_cancel(tp); + if (isnullstartblock(cmap.br_startblock)) + goto convert_delay; + xfs_trim_extent(&cmap, offset_fsb, count_fsb); goto found; } @@ -1182,7 +1216,7 @@ xfs_atomic_write_cow_iomap_begin( * atomic writes to that same range will be aligned (and don't require * this COW-based method). */ - error = xfs_bmapi_write(tp, ip, offset_fsb, count_fsb, + error = xfs_bmapi_write(tp, ip, offset_fsb, hole_count_fsb, XFS_BMAPI_COWFORK | XFS_BMAPI_PREALLOC | XFS_BMAPI_EXTSZALIGN, 0, &cmap, &nmaps); if (error) { @@ -1195,21 +1229,43 @@ xfs_atomic_write_cow_iomap_begin( if (error) goto out_unlock; + /* + * cmap could map more blocks than the range we passed into bmapi_write + * because of EXTSZALIGN or adjacent pre-existing unwritten mappings + * that were merged. Trim cmap to the original write range so that we + * don't convert more than we were asked to do for this write. + */ + xfs_trim_extent(&cmap, offset_fsb, count_fsb); + found: if (cmap.br_state != XFS_EXT_NORM) { - error = xfs_reflink_convert_cow_locked(ip, offset_fsb, - count_fsb); + error = xfs_reflink_convert_cow_locked(ip, cmap.br_startoff, + cmap.br_blockcount); if (error) goto out_unlock; cmap.br_state = XFS_EXT_NORM; + xfs_check_atomic_cow_conversion(ip, offset_fsb, count_fsb, + &cmap); } - length = XFS_FSB_TO_B(mp, cmap.br_startoff + cmap.br_blockcount); - trace_xfs_iomap_found(ip, offset, length - offset, XFS_COW_FORK, &cmap); + trace_xfs_iomap_found(ip, offset, length, XFS_COW_FORK, &cmap); seq = xfs_iomap_inode_sequence(ip, IOMAP_F_SHARED); xfs_iunlock(ip, XFS_ILOCK_EXCL); return xfs_bmbt_to_iomap(ip, iomap, &cmap, flags, IOMAP_F_SHARED, seq); +convert_delay: + xfs_iunlock(ip, XFS_ILOCK_EXCL); + error = xfs_bmapi_convert_delalloc(ip, XFS_COW_FORK, offset, iomap, + NULL); + if (error) + return error; + + /* + * Try the lookup again, because the delalloc conversion might have + * turned the COW mapping into unwritten, but we need it to be in + * written state. + */ + goto retry; out_unlock: xfs_iunlock(ip, XFS_ILOCK_EXCL); return error; diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index 1067ebb3b001bf..bc71aa9dcee8d6 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c @@ -1693,7 +1693,10 @@ xfs_fs_fill_super( if (error) return error; - sb_min_blocksize(sb, BBSIZE); + if (!sb_min_blocksize(sb, BBSIZE)) { + xfs_err(mp, "unable to set blocksize"); + return -EINVAL; + } sb->s_xattr = xfs_xattr_handlers; sb->s_export_op = &xfs_export_operations; #ifdef CONFIG_XFS_QUOTA diff --git a/fs/xfs/xfs_zone_alloc.c b/fs/xfs/xfs_zone_alloc.c index 0404022408078b..ef7a931ebde5a0 100644 --- a/fs/xfs/xfs_zone_alloc.c +++ b/fs/xfs/xfs_zone_alloc.c @@ -615,7 +615,7 @@ xfs_select_open_zone_mru( lockdep_assert_held(&zi->zi_open_zones_lock); list_for_each_entry_reverse(oz, &zi->zi_open_zones, oz_entry) - if (xfs_try_use_zone(zi, file_hint, oz, false)) + if (xfs_try_use_zone(zi, file_hint, oz, XFS_ZONE_ALLOC_OK)) return oz; cond_resched_lock(&zi->zi_open_zones_lock); @@ -1249,8 +1249,10 @@ xfs_mount_zones( while ((rtg = xfs_rtgroup_next(mp, rtg))) { error = xfs_init_zone(&iz, rtg, NULL); - if (error) + if (error) { + xfs_rtgroup_rele(rtg); goto out_free_zone_info; + } } } diff --git a/include/drm/Makefile b/include/drm/Makefile index 1df6962556efc2..48fae3f167c7e6 100644 --- a/include/drm/Makefile +++ b/include/drm/Makefile @@ -11,7 +11,7 @@ always-$(CONFIG_DRM_HEADER_TEST) += \ quiet_cmd_hdrtest = HDRTEST $(patsubst %.hdrtest,%.h,$@) cmd_hdrtest = \ $(CC) $(c_flags) -fsyntax-only -x c /dev/null -include $< -include $<; \ - PYTHONDONTWRITEBYTECODE=1 $(KERNELDOC) -none $(if $(CONFIG_WERROR)$(CONFIG_DRM_WERROR),-Werror) $<; \ + PYTHONDONTWRITEBYTECODE=1 $(PYTHON3) $(KERNELDOC) -none $(if $(CONFIG_WERROR)$(CONFIG_DRM_WERROR),-Werror) $<; \ touch $@ $(obj)/%.hdrtest: $(src)/%.h FORCE diff --git a/include/drm/intel/pciids.h b/include/drm/intel/pciids.h index da6301a6fceabc..69d4ae92d822a8 100644 --- a/include/drm/intel/pciids.h +++ b/include/drm/intel/pciids.h @@ -877,7 +877,10 @@ MACRO__(0xB08F, ## __VA_ARGS__), \ MACRO__(0xB090, ## __VA_ARGS__), \ MACRO__(0xB0A0, ## __VA_ARGS__), \ - MACRO__(0xB0B0, ## __VA_ARGS__), \ + MACRO__(0xB0B0, ## __VA_ARGS__) + +/* WCL */ +#define INTEL_WCL_IDS(MACRO__, ...) \ MACRO__(0xFD80, ## __VA_ARGS__), \ MACRO__(0xFD81, ## __VA_ARGS__) diff --git a/include/linux/ata.h b/include/linux/ata.h index 792e10a09787f8..c9013e472aa3d5 100644 --- a/include/linux/ata.h +++ b/include/linux/ata.h @@ -566,6 +566,7 @@ struct ata_bmdma_prd { #define ata_id_has_ncq(id) ((id)[ATA_ID_SATA_CAPABILITY] & (1 << 8)) #define ata_id_queue_depth(id) (((id)[ATA_ID_QUEUE_DEPTH] & 0x1f) + 1) #define ata_id_removable(id) ((id)[ATA_ID_CONFIG] & (1 << 7)) +#define ata_id_is_locked(id) (((id)[ATA_ID_DLF] & 0x7) == 0x7) #define ata_id_has_atapi_AN(id) \ ((((id)[ATA_ID_SATA_CAPABILITY] != 0x0000) && \ ((id)[ATA_ID_SATA_CAPABILITY] != 0xffff)) && \ diff --git a/include/linux/compiler_types.h b/include/linux/compiler_types.h index 59288a2c1ad277..0a1b9598940d05 100644 --- a/include/linux/compiler_types.h +++ b/include/linux/compiler_types.h @@ -250,10 +250,9 @@ struct ftrace_likely_data { /* * GCC does not warn about unused static inline functions for -Wunused-function. * Suppress the warning in clang as well by using __maybe_unused, but enable it - * for W=1 build. This will allow clang to find unused functions. Remove the - * __inline_maybe_unused entirely after fixing most of -Wunused-function warnings. + * for W=2 build. This will allow clang to find unused functions. */ -#ifdef KBUILD_EXTRA_WARN1 +#ifdef KBUILD_EXTRA_WARN2 #define __inline_maybe_unused #else #define __inline_maybe_unused __maybe_unused @@ -461,6 +460,12 @@ struct ftrace_likely_data { # define __nocfi #endif +#if defined(CONFIG_ARCH_USES_CFI_GENERIC_LLVM_PASS) +# define __nocfi_generic __nocfi +#else +# define __nocfi_generic +#endif + /* * Any place that could be marked with the "alloc_size" attribute is also * a place to be marked with the "malloc" attribute, except those that may diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h index 8248ff9363eed2..2ceda49c609fb7 100644 --- a/include/linux/dma-mapping.h +++ b/include/linux/dma-mapping.h @@ -90,7 +90,7 @@ */ #define DMA_MAPPING_ERROR (~(dma_addr_t)0) -#define DMA_BIT_MASK(n) (((n) == 64) ? ~0ULL : ((1ULL<<(n))-1)) +#define DMA_BIT_MASK(n) GENMASK_ULL(n - 1, 0) struct dma_iova_state { dma_addr_t addr; diff --git a/include/linux/entry-virt.h b/include/linux/entry-virt.h index 42c89e3e5ca7ac..bfa767702d9a69 100644 --- a/include/linux/entry-virt.h +++ b/include/linux/entry-virt.h @@ -32,7 +32,7 @@ */ static inline int arch_xfer_to_guest_mode_handle_work(unsigned long ti_work); -#ifndef arch_xfer_to_guest_mode_work +#ifndef arch_xfer_to_guest_mode_handle_work static inline int arch_xfer_to_guest_mode_handle_work(unsigned long ti_work) { return 0; diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h index c2d8b4ec62ebfc..5c9162193d2698 100644 --- a/include/linux/ethtool.h +++ b/include/linux/ethtool.h @@ -492,7 +492,7 @@ struct ethtool_pause_stats { }; #define ETHTOOL_MAX_LANES 8 -/** +/* * IEEE 802.3ck/df defines 16 bins for FEC histogram plus one more for * the end-of-list marker, total 17 items */ diff --git a/include/linux/filter.h b/include/linux/filter.h index f5c859b8131a3e..973233b82dc1fd 100644 --- a/include/linux/filter.h +++ b/include/linux/filter.h @@ -901,6 +901,26 @@ static inline void bpf_compute_data_pointers(struct sk_buff *skb) cb->data_end = skb->data + skb_headlen(skb); } +static inline int bpf_prog_run_data_pointers( + const struct bpf_prog *prog, + struct sk_buff *skb) +{ + struct bpf_skb_data_end *cb = (struct bpf_skb_data_end *)skb->cb; + void *save_data_meta, *save_data_end; + int res; + + save_data_meta = cb->data_meta; + save_data_end = cb->data_end; + + bpf_compute_data_pointers(skb); + res = bpf_prog_run(prog, skb); + + cb->data_meta = save_data_meta; + cb->data_end = save_data_end; + + return res; +} + /* Similar to bpf_compute_data_pointers(), except that save orginal * data in cb->data and cb->meta_data for restore. */ diff --git a/include/linux/firmware/cirrus/cs_dsp.h b/include/linux/firmware/cirrus/cs_dsp.h index a66eb7624730c4..0ec1cdc5585d25 100644 --- a/include/linux/firmware/cirrus/cs_dsp.h +++ b/include/linux/firmware/cirrus/cs_dsp.h @@ -102,7 +102,7 @@ struct cs_dsp_coeff_ctl { const char *subname; unsigned int subname_len; unsigned int offset; - size_t len; + unsigned int len; unsigned int type; unsigned int flags; unsigned int set:1; @@ -188,8 +188,8 @@ struct cs_dsp { #ifdef CONFIG_DEBUG_FS struct dentry *debugfs_root; - char *wmfw_file_name; - char *bin_file_name; + const char *wmfw_file_name; + const char *bin_file_name; #endif }; diff --git a/include/linux/firmware/cirrus/cs_dsp_test_utils.h b/include/linux/firmware/cirrus/cs_dsp_test_utils.h index ecd821ed8064f1..1f97764fdfd7d5 100644 --- a/include/linux/firmware/cirrus/cs_dsp_test_utils.h +++ b/include/linux/firmware/cirrus/cs_dsp_test_utils.h @@ -26,21 +26,21 @@ struct cs_dsp_test { struct cs_dsp_test_local *local; - /* Following members are private */ + /* private: Following members are private */ bool saw_bus_write; }; /** * struct cs_dsp_mock_alg_def - Info for creating a mock algorithm entry. * - * @id Algorithm ID. - * @ver; Algorithm version. - * @xm_base_words XM base address in DSP words. - * @xm_size_words XM size in DSP words. - * @ym_base_words YM base address in DSP words. - * @ym_size_words YM size in DSP words. - * @zm_base_words ZM base address in DSP words. - * @zm_size_words ZM size in DSP words. + * @id: Algorithm ID. + * @ver: Algorithm version. + * @xm_base_words: XM base address in DSP words. + * @xm_size_words: XM size in DSP words. + * @ym_base_words: YM base address in DSP words. + * @ym_size_words: YM size in DSP words. + * @zm_base_words: ZM base address in DSP words. + * @zm_size_words: ZM size in DSP words. */ struct cs_dsp_mock_alg_def { unsigned int id; diff --git a/include/linux/fs.h b/include/linux/fs.h index c895146c1444be..dd3b57cfadeeb4 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -2689,6 +2689,7 @@ struct file_system_type { #define FS_ALLOW_IDMAP 32 /* FS has been updated to handle vfs idmappings. */ #define FS_MGTIME 64 /* FS uses multigrain timestamps */ #define FS_LBS 128 /* FS supports LBS */ +#define FS_POWER_FREEZE 256 /* Always freeze on suspend/hibernate */ #define FS_RENAME_DOES_D_MOVE 32768 /* FS will handle d_move() during rename() internally. */ int (*init_fs_context)(struct fs_context *); const struct fs_parameter_spec *parameters; @@ -2823,6 +2824,7 @@ extern int current_umask(void); extern void ihold(struct inode * inode); extern void iput(struct inode *); +void iput_not_last(struct inode *); int inode_update_timestamps(struct inode *inode, int flags); int generic_update_time(struct inode *, int); @@ -3423,8 +3425,8 @@ static inline void remove_inode_hash(struct inode *inode) extern void inode_sb_list_add(struct inode *inode); extern void inode_add_lru(struct inode *inode); -extern int sb_set_blocksize(struct super_block *, int); -extern int sb_min_blocksize(struct super_block *, int); +int sb_set_blocksize(struct super_block *sb, int size); +int __must_check sb_min_blocksize(struct super_block *sb, int size); int generic_file_mmap(struct file *, struct vm_area_struct *); int generic_file_mmap_prepare(struct vm_area_desc *desc); @@ -3606,7 +3608,7 @@ extern void drop_super_exclusive(struct super_block *sb); extern void iterate_supers(void (*f)(struct super_block *, void *), void *arg); extern void iterate_supers_type(struct file_system_type *, void (*)(struct super_block *, void *), void *); -void filesystems_freeze(void); +void filesystems_freeze(bool freeze_all); void filesystems_thaw(void); extern int dcache_dir_open(struct inode *, struct file *); diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index 7ded7df6e9b504..07f8c309e43273 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -193,6 +193,10 @@ static __always_inline struct pt_regs *ftrace_get_regs(struct ftrace_regs *fregs #if !defined(CONFIG_HAVE_DYNAMIC_FTRACE_WITH_ARGS) || \ defined(CONFIG_HAVE_FTRACE_REGS_HAVING_PT_REGS) +#ifndef arch_ftrace_partial_regs +#define arch_ftrace_partial_regs(regs) do {} while (0) +#endif + static __always_inline struct pt_regs * ftrace_partial_regs(struct ftrace_regs *fregs, struct pt_regs *regs) { @@ -202,7 +206,11 @@ ftrace_partial_regs(struct ftrace_regs *fregs, struct pt_regs *regs) * Since arch_ftrace_get_regs() will check some members and may return * NULL, we can not use it. */ - return &arch_ftrace_regs(fregs)->regs; + regs = &arch_ftrace_regs(fregs)->regs; + + /* Allow arch specific updates to regs. */ + arch_ftrace_partial_regs(regs); + return regs; } #endif /* !CONFIG_HAVE_DYNAMIC_FTRACE_WITH_ARGS || CONFIG_HAVE_FTRACE_REGS_HAVING_PT_REGS */ diff --git a/include/linux/gfp.h b/include/linux/gfp.h index 0ceb4e09306c4a..623bee335383ef 100644 --- a/include/linux/gfp.h +++ b/include/linux/gfp.h @@ -7,6 +7,7 @@ #include #include #include +#include #include struct vm_area_struct; @@ -463,4 +464,6 @@ static inline struct folio *folio_alloc_gigantic_noprof(int order, gfp_t gfp, /* This should be paired with folio_put() rather than free_contig_range(). */ #define folio_alloc_gigantic(...) alloc_hooks(folio_alloc_gigantic_noprof(__VA_ARGS__)) +DEFINE_FREE(free_page, void *, free_page((unsigned long)_T)) + #endif /* __LINUX_GFP_H */ diff --git a/include/linux/gpio/consumer.h b/include/linux/gpio/consumer.h index 00df68c5140514..a8acb7c0b5af50 100644 --- a/include/linux/gpio/consumer.h +++ b/include/linux/gpio/consumer.h @@ -167,6 +167,8 @@ int gpiod_cansleep(const struct gpio_desc *desc); int gpiod_to_irq(const struct gpio_desc *desc); int gpiod_set_consumer_name(struct gpio_desc *desc, const char *name); +bool gpiod_is_shared(const struct gpio_desc *desc); + /* Convert between the old gpio_ and new gpiod_ interfaces */ struct gpio_desc *gpio_to_desc(unsigned gpio); int desc_to_gpio(const struct gpio_desc *desc); @@ -520,6 +522,13 @@ static inline int gpiod_set_consumer_name(struct gpio_desc *desc, return -EINVAL; } +static inline bool gpiod_is_shared(const struct gpio_desc *desc) +{ + /* GPIO can never have been requested */ + WARN_ON(desc); + return false; +} + static inline struct gpio_desc *gpio_to_desc(unsigned gpio) { return NULL; diff --git a/include/linux/highmem.h b/include/linux/highmem.h index 105cc4c00cc34d..abc20f9810fd42 100644 --- a/include/linux/highmem.h +++ b/include/linux/highmem.h @@ -249,10 +249,12 @@ static inline void clear_highpage_kasan_tagged(struct page *page) kunmap_local(kaddr); } -#ifndef __HAVE_ARCH_TAG_CLEAR_HIGHPAGE +#ifndef __HAVE_ARCH_TAG_CLEAR_HIGHPAGES -static inline void tag_clear_highpage(struct page *page) +/* Return false to let people know we did not initialize the pages */ +static inline bool tag_clear_highpages(struct page *page, int numpages) { + return false; } #endif diff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h index f327d62fc9852d..71ac78b9f834f6 100644 --- a/include/linux/huge_mm.h +++ b/include/linux/huge_mm.h @@ -376,45 +376,30 @@ bool non_uniform_split_supported(struct folio *folio, unsigned int new_order, int folio_split(struct folio *folio, unsigned int new_order, struct page *page, struct list_head *list); /* - * try_folio_split - try to split a @folio at @page using non uniform split. + * try_folio_split_to_order - try to split a @folio at @page to @new_order using + * non uniform split. * @folio: folio to be split - * @page: split to order-0 at the given page - * @list: store the after-split folios + * @page: split to @new_order at the given page + * @new_order: the target split order * - * Try to split a @folio at @page using non uniform split to order-0, if - * non uniform split is not supported, fall back to uniform split. + * Try to split a @folio at @page using non uniform split to @new_order, if + * non uniform split is not supported, fall back to uniform split. After-split + * folios are put back to LRU list. Use min_order_for_split() to get the lower + * bound of @new_order. * * Return: 0: split is successful, otherwise split failed. */ -static inline int try_folio_split(struct folio *folio, struct page *page, - struct list_head *list) +static inline int try_folio_split_to_order(struct folio *folio, + struct page *page, unsigned int new_order) { - int ret = min_order_for_split(folio); - - if (ret < 0) - return ret; - - if (!non_uniform_split_supported(folio, 0, false)) - return split_huge_page_to_list_to_order(&folio->page, list, - ret); - return folio_split(folio, ret, page, list); + if (!non_uniform_split_supported(folio, new_order, /* warns= */ false)) + return split_huge_page_to_list_to_order(&folio->page, NULL, + new_order); + return folio_split(folio, new_order, page, NULL); } static inline int split_huge_page(struct page *page) { - struct folio *folio = page_folio(page); - int ret = min_order_for_split(folio); - - if (ret < 0) - return ret; - - /* - * split_huge_page() locks the page before splitting and - * expects the same page that has been split to be locked when - * returned. split_folio(page_folio(page)) cannot be used here - * because it converts the page to folio and passes the head - * page to be split. - */ - return split_huge_page_to_list_to_order(page, NULL, ret); + return split_huge_page_to_list_to_order(page, NULL, 0); } void deferred_split_folio(struct folio *folio, bool partially_mapped); @@ -597,14 +582,20 @@ static inline int split_huge_page(struct page *page) return -EINVAL; } +static inline int min_order_for_split(struct folio *folio) +{ + VM_WARN_ON_ONCE_FOLIO(1, folio); + return -EINVAL; +} + static inline int split_folio_to_list(struct folio *folio, struct list_head *list) { VM_WARN_ON_ONCE_FOLIO(1, folio); return -EINVAL; } -static inline int try_folio_split(struct folio *folio, struct page *page, - struct list_head *list) +static inline int try_folio_split_to_order(struct folio *folio, + struct page *page, unsigned int new_order) { VM_WARN_ON_ONCE_FOLIO(1, folio); return -EINVAL; diff --git a/include/linux/map_benchmark.h b/include/linux/map_benchmark.h index 62674c83bde4ef..48e2ff95332f37 100644 --- a/include/linux/map_benchmark.h +++ b/include/linux/map_benchmark.h @@ -27,5 +27,6 @@ struct map_benchmark { __u32 dma_dir; /* DMA data direction */ __u32 dma_trans_ns; /* time for DMA transmission in ns */ __u32 granule; /* how many PAGE_SIZE will do map/unmap once a time */ + __u8 expansion[76]; /* For future use */ }; #endif /* _KERNEL_DMA_BENCHMARK_H */ diff --git a/include/linux/mlx5/cq.h b/include/linux/mlx5/cq.h index 7ef2c7c7d803de..9d47cdc727ad0d 100644 --- a/include/linux/mlx5/cq.h +++ b/include/linux/mlx5/cq.h @@ -183,6 +183,7 @@ static inline void mlx5_cq_put(struct mlx5_core_cq *cq) complete(&cq->free); } +void mlx5_add_cq_to_tasklet(struct mlx5_core_cq *cq, struct mlx5_eqe *eqe); int mlx5_create_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq, u32 *in, int inlen, u32 *out, int outlen); int mlx5_core_create_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq, diff --git a/include/linux/mm.h b/include/linux/mm.h index d16b33bacc32bc..7c79b3369b82c9 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -2074,7 +2074,7 @@ static inline unsigned long folio_nr_pages(const struct folio *folio) return folio_large_nr_pages(folio); } -#if !defined(CONFIG_ARCH_HAS_GIGANTIC_PAGE) +#if !defined(CONFIG_HAVE_GIGANTIC_FOLIOS) /* * We don't expect any folios that exceed buddy sizes (and consequently * memory sections). @@ -2087,10 +2087,17 @@ static inline unsigned long folio_nr_pages(const struct folio *folio) * pages are guaranteed to be contiguous. */ #define MAX_FOLIO_ORDER PFN_SECTION_SHIFT -#else +#elif defined(CONFIG_HUGETLB_PAGE) /* * There is no real limit on the folio size. We limit them to the maximum we - * currently expect (e.g., hugetlb, dax). + * currently expect (see CONFIG_HAVE_GIGANTIC_FOLIOS): with hugetlb, we expect + * no folios larger than 16 GiB on 64bit and 1 GiB on 32bit. + */ +#define MAX_FOLIO_ORDER get_order(IS_ENABLED(CONFIG_64BIT) ? SZ_16G : SZ_1G) +#else +/* + * Without hugetlb, gigantic folios that are bigger than a single PUD are + * currently impossible. */ #define MAX_FOLIO_ORDER PUD_ORDER #endif diff --git a/include/linux/net/intel/libie/fwlog.h b/include/linux/net/intel/libie/fwlog.h index 36b13fabca9ec2..7273c78c826b40 100644 --- a/include/linux/net/intel/libie/fwlog.h +++ b/include/linux/net/intel/libie/fwlog.h @@ -78,8 +78,20 @@ struct libie_fwlog { ); }; +#if IS_ENABLED(CONFIG_LIBIE_FWLOG) int libie_fwlog_init(struct libie_fwlog *fwlog, struct libie_fwlog_api *api); void libie_fwlog_deinit(struct libie_fwlog *fwlog); void libie_fwlog_reregister(struct libie_fwlog *fwlog); void libie_get_fwlog_data(struct libie_fwlog *fwlog, u8 *buf, u16 len); +#else +static inline int libie_fwlog_init(struct libie_fwlog *fwlog, + struct libie_fwlog_api *api) +{ + return -EOPNOTSUPP; +} +static inline void libie_fwlog_deinit(struct libie_fwlog *fwlog) { } +static inline void libie_fwlog_reregister(struct libie_fwlog *fwlog) { } +static inline void libie_get_fwlog_data(struct libie_fwlog *fwlog, u8 *buf, + u16 len) { } +#endif /* CONFIG_LIBIE_FWLOG */ #endif /* _LIBIE_FWLOG_H_ */ diff --git a/include/linux/of.h b/include/linux/of.h index 121a288ca92df7..57fb598b72d3db 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -316,6 +316,9 @@ extern struct property *of_find_property(const struct device_node *np, extern bool of_property_read_bool(const struct device_node *np, const char *propname); extern int of_property_count_elems_of_size(const struct device_node *np, const char *propname, int elem_size); +extern int of_property_read_u8_index(const struct device_node *np, + const char *propname, + u32 index, u8 *out_value); extern int of_property_read_u16_index(const struct device_node *np, const char *propname, u32 index, u16 *out_value); @@ -646,6 +649,12 @@ static inline int of_property_count_elems_of_size(const struct device_node *np, return -ENOSYS; } +static inline int of_property_read_u8_index(const struct device_node *np, + const char *propname, u32 index, u8 *out_value) +{ + return -ENOSYS; +} + static inline int of_property_read_u16_index(const struct device_node *np, const char *propname, u32 index, u16 *out_value) { diff --git a/include/linux/pci.h b/include/linux/pci.h index d1fdf81fbe1e42..bf97d49c23cf54 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -412,6 +412,8 @@ struct pci_dev { u16 l1ss; /* L1SS Capability pointer */ #ifdef CONFIG_PCIEASPM struct pcie_link_state *link_state; /* ASPM link state */ + unsigned int aspm_l0s_support:1; /* ASPM L0s support */ + unsigned int aspm_l1_support:1; /* ASPM L1 support */ unsigned int ltr_path:1; /* Latency Tolerance Reporting supported from root to here */ #endif diff --git a/include/linux/platform_data/x86/int3472.h b/include/linux/platform_data/x86/int3472.h index 1571e9157fa50b..b1b837583d5442 100644 --- a/include/linux/platform_data/x86/int3472.h +++ b/include/linux/platform_data/x86/int3472.h @@ -100,7 +100,6 @@ struct int3472_gpio_regulator { struct regulator_consumer_supply supply_map[GPIO_REGULATOR_SUPPLY_MAP_COUNT * 2]; char supply_name_upper[GPIO_SUPPLY_NAME_LENGTH]; char regulator_name[GPIO_REGULATOR_NAME_LENGTH]; - struct gpio_desc *ena_gpio; struct regulator_dev *rdev; struct regulator_desc rdesc; }; diff --git a/include/linux/soundwire/sdw_registers.h b/include/linux/soundwire/sdw_registers.h index 0a5939285583b6..cae8a0a5a9b041 100644 --- a/include/linux/soundwire/sdw_registers.h +++ b/include/linux/soundwire/sdw_registers.h @@ -355,4 +355,6 @@ /* Check the reserved and fixed bits in address */ #define SDW_SDCA_VALID_CTL(reg) (((reg) & (GENMASK(31, 25) | BIT(18) | BIT(13))) == BIT(30)) +#define SDW_SDCA_MAX_REGISTER 0x47FFFFFF + #endif /* __SDW_REGISTERS_H */ diff --git a/include/linux/string.h b/include/linux/string.h index fdd3442c6bcbd7..929d05d1247c76 100644 --- a/include/linux/string.h +++ b/include/linux/string.h @@ -562,4 +562,22 @@ static inline bool strstarts(const char *str, const char *prefix) return strncmp(str, prefix, strlen(prefix)) == 0; } +/** + * strends - Check if a string ends with another string. + * @str - NULL-terminated string to check against @suffix + * @suffix - NULL-terminated string defining the suffix to look for in @str + * + * Returns: + * True if @str ends with @suffix. False in all other cases. + */ +static inline bool strends(const char *str, const char *suffix) +{ + unsigned int str_len = strlen(str), suffix_len = strlen(suffix); + + if (str_len < suffix_len) + return false; + + return !(strcmp(str + str_len - suffix_len, suffix)); +} + #endif /* _LINUX_STRING_H_ */ diff --git a/include/linux/virtio_net.h b/include/linux/virtio_net.h index 4d1780848d0e04..b673c31569f320 100644 --- a/include/linux/virtio_net.h +++ b/include/linux/virtio_net.h @@ -401,7 +401,8 @@ virtio_net_hdr_tnl_from_skb(const struct sk_buff *skb, if (!tnl_hdr_negotiated) return -EINVAL; - vhdr->hash_hdr.hash_value = 0; + vhdr->hash_hdr.hash_value_lo = 0; + vhdr->hash_hdr.hash_value_hi = 0; vhdr->hash_hdr.hash_report = 0; vhdr->hash_hdr.padding = 0; diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index 8d0e703bc929e8..cb4c02d0075904 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h @@ -2783,6 +2783,11 @@ struct hci_ev_le_per_adv_report { __u8 data[]; } __packed; +#define HCI_EV_LE_PA_SYNC_LOST 0x10 +struct hci_ev_le_pa_sync_lost { + __le16 handle; +} __packed; + #define LE_PA_DATA_COMPLETE 0x00 #define LE_PA_DATA_MORE_TO_COME 0x01 #define LE_PA_DATA_TRUNCATED 0x02 diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h index bca0333f1e9916..f5be96f08b9d98 100644 --- a/include/net/bluetooth/mgmt.h +++ b/include/net/bluetooth/mgmt.h @@ -780,7 +780,7 @@ struct mgmt_adv_pattern { __u8 ad_type; __u8 offset; __u8 length; - __u8 value[31]; + __u8 value[HCI_MAX_AD_LENGTH]; } __packed; #define MGMT_OP_ADD_ADV_PATTERNS_MONITOR 0x0052 diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 781624f5913af9..820e299f06b5ee 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -6435,6 +6435,11 @@ static inline void wiphy_delayed_work_init(struct wiphy_delayed_work *dwork, * after wiphy_lock() was called. Therefore, wiphy_cancel_work() can * use just cancel_work() instead of cancel_work_sync(), it requires * being in a section protected by wiphy_lock(). + * + * Note that these are scheduled with a timer where the accuracy + * becomes less the longer in the future the scheduled timer is. Use + * wiphy_hrtimer_work_queue() if the timer must be not be late by more + * than approximately 10 percent. */ void wiphy_delayed_work_queue(struct wiphy *wiphy, struct wiphy_delayed_work *dwork, @@ -6506,6 +6511,79 @@ void wiphy_delayed_work_flush(struct wiphy *wiphy, bool wiphy_delayed_work_pending(struct wiphy *wiphy, struct wiphy_delayed_work *dwork); +struct wiphy_hrtimer_work { + struct wiphy_work work; + struct wiphy *wiphy; + struct hrtimer timer; +}; + +enum hrtimer_restart wiphy_hrtimer_work_timer(struct hrtimer *t); + +static inline void wiphy_hrtimer_work_init(struct wiphy_hrtimer_work *hrwork, + wiphy_work_func_t func) +{ + hrtimer_setup(&hrwork->timer, wiphy_hrtimer_work_timer, + CLOCK_BOOTTIME, HRTIMER_MODE_REL); + wiphy_work_init(&hrwork->work, func); +} + +/** + * wiphy_hrtimer_work_queue - queue hrtimer work for the wiphy + * @wiphy: the wiphy to queue for + * @hrwork: the high resolution timer worker + * @delay: the delay given as a ktime_t + * + * Please refer to wiphy_delayed_work_queue(). The difference is that + * the hrtimer work uses a high resolution timer for scheduling. This + * may be needed if timeouts might be scheduled further in the future + * and the accuracy of the normal timer is not sufficient. + * + * Expect a delay of a few milliseconds as the timer is scheduled + * with some slack and some more time may pass between queueing the + * work and its start. + */ +void wiphy_hrtimer_work_queue(struct wiphy *wiphy, + struct wiphy_hrtimer_work *hrwork, + ktime_t delay); + +/** + * wiphy_hrtimer_work_cancel - cancel previously queued hrtimer work + * @wiphy: the wiphy, for debug purposes + * @hrtimer: the hrtimer work to cancel + * + * Cancel the work *without* waiting for it, this assumes being + * called under the wiphy mutex acquired by wiphy_lock(). + */ +void wiphy_hrtimer_work_cancel(struct wiphy *wiphy, + struct wiphy_hrtimer_work *hrtimer); + +/** + * wiphy_hrtimer_work_flush - flush previously queued hrtimer work + * @wiphy: the wiphy, for debug purposes + * @hrwork: the hrtimer work to flush + * + * Flush the work (i.e. run it if pending). This must be called + * under the wiphy mutex acquired by wiphy_lock(). + */ +void wiphy_hrtimer_work_flush(struct wiphy *wiphy, + struct wiphy_hrtimer_work *hrwork); + +/** + * wiphy_hrtimer_work_pending - Find out whether a wiphy hrtimer + * work item is currently pending. + * + * @wiphy: the wiphy, for debug purposes + * @hrwork: the hrtimer work in question + * + * Return: true if timer is pending, false otherwise + * + * Please refer to the wiphy_delayed_work_pending() documentation as + * this is the equivalent function for hrtimer based delayed work + * items. + */ +bool wiphy_hrtimer_work_pending(struct wiphy *wiphy, + struct wiphy_hrtimer_work *hrwork); + /** * enum ieee80211_ap_reg_power - regulatory power for an Access Point * diff --git a/include/net/libeth/xdp.h b/include/net/libeth/xdp.h index bc3507edd58920..898723ab62e812 100644 --- a/include/net/libeth/xdp.h +++ b/include/net/libeth/xdp.h @@ -513,7 +513,7 @@ struct libeth_xdp_tx_desc { * can't fail, but can send less frames if there's no enough free descriptors * available. The actual free space is returned by @prep from the driver. */ -static __always_inline u32 +static __always_inline __nocfi_generic u32 libeth_xdp_tx_xmit_bulk(const struct libeth_xdp_tx_frame *bulk, void *xdpsq, u32 n, bool unroll, u64 priv, u32 (*prep)(void *xdpsq, struct libeth_xdpsq *sq), diff --git a/include/net/xfrm.h b/include/net/xfrm.h index f3014e4f54fc36..0a14daaa5dd407 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -536,7 +536,8 @@ static inline int xfrm_af2proto(unsigned int family) static inline const struct xfrm_mode *xfrm_ip2inner_mode(struct xfrm_state *x, int ipproto) { - if ((ipproto == IPPROTO_IPIP && x->props.family == AF_INET) || + if ((x->sel.family != AF_UNSPEC) || + (ipproto == IPPROTO_IPIP && x->props.family == AF_INET) || (ipproto == IPPROTO_IPV6 && x->props.family == AF_INET6)) return &x->inner_mode; else diff --git a/include/sound/cs35l56.h b/include/sound/cs35l56.h index 0a740a99ad3142..5928af539c4681 100644 --- a/include/sound/cs35l56.h +++ b/include/sound/cs35l56.h @@ -16,6 +16,8 @@ #include #include +struct snd_ctl_elem_value; + #define CS35L56_DEVID 0x0000000 #define CS35L56_REVID 0x0000004 #define CS35L56_RELID 0x000000C @@ -268,6 +270,10 @@ #define CS35L56_CAL_STATUS_SUCCESS 1 #define CS35L56_CAL_STATUS_OUT_OF_RANGE 3 +#define CS35L56_CAL_SET_STATUS_UNKNOWN 0 +#define CS35L56_CAL_SET_STATUS_DEFAULT 1 +#define CS35L56_CAL_SET_STATUS_SET 2 + #define CS35L56_CONTROL_PORT_READY_US 2200 #define CS35L56_HALO_STATE_POLL_US 1000 #define CS35L56_HALO_STATE_TIMEOUT_US 250000 @@ -363,6 +369,7 @@ extern const struct regmap_config cs35l63_regmap_i2c; extern const struct regmap_config cs35l63_regmap_sdw; extern const struct cirrus_amp_cal_controls cs35l56_calibration_controls; +extern const char * const cs35l56_cal_set_status_text[3]; extern const char * const cs35l56_tx_input_texts[CS35L56_NUM_INPUT_SRC]; extern const unsigned int cs35l56_tx_input_values[CS35L56_NUM_INPUT_SRC]; @@ -381,6 +388,8 @@ int cs35l56_runtime_suspend_common(struct cs35l56_base *cs35l56_base); int cs35l56_runtime_resume_common(struct cs35l56_base *cs35l56_base, bool is_soundwire); void cs35l56_init_cs_dsp(struct cs35l56_base *cs35l56_base, struct cs_dsp *cs_dsp); int cs35l56_get_calibration(struct cs35l56_base *cs35l56_base); +int cs35l56_stash_calibration(struct cs35l56_base *cs35l56_base, + const struct cirrus_amp_cal_data *data); ssize_t cs35l56_calibrate_debugfs_write(struct cs35l56_base *cs35l56_base, const char __user *from, size_t count, loff_t *ppos); @@ -396,8 +405,11 @@ ssize_t cs35l56_cal_data_debugfs_write(struct cs35l56_base *cs35l56_base, void cs35l56_create_cal_debugfs(struct cs35l56_base *cs35l56_base, const struct cs35l56_cal_debugfs_fops *fops); void cs35l56_remove_cal_debugfs(struct cs35l56_base *cs35l56_base); +int cs35l56_cal_set_status_get(struct cs35l56_base *cs35l56_base, + struct snd_ctl_elem_value *uvalue); int cs35l56_read_prot_status(struct cs35l56_base *cs35l56_base, bool *fw_missing, unsigned int *fw_version); +void cs35l56_warn_if_firmware_missing(struct cs35l56_base *cs35l56_base); void cs35l56_log_tuning(struct cs35l56_base *cs35l56_base, struct cs_dsp *cs_dsp); int cs35l56_hw_init(struct cs35l56_base *cs35l56_base); int cs35l56_get_speaker_id(struct cs35l56_base *cs35l56_base); diff --git a/include/sound/sdca.h b/include/sound/sdca.h index d38cdbfeb35f5f..67ff3c88705d5e 100644 --- a/include/sound/sdca.h +++ b/include/sound/sdca.h @@ -13,19 +13,23 @@ #include struct acpi_table_swft; +struct fwnode_handle; struct sdw_slave; +struct sdca_dev; #define SDCA_MAX_FUNCTION_COUNT 8 /** * struct sdca_function_desc - short descriptor for an SDCA Function * @node: firmware node for the Function. + * @func_dev: pointer to SDCA function device. * @name: Human-readable string. * @type: Function topology type. * @adr: ACPI address (used for SDCA register access). */ struct sdca_function_desc { struct fwnode_handle *node; + struct sdca_dev *func_dev; const char *name; u32 type; u8 adr; @@ -58,6 +62,8 @@ void sdca_lookup_functions(struct sdw_slave *slave); void sdca_lookup_swft(struct sdw_slave *slave); void sdca_lookup_interface_revision(struct sdw_slave *slave); bool sdca_device_quirk_match(struct sdw_slave *slave, enum sdca_quirk quirk); +int sdca_dev_register_functions(struct sdw_slave *slave); +void sdca_dev_unregister_functions(struct sdw_slave *slave); #else @@ -68,6 +74,14 @@ static inline bool sdca_device_quirk_match(struct sdw_slave *slave, enum sdca_qu { return false; } + +static inline int sdca_dev_register_functions(struct sdw_slave *slave) +{ + return 0; +} + +static inline void sdca_dev_unregister_functions(struct sdw_slave *slave) {} + #endif #endif diff --git a/include/sound/sdca_fdl.h b/include/sound/sdca_fdl.h index f4ba809cb203a4..fbaf4b384c8af8 100644 --- a/include/sound/sdca_fdl.h +++ b/include/sound/sdca_fdl.h @@ -64,6 +64,8 @@ struct fdl_state { SDCA_CTL_XU_FDLD_ACK_TRANSFER | \ SDCA_CTL_XU_FDLD_NEEDS_SET) +#if IS_ENABLED(CONFIG_SND_SOC_SDCA_FDL) + int sdca_fdl_alloc_state(struct sdca_interrupt *interrupt); int sdca_fdl_process(struct sdca_interrupt *interrupt); int sdca_fdl_sync(struct device *dev, struct sdca_function_data *function, @@ -72,4 +74,32 @@ int sdca_fdl_sync(struct device *dev, struct sdca_function_data *function, int sdca_reset_function(struct device *dev, struct sdca_function_data *function, struct regmap *regmap); +#else + +static inline int sdca_fdl_alloc_state(struct sdca_interrupt *interrupt) +{ + return 0; +} + +static inline int sdca_fdl_process(struct sdca_interrupt *interrupt) +{ + return 0; +} + +static inline int sdca_fdl_sync(struct device *dev, + struct sdca_function_data *function, + struct sdca_interrupt_info *info) +{ + return 0; +} + +static inline int sdca_reset_function(struct device *dev, + struct sdca_function_data *function, + struct regmap *regmap) +{ + return 0; +} + +#endif // CONFIG_SND_SOC_SDCA_FDL + #endif // __SDCA_FDL_H__ diff --git a/include/sound/sdca_function.h b/include/sound/sdca_function.h index 99cb978f7099b1..6e9391b3816c6a 100644 --- a/include/sound/sdca_function.h +++ b/include/sound/sdca_function.h @@ -64,6 +64,7 @@ struct sdca_function_desc; * @SDCA_FUNCTION_TYPE_RJ: Retaskable jack. * @SDCA_FUNCTION_TYPE_SIMPLE_JACK: Subset of UAJ. * @SDCA_FUNCTION_TYPE_HID: Human Interface Device, for e.g. buttons. + * @SDCA_FUNCTION_TYPE_COMPANION_AMP: Sources audio from another amp. * @SDCA_FUNCTION_TYPE_IMP_DEF: Implementation-defined function. * * SDCA Function Types from SDCA specification v1.0a Section 5.1.2 @@ -83,6 +84,7 @@ enum sdca_function_type { SDCA_FUNCTION_TYPE_RJ = 0x07, SDCA_FUNCTION_TYPE_SIMPLE_JACK = 0x08, SDCA_FUNCTION_TYPE_HID = 0x0A, + SDCA_FUNCTION_TYPE_COMPANION_AMP = 0x0B, SDCA_FUNCTION_TYPE_IMP_DEF = 0x1F, }; @@ -96,6 +98,7 @@ enum sdca_function_type { #define SDCA_FUNCTION_TYPE_RJ_NAME "RJ" #define SDCA_FUNCTION_TYPE_SIMPLE_NAME "SimpleJack" #define SDCA_FUNCTION_TYPE_HID_NAME "HID" +#define SDCA_FUNCTION_TYPE_COMPANION_AMP_NAME "CompanionAmp" #define SDCA_FUNCTION_TYPE_IMP_DEF_NAME "ImplementationDefined" /** @@ -608,7 +611,7 @@ enum sdca_entity0_controls { #define SDCA_CTL_NDAI_PACKETTYPE_NAME "NDAI Packet Type" #define SDCA_CTL_MIXER_NAME "Mixer" #define SDCA_CTL_SELECTOR_NAME "Selector" -#define SDCA_CTL_MUTE_NAME "Mute" +#define SDCA_CTL_MUTE_NAME "Channel" #define SDCA_CTL_CHANNEL_VOLUME_NAME "Channel Volume" #define SDCA_CTL_AGC_NAME "AGC" #define SDCA_CTL_BASS_BOOST_NAME "Bass Boost" @@ -1453,6 +1456,8 @@ int sdca_parse_function(struct device *dev, struct sdw_slave *sdw, struct sdca_function_desc *desc, struct sdca_function_data *function); +const char *sdca_find_terminal_name(enum sdca_terminal_type type); + struct sdca_control *sdca_selector_find_control(struct device *dev, struct sdca_entity *entity, const int sel); diff --git a/include/sound/sdca_regmap.h b/include/sound/sdca_regmap.h index b2e3c2ad2bb888..792540a530fc4c 100644 --- a/include/sound/sdca_regmap.h +++ b/include/sound/sdca_regmap.h @@ -27,5 +27,7 @@ int sdca_regmap_populate_constants(struct device *dev, struct sdca_function_data int sdca_regmap_write_defaults(struct device *dev, struct regmap *regmap, struct sdca_function_data *function); +int sdca_regmap_write_init(struct device *dev, struct regmap *regmap, + struct sdca_function_data *function); #endif // __SDCA_REGMAP_H__ diff --git a/include/sound/soc.h b/include/sound/soc.h index 53b4129ee97a84..aa0fe6b802934b 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -319,6 +319,13 @@ struct platform_device; #define SOC_VALUE_ENUM_EXT(xname, xenum, xhandler_get, xhandler_put) \ SOC_ENUM_EXT(xname, xenum, xhandler_get, xhandler_put) +#define SOC_ENUM_EXT_ACC(xname, xenum, xhandler_get, xhandler_put, xaccess) \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ + .access = xaccess, \ + .info = snd_soc_info_enum_double, \ + .get = xhandler_get, .put = xhandler_put, \ + .private_value = (unsigned long)&xenum } + #define SND_SOC_BYTES(xname, xbase, xregs) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ .info = snd_soc_bytes_info, .get = snd_soc_bytes_get, \ @@ -331,6 +338,13 @@ struct platform_device; .put = xhandler_put, .private_value = \ ((unsigned long)&(struct soc_bytes) \ {.base = xbase, .num_regs = xregs }) } +#define SND_SOC_BYTES_E_ACC(xname, xbase, xregs, xhandler_get, xhandler_put, xaccess) \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ + .access = xaccess, \ + .info = snd_soc_bytes_info, .get = xhandler_get, \ + .put = xhandler_put, .private_value = \ + ((unsigned long)&(struct soc_bytes) \ + {.base = xbase, .num_regs = xregs }) } #define SND_SOC_BYTES_MASK(xname, xbase, xregs, xmask) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ @@ -1467,22 +1481,22 @@ static inline void _snd_soc_dapm_mutex_assert_held_c(struct snd_soc_card *card) static inline void _snd_soc_dapm_mutex_lock_root_d(struct snd_soc_dapm_context *dapm) { - _snd_soc_dapm_mutex_lock_root_c(dapm->card); + _snd_soc_dapm_mutex_lock_root_c(snd_soc_dapm_to_card(dapm)); } static inline void _snd_soc_dapm_mutex_lock_d(struct snd_soc_dapm_context *dapm) { - _snd_soc_dapm_mutex_lock_c(dapm->card); + _snd_soc_dapm_mutex_lock_c(snd_soc_dapm_to_card(dapm)); } static inline void _snd_soc_dapm_mutex_unlock_d(struct snd_soc_dapm_context *dapm) { - _snd_soc_dapm_mutex_unlock_c(dapm->card); + _snd_soc_dapm_mutex_unlock_c(snd_soc_dapm_to_card(dapm)); } static inline void _snd_soc_dapm_mutex_assert_held_d(struct snd_soc_dapm_context *dapm) { - _snd_soc_dapm_mutex_assert_held_c(dapm->card); + _snd_soc_dapm_mutex_assert_held_c(snd_soc_dapm_to_card(dapm)); } #define snd_soc_dapm_mutex_lock_root(x) _Generic((x), \ diff --git a/include/sound/soc_sdw_utils.h b/include/sound/soc_sdw_utils.h index 76c64c5245d47c..227347c8f0b336 100644 --- a/include/sound/soc_sdw_utils.h +++ b/include/sound/soc_sdw_utils.h @@ -13,6 +13,7 @@ #include #define SOC_SDW_MAX_DAI_NUM 8 +#define SOC_SDW_MAX_AUX_NUM 2 #define SOC_SDW_MAX_NO_PROPS 2 #define SOC_SDW_JACK_JDSRC(quirk) ((quirk) & GENMASK(3, 0)) @@ -45,6 +46,7 @@ struct asoc_sdw_codec_info; struct asoc_sdw_dai_info { const bool direction[2]; /* playback & capture support */ + const char *codec_name; const char *dai_name; const char *component_name; const int dai_type; @@ -64,10 +66,13 @@ struct asoc_sdw_dai_info { bool quirk_exclude; }; +struct asoc_sdw_aux_info { + const char *codec_name; +}; + struct asoc_sdw_codec_info { const int part_id; const int version_id; - const char *codec_name; const char *name_prefix; int amp_num; const u8 acpi_id[ACPI_ID_LEN]; @@ -75,6 +80,8 @@ struct asoc_sdw_codec_info { const struct snd_soc_ops *ops; struct asoc_sdw_dai_info dais[SOC_SDW_MAX_DAI_NUM]; const int dai_num; + struct asoc_sdw_aux_info auxs[SOC_SDW_MAX_AUX_NUM]; + const int aux_num; int (*codec_card_late_probe)(struct snd_soc_card *card); @@ -131,7 +138,7 @@ int asoc_sdw_hw_free(struct snd_pcm_substream *substream); void asoc_sdw_shutdown(struct snd_pcm_substream *substream); const char *asoc_sdw_get_codec_name(struct device *dev, - const struct asoc_sdw_codec_info *codec_info, + const struct asoc_sdw_dai_info *dai_info, const struct snd_soc_acpi_link_adr *adr_link, int adr_index); @@ -165,13 +172,15 @@ int asoc_sdw_init_simple_dai_link(struct device *dev, struct snd_soc_dai_link *d int no_pcm, int (*init)(struct snd_soc_pcm_runtime *rtd), const struct snd_soc_ops *ops); -int asoc_sdw_count_sdw_endpoints(struct snd_soc_card *card, int *num_devs, int *num_ends); +int asoc_sdw_count_sdw_endpoints(struct snd_soc_card *card, + int *num_devs, int *num_ends, int *num_aux); struct asoc_sdw_dailink *asoc_sdw_find_dailink(struct asoc_sdw_dailink *dailinks, const struct snd_soc_acpi_endpoint *new); int asoc_sdw_get_dai_type(u32 type); int asoc_sdw_parse_sdw_endpoints(struct snd_soc_card *card, + struct snd_soc_aux_dev *soc_aux, struct asoc_sdw_dailink *soc_dais, struct asoc_sdw_endpoint *soc_ends, int *num_devs); @@ -248,6 +257,8 @@ int asoc_sdw_cs42l42_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_da int asoc_sdw_cs42l43_hs_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai); int asoc_sdw_cs42l43_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai); int asoc_sdw_cs42l43_dmic_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai); +int asoc_sdw_cs42l45_hs_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai); +int asoc_sdw_cs42l45_dmic_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai); int asoc_sdw_cs_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai); int asoc_sdw_maxim_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai); /* TI */ diff --git a/include/sound/tas2781.h b/include/sound/tas2781.h index c3b4c43dd2bfc3..9d3c54cb8223c9 100644 --- a/include/sound/tas2781.h +++ b/include/sound/tas2781.h @@ -117,15 +117,20 @@ enum audio_device { TAS2120, TAS2320, TAS2563, + TAS2568, TAS2570, TAS2572, + TAS2574, TAS2781, TAS5802, + TAS5806M, + TAS5806MD, TAS5815, TAS5822, TAS5825, TAS5827, TAS5828, + TAS5830, TAS_OTHERS, }; @@ -198,7 +203,6 @@ struct tasdevice_priv { struct acoustic_data acou_data; #endif struct tasdevice_fw *fmw; - struct gpio_desc *speaker_id; struct gpio_desc *reset; struct mutex codec_lock; struct regmap *regmap; @@ -216,6 +220,7 @@ struct tasdevice_priv { unsigned int magic_num; unsigned int chip_id; unsigned int sysclk; + int speaker_id; int irq; int cur_prog; diff --git a/include/trace/events/asoc.h b/include/trace/events/asoc.h index 6696dbcc2b96dd..4a645549164e91 100644 --- a/include/trace/events/asoc.h +++ b/include/trace/events/asoc.h @@ -27,8 +27,8 @@ DECLARE_EVENT_CLASS(snd_soc_dapm, TP_ARGS(dapm, val), TP_STRUCT__entry( - __string( card_name, dapm->card->name) - __string( comp_name, dapm->component ? dapm->component->name : "(none)") + __string( card_name, snd_soc_dapm_to_card(dapm)->name) + __string( comp_name, snd_soc_dapm_to_component(dapm) ? snd_soc_dapm_to_component(dapm)->name : "(none)") __field( int, val) ), diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h index ea91aa8afde93d..e527b24bd824b1 100644 --- a/include/uapi/drm/drm_fourcc.h +++ b/include/uapi/drm/drm_fourcc.h @@ -979,14 +979,20 @@ extern "C" { * 2 = Gob Height 8, Turing+ Page Kind mapping * 3 = Reserved for future use. * - * 22:22 s Sector layout. On Tegra GPUs prior to Xavier, there is a further - * bit remapping step that occurs at an even lower level than the - * page kind and block linear swizzles. This causes the layout of - * surfaces mapped in those SOC's GPUs to be incompatible with the - * equivalent mapping on other GPUs in the same system. - * - * 0 = Tegra K1 - Tegra Parker/TX2 Layout. - * 1 = Desktop GPU and Tegra Xavier+ Layout + * 22:22 s Sector layout. There is a further bit remapping step that occurs + * 26:27 at an even lower level than the page kind and block linear + * swizzles. This causes the bit arrangement of surfaces in memory + * to differ subtly, and prevents direct sharing of surfaces between + * GPUs with different layouts. + * + * 0 = Tegra K1 - Tegra Parker/TX2 Layout + * 1 = Pre-GB20x, GB20x 32+ bpp, GB10, Tegra Xavier-Orin Layout + * 2 = GB20x(Blackwell 2)+ 8 bpp surface layout + * 3 = GB20x(Blackwell 2)+ 16 bpp surface layout + * 4 = Reserved for future use. + * 5 = Reserved for future use. + * 6 = Reserved for future use. + * 7 = Reserved for future use. * * 25:23 c Lossless Framebuffer Compression type. * @@ -1001,7 +1007,7 @@ extern "C" { * 6 = Reserved for future use * 7 = Reserved for future use * - * 55:25 - Reserved for future use. Must be zero. + * 55:28 - Reserved for future use. Must be zero. */ #define DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(c, s, g, k, h) \ fourcc_mod_code(NVIDIA, (0x10 | \ @@ -1009,6 +1015,7 @@ extern "C" { (((k) & 0xff) << 12) | \ (((g) & 0x3) << 20) | \ (((s) & 0x1) << 22) | \ + (((s) & 0x6) << 25) | \ (((c) & 0x7) << 23))) /* To grandfather in prior block linear format modifiers to the above layout, diff --git a/include/uapi/linux/input-event-codes.h b/include/uapi/linux/input-event-codes.h index 4a9fbf42aa9fa9..30f3c9eaafaad9 100644 --- a/include/uapi/linux/input-event-codes.h +++ b/include/uapi/linux/input-event-codes.h @@ -27,7 +27,7 @@ #define INPUT_PROP_TOPBUTTONPAD 0x04 /* softbuttons at top of pad */ #define INPUT_PROP_POINTING_STICK 0x05 /* is a pointing stick */ #define INPUT_PROP_ACCELEROMETER 0x06 /* has accelerometer */ -#define INPUT_PROP_HAPTIC_TOUCHPAD 0x07 /* is a haptic touchpad */ +#define INPUT_PROP_PRESSUREPAD 0x07 /* pressure triggers clicks */ #define INPUT_PROP_MAX 0x1f #define INPUT_PROP_CNT (INPUT_PROP_MAX + 1) @@ -631,6 +631,18 @@ #define KEY_BRIGHTNESS_MIN 0x250 /* Set Brightness to Minimum */ #define KEY_BRIGHTNESS_MAX 0x251 /* Set Brightness to Maximum */ +/* + * Keycodes for hotkeys toggling the electronic privacy screen found on some + * laptops on/off. Note when the embedded-controller turns on/off the eprivacy + * screen itself then the state should be reported through drm connecter props: + * https://www.kernel.org/doc/html/latest/gpu/drm-kms.html#standard-connector-properties + * Except when implementing the drm connecter properties API is not possible + * because e.g. the firmware does not allow querying the presence and/or status + * of the eprivacy screen at boot. + */ +#define KEY_EPRIVACY_SCREEN_ON 0x252 +#define KEY_EPRIVACY_SCREEN_OFF 0x253 + #define KEY_KBDINPUTASSIST_PREV 0x260 #define KEY_KBDINPUTASSIST_NEXT 0x261 #define KEY_KBDINPUTASSIST_PREVGROUP 0x262 diff --git a/include/uapi/linux/io_uring.h b/include/uapi/linux/io_uring.h index 263bed13473ef1..b7c8dad2669087 100644 --- a/include/uapi/linux/io_uring.h +++ b/include/uapi/linux/io_uring.h @@ -689,9 +689,6 @@ enum io_uring_register_op { /* query various aspects of io_uring, see linux/io_uring/query.h */ IORING_REGISTER_QUERY = 35, - /* return zcrx buffers back into circulation */ - IORING_REGISTER_ZCRX_REFILL = 36, - /* this goes last */ IORING_REGISTER_LAST, @@ -1073,15 +1070,6 @@ struct io_uring_zcrx_ifq_reg { __u64 __resv[3]; }; -struct io_uring_zcrx_sync_refill { - __u32 zcrx_id; - /* the number of entries to return */ - __u32 nr_entries; - /* pointer to an array of struct io_uring_zcrx_rqe */ - __u64 rqes; - __u64 __resv[2]; -}; - #ifdef __cplusplus } #endif diff --git a/include/uapi/linux/io_uring/query.h b/include/uapi/linux/io_uring/query.h index 5d754322a27c80..3539ccbfd0644c 100644 --- a/include/uapi/linux/io_uring/query.h +++ b/include/uapi/linux/io_uring/query.h @@ -36,6 +36,9 @@ struct io_uring_query_opcode { __u64 enter_flags; /* Bitmask of all supported IOSQE_* flags */ __u64 sqe_flags; + /* The number of available query opcodes */ + __u32 nr_query_opcodes; + __u32 __pad; }; #endif diff --git a/include/uapi/linux/isst_if.h b/include/uapi/linux/isst_if.h index 8197a4800604ed..40aa545101a398 100644 --- a/include/uapi/linux/isst_if.h +++ b/include/uapi/linux/isst_if.h @@ -52,7 +52,7 @@ struct isst_if_cpu_map { /** * struct isst_if_cpu_maps - structure for CPU map IOCTL * @cmd_count: Number of CPU mapping command in cpu_map[] - * @cpu_map[]: Holds one or more CPU map data structure + * @cpu_map: Holds one or more CPU map data structure * * This structure used with ioctl ISST_IF_GET_PHY_ID to send * one or more CPU mapping commands. Here IOCTL return value indicates @@ -82,8 +82,8 @@ struct isst_if_io_reg { /** * struct isst_if_io_regs - structure for IO register commands - * @cmd_count: Number of io reg commands in io_reg[] - * @io_reg[]: Holds one or more io_reg command structure + * @req_count: Number of io reg commands in io_reg[] + * @io_reg: Holds one or more io_reg command structure * * This structure used with ioctl ISST_IF_IO_CMD to send * one or more read/write commands to PUNIT. Here IOCTL return value @@ -120,7 +120,7 @@ struct isst_if_mbox_cmd { /** * struct isst_if_mbox_cmds - structure for mailbox commands * @cmd_count: Number of mailbox commands in mbox_cmd[] - * @mbox_cmd[]: Holds one or more mbox commands + * @mbox_cmd: Holds one or more mbox commands * * This structure used with ioctl ISST_IF_MBOX_COMMAND to send * one or more mailbox commands to PUNIT. Here IOCTL return value @@ -152,7 +152,7 @@ struct isst_if_msr_cmd { /** * struct isst_if_msr_cmds - structure for msr commands * @cmd_count: Number of mailbox commands in msr_cmd[] - * @msr_cmd[]: Holds one or more msr commands + * @msr_cmd: Holds one or more msr commands * * This structure used with ioctl ISST_IF_MSR_COMMAND to send * one or more MSR commands. IOCTL return value indicates number of @@ -167,8 +167,9 @@ struct isst_if_msr_cmds { * struct isst_core_power - Structure to get/set core_power feature * @get_set: 0: Get, 1: Set * @socket_id: Socket/package id - * @power_domain: Power Domain id + * @power_domain_id: Power Domain id * @enable: Feature enable status + * @supported: Power domain supports SST_CP interface * @priority_type: Priority type for the feature (ordered/proportional) * * Structure to get/set core_power feature state using IOCTL @@ -187,11 +188,11 @@ struct isst_core_power { * struct isst_clos_param - Structure to get/set clos praram * @get_set: 0: Get, 1: Set * @socket_id: Socket/package id - * @power_domain: Power Domain id - * clos: Clos ID for the parameters - * min_freq_mhz: Minimum frequency in MHz - * max_freq_mhz: Maximum frequency in MHz - * prop_prio: Proportional priority from 0-15 + * @power_domain_id: Power Domain id + * @clos: Clos ID for the parameters + * @min_freq_mhz: Minimum frequency in MHz + * @max_freq_mhz: Maximum frequency in MHz + * @prop_prio: Proportional priority from 0-15 * * Structure to get/set per clos property using IOCTL * ISST_IF_CLOS_PARAM. @@ -209,7 +210,7 @@ struct isst_clos_param { /** * struct isst_if_clos_assoc - Structure to assign clos to a CPU * @socket_id: Socket/package id - * @power_domain: Power Domain id + * @power_domain_id: Power Domain id * @logical_cpu: CPU number * @clos: Clos ID to assign to the logical CPU * @@ -228,6 +229,7 @@ struct isst_if_clos_assoc { * @get_set: Request is for get or set * @punit_cpu_map: Set to 1 if the CPU number is punit numbering not * Linux CPU number + * @assoc_info: CLOS data for this CPU * * Structure used to get/set associate CPUs to clos using IOCTL * ISST_IF_CLOS_ASSOC. @@ -257,7 +259,7 @@ struct isst_tpmi_instance_count { /** * struct isst_perf_level_info - Structure to get information on SST-PP levels * @socket_id: Socket/package id - * @power_domain: Power Domain id + * @power_domain_id: Power Domain id * @logical_cpu: CPU number * @clos: Clos ID to assign to the logical CPU * @max_level: Maximum performance level supported by the platform @@ -267,8 +269,8 @@ struct isst_tpmi_instance_count { * @feature_state: SST-BF and SST-TF (enabled/disabled) status at current level * @locked: SST-PP performance level change is locked/unlocked * @enabled: SST-PP feature is enabled or not - * @sst-tf_support: SST-TF support status at this level - * @sst-bf_support: SST-BF support status at this level + * @sst_tf_support: SST-TF support status at this level + * @sst_bf_support: SST-BF support status at this level * * Structure to get SST-PP details using IOCTL ISST_IF_PERF_LEVELS. */ @@ -289,7 +291,7 @@ struct isst_perf_level_info { /** * struct isst_perf_level_control - Structure to set SST-PP level * @socket_id: Socket/package id - * @power_domain: Power Domain id + * @power_domain_id: Power Domain id * @level: level to set * * Structure used change SST-PP level using IOCTL ISST_IF_PERF_SET_LEVEL. @@ -303,7 +305,7 @@ struct isst_perf_level_control { /** * struct isst_perf_feature_control - Structure to activate SST-BF/SST-TF * @socket_id: Socket/package id - * @power_domain: Power Domain id + * @power_domain_id: Power Domain id * @feature: bit 0 = SST-BF state, bit 1 = SST-TF state * * Structure used to enable SST-BF/SST-TF using IOCTL ISST_IF_PERF_SET_FEATURE. @@ -320,7 +322,7 @@ struct isst_perf_feature_control { /** * struct isst_perf_level_data_info - Structure to get SST-PP level details * @socket_id: Socket/package id - * @power_domain: Power Domain id + * @power_domain_id: Power Domain id * @level: SST-PP level for which caller wants to get information * @tdp_ratio: TDP Ratio * @base_freq_mhz: Base frequency in MHz @@ -341,8 +343,8 @@ struct isst_perf_feature_control { * @pm_fabric_freq_mhz: Fabric (Uncore) minimum frequency * @max_buckets: Maximum trl buckets * @max_trl_levels: Maximum trl levels - * @bucket_core_counts[TRL_MAX_BUCKETS]: Number of cores per bucket - * @trl_freq_mhz[TRL_MAX_LEVELS][TRL_MAX_BUCKETS]: maximum frequency + * @bucket_core_counts: Number of cores per bucket + * @trl_freq_mhz: maximum frequency * for a bucket and trl level * * Structure used to get information on frequencies and TDP for a SST-PP @@ -402,7 +404,7 @@ struct isst_perf_level_fabric_info { /** * struct isst_perf_level_cpu_mask - Structure to get SST-PP level CPU mask * @socket_id: Socket/package id - * @power_domain: Power Domain id + * @power_domain_id: Power Domain id * @level: SST-PP level for which caller wants to get information * @punit_cpu_map: Set to 1 if the CPU number is punit numbering not * Linux CPU number. If 0 CPU buffer is copied to user space @@ -430,7 +432,7 @@ struct isst_perf_level_cpu_mask { /** * struct isst_base_freq_info - Structure to get SST-BF frequencies * @socket_id: Socket/package id - * @power_domain: Power Domain id + * @power_domain_id: Power Domain id * @level: SST-PP level for which caller wants to get information * @high_base_freq_mhz: High priority CPU base frequency * @low_base_freq_mhz: Low priority CPU base frequency @@ -453,9 +455,11 @@ struct isst_base_freq_info { /** * struct isst_turbo_freq_info - Structure to get SST-TF frequencies * @socket_id: Socket/package id - * @power_domain: Power Domain id + * @power_domain_id: Power Domain id * @level: SST-PP level for which caller wants to get information * @max_clip_freqs: Maximum number of low priority core clipping frequencies + * @max_buckets: Maximum trl buckets + * @max_trl_levels: Maximum trl levels * @lp_clip_freq_mhz: Clip frequencies per trl level * @bucket_core_counts: Maximum number of cores for a bucket * @trl_freq_mhz: Frequencies per trl level for each bucket diff --git a/include/uapi/linux/mount.h b/include/uapi/linux/mount.h index 7fa67c2031a5db..5d3f8c9e3a6256 100644 --- a/include/uapi/linux/mount.h +++ b/include/uapi/linux/mount.h @@ -197,7 +197,7 @@ struct statmount { */ struct mnt_id_req { __u32 size; - __u32 spare; + __u32 mnt_ns_fd; __u64 mnt_id; __u64 param; __u64 mnt_ns_id; diff --git a/include/uapi/linux/tee.h b/include/uapi/linux/tee.h index 386ad36f1a0a6e..cab5cadca8ef99 100644 --- a/include/uapi/linux/tee.h +++ b/include/uapi/linux/tee.h @@ -249,8 +249,9 @@ struct tee_ioctl_param { * @cancel_id: [in] Cancellation id, a unique value to identify this request * @session: [out] Session id * @ret: [out] return value - * @ret_origin [out] origin of the return value - * @num_params [in] number of parameters following this struct + * @ret_origin: [out] origin of the return value + * @num_params: [in] number of &struct tee_ioctl_param entries in @params + * @params: array of ioctl parameters */ struct tee_ioctl_open_session_arg { __u8 uuid[TEE_IOCTL_UUID_LEN]; @@ -276,14 +277,14 @@ struct tee_ioctl_open_session_arg { struct tee_ioctl_buf_data) /** - * struct tee_ioctl_invoke_func_arg - Invokes a function in a Trusted - * Application + * struct tee_ioctl_invoke_arg - Invokes a function in a Trusted Application * @func: [in] Trusted Application function, specific to the TA * @session: [in] Session id * @cancel_id: [in] Cancellation id, a unique value to identify this request * @ret: [out] return value - * @ret_origin [out] origin of the return value - * @num_params [in] number of parameters following this struct + * @ret_origin: [out] origin of the return value + * @num_params: [in] number of parameters following this struct + * @params: array of ioctl parameters */ struct tee_ioctl_invoke_arg { __u32 func; @@ -338,7 +339,8 @@ struct tee_ioctl_close_session_arg { /** * struct tee_iocl_supp_recv_arg - Receive a request for a supplicant function * @func: [in] supplicant function - * @num_params [in/out] number of parameters following this struct + * @num_params: [in/out] number of &struct tee_ioctl_param entries in @params + * @params: array of ioctl parameters * * @num_params is the number of params that tee-supplicant has room to * receive when input, @num_params is the number of actual params @@ -363,7 +365,8 @@ struct tee_iocl_supp_recv_arg { /** * struct tee_iocl_supp_send_arg - Send a response to a received request * @ret: [out] return value - * @num_params [in] number of parameters following this struct + * @num_params: [in] number of &struct tee_ioctl_param entries in @params + * @params: array of ioctl parameters */ struct tee_iocl_supp_send_arg { __u32 ret; @@ -454,11 +457,13 @@ struct tee_ioctl_shm_register_fd_data { */ /** - * struct tee_ioctl_invoke_func_arg - Invokes an object in a Trusted Application + * struct tee_ioctl_object_invoke_arg - Invokes an object in a + * Trusted Application * @id: [in] Object id * @op: [in] Object operation, specific to the object * @ret: [out] return value * @num_params: [in] number of parameters following this struct + * @params: array of ioctl parameters */ struct tee_ioctl_object_invoke_arg { __u64 id; diff --git a/include/uapi/linux/virtio_net.h b/include/uapi/linux/virtio_net.h index 8bf27ab8bcb4dd..1db45b01532b58 100644 --- a/include/uapi/linux/virtio_net.h +++ b/include/uapi/linux/virtio_net.h @@ -193,7 +193,8 @@ struct virtio_net_hdr_v1 { struct virtio_net_hdr_v1_hash { struct virtio_net_hdr_v1 hdr; - __le32 hash_value; + __le16 hash_value_lo; + __le16 hash_value_hi; #define VIRTIO_NET_HASH_REPORT_NONE 0 #define VIRTIO_NET_HASH_REPORT_IPv4 1 #define VIRTIO_NET_HASH_REPORT_TCPv4 2 diff --git a/include/uapi/sound/intel/avs/tokens.h b/include/uapi/sound/intel/avs/tokens.h index f3ff6aae09a9ec..3ff6d9150822f2 100644 --- a/include/uapi/sound/intel/avs/tokens.h +++ b/include/uapi/sound/intel/avs/tokens.h @@ -21,6 +21,7 @@ enum avs_tplg_token { AVS_TKN_MANIFEST_NUM_BINDINGS_U32 = 8, AVS_TKN_MANIFEST_NUM_CONDPATH_TMPLS_U32 = 9, AVS_TKN_MANIFEST_NUM_INIT_CONFIGS_U32 = 10, + AVS_TKN_MANIFEST_NUM_NHLT_CONFIGS_U32 = 11, /* struct avs_tplg_library */ AVS_TKN_LIBRARY_ID_U32 = 101, @@ -124,6 +125,7 @@ enum avs_tplg_token { AVS_TKN_MOD_KCONTROL_ID_U32 = 1707, AVS_TKN_MOD_INIT_CONFIG_NUM_IDS_U32 = 1708, AVS_TKN_MOD_INIT_CONFIG_ID_U32 = 1709, + AVS_TKN_MOD_NHLT_CONFIG_ID_U32 = 1710, /* struct avs_tplg_path_template */ AVS_TKN_PATH_TMPL_ID_U32 = 1801, @@ -160,6 +162,10 @@ enum avs_tplg_token { AVS_TKN_INIT_CONFIG_ID_U32 = 2401, AVS_TKN_INIT_CONFIG_PARAM_U8 = 2402, AVS_TKN_INIT_CONFIG_LENGTH_U32 = 2403, + + /* struct avs_tplg_nhlt_config */ + AVS_TKN_NHLT_CONFIG_ID_U32 = 2501, + AVS_TKN_NHLT_CONFIG_SIZE_U32 = 2502, }; #endif diff --git a/include/ufs/ufshcd.h b/include/ufs/ufshcd.h index 9425cfd9d00eb0..0f95576bf1f6ca 100644 --- a/include/ufs/ufshcd.h +++ b/include/ufs/ufshcd.h @@ -688,6 +688,13 @@ enum ufshcd_quirks { * single doorbell mode. */ UFSHCD_QUIRK_BROKEN_LSDBS_CAP = 1 << 25, + + /* + * This quirk indicates that DME_LINKSTARTUP should not be issued a 2nd + * time (refer link_startup_again) after the 1st time was successful, + * because it causes link startup to become unreliable. + */ + UFSHCD_QUIRK_PERFORM_LINK_STARTUP_ONCE = 1 << 26, }; enum ufshcd_caps { diff --git a/io_uring/cmd_net.c b/io_uring/cmd_net.c index 27a09aa4c9d0b4..3b75931bd56952 100644 --- a/io_uring/cmd_net.c +++ b/io_uring/cmd_net.c @@ -127,7 +127,7 @@ static int io_uring_cmd_timestamp(struct socket *sock, if (!unlikely(skb_queue_empty(&list))) { scoped_guard(spinlock_irqsave, &q->lock) - skb_queue_splice(q, &list); + skb_queue_splice(&list, q); } return -EAGAIN; } diff --git a/io_uring/memmap.c b/io_uring/memmap.c index 2e99dffddfc5cc..add03ca75cb90e 100644 --- a/io_uring/memmap.c +++ b/io_uring/memmap.c @@ -135,7 +135,7 @@ static int io_region_pin_pages(struct io_ring_ctx *ctx, struct io_mapped_region *mr, struct io_uring_region_desc *reg) { - unsigned long size = mr->nr_pages << PAGE_SHIFT; + unsigned long size = (size_t) mr->nr_pages << PAGE_SHIFT; struct page **pages; int nr_pages; diff --git a/io_uring/query.c b/io_uring/query.c index 645301bd2c8293..cf02893ba911b6 100644 --- a/io_uring/query.c +++ b/io_uring/query.c @@ -20,6 +20,8 @@ static ssize_t io_query_ops(void *data) e->ring_setup_flags = IORING_SETUP_FLAGS; e->enter_flags = IORING_ENTER_FLAGS; e->sqe_flags = SQE_VALID_FLAGS; + e->nr_query_opcodes = __IO_URING_QUERY_MAX; + e->__pad = 0; return sizeof(*e); } diff --git a/io_uring/register.c b/io_uring/register.c index 2e4717f1357c7a..d189b266b8ccec 100644 --- a/io_uring/register.c +++ b/io_uring/register.c @@ -827,9 +827,6 @@ static int __io_uring_register(struct io_ring_ctx *ctx, unsigned opcode, case IORING_REGISTER_QUERY: ret = io_query(ctx, arg, nr_args); break; - case IORING_REGISTER_ZCRX_REFILL: - ret = io_zcrx_return_bufs(ctx, arg, nr_args); - break; default: ret = -EINVAL; break; diff --git a/io_uring/rsrc.c b/io_uring/rsrc.c index d787c16dc1c3a2..0010c499249060 100644 --- a/io_uring/rsrc.c +++ b/io_uring/rsrc.c @@ -943,8 +943,8 @@ int io_buffer_register_bvec(struct io_uring_cmd *cmd, struct request *rq, struct req_iterator rq_iter; struct io_mapped_ubuf *imu; struct io_rsrc_node *node; - struct bio_vec bv, *bvec; - u16 nr_bvecs; + struct bio_vec bv; + unsigned int nr_bvecs = 0; int ret = 0; io_ring_submit_lock(ctx, issue_flags); @@ -965,8 +965,11 @@ int io_buffer_register_bvec(struct io_uring_cmd *cmd, struct request *rq, goto unlock; } - nr_bvecs = blk_rq_nr_phys_segments(rq); - imu = io_alloc_imu(ctx, nr_bvecs); + /* + * blk_rq_nr_phys_segments() may overestimate the number of bvecs + * but avoids needing to iterate over the bvecs + */ + imu = io_alloc_imu(ctx, blk_rq_nr_phys_segments(rq)); if (!imu) { kfree(node); ret = -ENOMEM; @@ -977,16 +980,15 @@ int io_buffer_register_bvec(struct io_uring_cmd *cmd, struct request *rq, imu->len = blk_rq_bytes(rq); imu->acct_pages = 0; imu->folio_shift = PAGE_SHIFT; - imu->nr_bvecs = nr_bvecs; refcount_set(&imu->refs, 1); imu->release = release; imu->priv = rq; imu->is_kbuf = true; imu->dir = 1 << rq_data_dir(rq); - bvec = imu->bvec; rq_for_each_bvec(bv, rq, rq_iter) - *bvec++ = bv; + imu->bvec[nr_bvecs++] = bv; + imu->nr_bvecs = nr_bvecs; node->buf = imu; data->nodes[index] = node; @@ -1403,8 +1405,11 @@ static int io_estimate_bvec_size(struct iovec *iov, unsigned nr_iovs, size_t max_segs = 0; unsigned i; - for (i = 0; i < nr_iovs; i++) + for (i = 0; i < nr_iovs; i++) { max_segs += (iov[i].iov_len >> shift) + 2; + if (max_segs > INT_MAX) + return -EOVERFLOW; + } return max_segs; } @@ -1510,7 +1515,11 @@ int io_import_reg_vec(int ddir, struct iov_iter *iter, if (unlikely(ret)) return ret; } else { - nr_segs = io_estimate_bvec_size(iov, nr_iovs, imu); + int ret = io_estimate_bvec_size(iov, nr_iovs, imu); + + if (ret < 0) + return ret; + nr_segs = ret; } if (sizeof(struct bio_vec) > sizeof(struct iovec)) { diff --git a/io_uring/rw.c b/io_uring/rw.c index 5b2241a5813c98..abe68ba9c9dc85 100644 --- a/io_uring/rw.c +++ b/io_uring/rw.c @@ -463,7 +463,10 @@ int io_read_mshot_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) void io_readv_writev_cleanup(struct io_kiocb *req) { + struct io_async_rw *rw = req->async_data; + lockdep_assert_held(&req->ctx->uring_lock); + io_vec_free(&rw->vec); io_rw_recycle(req, 0); } diff --git a/io_uring/zcrx.c b/io_uring/zcrx.c index a816f5902091cd..b1b723222cdb81 100644 --- a/io_uring/zcrx.c +++ b/io_uring/zcrx.c @@ -928,74 +928,6 @@ static const struct memory_provider_ops io_uring_pp_zc_ops = { .uninstall = io_pp_uninstall, }; -#define IO_ZCRX_MAX_SYS_REFILL_BUFS (1 << 16) -#define IO_ZCRX_SYS_REFILL_BATCH 32 - -static void io_return_buffers(struct io_zcrx_ifq *ifq, - struct io_uring_zcrx_rqe *rqes, unsigned nr) -{ - int i; - - for (i = 0; i < nr; i++) { - struct net_iov *niov; - netmem_ref netmem; - - if (!io_parse_rqe(&rqes[i], ifq, &niov)) - continue; - - scoped_guard(spinlock_bh, &ifq->rq_lock) { - if (!io_zcrx_put_niov_uref(niov)) - continue; - } - - netmem = net_iov_to_netmem(niov); - if (!page_pool_unref_and_test(netmem)) - continue; - io_zcrx_return_niov(niov); - } -} - -int io_zcrx_return_bufs(struct io_ring_ctx *ctx, - void __user *arg, unsigned nr_arg) -{ - struct io_uring_zcrx_rqe rqes[IO_ZCRX_SYS_REFILL_BATCH]; - struct io_uring_zcrx_rqe __user *user_rqes; - struct io_uring_zcrx_sync_refill zr; - struct io_zcrx_ifq *ifq; - unsigned nr, i; - - if (nr_arg) - return -EINVAL; - if (copy_from_user(&zr, arg, sizeof(zr))) - return -EFAULT; - if (!zr.nr_entries || zr.nr_entries > IO_ZCRX_MAX_SYS_REFILL_BUFS) - return -EINVAL; - if (!mem_is_zero(&zr.__resv, sizeof(zr.__resv))) - return -EINVAL; - - ifq = xa_load(&ctx->zcrx_ctxs, zr.zcrx_id); - if (!ifq) - return -EINVAL; - nr = zr.nr_entries; - user_rqes = u64_to_user_ptr(zr.rqes); - - for (i = 0; i < nr;) { - unsigned batch = min(nr - i, IO_ZCRX_SYS_REFILL_BATCH); - size_t size = batch * sizeof(rqes[0]); - - if (copy_from_user(rqes, user_rqes + i, size)) - return i ? i : -EFAULT; - io_return_buffers(ifq, rqes, batch); - - i += batch; - - if (fatal_signal_pending(current)) - return i; - cond_resched(); - } - return nr; -} - static bool io_zcrx_queue_cqe(struct io_kiocb *req, struct net_iov *niov, struct io_zcrx_ifq *ifq, int off, int len) { diff --git a/io_uring/zcrx.h b/io_uring/zcrx.h index 33ef61503092df..a48871b5adad2d 100644 --- a/io_uring/zcrx.h +++ b/io_uring/zcrx.h @@ -63,8 +63,6 @@ struct io_zcrx_ifq { }; #if defined(CONFIG_IO_URING_ZCRX) -int io_zcrx_return_bufs(struct io_ring_ctx *ctx, - void __user *arg, unsigned nr_arg); int io_register_zcrx_ifq(struct io_ring_ctx *ctx, struct io_uring_zcrx_ifq_reg __user *arg); void io_unregister_zcrx_ifqs(struct io_ring_ctx *ctx); @@ -97,11 +95,6 @@ static inline struct io_mapped_region *io_zcrx_get_region(struct io_ring_ctx *ct { return NULL; } -static inline int io_zcrx_return_bufs(struct io_ring_ctx *ctx, - void __user *arg, unsigned nr_arg) -{ - return -EOPNOTSUPP; -} #endif int io_recvzc(struct io_kiocb *req, unsigned int issue_flags); diff --git a/kernel/Kconfig.kexec b/kernel/Kconfig.kexec index 422270d6482020..54e58107261769 100644 --- a/kernel/Kconfig.kexec +++ b/kernel/Kconfig.kexec @@ -109,6 +109,15 @@ config KEXEC_HANDOVER to keep data or state alive across the kexec. For this to work, both source and target kernels need to have this option enabled. +config KEXEC_HANDOVER_DEBUG + bool "Enable Kexec Handover debug checks" + depends on KEXEC_HANDOVER + help + This option enables extra sanity checks for the Kexec Handover + subsystem. Since, KHO performance is crucial in live update + scenarios and the extra code might be adding overhead it is + only optionally enabled. + config CRASH_DUMP bool "kernel crash dumps" default ARCH_DEFAULT_CRASH_DUMP diff --git a/kernel/Makefile b/kernel/Makefile index df3dd8291bb601..9fe722305c9bec 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -83,6 +83,7 @@ obj-$(CONFIG_KEXEC) += kexec.o obj-$(CONFIG_KEXEC_FILE) += kexec_file.o obj-$(CONFIG_KEXEC_ELF) += kexec_elf.o obj-$(CONFIG_KEXEC_HANDOVER) += kexec_handover.o +obj-$(CONFIG_KEXEC_HANDOVER_DEBUG) += kexec_handover_debug.o obj-$(CONFIG_BACKTRACE_SELF_TEST) += backtracetest.o obj-$(CONFIG_COMPAT) += compat.o obj-$(CONFIG_CGROUPS) += cgroup/ diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c index eb25e70e0bdc03..e4007fea49091c 100644 --- a/kernel/bpf/helpers.c +++ b/kernel/bpf/helpers.c @@ -4169,7 +4169,8 @@ static int bpf_task_work_schedule(struct task_struct *task, struct bpf_task_work } /** - * bpf_task_work_schedule_signal - Schedule BPF callback using task_work_add with TWA_SIGNAL mode + * bpf_task_work_schedule_signal_impl - Schedule BPF callback using task_work_add with TWA_SIGNAL + * mode * @task: Task struct for which callback should be scheduled * @tw: Pointer to struct bpf_task_work in BPF map value for internal bookkeeping * @map__map: bpf_map that embeds struct bpf_task_work in the values @@ -4178,15 +4179,17 @@ static int bpf_task_work_schedule(struct task_struct *task, struct bpf_task_work * * Return: 0 if task work has been scheduled successfully, negative error code otherwise */ -__bpf_kfunc int bpf_task_work_schedule_signal(struct task_struct *task, struct bpf_task_work *tw, - void *map__map, bpf_task_work_callback_t callback, - void *aux__prog) +__bpf_kfunc int bpf_task_work_schedule_signal_impl(struct task_struct *task, + struct bpf_task_work *tw, void *map__map, + bpf_task_work_callback_t callback, + void *aux__prog) { return bpf_task_work_schedule(task, tw, map__map, callback, aux__prog, TWA_SIGNAL); } /** - * bpf_task_work_schedule_resume - Schedule BPF callback using task_work_add with TWA_RESUME mode + * bpf_task_work_schedule_resume_impl - Schedule BPF callback using task_work_add with TWA_RESUME + * mode * @task: Task struct for which callback should be scheduled * @tw: Pointer to struct bpf_task_work in BPF map value for internal bookkeeping * @map__map: bpf_map that embeds struct bpf_task_work in the values @@ -4195,9 +4198,10 @@ __bpf_kfunc int bpf_task_work_schedule_signal(struct task_struct *task, struct b * * Return: 0 if task work has been scheduled successfully, negative error code otherwise */ -__bpf_kfunc int bpf_task_work_schedule_resume(struct task_struct *task, struct bpf_task_work *tw, - void *map__map, bpf_task_work_callback_t callback, - void *aux__prog) +__bpf_kfunc int bpf_task_work_schedule_resume_impl(struct task_struct *task, + struct bpf_task_work *tw, void *map__map, + bpf_task_work_callback_t callback, + void *aux__prog) { return bpf_task_work_schedule(task, tw, map__map, callback, aux__prog, TWA_RESUME); } @@ -4376,9 +4380,9 @@ BTF_ID_FLAGS(func, bpf_strnstr); #if defined(CONFIG_BPF_LSM) && defined(CONFIG_CGROUPS) BTF_ID_FLAGS(func, bpf_cgroup_read_xattr, KF_RCU) #endif -BTF_ID_FLAGS(func, bpf_stream_vprintk, KF_TRUSTED_ARGS) -BTF_ID_FLAGS(func, bpf_task_work_schedule_signal, KF_TRUSTED_ARGS) -BTF_ID_FLAGS(func, bpf_task_work_schedule_resume, KF_TRUSTED_ARGS) +BTF_ID_FLAGS(func, bpf_stream_vprintk_impl, KF_TRUSTED_ARGS) +BTF_ID_FLAGS(func, bpf_task_work_schedule_signal_impl, KF_TRUSTED_ARGS) +BTF_ID_FLAGS(func, bpf_task_work_schedule_resume_impl, KF_TRUSTED_ARGS) BTF_KFUNCS_END(common_btf_ids) static const struct btf_kfunc_id_set common_kfunc_set = { diff --git a/kernel/bpf/stream.c b/kernel/bpf/stream.c index eb6c5a21c2efee..ff16c631951bb6 100644 --- a/kernel/bpf/stream.c +++ b/kernel/bpf/stream.c @@ -355,7 +355,8 @@ __bpf_kfunc_start_defs(); * Avoid using enum bpf_stream_id so that kfunc users don't have to pull in the * enum in headers. */ -__bpf_kfunc int bpf_stream_vprintk(int stream_id, const char *fmt__str, const void *args, u32 len__sz, void *aux__prog) +__bpf_kfunc int bpf_stream_vprintk_impl(int stream_id, const char *fmt__str, const void *args, + u32 len__sz, void *aux__prog) { struct bpf_bprintf_data data = { .get_bin_args = true, diff --git a/kernel/bpf/trampoline.c b/kernel/bpf/trampoline.c index 5949095e51c3d0..f2cb0b09709330 100644 --- a/kernel/bpf/trampoline.c +++ b/kernel/bpf/trampoline.c @@ -479,11 +479,6 @@ static int bpf_trampoline_update(struct bpf_trampoline *tr, bool lock_direct_mut * BPF_TRAMP_F_SHARE_IPMODIFY is set, we can generate the * trampoline again, and retry register. */ - /* reset fops->func and fops->trampoline for re-register */ - tr->fops->func = NULL; - tr->fops->trampoline = 0; - - /* free im memory and reallocate later */ bpf_tramp_image_free(im); goto again; } diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index ff40e5e65c4358..fbe4bb91c564ae 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -8866,7 +8866,7 @@ static int widen_imprecise_scalars(struct bpf_verifier_env *env, struct bpf_verifier_state *cur) { struct bpf_func_state *fold, *fcur; - int i, fr; + int i, fr, num_slots; reset_idmap_scratch(env); for (fr = old->curframe; fr >= 0; fr--) { @@ -8879,7 +8879,9 @@ static int widen_imprecise_scalars(struct bpf_verifier_env *env, &fcur->regs[i], &env->idmap_scratch); - for (i = 0; i < fold->allocated_stack / BPF_REG_SIZE; i++) { + num_slots = min(fold->allocated_stack / BPF_REG_SIZE, + fcur->allocated_stack / BPF_REG_SIZE); + for (i = 0; i < num_slots; i++) { if (!is_spilled_reg(&fold->stack[i]) || !is_spilled_reg(&fcur->stack[i])) continue; @@ -12259,8 +12261,8 @@ enum special_kfunc_type { KF_bpf_res_spin_lock_irqsave, KF_bpf_res_spin_unlock_irqrestore, KF___bpf_trap, - KF_bpf_task_work_schedule_signal, - KF_bpf_task_work_schedule_resume, + KF_bpf_task_work_schedule_signal_impl, + KF_bpf_task_work_schedule_resume_impl, }; BTF_ID_LIST(special_kfunc_list) @@ -12331,13 +12333,13 @@ BTF_ID(func, bpf_res_spin_unlock) BTF_ID(func, bpf_res_spin_lock_irqsave) BTF_ID(func, bpf_res_spin_unlock_irqrestore) BTF_ID(func, __bpf_trap) -BTF_ID(func, bpf_task_work_schedule_signal) -BTF_ID(func, bpf_task_work_schedule_resume) +BTF_ID(func, bpf_task_work_schedule_signal_impl) +BTF_ID(func, bpf_task_work_schedule_resume_impl) static bool is_task_work_add_kfunc(u32 func_id) { - return func_id == special_kfunc_list[KF_bpf_task_work_schedule_signal] || - func_id == special_kfunc_list[KF_bpf_task_work_schedule_resume]; + return func_id == special_kfunc_list[KF_bpf_task_work_schedule_signal_impl] || + func_id == special_kfunc_list[KF_bpf_task_work_schedule_resume_impl]; } static bool is_kfunc_ret_null(struct bpf_kfunc_call_arg_meta *meta) diff --git a/kernel/crash_core.c b/kernel/crash_core.c index 3b1c43382eec6d..99dac1aa972af0 100644 --- a/kernel/crash_core.c +++ b/kernel/crash_core.c @@ -373,7 +373,7 @@ static int __crash_shrink_memory(struct resource *old_res, old_res->start = 0; old_res->end = 0; } else { - crashk_res.end = ram_res->start - 1; + old_res->end = ram_res->start - 1; } crash_free_reserved_phys_range(ram_res->start, ram_res->end); diff --git a/kernel/events/core.c b/kernel/events/core.c index 177e57c1a362f2..2c35acc2722b0f 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -11773,7 +11773,8 @@ static enum hrtimer_restart perf_swevent_hrtimer(struct hrtimer *hrtimer) event = container_of(hrtimer, struct perf_event, hw.hrtimer); - if (event->state != PERF_EVENT_STATE_ACTIVE) + if (event->state != PERF_EVENT_STATE_ACTIVE || + event->hw.state & PERF_HES_STOPPED) return HRTIMER_NORESTART; event->pmu->read(event); @@ -11819,15 +11820,20 @@ static void perf_swevent_cancel_hrtimer(struct perf_event *event) struct hw_perf_event *hwc = &event->hw; /* - * The throttle can be triggered in the hrtimer handler. - * The HRTIMER_NORESTART should be used to stop the timer, - * rather than hrtimer_cancel(). See perf_swevent_hrtimer() + * Careful: this function can be triggered in the hrtimer handler, + * for cpu-clock events, so hrtimer_cancel() would cause a + * deadlock. + * + * So use hrtimer_try_to_cancel() to try to stop the hrtimer, + * and the cpu-clock handler also sets the PERF_HES_STOPPED flag, + * which guarantees that perf_swevent_hrtimer() will stop the + * hrtimer once it sees the PERF_HES_STOPPED flag. */ if (is_sampling_event(event) && (hwc->interrupts != MAX_INTERRUPTS)) { ktime_t remaining = hrtimer_get_remaining(&hwc->hrtimer); local64_set(&hwc->period_left, ktime_to_ns(remaining)); - hrtimer_cancel(&hwc->hrtimer); + hrtimer_try_to_cancel(&hwc->hrtimer); } } @@ -11871,12 +11877,14 @@ static void cpu_clock_event_update(struct perf_event *event) static void cpu_clock_event_start(struct perf_event *event, int flags) { + event->hw.state = 0; local64_set(&event->hw.prev_count, local_clock()); perf_swevent_start_hrtimer(event); } static void cpu_clock_event_stop(struct perf_event *event, int flags) { + event->hw.state = PERF_HES_STOPPED; perf_swevent_cancel_hrtimer(event); if (flags & PERF_EF_UPDATE) cpu_clock_event_update(event); @@ -11893,7 +11901,7 @@ static int cpu_clock_event_add(struct perf_event *event, int flags) static void cpu_clock_event_del(struct perf_event *event, int flags) { - cpu_clock_event_stop(event, flags); + cpu_clock_event_stop(event, PERF_EF_UPDATE); } static void cpu_clock_event_read(struct perf_event *event) @@ -11950,12 +11958,14 @@ static void task_clock_event_update(struct perf_event *event, u64 now) static void task_clock_event_start(struct perf_event *event, int flags) { + event->hw.state = 0; local64_set(&event->hw.prev_count, event->ctx->time); perf_swevent_start_hrtimer(event); } static void task_clock_event_stop(struct perf_event *event, int flags) { + event->hw.state = PERF_HES_STOPPED; perf_swevent_cancel_hrtimer(event); if (flags & PERF_EF_UPDATE) task_clock_event_update(event, event->ctx->time); diff --git a/kernel/futex/core.c b/kernel/futex/core.c index 125804fbb5cb17..2e77a6e5c8657b 100644 --- a/kernel/futex/core.c +++ b/kernel/futex/core.c @@ -1680,10 +1680,10 @@ static bool futex_ref_get(struct futex_private_hash *fph) { struct mm_struct *mm = fph->mm; - guard(rcu)(); + guard(preempt)(); - if (smp_load_acquire(&fph->state) == FR_PERCPU) { - this_cpu_inc(*mm->futex_ref); + if (READ_ONCE(fph->state) == FR_PERCPU) { + __this_cpu_inc(*mm->futex_ref); return true; } @@ -1694,10 +1694,10 @@ static bool futex_ref_put(struct futex_private_hash *fph) { struct mm_struct *mm = fph->mm; - guard(rcu)(); + guard(preempt)(); - if (smp_load_acquire(&fph->state) == FR_PERCPU) { - this_cpu_dec(*mm->futex_ref); + if (READ_ONCE(fph->state) == FR_PERCPU) { + __this_cpu_dec(*mm->futex_ref); return false; } diff --git a/kernel/gcov/gcc_4_7.c b/kernel/gcov/gcc_4_7.c index a08cc076f3322f..ffde93d051a471 100644 --- a/kernel/gcov/gcc_4_7.c +++ b/kernel/gcov/gcc_4_7.c @@ -18,7 +18,9 @@ #include #include "gcov.h" -#if (__GNUC__ >= 14) +#if (__GNUC__ >= 15) +#define GCOV_COUNTERS 10 +#elif (__GNUC__ >= 14) #define GCOV_COUNTERS 9 #elif (__GNUC__ >= 10) #define GCOV_COUNTERS 8 diff --git a/kernel/kexec_handover.c b/kernel/kexec_handover.c index 76f0940fb48560..03d12e27189fc4 100644 --- a/kernel/kexec_handover.c +++ b/kernel/kexec_handover.c @@ -8,6 +8,7 @@ #define pr_fmt(fmt) "KHO: " fmt +#include #include #include #include @@ -22,6 +23,7 @@ #include +#include "kexec_handover_internal.h" /* * KHO is tightly coupled with mm init and needs access to some of mm * internal APIs. @@ -67,10 +69,10 @@ early_param("kho", kho_parse_enable); * Keep track of memory that is to be preserved across KHO. * * The serializing side uses two levels of xarrays to manage chunks of per-order - * 512 byte bitmaps. For instance if PAGE_SIZE = 4096, the entire 1G order of a - * 1TB system would fit inside a single 512 byte bitmap. For order 0 allocations - * each bitmap will cover 16M of address space. Thus, for 16G of memory at most - * 512K of bitmap memory will be needed for order 0. + * PAGE_SIZE byte bitmaps. For instance if PAGE_SIZE = 4096, the entire 1G order + * of a 8TB system would fit inside a single 4096 byte bitmap. For order 0 + * allocations each bitmap will cover 128M of address space. Thus, for 16G of + * memory at most 512K of bitmap memory will be needed for order 0. * * This approach is fully incremental, as the serialization progresses folios * can continue be aggregated to the tracker. The final step, immediately prior @@ -78,12 +80,14 @@ early_param("kho", kho_parse_enable); * successor kernel to parse. */ -#define PRESERVE_BITS (512 * 8) +#define PRESERVE_BITS (PAGE_SIZE * 8) struct kho_mem_phys_bits { DECLARE_BITMAP(preserve, PRESERVE_BITS); }; +static_assert(sizeof(struct kho_mem_phys_bits) == PAGE_SIZE); + struct kho_mem_phys { /* * Points to kho_mem_phys_bits, a sparse bitmap array. Each bit is sized @@ -131,28 +135,28 @@ static struct kho_out kho_out = { .finalized = false, }; -static void *xa_load_or_alloc(struct xarray *xa, unsigned long index, size_t sz) +static void *xa_load_or_alloc(struct xarray *xa, unsigned long index) { - void *elm, *res; + void *res = xa_load(xa, index); + + if (res) + return res; - elm = xa_load(xa, index); - if (elm) - return elm; + void *elm __free(free_page) = (void *)get_zeroed_page(GFP_KERNEL); - elm = kzalloc(sz, GFP_KERNEL); if (!elm) return ERR_PTR(-ENOMEM); + if (WARN_ON(kho_scratch_overlap(virt_to_phys(elm), PAGE_SIZE))) + return ERR_PTR(-EINVAL); + res = xa_cmpxchg(xa, index, NULL, elm, GFP_KERNEL); if (xa_is_err(res)) - res = ERR_PTR(xa_err(res)); - - if (res) { - kfree(elm); + return ERR_PTR(xa_err(res)); + else if (res) return res; - } - return elm; + return no_free_ptr(elm); } static void __kho_unpreserve(struct kho_mem_track *track, unsigned long pfn, @@ -167,12 +171,12 @@ static void __kho_unpreserve(struct kho_mem_track *track, unsigned long pfn, const unsigned long pfn_high = pfn >> order; physxa = xa_load(&track->orders, order); - if (!physxa) - continue; + if (WARN_ON_ONCE(!physxa)) + return; bits = xa_load(&physxa->phys_bits, pfn_high / PRESERVE_BITS); - if (!bits) - continue; + if (WARN_ON_ONCE(!bits)) + return; clear_bit(pfn_high % PRESERVE_BITS, bits->preserve); @@ -216,8 +220,7 @@ static int __kho_preserve_order(struct kho_mem_track *track, unsigned long pfn, } } - bits = xa_load_or_alloc(&physxa->phys_bits, pfn_high / PRESERVE_BITS, - sizeof(*bits)); + bits = xa_load_or_alloc(&physxa->phys_bits, pfn_high / PRESERVE_BITS); if (IS_ERR(bits)) return PTR_ERR(bits); @@ -345,15 +348,19 @@ static_assert(sizeof(struct khoser_mem_chunk) == PAGE_SIZE); static struct khoser_mem_chunk *new_chunk(struct khoser_mem_chunk *cur_chunk, unsigned long order) { - struct khoser_mem_chunk *chunk; + struct khoser_mem_chunk *chunk __free(free_page) = NULL; - chunk = kzalloc(PAGE_SIZE, GFP_KERNEL); + chunk = (void *)get_zeroed_page(GFP_KERNEL); if (!chunk) - return NULL; + return ERR_PTR(-ENOMEM); + + if (WARN_ON(kho_scratch_overlap(virt_to_phys(chunk), PAGE_SIZE))) + return ERR_PTR(-EINVAL); + chunk->hdr.order = order; if (cur_chunk) KHOSER_STORE_PTR(cur_chunk->hdr.next, chunk); - return chunk; + return no_free_ptr(chunk); } static void kho_mem_ser_free(struct khoser_mem_chunk *first_chunk) @@ -374,14 +381,17 @@ static int kho_mem_serialize(struct kho_serialization *ser) struct khoser_mem_chunk *chunk = NULL; struct kho_mem_phys *physxa; unsigned long order; + int err = -ENOMEM; xa_for_each(&ser->track.orders, order, physxa) { struct kho_mem_phys_bits *bits; unsigned long phys; chunk = new_chunk(chunk, order); - if (!chunk) + if (IS_ERR(chunk)) { + err = PTR_ERR(chunk); goto err_free; + } if (!first_chunk) first_chunk = chunk; @@ -391,8 +401,10 @@ static int kho_mem_serialize(struct kho_serialization *ser) if (chunk->hdr.num_elms == ARRAY_SIZE(chunk->bitmaps)) { chunk = new_chunk(chunk, order); - if (!chunk) + if (IS_ERR(chunk)) { + err = PTR_ERR(chunk); goto err_free; + } } elm = &chunk->bitmaps[chunk->hdr.num_elms]; @@ -409,7 +421,7 @@ static int kho_mem_serialize(struct kho_serialization *ser) err_free: kho_mem_ser_free(first_chunk); - return -ENOMEM; + return err; } static void __init deserialize_bitmap(unsigned int order, @@ -465,8 +477,8 @@ static void __init kho_mem_deserialize(const void *fdt) * area for early allocations that happen before page allocator is * initialized. */ -static struct kho_scratch *kho_scratch; -static unsigned int kho_scratch_cnt; +struct kho_scratch *kho_scratch; +unsigned int kho_scratch_cnt; /* * The scratch areas are scaled by default as percent of memory allocated from @@ -752,6 +764,9 @@ int kho_preserve_folio(struct folio *folio) const unsigned int order = folio_order(folio); struct kho_mem_track *track = &kho_out.ser.track; + if (WARN_ON(kho_scratch_overlap(pfn << PAGE_SHIFT, PAGE_SIZE << order))) + return -EINVAL; + return __kho_preserve_order(track, pfn, order); } EXPORT_SYMBOL_GPL(kho_preserve_folio); @@ -775,6 +790,11 @@ int kho_preserve_pages(struct page *page, unsigned int nr_pages) unsigned long failed_pfn = 0; int err = 0; + if (WARN_ON(kho_scratch_overlap(start_pfn << PAGE_SHIFT, + nr_pages << PAGE_SHIFT))) { + return -EINVAL; + } + while (pfn < end_pfn) { const unsigned int order = min(count_trailing_zeros(pfn), ilog2(end_pfn - pfn)); @@ -862,16 +882,17 @@ static struct kho_vmalloc_chunk *new_vmalloc_chunk(struct kho_vmalloc_chunk *cur return NULL; } -static void kho_vmalloc_unpreserve_chunk(struct kho_vmalloc_chunk *chunk) +static void kho_vmalloc_unpreserve_chunk(struct kho_vmalloc_chunk *chunk, + unsigned short order) { struct kho_mem_track *track = &kho_out.ser.track; unsigned long pfn = PHYS_PFN(virt_to_phys(chunk)); __kho_unpreserve(track, pfn, pfn + 1); - for (int i = 0; chunk->phys[i]; i++) { + for (int i = 0; i < ARRAY_SIZE(chunk->phys) && chunk->phys[i]; i++) { pfn = PHYS_PFN(chunk->phys[i]); - __kho_unpreserve(track, pfn, pfn + 1); + __kho_unpreserve(track, pfn, pfn + (1 << order)); } } @@ -882,7 +903,7 @@ static void kho_vmalloc_free_chunks(struct kho_vmalloc *kho_vmalloc) while (chunk) { struct kho_vmalloc_chunk *tmp = chunk; - kho_vmalloc_unpreserve_chunk(chunk); + kho_vmalloc_unpreserve_chunk(chunk, kho_vmalloc->order); chunk = KHOSER_LOAD_PTR(chunk->hdr.next); free_page((unsigned long)tmp); @@ -992,7 +1013,7 @@ void *kho_restore_vmalloc(const struct kho_vmalloc *preservation) while (chunk) { struct page *page; - for (int i = 0; chunk->phys[i]; i++) { + for (int i = 0; i < ARRAY_SIZE(chunk->phys) && chunk->phys[i]; i++) { phys_addr_t phys = chunk->phys[i]; if (idx + contig_pages > total_pages) diff --git a/kernel/kexec_handover_debug.c b/kernel/kexec_handover_debug.c new file mode 100644 index 00000000000000..6efb696f542612 --- /dev/null +++ b/kernel/kexec_handover_debug.c @@ -0,0 +1,25 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * kexec_handover_debug.c - kexec handover optional debug functionality + * Copyright (C) 2025 Google LLC, Pasha Tatashin + */ + +#define pr_fmt(fmt) "KHO: " fmt + +#include "kexec_handover_internal.h" + +bool kho_scratch_overlap(phys_addr_t phys, size_t size) +{ + phys_addr_t scratch_start, scratch_end; + unsigned int i; + + for (i = 0; i < kho_scratch_cnt; i++) { + scratch_start = kho_scratch[i].addr; + scratch_end = kho_scratch[i].addr + kho_scratch[i].size; + + if (phys < scratch_end && (phys + size) > scratch_start) + return true; + } + + return false; +} diff --git a/kernel/kexec_handover_internal.h b/kernel/kexec_handover_internal.h new file mode 100644 index 00000000000000..3c3c7148ceed4d --- /dev/null +++ b/kernel/kexec_handover_internal.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef LINUX_KEXEC_HANDOVER_INTERNAL_H +#define LINUX_KEXEC_HANDOVER_INTERNAL_H + +#include +#include + +extern struct kho_scratch *kho_scratch; +extern unsigned int kho_scratch_cnt; + +#ifdef CONFIG_KEXEC_HANDOVER_DEBUG +bool kho_scratch_overlap(phys_addr_t phys, size_t size); +#else +static inline bool kho_scratch_overlap(phys_addr_t phys, size_t size) +{ + return false; +} +#endif /* CONFIG_KEXEC_HANDOVER_DEBUG */ + +#endif /* LINUX_KEXEC_HANDOVER_INTERNAL_H */ diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c index 53166ef86ba468..26e45f86b9554e 100644 --- a/kernel/power/hibernate.c +++ b/kernel/power/hibernate.c @@ -821,8 +821,7 @@ int hibernate(void) goto Restore; ksys_sync_helper(); - if (filesystem_freeze_enabled) - filesystems_freeze(); + filesystems_freeze(filesystem_freeze_enabled); error = freeze_processes(); if (error) @@ -928,8 +927,7 @@ int hibernate_quiet_exec(int (*func)(void *data), void *data) if (error) goto restore; - if (filesystem_freeze_enabled) - filesystems_freeze(); + filesystems_freeze(filesystem_freeze_enabled); error = freeze_processes(); if (error) @@ -1079,8 +1077,7 @@ static int software_resume(void) if (error) goto Restore; - if (filesystem_freeze_enabled) - filesystems_freeze(); + filesystems_freeze(filesystem_freeze_enabled); pm_pr_dbg("Preparing processes for hibernation restore.\n"); error = freeze_processes(); diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c index b4ca17c2fecf4d..3d4ebedad69f6a 100644 --- a/kernel/power/suspend.c +++ b/kernel/power/suspend.c @@ -375,8 +375,7 @@ static int suspend_prepare(suspend_state_t state) if (error) goto Restore; - if (filesystem_freeze_enabled) - filesystems_freeze(); + filesystems_freeze(filesystem_freeze_enabled); trace_suspend_resume(TPS("freeze_processes"), 0, true); error = suspend_freeze_processes(); trace_suspend_resume(TPS("freeze_processes"), 0, false); diff --git a/kernel/power/swap.c b/kernel/power/swap.c index 0beff7eeaabaf8..70ae21f7370d4c 100644 --- a/kernel/power/swap.c +++ b/kernel/power/swap.c @@ -635,7 +635,7 @@ struct cmp_data { }; /* Indicates the image size after compression */ -static atomic_t compressed_size = ATOMIC_INIT(0); +static atomic64_t compressed_size = ATOMIC_INIT(0); /* * Compression function that runs in its own thread. @@ -664,7 +664,7 @@ static int compress_threadfn(void *data) d->ret = crypto_acomp_compress(d->cr); d->cmp_len = d->cr->dlen; - atomic_set(&compressed_size, atomic_read(&compressed_size) + d->cmp_len); + atomic64_add(d->cmp_len, &compressed_size); atomic_set_release(&d->stop, 1); wake_up(&d->done); } @@ -689,14 +689,14 @@ static int save_compressed_image(struct swap_map_handle *handle, ktime_t start; ktime_t stop; size_t off; - unsigned thr, run_threads, nr_threads; + unsigned int thr, run_threads, nr_threads; unsigned char *page = NULL; struct cmp_data *data = NULL; struct crc_data *crc = NULL; hib_init_batch(&hb); - atomic_set(&compressed_size, 0); + atomic64_set(&compressed_size, 0); /* * We'll limit the number of threads for compression to limit memory @@ -877,11 +877,14 @@ static int save_compressed_image(struct swap_map_handle *handle, stop = ktime_get(); if (!ret) ret = err2; - if (!ret) + if (!ret) { + swsusp_show_speed(start, stop, nr_to_write, "Wrote"); + pr_info("Image size after compression: %lld kbytes\n", + (atomic64_read(&compressed_size) / 1024)); pr_info("Image saving done\n"); - swsusp_show_speed(start, stop, nr_to_write, "Wrote"); - pr_info("Image size after compression: %d kbytes\n", - (atomic_read(&compressed_size) / 1024)); + } else { + pr_err("Image saving failed: %d\n", ret); + } out_clean: hib_finish_batch(&hb); @@ -899,7 +902,8 @@ static int save_compressed_image(struct swap_map_handle *handle, } vfree(data); } - if (page) free_page((unsigned long)page); + if (page) + free_page((unsigned long)page); return ret; } diff --git a/kernel/sched/core.c b/kernel/sched/core.c index f1ebf67b48e211..f754a60de84849 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -9606,7 +9606,7 @@ static int tg_set_cfs_bandwidth(struct task_group *tg, guard(rq_lock_irq)(rq); cfs_rq->runtime_enabled = runtime_enabled; - cfs_rq->runtime_remaining = 0; + cfs_rq->runtime_remaining = 1; if (cfs_rq->throttled) unthrottle_cfs_rq(cfs_rq); diff --git a/kernel/sched/ext.c b/kernel/sched/ext.c index ecb251e883eab3..979484dab2d3d1 100644 --- a/kernel/sched/ext.c +++ b/kernel/sched/ext.c @@ -25,7 +25,7 @@ static struct scx_sched __rcu *scx_root; * guarantee system safety. Maintain a dedicated task list which contains every * task between its fork and eventual free. */ -static DEFINE_SPINLOCK(scx_tasks_lock); +static DEFINE_RAW_SPINLOCK(scx_tasks_lock); static LIST_HEAD(scx_tasks); /* ops enable/disable */ @@ -476,7 +476,7 @@ static void scx_task_iter_start(struct scx_task_iter *iter) BUILD_BUG_ON(__SCX_DSQ_ITER_ALL_FLAGS & ((1U << __SCX_DSQ_LNODE_PRIV_SHIFT) - 1)); - spin_lock_irq(&scx_tasks_lock); + raw_spin_lock_irq(&scx_tasks_lock); iter->cursor = (struct sched_ext_entity){ .flags = SCX_TASK_CURSOR }; list_add(&iter->cursor.tasks_node, &scx_tasks); @@ -507,14 +507,14 @@ static void scx_task_iter_unlock(struct scx_task_iter *iter) __scx_task_iter_rq_unlock(iter); if (iter->list_locked) { iter->list_locked = false; - spin_unlock_irq(&scx_tasks_lock); + raw_spin_unlock_irq(&scx_tasks_lock); } } static void __scx_task_iter_maybe_relock(struct scx_task_iter *iter) { if (!iter->list_locked) { - spin_lock_irq(&scx_tasks_lock); + raw_spin_lock_irq(&scx_tasks_lock); iter->list_locked = true; } } @@ -2940,9 +2940,9 @@ void scx_post_fork(struct task_struct *p) } } - spin_lock_irq(&scx_tasks_lock); + raw_spin_lock_irq(&scx_tasks_lock); list_add_tail(&p->scx.tasks_node, &scx_tasks); - spin_unlock_irq(&scx_tasks_lock); + raw_spin_unlock_irq(&scx_tasks_lock); percpu_up_read(&scx_fork_rwsem); } @@ -2966,9 +2966,9 @@ void sched_ext_free(struct task_struct *p) { unsigned long flags; - spin_lock_irqsave(&scx_tasks_lock, flags); + raw_spin_lock_irqsave(&scx_tasks_lock, flags); list_del_init(&p->scx.tasks_node); - spin_unlock_irqrestore(&scx_tasks_lock, flags); + raw_spin_unlock_irqrestore(&scx_tasks_lock, flags); /* * @p is off scx_tasks and wholly ours. scx_enable()'s READY -> ENABLED @@ -4276,7 +4276,7 @@ static void scx_dump_state(struct scx_exit_info *ei, size_t dump_len) size_t avail, used; bool idle; - rq_lock(rq, &rf); + rq_lock_irqsave(rq, &rf); idle = list_empty(&rq->scx.runnable_list) && rq->curr->sched_class == &idle_sched_class; @@ -4345,7 +4345,7 @@ static void scx_dump_state(struct scx_exit_info *ei, size_t dump_len) list_for_each_entry(p, &rq->scx.runnable_list, scx.runnable_node) scx_dump_task(&s, &dctx, p, ' '); next: - rq_unlock(rq, &rf); + rq_unlock_irqrestore(rq, &rf); } dump_newline(&s); @@ -4479,8 +4479,11 @@ static struct scx_sched *scx_alloc_and_add_sched(struct sched_ext_ops *ops) goto err_free_gdsqs; sch->helper = kthread_run_worker(0, "sched_ext_helper"); - if (!sch->helper) + if (IS_ERR(sch->helper)) { + ret = PTR_ERR(sch->helper); goto err_free_pcpu; + } + sched_set_fifo(sch->helper->task); atomic_set(&sch->exit_kind, SCX_EXIT_NONE); @@ -5321,8 +5324,8 @@ void __init init_sched_ext_class(void) BUG_ON(!zalloc_cpumask_var_node(&rq->scx.cpus_to_kick_if_idle, GFP_KERNEL, n)); BUG_ON(!zalloc_cpumask_var_node(&rq->scx.cpus_to_preempt, GFP_KERNEL, n)); BUG_ON(!zalloc_cpumask_var_node(&rq->scx.cpus_to_wait, GFP_KERNEL, n)); - init_irq_work(&rq->scx.deferred_irq_work, deferred_irq_workfn); - init_irq_work(&rq->scx.kick_cpus_irq_work, kick_cpus_irq_workfn); + rq->scx.deferred_irq_work = IRQ_WORK_INIT_HARD(deferred_irq_workfn); + rq->scx.kick_cpus_irq_work = IRQ_WORK_INIT_HARD(kick_cpus_irq_workfn); if (cpu_online(cpu)) cpu_rq(cpu)->scx.flags |= SCX_RQ_ONLINE; @@ -6401,7 +6404,7 @@ __bpf_kfunc void scx_bpf_cpuperf_set(s32 cpu, u32 perf) guard(rcu)(); - sch = rcu_dereference(sch); + sch = rcu_dereference(scx_root); if (unlikely(!sch)) return; diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 25970dbbb27959..5b752324270b08 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -6024,20 +6024,17 @@ void unthrottle_cfs_rq(struct cfs_rq *cfs_rq) struct sched_entity *se = cfs_rq->tg->se[cpu_of(rq)]; /* - * It's possible we are called with !runtime_remaining due to things - * like user changed quota setting(see tg_set_cfs_bandwidth()) or async - * unthrottled us with a positive runtime_remaining but other still - * running entities consumed those runtime before we reached here. + * It's possible we are called with runtime_remaining < 0 due to things + * like async unthrottled us with a positive runtime_remaining but other + * still running entities consumed those runtime before we reached here. * - * Anyway, we can't unthrottle this cfs_rq without any runtime remaining - * because any enqueue in tg_unthrottle_up() will immediately trigger a - * throttle, which is not supposed to happen on unthrottle path. + * We can't unthrottle this cfs_rq without any runtime remaining because + * any enqueue in tg_unthrottle_up() will immediately trigger a throttle, + * which is not supposed to happen on unthrottle path. */ if (cfs_rq->runtime_enabled && cfs_rq->runtime_remaining <= 0) return; - se = cfs_rq->tg->se[cpu_of(rq)]; - cfs_rq->throttled = 0; update_rq_clock(rq); diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c index aa3120104a5128..56e17b625c72e8 100644 --- a/kernel/time/posix-timers.c +++ b/kernel/time/posix-timers.c @@ -475,12 +475,6 @@ static int do_timer_create(clockid_t which_clock, struct sigevent *event, if (!kc->timer_create) return -EOPNOTSUPP; - new_timer = alloc_posix_timer(); - if (unlikely(!new_timer)) - return -EAGAIN; - - spin_lock_init(&new_timer->it_lock); - /* Special case for CRIU to restore timers with a given timer ID. */ if (unlikely(current->signal->timer_create_restore_ids)) { if (copy_from_user(&req_id, created_timer_id, sizeof(req_id))) @@ -490,6 +484,12 @@ static int do_timer_create(clockid_t which_clock, struct sigevent *event, return -EINVAL; } + new_timer = alloc_posix_timer(); + if (unlikely(!new_timer)) + return -EAGAIN; + + spin_lock_init(&new_timer->it_lock); + /* * Add the timer to the hash table. The timer is not yet valid * after insertion, but has a unique ID allocated. diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index c527b421c8652c..466e083c827218 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c @@ -1152,16 +1152,15 @@ static bool report_idle_softirq(void) return false; } - if (ratelimit >= 10) - return false; - /* On RT, softirq handling may be waiting on some lock */ if (local_bh_blocked()) return false; - pr_warn("NOHZ tick-stop error: local softirq work is pending, handler #%02x!!!\n", - pending); - ratelimit++; + if (ratelimit < 10) { + pr_warn("NOHZ tick-stop error: local softirq work is pending, handler #%02x!!!\n", + pending); + ratelimit++; + } return true; } diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index 3a4d3b2e3f7409..08e0943b54da6f 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c @@ -3060,29 +3060,32 @@ static const struct attribute_group aux_clock_enable_attr_group = { static int __init tk_aux_sysfs_init(void) { struct kobject *auxo, *tko = kobject_create_and_add("time", kernel_kobj); + int ret = -ENOMEM; if (!tko) - return -ENOMEM; + return ret; auxo = kobject_create_and_add("aux_clocks", tko); - if (!auxo) { - kobject_put(tko); - return -ENOMEM; - } + if (!auxo) + goto err_clean; for (int i = 0; i < MAX_AUX_CLOCKS; i++) { char id[2] = { [0] = '0' + i, }; struct kobject *clk = kobject_create_and_add(id, auxo); if (!clk) - return -ENOMEM; - - int ret = sysfs_create_group(clk, &aux_clock_enable_attr_group); + goto err_clean; + ret = sysfs_create_group(clk, &aux_clock_enable_attr_group); if (ret) - return ret; + goto err_clean; } return 0; + +err_clean: + kobject_put(auxo); + kobject_put(tko); + return ret; } late_initcall(tk_aux_sysfs_init); diff --git a/kernel/time/timer.c b/kernel/time/timer.c index 553fa469d7ccfb..d5ebb1d927ea6f 100644 --- a/kernel/time/timer.c +++ b/kernel/time/timer.c @@ -1458,10 +1458,11 @@ static int __try_to_del_timer_sync(struct timer_list *timer, bool shutdown) base = lock_timer_base(timer, &flags); - if (base->running_timer != timer) + if (base->running_timer != timer) { ret = detach_if_pending(timer, base, true); - if (shutdown) - timer->function = NULL; + if (shutdown) + timer->function = NULL; + } raw_spin_unlock_irqrestore(&base->lock, flags); diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 42bd2ba68a8219..59cfacb8a5bbdc 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -1971,7 +1971,8 @@ static void ftrace_hash_rec_enable_modify(struct ftrace_ops *ops) */ static int __ftrace_hash_update_ipmodify(struct ftrace_ops *ops, struct ftrace_hash *old_hash, - struct ftrace_hash *new_hash) + struct ftrace_hash *new_hash, + bool update_target) { struct ftrace_page *pg; struct dyn_ftrace *rec, *end = NULL; @@ -2006,10 +2007,13 @@ static int __ftrace_hash_update_ipmodify(struct ftrace_ops *ops, if (rec->flags & FTRACE_FL_DISABLED) continue; - /* We need to update only differences of filter_hash */ + /* + * Unless we are updating the target of a direct function, + * we only need to update differences of filter_hash + */ in_old = !!ftrace_lookup_ip(old_hash, rec->ip); in_new = !!ftrace_lookup_ip(new_hash, rec->ip); - if (in_old == in_new) + if (!update_target && (in_old == in_new)) continue; if (in_new) { @@ -2020,7 +2024,16 @@ static int __ftrace_hash_update_ipmodify(struct ftrace_ops *ops, if (is_ipmodify) goto rollback; - FTRACE_WARN_ON(rec->flags & FTRACE_FL_DIRECT); + /* + * If this is called by __modify_ftrace_direct() + * then it is only changing where the direct + * pointer is jumping to, and the record already + * points to a direct trampoline. If it isn't, + * then it is a bug to update ipmodify on a direct + * caller. + */ + FTRACE_WARN_ON(!update_target && + (rec->flags & FTRACE_FL_DIRECT)); /* * Another ops with IPMODIFY is already @@ -2076,7 +2089,7 @@ static int ftrace_hash_ipmodify_enable(struct ftrace_ops *ops) if (ftrace_hash_empty(hash)) hash = NULL; - return __ftrace_hash_update_ipmodify(ops, EMPTY_HASH, hash); + return __ftrace_hash_update_ipmodify(ops, EMPTY_HASH, hash, false); } /* Disabling always succeeds */ @@ -2087,7 +2100,7 @@ static void ftrace_hash_ipmodify_disable(struct ftrace_ops *ops) if (ftrace_hash_empty(hash)) hash = NULL; - __ftrace_hash_update_ipmodify(ops, hash, EMPTY_HASH); + __ftrace_hash_update_ipmodify(ops, hash, EMPTY_HASH, false); } static int ftrace_hash_ipmodify_update(struct ftrace_ops *ops, @@ -2101,7 +2114,7 @@ static int ftrace_hash_ipmodify_update(struct ftrace_ops *ops, if (ftrace_hash_empty(new_hash)) new_hash = NULL; - return __ftrace_hash_update_ipmodify(ops, old_hash, new_hash); + return __ftrace_hash_update_ipmodify(ops, old_hash, new_hash, false); } static void print_ip_ins(const char *fmt, const unsigned char *p) @@ -5953,6 +5966,17 @@ static void register_ftrace_direct_cb(struct rcu_head *rhp) free_ftrace_hash(fhp); } +static void reset_direct(struct ftrace_ops *ops, unsigned long addr) +{ + struct ftrace_hash *hash = ops->func_hash->filter_hash; + + remove_direct_functions_hash(hash, addr); + + /* cleanup for possible another register call */ + ops->func = NULL; + ops->trampoline = 0; +} + /** * register_ftrace_direct - Call a custom trampoline directly * for multiple functions registered in @ops @@ -6048,6 +6072,8 @@ int register_ftrace_direct(struct ftrace_ops *ops, unsigned long addr) ops->direct_call = addr; err = register_ftrace_function_nolock(ops); + if (err) + reset_direct(ops, addr); out_unlock: mutex_unlock(&direct_mutex); @@ -6080,7 +6106,6 @@ EXPORT_SYMBOL_GPL(register_ftrace_direct); int unregister_ftrace_direct(struct ftrace_ops *ops, unsigned long addr, bool free_filters) { - struct ftrace_hash *hash = ops->func_hash->filter_hash; int err; if (check_direct_multi(ops)) @@ -6090,13 +6115,9 @@ int unregister_ftrace_direct(struct ftrace_ops *ops, unsigned long addr, mutex_lock(&direct_mutex); err = unregister_ftrace_function(ops); - remove_direct_functions_hash(hash, addr); + reset_direct(ops, addr); mutex_unlock(&direct_mutex); - /* cleanup for possible another register call */ - ops->func = NULL; - ops->trampoline = 0; - if (free_filters) ftrace_free_filter(ops); return err; @@ -6106,7 +6127,7 @@ EXPORT_SYMBOL_GPL(unregister_ftrace_direct); static int __modify_ftrace_direct(struct ftrace_ops *ops, unsigned long addr) { - struct ftrace_hash *hash; + struct ftrace_hash *hash = ops->func_hash->filter_hash; struct ftrace_func_entry *entry, *iter; static struct ftrace_ops tmp_ops = { .func = ftrace_stub, @@ -6126,13 +6147,21 @@ __modify_ftrace_direct(struct ftrace_ops *ops, unsigned long addr) if (err) return err; + /* + * Call __ftrace_hash_update_ipmodify() here, so that we can call + * ops->ops_func for the ops. This is needed because the above + * register_ftrace_function_nolock() worked on tmp_ops. + */ + err = __ftrace_hash_update_ipmodify(ops, hash, hash, true); + if (err) + goto out; + /* * Now the ftrace_ops_list_func() is called to do the direct callers. * We can safely change the direct functions attached to each entry. */ mutex_lock(&ftrace_lock); - hash = ops->func_hash->filter_hash; size = 1 << hash->size_bits; for (i = 0; i < size; i++) { hlist_for_each_entry(iter, &hash->buckets[i], hlist) { @@ -6147,6 +6176,7 @@ __modify_ftrace_direct(struct ftrace_ops *ops, unsigned long addr) mutex_unlock(&ftrace_lock); +out: /* Removing the tmp_ops will add the updated direct callers to the functions */ unregister_ftrace_function(&tmp_ops); diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index 1244d2c5c384ad..afcd3747264d2e 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -7344,6 +7344,10 @@ int ring_buffer_map_get_reader(struct trace_buffer *buffer, int cpu) goto out; } + /* Did the reader catch up with the writer? */ + if (cpu_buffer->reader_page == cpu_buffer->commit_page) + goto out; + reader = rb_get_reader_page(cpu_buffer); if (WARN_ON(!reader)) goto out; diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c index 1d536219b62482..6bfaf1210dd24e 100644 --- a/kernel/trace/trace_events_hist.c +++ b/kernel/trace/trace_events_hist.c @@ -3272,14 +3272,16 @@ static struct field_var *create_field_var(struct hist_trigger_data *hist_data, var = create_var(hist_data, file, field_name, val->size, val->type); if (IS_ERR(var)) { hist_err(tr, HIST_ERR_VAR_CREATE_FIND_FAIL, errpos(field_name)); - kfree(val); + destroy_hist_field(val, 0); ret = PTR_ERR(var); goto err; } field_var = kzalloc(sizeof(struct field_var), GFP_KERNEL); if (!field_var) { - kfree(val); + destroy_hist_field(val, 0); + kfree_const(var->type); + kfree(var->var.name); kfree(var); ret = -ENOMEM; goto err; diff --git a/kernel/trace/trace_fprobe.c b/kernel/trace/trace_fprobe.c index ad9d6347b5fa03..8001dbf1689191 100644 --- a/kernel/trace/trace_fprobe.c +++ b/kernel/trace/trace_fprobe.c @@ -106,13 +106,14 @@ static struct tracepoint_user *__tracepoint_user_init(const char *name, struct t if (!tuser->name) return NULL; + /* Register tracepoint if it is loaded. */ if (tpoint) { + tuser->tpoint = tpoint; ret = tracepoint_user_register(tuser); if (ret) return ERR_PTR(ret); } - tuser->tpoint = tpoint; tuser->refcount = 1; INIT_LIST_HEAD(&tuser->list); list_add(&tuser->list, &tracepoint_user_list); @@ -1513,6 +1514,10 @@ static int disable_trace_fprobe(struct trace_event_call *call, if (!trace_probe_is_enabled(tp)) { list_for_each_entry(tf, trace_probe_probe_list(tp), tp.list) { unregister_fprobe(&tf->fp); + if (tf->tuser) { + tracepoint_user_put(tf->tuser); + tf->tuser = NULL; + } } } diff --git a/lib/crypto/Kconfig b/lib/crypto/Kconfig index 8886055e938f2f..16859c6226dd4b 100644 --- a/lib/crypto/Kconfig +++ b/lib/crypto/Kconfig @@ -64,7 +64,7 @@ config CRYPTO_LIB_CURVE25519 config CRYPTO_LIB_CURVE25519_ARCH bool depends on CRYPTO_LIB_CURVE25519 && !UML && !KMSAN - default y if ARM && KERNEL_MODE_NEON + default y if ARM && KERNEL_MODE_NEON && !CPU_BIG_ENDIAN default y if PPC64 && CPU_LITTLE_ENDIAN default y if X86_64 diff --git a/lib/crypto/Makefile b/lib/crypto/Makefile index bded351aeacef2..d2845b21458581 100644 --- a/lib/crypto/Makefile +++ b/lib/crypto/Makefile @@ -90,7 +90,7 @@ else libcurve25519-$(CONFIG_CRYPTO_LIB_CURVE25519_GENERIC) += curve25519-fiat32.o endif # clang versions prior to 18 may blow out the stack with KASAN -ifeq ($(call clang-min-version, 180000),) +ifeq ($(CONFIG_CC_IS_CLANG)_$(call clang-min-version, 180000),y_) KASAN_SANITIZE_curve25519-hacl64.o := n endif diff --git a/lib/crypto/tests/sha256_kunit.c b/lib/crypto/tests/sha256_kunit.c index dcedfca06df658..5dccdee79693a8 100644 --- a/lib/crypto/tests/sha256_kunit.c +++ b/lib/crypto/tests/sha256_kunit.c @@ -68,6 +68,7 @@ static void test_sha256_finup_2x(struct kunit *test) rand_bytes(data1_buf, max_data_len); rand_bytes(data2_buf, max_data_len); rand_bytes(salt, sizeof(salt)); + memset(ctx, 0, sizeof(*ctx)); for (size_t i = 0; i < 500; i++) { size_t salt_len = rand_length(sizeof(salt)); diff --git a/lib/maple_tree.c b/lib/maple_tree.c index 39bb779cb311d3..5aa4c95000188d 100644 --- a/lib/maple_tree.c +++ b/lib/maple_tree.c @@ -64,6 +64,8 @@ #define CREATE_TRACE_POINTS #include +#define TP_FCT tracepoint_string(__func__) + /* * Kernel pointer hashing renders much of the maple tree dump useless as tagged * pointers get hashed to arbitrary values. @@ -2756,7 +2758,7 @@ static inline void mas_rebalance(struct ma_state *mas, MA_STATE(l_mas, mas->tree, mas->index, mas->last); MA_STATE(r_mas, mas->tree, mas->index, mas->last); - trace_ma_op(__func__, mas); + trace_ma_op(TP_FCT, mas); /* * Rebalancing occurs if a node is insufficient. Data is rebalanced @@ -2997,7 +2999,7 @@ static void mas_split(struct ma_state *mas, struct maple_big_node *b_node) MA_STATE(prev_l_mas, mas->tree, mas->index, mas->last); MA_STATE(prev_r_mas, mas->tree, mas->index, mas->last); - trace_ma_op(__func__, mas); + trace_ma_op(TP_FCT, mas); mast.l = &l_mas; mast.r = &r_mas; @@ -3172,7 +3174,7 @@ static bool mas_is_span_wr(struct ma_wr_state *wr_mas) return false; } - trace_ma_write(__func__, wr_mas->mas, wr_mas->r_max, entry); + trace_ma_write(TP_FCT, wr_mas->mas, wr_mas->r_max, entry); return true; } @@ -3416,7 +3418,7 @@ static noinline void mas_wr_spanning_store(struct ma_wr_state *wr_mas) * of data may happen. */ mas = wr_mas->mas; - trace_ma_op(__func__, mas); + trace_ma_op(TP_FCT, mas); if (unlikely(!mas->index && mas->last == ULONG_MAX)) return mas_new_root(mas, wr_mas->entry); @@ -3552,7 +3554,7 @@ static inline void mas_wr_node_store(struct ma_wr_state *wr_mas, } else { memcpy(wr_mas->node, newnode, sizeof(struct maple_node)); } - trace_ma_write(__func__, mas, 0, wr_mas->entry); + trace_ma_write(TP_FCT, mas, 0, wr_mas->entry); mas_update_gap(mas); mas->end = new_end; return; @@ -3596,7 +3598,7 @@ static inline void mas_wr_slot_store(struct ma_wr_state *wr_mas) mas->offset++; /* Keep mas accurate. */ } - trace_ma_write(__func__, mas, 0, wr_mas->entry); + trace_ma_write(TP_FCT, mas, 0, wr_mas->entry); /* * Only update gap when the new entry is empty or there is an empty * entry in the original two ranges. @@ -3717,7 +3719,7 @@ static inline void mas_wr_append(struct ma_wr_state *wr_mas, mas_update_gap(mas); mas->end = new_end; - trace_ma_write(__func__, mas, new_end, wr_mas->entry); + trace_ma_write(TP_FCT, mas, new_end, wr_mas->entry); return; } @@ -3731,7 +3733,7 @@ static void mas_wr_bnode(struct ma_wr_state *wr_mas) { struct maple_big_node b_node; - trace_ma_write(__func__, wr_mas->mas, 0, wr_mas->entry); + trace_ma_write(TP_FCT, wr_mas->mas, 0, wr_mas->entry); memset(&b_node, 0, sizeof(struct maple_big_node)); mas_store_b_node(wr_mas, &b_node, wr_mas->offset_end); mas_commit_b_node(wr_mas, &b_node); @@ -5062,7 +5064,7 @@ void *mas_store(struct ma_state *mas, void *entry) { MA_WR_STATE(wr_mas, mas, entry); - trace_ma_write(__func__, mas, 0, entry); + trace_ma_write(TP_FCT, mas, 0, entry); #ifdef CONFIG_DEBUG_MAPLE_TREE if (MAS_WARN_ON(mas, mas->index > mas->last)) pr_err("Error %lX > %lX " PTR_FMT "\n", mas->index, mas->last, @@ -5163,7 +5165,7 @@ void mas_store_prealloc(struct ma_state *mas, void *entry) } store: - trace_ma_write(__func__, mas, 0, entry); + trace_ma_write(TP_FCT, mas, 0, entry); mas_wr_store_entry(&wr_mas); MAS_WR_BUG_ON(&wr_mas, mas_is_err(mas)); mas_destroy(mas); @@ -5882,7 +5884,7 @@ void *mtree_load(struct maple_tree *mt, unsigned long index) MA_STATE(mas, mt, index, index); void *entry; - trace_ma_read(__func__, &mas); + trace_ma_read(TP_FCT, &mas); rcu_read_lock(); retry: entry = mas_start(&mas); @@ -5925,7 +5927,7 @@ int mtree_store_range(struct maple_tree *mt, unsigned long index, MA_STATE(mas, mt, index, last); int ret = 0; - trace_ma_write(__func__, &mas, 0, entry); + trace_ma_write(TP_FCT, &mas, 0, entry); if (WARN_ON_ONCE(xa_is_advanced(entry))) return -EINVAL; @@ -6148,7 +6150,7 @@ void *mtree_erase(struct maple_tree *mt, unsigned long index) void *entry = NULL; MA_STATE(mas, mt, index, index); - trace_ma_op(__func__, &mas); + trace_ma_op(TP_FCT, &mas); mtree_lock(mt); entry = mas_erase(&mas); @@ -6485,7 +6487,7 @@ void *mt_find(struct maple_tree *mt, unsigned long *index, unsigned long max) unsigned long copy = *index; #endif - trace_ma_read(__func__, &mas); + trace_ma_read(TP_FCT, &mas); if ((*index) > max) return NULL; diff --git a/lib/test_kho.c b/lib/test_kho.c index 60cd899ea74539..fff018e5548d66 100644 --- a/lib/test_kho.c +++ b/lib/test_kho.c @@ -301,6 +301,9 @@ static int __init kho_test_init(void) phys_addr_t fdt_phys; int err; + if (!kho_is_enabled()) + return 0; + err = kho_retrieve_subtree(KHO_TEST_FDT, &fdt_phys); if (!err) return kho_test_restore(fdt_phys); diff --git a/lib/tests/string_kunit.c b/lib/tests/string_kunit.c index 0ed7448a26d3aa..f9a8e557ba7734 100644 --- a/lib/tests/string_kunit.c +++ b/lib/tests/string_kunit.c @@ -602,6 +602,18 @@ static void string_test_memtostr(struct kunit *test) KUNIT_EXPECT_EQ(test, dest[7], '\0'); } +static void string_test_strends(struct kunit *test) +{ + KUNIT_EXPECT_TRUE(test, strends("foo-bar", "bar")); + KUNIT_EXPECT_TRUE(test, strends("foo-bar", "-bar")); + KUNIT_EXPECT_TRUE(test, strends("foobar", "foobar")); + KUNIT_EXPECT_TRUE(test, strends("foobar", "")); + KUNIT_EXPECT_FALSE(test, strends("bar", "foobar")); + KUNIT_EXPECT_FALSE(test, strends("", "foo")); + KUNIT_EXPECT_FALSE(test, strends("foobar", "ba")); + KUNIT_EXPECT_TRUE(test, strends("", "")); +} + static struct kunit_case string_test_cases[] = { KUNIT_CASE(string_test_memset16), KUNIT_CASE(string_test_memset32), @@ -623,6 +635,7 @@ static struct kunit_case string_test_cases[] = { KUNIT_CASE(string_test_strlcat), KUNIT_CASE(string_test_strtomem), KUNIT_CASE(string_test_memtostr), + KUNIT_CASE(string_test_strends), {} }; diff --git a/mm/Kconfig b/mm/Kconfig index 0e26f4fc8717b9..ca3f146bc7053a 100644 --- a/mm/Kconfig +++ b/mm/Kconfig @@ -908,6 +908,13 @@ config PAGE_MAPCOUNT config PGTABLE_HAS_HUGE_LEAVES def_bool TRANSPARENT_HUGEPAGE || HUGETLB_PAGE +# +# We can end up creating gigantic folio. +# +config HAVE_GIGANTIC_FOLIOS + def_bool (HUGETLB_PAGE && ARCH_HAS_GIGANTIC_PAGE) || \ + (ZONE_DEVICE && HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD) + # TODO: Allow to be enabled without THP config ARCH_SUPPORTS_HUGE_PFNMAP def_bool n diff --git a/mm/damon/stat.c b/mm/damon/stat.c index d8010968bbedd1..bf8626859902f3 100644 --- a/mm/damon/stat.c +++ b/mm/damon/stat.c @@ -46,6 +46,8 @@ MODULE_PARM_DESC(aggr_interval_us, static struct damon_ctx *damon_stat_context; +static unsigned long damon_stat_last_refresh_jiffies; + static void damon_stat_set_estimated_memory_bandwidth(struct damon_ctx *c) { struct damon_target *t; @@ -130,13 +132,12 @@ static void damon_stat_set_idletime_percentiles(struct damon_ctx *c) static int damon_stat_damon_call_fn(void *data) { struct damon_ctx *c = data; - static unsigned long last_refresh_jiffies; /* avoid unnecessarily frequent stat update */ - if (time_before_eq(jiffies, last_refresh_jiffies + + if (time_before_eq(jiffies, damon_stat_last_refresh_jiffies + msecs_to_jiffies(5 * MSEC_PER_SEC))) return 0; - last_refresh_jiffies = jiffies; + damon_stat_last_refresh_jiffies = jiffies; aggr_interval_us = c->attrs.aggr_interval; damon_stat_set_estimated_memory_bandwidth(c); @@ -210,6 +211,8 @@ static int damon_stat_start(void) err = damon_start(&damon_stat_context, 1, true); if (err) return err; + + damon_stat_last_refresh_jiffies = jiffies; call_control.data = damon_stat_context; return damon_call(damon_stat_context, &call_control); } diff --git a/mm/damon/sysfs.c b/mm/damon/sysfs.c index cd6815ecc04ef1..3c0d727788c875 100644 --- a/mm/damon/sysfs.c +++ b/mm/damon/sysfs.c @@ -1552,16 +1552,17 @@ static struct damon_ctx *damon_sysfs_build_ctx( return ctx; } +static unsigned long damon_sysfs_next_update_jiffies; + static int damon_sysfs_repeat_call_fn(void *data) { struct damon_sysfs_kdamond *sysfs_kdamond = data; - static unsigned long next_update_jiffies; if (!sysfs_kdamond->refresh_ms) return 0; - if (time_before(jiffies, next_update_jiffies)) + if (time_before(jiffies, damon_sysfs_next_update_jiffies)) return 0; - next_update_jiffies = jiffies + + damon_sysfs_next_update_jiffies = jiffies + msecs_to_jiffies(sysfs_kdamond->refresh_ms); if (!mutex_trylock(&damon_sysfs_lock)) @@ -1607,6 +1608,9 @@ static int damon_sysfs_turn_damon_on(struct damon_sysfs_kdamond *kdamond) } kdamond->damon_ctx = ctx; + damon_sysfs_next_update_jiffies = + jiffies + msecs_to_jiffies(kdamond->refresh_ms); + repeat_call_control->fn = damon_sysfs_repeat_call_fn; repeat_call_control->data = kdamond; repeat_call_control->repeat = true; diff --git a/mm/filemap.c b/mm/filemap.c index 13f0259d993c9c..2f1e7e283a5102 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -3681,7 +3681,8 @@ static struct folio *next_uptodate_folio(struct xa_state *xas, static vm_fault_t filemap_map_folio_range(struct vm_fault *vmf, struct folio *folio, unsigned long start, unsigned long addr, unsigned int nr_pages, - unsigned long *rss, unsigned short *mmap_miss) + unsigned long *rss, unsigned short *mmap_miss, + bool can_map_large) { unsigned int ref_from_caller = 1; vm_fault_t ret = 0; @@ -3696,7 +3697,7 @@ static vm_fault_t filemap_map_folio_range(struct vm_fault *vmf, * The folio must not cross VMA or page table boundary. */ addr0 = addr - start * PAGE_SIZE; - if (folio_within_vma(folio, vmf->vma) && + if (can_map_large && folio_within_vma(folio, vmf->vma) && (addr0 & PMD_MASK) == ((addr0 + folio_size(folio) - 1) & PMD_MASK)) { vmf->pte -= start; page -= start; @@ -3811,13 +3812,27 @@ vm_fault_t filemap_map_pages(struct vm_fault *vmf, unsigned long rss = 0; unsigned int nr_pages = 0, folio_type; unsigned short mmap_miss = 0, mmap_miss_saved; + bool can_map_large; rcu_read_lock(); folio = next_uptodate_folio(&xas, mapping, end_pgoff); if (!folio) goto out; - if (filemap_map_pmd(vmf, folio, start_pgoff)) { + file_end = DIV_ROUND_UP(i_size_read(mapping->host), PAGE_SIZE) - 1; + end_pgoff = min(end_pgoff, file_end); + + /* + * Do not allow to map with PTEs beyond i_size and with PMD + * across i_size to preserve SIGBUS semantics. + * + * Make an exception for shmem/tmpfs that for long time + * intentionally mapped with PMDs across i_size. + */ + can_map_large = shmem_mapping(mapping) || + file_end >= folio_next_index(folio); + + if (can_map_large && filemap_map_pmd(vmf, folio, start_pgoff)) { ret = VM_FAULT_NOPAGE; goto out; } @@ -3830,10 +3845,6 @@ vm_fault_t filemap_map_pages(struct vm_fault *vmf, goto out; } - file_end = DIV_ROUND_UP(i_size_read(mapping->host), PAGE_SIZE) - 1; - if (end_pgoff > file_end) - end_pgoff = file_end; - folio_type = mm_counter_file(folio); do { unsigned long end; @@ -3850,7 +3861,8 @@ vm_fault_t filemap_map_pages(struct vm_fault *vmf, else ret |= filemap_map_folio_range(vmf, folio, xas.xa_index - folio->index, addr, - nr_pages, &rss, &mmap_miss); + nr_pages, &rss, &mmap_miss, + can_map_large); folio_unlock(folio); } while ((folio = next_uptodate_folio(&xas, mapping, end_pgoff)) != NULL); diff --git a/mm/huge_memory.c b/mm/huge_memory.c index 1d1b74950332e6..2f2a521e5d6830 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -214,7 +214,8 @@ static bool get_huge_zero_folio(void) if (likely(atomic_inc_not_zero(&huge_zero_refcount))) return true; - zero_folio = folio_alloc((GFP_TRANSHUGE | __GFP_ZERO) & ~__GFP_MOVABLE, + zero_folio = folio_alloc((GFP_TRANSHUGE | __GFP_ZERO | __GFP_ZEROTAGS) & + ~__GFP_MOVABLE, HPAGE_PMD_ORDER); if (!zero_folio) { count_vm_event(THP_ZERO_PAGE_ALLOC_FAILED); @@ -3263,6 +3264,14 @@ bool can_split_folio(struct folio *folio, int caller_pins, int *pextra_pins) caller_pins; } +static bool page_range_has_hwpoisoned(struct page *page, long nr_pages) +{ + for (; nr_pages; page++, nr_pages--) + if (PageHWPoison(page)) + return true; + return false; +} + /* * It splits @folio into @new_order folios and copies the @folio metadata to * all the resulting folios. @@ -3270,17 +3279,24 @@ bool can_split_folio(struct folio *folio, int caller_pins, int *pextra_pins) static void __split_folio_to_order(struct folio *folio, int old_order, int new_order) { + /* Scan poisoned pages when split a poisoned folio to large folios */ + const bool handle_hwpoison = folio_test_has_hwpoisoned(folio) && new_order; long new_nr_pages = 1 << new_order; long nr_pages = 1 << old_order; long i; + folio_clear_has_hwpoisoned(folio); + + /* Check first new_nr_pages since the loop below skips them */ + if (handle_hwpoison && + page_range_has_hwpoisoned(folio_page(folio, 0), new_nr_pages)) + folio_set_has_hwpoisoned(folio); /* * Skip the first new_nr_pages, since the new folio from them have all * the flags from the original folio. */ for (i = new_nr_pages; i < nr_pages; i += new_nr_pages) { struct page *new_head = &folio->page + i; - /* * Careful: new_folio is not a "real" folio before we cleared PageTail. * Don't pass it around before clear_compound_head(). @@ -3322,6 +3338,10 @@ static void __split_folio_to_order(struct folio *folio, int old_order, (1L << PG_dirty) | LRU_GEN_MASK | LRU_REFS_MASK)); + if (handle_hwpoison && + page_range_has_hwpoisoned(new_head, new_nr_pages)) + folio_set_has_hwpoisoned(new_folio); + new_folio->mapping = folio->mapping; new_folio->index = folio->index + i; @@ -3422,8 +3442,6 @@ static int __split_unmapped_folio(struct folio *folio, int new_order, if (folio_test_anon(folio)) mod_mthp_stat(order, MTHP_STAT_NR_ANON, -1); - folio_clear_has_hwpoisoned(folio); - /* * split to new_order one order at a time. For uniform split, * folio is split to new_order directly. @@ -3504,7 +3522,8 @@ bool non_uniform_split_supported(struct folio *folio, unsigned int new_order, /* order-1 is not supported for anonymous THP. */ VM_WARN_ONCE(warns && new_order == 1, "Cannot split to order-1 folio"); - return new_order != 1; + if (new_order == 1) + return false; } else if (IS_ENABLED(CONFIG_READ_ONLY_THP_FOR_FS) && !mapping_large_folio_support(folio->mapping)) { /* @@ -3535,7 +3554,8 @@ bool uniform_split_supported(struct folio *folio, unsigned int new_order, if (folio_test_anon(folio)) { VM_WARN_ONCE(warns && new_order == 1, "Cannot split to order-1 folio"); - return new_order != 1; + if (new_order == 1) + return false; } else if (new_order) { if (IS_ENABLED(CONFIG_READ_ONLY_THP_FOR_FS) && !mapping_large_folio_support(folio->mapping)) { @@ -3653,8 +3673,6 @@ static int __folio_split(struct folio *folio, unsigned int new_order, min_order = mapping_min_folio_order(folio->mapping); if (new_order < min_order) { - VM_WARN_ONCE(1, "Cannot split mapped folio below min-order: %u", - min_order); ret = -EINVAL; goto out; } @@ -3986,12 +4004,7 @@ int min_order_for_split(struct folio *folio) int split_folio_to_list(struct folio *folio, struct list_head *list) { - int ret = min_order_for_split(folio); - - if (ret < 0) - return ret; - - return split_huge_page_to_list_to_order(&folio->page, list, ret); + return split_huge_page_to_list_to_order(&folio->page, list, 0); } /* diff --git a/mm/kmsan/core.c b/mm/kmsan/core.c index 8bca7fece47f0e..35ceaa8adb41eb 100644 --- a/mm/kmsan/core.c +++ b/mm/kmsan/core.c @@ -72,9 +72,6 @@ depot_stack_handle_t kmsan_save_stack_with_flags(gfp_t flags, nr_entries = stack_trace_save(entries, KMSAN_STACK_DEPTH, 0); - /* Don't sleep. */ - flags &= ~(__GFP_DIRECT_RECLAIM | __GFP_KSWAPD_RECLAIM); - handle = stack_depot_save(entries, nr_entries, flags); return stack_depot_set_extra_bits(handle, extra); } diff --git a/mm/kmsan/hooks.c b/mm/kmsan/hooks.c index 2cee59d89c808f..8f22d1f229813f 100644 --- a/mm/kmsan/hooks.c +++ b/mm/kmsan/hooks.c @@ -84,7 +84,8 @@ void kmsan_slab_free(struct kmem_cache *s, void *object) if (s->ctor) return; kmsan_enter_runtime(); - kmsan_internal_poison_memory(object, s->object_size, GFP_KERNEL, + kmsan_internal_poison_memory(object, s->object_size, + GFP_KERNEL & ~(__GFP_RECLAIM), KMSAN_POISON_CHECK | KMSAN_POISON_FREE); kmsan_leave_runtime(); } @@ -114,7 +115,8 @@ void kmsan_kfree_large(const void *ptr) kmsan_enter_runtime(); page = virt_to_head_page((void *)ptr); KMSAN_WARN_ON(ptr != page_address(page)); - kmsan_internal_poison_memory((void *)ptr, page_size(page), GFP_KERNEL, + kmsan_internal_poison_memory((void *)ptr, page_size(page), + GFP_KERNEL & ~(__GFP_RECLAIM), KMSAN_POISON_CHECK | KMSAN_POISON_FREE); kmsan_leave_runtime(); } diff --git a/mm/kmsan/shadow.c b/mm/kmsan/shadow.c index 54f3c3c962f078..55fdea199aaf01 100644 --- a/mm/kmsan/shadow.c +++ b/mm/kmsan/shadow.c @@ -208,7 +208,7 @@ void kmsan_free_page(struct page *page, unsigned int order) return; kmsan_enter_runtime(); kmsan_internal_poison_memory(page_address(page), page_size(page), - GFP_KERNEL, + GFP_KERNEL & ~(__GFP_RECLAIM), KMSAN_POISON_CHECK | KMSAN_POISON_FREE); kmsan_leave_runtime(); } diff --git a/mm/ksm.c b/mm/ksm.c index 7bc726b50b2f8c..c4e73040994999 100644 --- a/mm/ksm.c +++ b/mm/ksm.c @@ -2455,6 +2455,95 @@ static bool should_skip_rmap_item(struct folio *folio, return true; } +struct ksm_next_page_arg { + struct folio *folio; + struct page *page; + unsigned long addr; +}; + +static int ksm_next_page_pmd_entry(pmd_t *pmdp, unsigned long addr, unsigned long end, + struct mm_walk *walk) +{ + struct ksm_next_page_arg *private = walk->private; + struct vm_area_struct *vma = walk->vma; + pte_t *start_ptep = NULL, *ptep, pte; + struct mm_struct *mm = walk->mm; + struct folio *folio; + struct page *page; + spinlock_t *ptl; + pmd_t pmd; + + if (ksm_test_exit(mm)) + return 0; + + cond_resched(); + + pmd = pmdp_get_lockless(pmdp); + if (!pmd_present(pmd)) + return 0; + + if (IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE) && pmd_leaf(pmd)) { + ptl = pmd_lock(mm, pmdp); + pmd = pmdp_get(pmdp); + + if (!pmd_present(pmd)) { + goto not_found_unlock; + } else if (pmd_leaf(pmd)) { + page = vm_normal_page_pmd(vma, addr, pmd); + if (!page) + goto not_found_unlock; + folio = page_folio(page); + + if (folio_is_zone_device(folio) || !folio_test_anon(folio)) + goto not_found_unlock; + + page += ((addr & (PMD_SIZE - 1)) >> PAGE_SHIFT); + goto found_unlock; + } + spin_unlock(ptl); + } + + start_ptep = pte_offset_map_lock(mm, pmdp, addr, &ptl); + if (!start_ptep) + return 0; + + for (ptep = start_ptep; addr < end; ptep++, addr += PAGE_SIZE) { + pte = ptep_get(ptep); + + if (!pte_present(pte)) + continue; + + page = vm_normal_page(vma, addr, pte); + if (!page) + continue; + folio = page_folio(page); + + if (folio_is_zone_device(folio) || !folio_test_anon(folio)) + continue; + goto found_unlock; + } + +not_found_unlock: + spin_unlock(ptl); + if (start_ptep) + pte_unmap(start_ptep); + return 0; +found_unlock: + folio_get(folio); + spin_unlock(ptl); + if (start_ptep) + pte_unmap(start_ptep); + private->page = page; + private->folio = folio; + private->addr = addr; + return 1; +} + +static struct mm_walk_ops ksm_next_page_ops = { + .pmd_entry = ksm_next_page_pmd_entry, + .walk_lock = PGWALK_RDLOCK, +}; + static struct ksm_rmap_item *scan_get_next_rmap_item(struct page **page) { struct mm_struct *mm; @@ -2542,21 +2631,27 @@ static struct ksm_rmap_item *scan_get_next_rmap_item(struct page **page) ksm_scan.address = vma->vm_end; while (ksm_scan.address < vma->vm_end) { + struct ksm_next_page_arg ksm_next_page_arg; struct page *tmp_page = NULL; - struct folio_walk fw; struct folio *folio; if (ksm_test_exit(mm)) break; - folio = folio_walk_start(&fw, vma, ksm_scan.address, 0); - if (folio) { - if (!folio_is_zone_device(folio) && - folio_test_anon(folio)) { - folio_get(folio); - tmp_page = fw.page; - } - folio_walk_end(&fw, vma); + int found; + + found = walk_page_range_vma(vma, ksm_scan.address, + vma->vm_end, + &ksm_next_page_ops, + &ksm_next_page_arg); + + if (found > 0) { + folio = ksm_next_page_arg.folio; + tmp_page = ksm_next_page_arg.page; + ksm_scan.address = ksm_next_page_arg.addr; + } else { + VM_WARN_ON_ONCE(found < 0); + ksm_scan.address = vma->vm_end - PAGE_SIZE; } if (tmp_page) { diff --git a/mm/memblock.c b/mm/memblock.c index e23e16618e9b38..f0f2dc66e9a20c 100644 --- a/mm/memblock.c +++ b/mm/memblock.c @@ -1826,7 +1826,8 @@ phys_addr_t __init_memblock memblock_reserved_kern_size(phys_addr_t limit, int n */ unsigned long __init memblock_estimated_nr_free_pages(void) { - return PHYS_PFN(memblock_phys_mem_size() - memblock_reserved_size()); + return PHYS_PFN(memblock_phys_mem_size() - + memblock_reserved_kern_size(MEMBLOCK_ALLOC_ANYWHERE, NUMA_NO_NODE)); } /* lowest address */ diff --git a/mm/memory.c b/mm/memory.c index 74b45e258323e5..b59ae7ce42ebc7 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -65,6 +65,7 @@ #include #include #include +#include #include #include #include @@ -5501,8 +5502,25 @@ vm_fault_t finish_fault(struct vm_fault *vmf) return ret; } + if (!needs_fallback && vma->vm_file) { + struct address_space *mapping = vma->vm_file->f_mapping; + pgoff_t file_end; + + file_end = DIV_ROUND_UP(i_size_read(mapping->host), PAGE_SIZE); + + /* + * Do not allow to map with PTEs beyond i_size and with PMD + * across i_size to preserve SIGBUS semantics. + * + * Make an exception for shmem/tmpfs that for long time + * intentionally mapped with PMDs across i_size. + */ + needs_fallback = !shmem_mapping(mapping) && + file_end < folio_next_index(folio); + } + if (pmd_none(*vmf->pmd)) { - if (folio_test_pmd_mappable(folio)) { + if (!needs_fallback && folio_test_pmd_mappable(folio)) { ret = do_set_pmd(vmf, folio, page); if (ret != VM_FAULT_FALLBACK) return ret; diff --git a/mm/mempool.c b/mm/mempool.c index 1c38e873e546fa..d7bbf1189db9f0 100644 --- a/mm/mempool.c +++ b/mm/mempool.c @@ -68,10 +68,20 @@ static void check_element(mempool_t *pool, void *element) } else if (pool->free == mempool_free_pages) { /* Mempools backed by page allocator */ int order = (int)(long)pool->pool_data; - void *addr = kmap_local_page((struct page *)element); - __check_element(pool, addr, 1UL << (PAGE_SHIFT + order)); - kunmap_local(addr); +#ifdef CONFIG_HIGHMEM + for (int i = 0; i < (1 << order); i++) { + struct page *page = (struct page *)element; + void *addr = kmap_local_page(page + i); + + __check_element(pool, addr, PAGE_SIZE); + kunmap_local(addr); + } +#else + void *addr = page_address((struct page *)element); + + __check_element(pool, addr, PAGE_SIZE << order); +#endif } } @@ -97,10 +107,20 @@ static void poison_element(mempool_t *pool, void *element) } else if (pool->alloc == mempool_alloc_pages) { /* Mempools backed by page allocator */ int order = (int)(long)pool->pool_data; - void *addr = kmap_local_page((struct page *)element); - __poison_element(addr, 1UL << (PAGE_SHIFT + order)); - kunmap_local(addr); +#ifdef CONFIG_HIGHMEM + for (int i = 0; i < (1 << order); i++) { + struct page *page = (struct page *)element; + void *addr = kmap_local_page(page + i); + + __poison_element(addr, PAGE_SIZE); + kunmap_local(addr); + } +#else + void *addr = page_address((struct page *)element); + + __poison_element(addr, PAGE_SIZE << order); +#endif } } #else /* CONFIG_SLUB_DEBUG_ON */ diff --git a/mm/mm_init.c b/mm/mm_init.c index 3db2dea7db4c57..7712d887b6963b 100644 --- a/mm/mm_init.c +++ b/mm/mm_init.c @@ -2469,7 +2469,7 @@ void *__init alloc_large_system_hash(const char *tablename, panic("Failed to allocate %s hash table\n", tablename); pr_info("%s hash table entries: %ld (order: %d, %lu bytes, %s)\n", - tablename, 1UL << log2qty, ilog2(size) - PAGE_SHIFT, size, + tablename, 1UL << log2qty, get_order(size), size, virt ? (huge ? "vmalloc hugepage" : "vmalloc") : "linear"); if (_hash_shift) diff --git a/mm/mremap.c b/mm/mremap.c index bd7314898ec539..419a0ea0a8708a 100644 --- a/mm/mremap.c +++ b/mm/mremap.c @@ -187,7 +187,7 @@ static int mremap_folio_pte_batch(struct vm_area_struct *vma, unsigned long addr if (!folio || !folio_test_large(folio)) return 1; - return folio_pte_batch(folio, ptep, pte, max_nr); + return folio_pte_batch_flags(folio, NULL, ptep, &pte, max_nr, FPB_RESPECT_WRITE); } static int move_ptes(struct pagetable_move_control *pmc, diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 600d9e981c23d7..ed82ee55e66aff 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -1822,14 +1822,9 @@ inline void post_alloc_hook(struct page *page, unsigned int order, * If memory tags should be zeroed * (which happens only when memory should be initialized as well). */ - if (zero_tags) { - /* Initialize both memory and memory tags. */ - for (i = 0; i != 1 << order; ++i) - tag_clear_highpage(page + i); + if (zero_tags) + init = !tag_clear_highpages(page, 1 << order); - /* Take note that memory was initialized by the loop above. */ - init = false; - } if (!should_skip_kasan_unpoison(gfp_flags) && kasan_unpoison_pages(page, order, init)) { /* Take note that memory was initialized by KASAN. */ diff --git a/mm/secretmem.c b/mm/secretmem.c index 60137305bc20fd..b59350daffe318 100644 --- a/mm/secretmem.c +++ b/mm/secretmem.c @@ -82,13 +82,13 @@ static vm_fault_t secretmem_fault(struct vm_fault *vmf) __folio_mark_uptodate(folio); err = filemap_add_folio(mapping, folio, offset, gfp); if (unlikely(err)) { - folio_put(folio); /* * If a split of large page was required, it * already happened when we marked the page invalid * which guarantees that this call won't fail */ set_direct_map_default_noflush(folio_page(folio, 0)); + folio_put(folio); if (err == -EEXIST) goto retry; diff --git a/mm/shmem.c b/mm/shmem.c index b9081b817d28f3..5a3f0f754dc0c6 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -131,8 +131,7 @@ struct shmem_options { #define SHMEM_SEEN_INODES 2 #define SHMEM_SEEN_HUGE 4 #define SHMEM_SEEN_INUMS 8 -#define SHMEM_SEEN_NOSWAP 16 -#define SHMEM_SEEN_QUOTA 32 +#define SHMEM_SEEN_QUOTA 16 }; #ifdef CONFIG_TRANSPARENT_HUGEPAGE @@ -1882,6 +1881,7 @@ static struct folio *shmem_alloc_and_add_folio(struct vm_fault *vmf, struct shmem_inode_info *info = SHMEM_I(inode); unsigned long suitable_orders = 0; struct folio *folio = NULL; + pgoff_t aligned_index; long pages; int error, order; @@ -1895,10 +1895,12 @@ static struct folio *shmem_alloc_and_add_folio(struct vm_fault *vmf, order = highest_order(suitable_orders); while (suitable_orders) { pages = 1UL << order; - index = round_down(index, pages); - folio = shmem_alloc_folio(gfp, order, info, index); - if (folio) + aligned_index = round_down(index, pages); + folio = shmem_alloc_folio(gfp, order, info, aligned_index); + if (folio) { + index = aligned_index; goto allocated; + } if (pages == HPAGE_PMD_NR) count_vm_event(THP_FILE_FALLBACK); @@ -4677,7 +4679,6 @@ static int shmem_parse_one(struct fs_context *fc, struct fs_parameter *param) "Turning off swap in unprivileged tmpfs mounts unsupported"); } ctx->noswap = true; - ctx->seen |= SHMEM_SEEN_NOSWAP; break; case Opt_quota: if (fc->user_ns != &init_user_ns) @@ -4827,14 +4828,15 @@ static int shmem_reconfigure(struct fs_context *fc) err = "Current inum too high to switch to 32-bit inums"; goto out; } - if ((ctx->seen & SHMEM_SEEN_NOSWAP) && ctx->noswap && !sbinfo->noswap) { + + /* + * "noswap" doesn't use fsparam_flag_no, i.e. there's no "swap" + * counterpart for (re-)enabling swap. + */ + if (ctx->noswap && !sbinfo->noswap) { err = "Cannot disable swap on remount"; goto out; } - if (!(ctx->seen & SHMEM_SEEN_NOSWAP) && !ctx->noswap && sbinfo->noswap) { - err = "Cannot enable swap on remount if it was disabled on first mount"; - goto out; - } if (ctx->seen & SHMEM_SEEN_QUOTA && !sb_any_quota_loaded(fc->root->d_sb)) { diff --git a/mm/slub.c b/mm/slub.c index d4367f25b20db9..a0b905c2a557ef 100644 --- a/mm/slub.c +++ b/mm/slub.c @@ -2046,7 +2046,11 @@ static inline void mark_objexts_empty(struct slabobj_ext *obj_exts) if (slab_exts) { unsigned int offs = obj_to_index(obj_exts_slab->slab_cache, obj_exts_slab, obj_exts); - /* codetag should be NULL */ + + if (unlikely(is_codetag_empty(&slab_exts[offs].ref))) + return; + + /* codetag should be NULL here */ WARN_ON(slab_exts[offs].ref.ct); set_codetag_empty(&slab_exts[offs].ref); } @@ -4666,8 +4670,12 @@ static void *___slab_alloc(struct kmem_cache *s, gfp_t gfpflags, int node, if (kmem_cache_debug(s)) { freelist = alloc_single_from_new_slab(s, slab, orig_size, gfpflags); - if (unlikely(!freelist)) + if (unlikely(!freelist)) { + /* This could cause an endless loop. Fail instead. */ + if (!allow_spin) + return NULL; goto new_objects; + } if (s->flags & SLAB_STORE_USER) set_track(s, freelist, TRACK_ALLOC, addr, @@ -6328,8 +6336,6 @@ static void free_to_pcs_bulk(struct kmem_cache *s, size_t size, void **p) if (unlikely(!slab_free_hook(s, p[i], init, false))) { p[i] = p[--size]; - if (!size) - goto flush_remote; continue; } @@ -6344,6 +6350,9 @@ static void free_to_pcs_bulk(struct kmem_cache *s, size_t size, void **p) i++; } + if (!size) + goto flush_remote; + next_batch: if (!local_trylock(&s->cpu_sheaves->lock)) goto fallback; @@ -6398,6 +6407,9 @@ static void free_to_pcs_bulk(struct kmem_cache *s, size_t size, void **p) goto next_batch; } + if (remote_nr) + goto flush_remote; + return; no_empty: diff --git a/mm/swap_state.c b/mm/swap_state.c index b13e9c4baa90b5..f4980dde5394b5 100644 --- a/mm/swap_state.c +++ b/mm/swap_state.c @@ -748,6 +748,8 @@ static struct folio *swap_vma_readahead(swp_entry_t targ_entry, gfp_t gfp_mask, blk_start_plug(&plug); for (addr = start; addr < end; ilx++, addr += PAGE_SIZE) { + struct swap_info_struct *si = NULL; + if (!pte++) { pte = pte_offset_map(vmf->pmd, addr); if (!pte) @@ -761,8 +763,19 @@ static struct folio *swap_vma_readahead(swp_entry_t targ_entry, gfp_t gfp_mask, continue; pte_unmap(pte); pte = NULL; + /* + * Readahead entry may come from a device that we are not + * holding a reference to, try to grab a reference, or skip. + */ + if (swp_type(entry) != swp_type(targ_entry)) { + si = get_swap_device(entry); + if (!si) + continue; + } folio = __read_swap_cache_async(entry, gfp_mask, mpol, ilx, &page_allocated, false); + if (si) + put_swap_device(si); if (!folio) continue; if (page_allocated) { diff --git a/mm/truncate.c b/mm/truncate.c index 91eb92a5ce4fdc..3c5a50ae327413 100644 --- a/mm/truncate.c +++ b/mm/truncate.c @@ -177,6 +177,32 @@ int truncate_inode_folio(struct address_space *mapping, struct folio *folio) return 0; } +static int try_folio_split_or_unmap(struct folio *folio, struct page *split_at, + unsigned long min_order) +{ + enum ttu_flags ttu_flags = + TTU_SYNC | + TTU_SPLIT_HUGE_PMD | + TTU_IGNORE_MLOCK; + int ret; + + ret = try_folio_split_to_order(folio, split_at, min_order); + + /* + * If the split fails, unmap the folio, so it will be refaulted + * with PTEs to respect SIGBUS semantics. + * + * Make an exception for shmem/tmpfs that for long time + * intentionally mapped with PMDs across i_size. + */ + if (ret && !shmem_mapping(folio->mapping)) { + try_to_unmap(folio, ttu_flags); + WARN_ON(folio_mapped(folio)); + } + + return ret; +} + /* * Handle partial folios. The folio may be entirely within the * range if a split has raced with us. If not, we zero the part of the @@ -194,6 +220,7 @@ bool truncate_inode_partial_folio(struct folio *folio, loff_t start, loff_t end) size_t size = folio_size(folio); unsigned int offset, length; struct page *split_at, *split_at2; + unsigned int min_order; if (pos < start) offset = start - pos; @@ -223,8 +250,9 @@ bool truncate_inode_partial_folio(struct folio *folio, loff_t start, loff_t end) if (!folio_test_large(folio)) return true; + min_order = mapping_min_folio_order(folio->mapping); split_at = folio_page(folio, PAGE_ALIGN_DOWN(offset) / PAGE_SIZE); - if (!try_folio_split(folio, split_at, NULL)) { + if (!try_folio_split_or_unmap(folio, split_at, min_order)) { /* * try to split at offset + length to make sure folios within * the range can be dropped, especially to avoid memory waste @@ -248,13 +276,10 @@ bool truncate_inode_partial_folio(struct folio *folio, loff_t start, loff_t end) if (!folio_trylock(folio2)) goto out; - /* - * make sure folio2 is large and does not change its mapping. - * Its split result does not matter here. - */ + /* make sure folio2 is large and does not change its mapping */ if (folio_test_large(folio2) && folio2->mapping == folio->mapping) - try_folio_split(folio2, split_at2, NULL); + try_folio_split_or_unmap(folio2, split_at2, min_order); folio_unlock(folio2); out: diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c index fda3a80e9340cf..2b74ed56eb166d 100644 --- a/net/8021q/vlan.c +++ b/net/8021q/vlan.c @@ -193,6 +193,8 @@ int register_vlan_dev(struct net_device *dev, struct netlink_ext_ack *extack) vlan_group_set_device(grp, vlan->vlan_proto, vlan_id, dev); grp->nr_vlan_devs++; + netdev_update_features(dev); + return 0; out_unregister_netdev: diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c index f0c862091bff20..2c21ae8abadc22 100644 --- a/net/bluetooth/6lowpan.c +++ b/net/bluetooth/6lowpan.c @@ -53,6 +53,11 @@ static bool enable_6lowpan; static struct l2cap_chan *listen_chan; static DEFINE_MUTEX(set_lock); +enum { + LOWPAN_PEER_CLOSING, + LOWPAN_PEER_MAXBITS +}; + struct lowpan_peer { struct list_head list; struct rcu_head rcu; @@ -61,6 +66,8 @@ struct lowpan_peer { /* peer addresses in various formats */ unsigned char lladdr[ETH_ALEN]; struct in6_addr peer_addr; + + DECLARE_BITMAP(flags, LOWPAN_PEER_MAXBITS); }; struct lowpan_btle_dev { @@ -289,6 +296,7 @@ static int recv_pkt(struct sk_buff *skb, struct net_device *dev, local_skb->pkt_type = PACKET_HOST; local_skb->dev = dev; + skb_reset_mac_header(local_skb); skb_set_transport_header(local_skb, sizeof(struct ipv6hdr)); if (give_skb_to_upper(local_skb, dev) != NET_RX_SUCCESS) { @@ -919,7 +927,9 @@ static int bt_6lowpan_disconnect(struct l2cap_conn *conn, u8 dst_type) BT_DBG("peer %p chan %p", peer, peer->chan); + l2cap_chan_lock(peer->chan); l2cap_chan_close(peer->chan, ENOENT); + l2cap_chan_unlock(peer->chan); return 0; } @@ -956,10 +966,11 @@ static struct l2cap_chan *bt_6lowpan_listen(void) } static int get_l2cap_conn(char *buf, bdaddr_t *addr, u8 *addr_type, - struct l2cap_conn **conn) + struct l2cap_conn **conn, bool disconnect) { struct hci_conn *hcon; struct hci_dev *hdev; + int le_addr_type; int n; n = sscanf(buf, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx %hhu", @@ -970,13 +981,32 @@ static int get_l2cap_conn(char *buf, bdaddr_t *addr, u8 *addr_type, if (n < 7) return -EINVAL; + if (disconnect) { + /* The "disconnect" debugfs command has used different address + * type constants than "connect" since 2015. Let's retain that + * for now even though it's obviously buggy... + */ + *addr_type += 1; + } + + switch (*addr_type) { + case BDADDR_LE_PUBLIC: + le_addr_type = ADDR_LE_DEV_PUBLIC; + break; + case BDADDR_LE_RANDOM: + le_addr_type = ADDR_LE_DEV_RANDOM; + break; + default: + return -EINVAL; + } + /* The LE_PUBLIC address type is ignored because of BDADDR_ANY */ hdev = hci_get_route(addr, BDADDR_ANY, BDADDR_LE_PUBLIC); if (!hdev) return -ENOENT; hci_dev_lock(hdev); - hcon = hci_conn_hash_lookup_le(hdev, addr, *addr_type); + hcon = hci_conn_hash_lookup_le(hdev, addr, le_addr_type); hci_dev_unlock(hdev); hci_dev_put(hdev); @@ -993,41 +1023,52 @@ static int get_l2cap_conn(char *buf, bdaddr_t *addr, u8 *addr_type, static void disconnect_all_peers(void) { struct lowpan_btle_dev *entry; - struct lowpan_peer *peer, *tmp_peer, *new_peer; - struct list_head peers; - - INIT_LIST_HEAD(&peers); + struct lowpan_peer *peer; + int nchans; - /* We make a separate list of peers as the close_cb() will - * modify the device peers list so it is better not to mess - * with the same list at the same time. + /* l2cap_chan_close() cannot be called from RCU, and lock ordering + * chan->lock > devices_lock prevents taking write side lock, so copy + * then close. */ rcu_read_lock(); + list_for_each_entry_rcu(entry, &bt_6lowpan_devices, list) + list_for_each_entry_rcu(peer, &entry->peers, list) + clear_bit(LOWPAN_PEER_CLOSING, peer->flags); + rcu_read_unlock(); - list_for_each_entry_rcu(entry, &bt_6lowpan_devices, list) { - list_for_each_entry_rcu(peer, &entry->peers, list) { - new_peer = kmalloc(sizeof(*new_peer), GFP_ATOMIC); - if (!new_peer) - break; + do { + struct l2cap_chan *chans[32]; + int i; - new_peer->chan = peer->chan; - INIT_LIST_HEAD(&new_peer->list); + nchans = 0; - list_add(&new_peer->list, &peers); - } - } + spin_lock(&devices_lock); - rcu_read_unlock(); + list_for_each_entry_rcu(entry, &bt_6lowpan_devices, list) { + list_for_each_entry_rcu(peer, &entry->peers, list) { + if (test_and_set_bit(LOWPAN_PEER_CLOSING, + peer->flags)) + continue; - spin_lock(&devices_lock); - list_for_each_entry_safe(peer, tmp_peer, &peers, list) { - l2cap_chan_close(peer->chan, ENOENT); + l2cap_chan_hold(peer->chan); + chans[nchans++] = peer->chan; - list_del_rcu(&peer->list); - kfree_rcu(peer, rcu); - } - spin_unlock(&devices_lock); + if (nchans >= ARRAY_SIZE(chans)) + goto done; + } + } + +done: + spin_unlock(&devices_lock); + + for (i = 0; i < nchans; ++i) { + l2cap_chan_lock(chans[i]); + l2cap_chan_close(chans[i], ENOENT); + l2cap_chan_unlock(chans[i]); + l2cap_chan_put(chans[i]); + } + } while (nchans); } struct set_enable { @@ -1050,7 +1091,9 @@ static void do_enable_set(struct work_struct *work) mutex_lock(&set_lock); if (listen_chan) { + l2cap_chan_lock(listen_chan); l2cap_chan_close(listen_chan, 0); + l2cap_chan_unlock(listen_chan); l2cap_chan_put(listen_chan); } @@ -1103,13 +1146,15 @@ static ssize_t lowpan_control_write(struct file *fp, buf[buf_size] = '\0'; if (memcmp(buf, "connect ", 8) == 0) { - ret = get_l2cap_conn(&buf[8], &addr, &addr_type, &conn); + ret = get_l2cap_conn(&buf[8], &addr, &addr_type, &conn, false); if (ret == -EINVAL) return ret; mutex_lock(&set_lock); if (listen_chan) { + l2cap_chan_lock(listen_chan); l2cap_chan_close(listen_chan, 0); + l2cap_chan_unlock(listen_chan); l2cap_chan_put(listen_chan); listen_chan = NULL; } @@ -1140,7 +1185,7 @@ static ssize_t lowpan_control_write(struct file *fp, } if (memcmp(buf, "disconnect ", 11) == 0) { - ret = get_l2cap_conn(&buf[11], &addr, &addr_type, &conn); + ret = get_l2cap_conn(&buf[11], &addr, &addr_type, &conn, true); if (ret < 0) return ret; @@ -1271,7 +1316,9 @@ static void __exit bt_6lowpan_exit(void) debugfs_remove(lowpan_control_debugfs); if (listen_chan) { + l2cap_chan_lock(listen_chan); l2cap_chan_close(listen_chan, 0); + l2cap_chan_unlock(listen_chan); l2cap_chan_put(listen_chan); } diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index c5dedf39a1293f..6fc0692abf0576 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c @@ -769,21 +769,23 @@ static void find_bis(struct hci_conn *conn, void *data) d->count++; } -static int hci_le_big_terminate(struct hci_dev *hdev, u8 big, struct hci_conn *conn) +static int hci_le_big_terminate(struct hci_dev *hdev, struct hci_conn *conn) { struct iso_list_data *d; int ret; - bt_dev_dbg(hdev, "big 0x%2.2x sync_handle 0x%4.4x", big, conn->sync_handle); + bt_dev_dbg(hdev, "hcon %p big 0x%2.2x sync_handle 0x%4.4x", conn, + conn->iso_qos.bcast.big, conn->sync_handle); d = kzalloc(sizeof(*d), GFP_KERNEL); if (!d) return -ENOMEM; - d->big = big; + d->big = conn->iso_qos.bcast.big; d->sync_handle = conn->sync_handle; - if (test_and_clear_bit(HCI_CONN_PA_SYNC, &conn->flags)) { + if (conn->type == PA_LINK && + test_and_clear_bit(HCI_CONN_PA_SYNC, &conn->flags)) { hci_conn_hash_list_flag(hdev, find_bis, PA_LINK, HCI_CONN_PA_SYNC, d); @@ -801,6 +803,9 @@ static int hci_le_big_terminate(struct hci_dev *hdev, u8 big, struct hci_conn *c d->big_sync_term = true; } + if (!d->pa_sync_term && !d->big_sync_term) + return 0; + ret = hci_cmd_sync_queue(hdev, big_terminate_sync, d, terminate_big_destroy); if (ret) @@ -852,8 +857,7 @@ static void bis_cleanup(struct hci_conn *conn) hci_le_terminate_big(hdev, conn); } else { - hci_le_big_terminate(hdev, conn->iso_qos.bcast.big, - conn); + hci_le_big_terminate(hdev, conn); } } @@ -994,19 +998,20 @@ static struct hci_conn *__hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t conn->mtu = hdev->le_mtu ? hdev->le_mtu : hdev->acl_mtu; break; case CIS_LINK: - case BIS_LINK: - case PA_LINK: /* conn->src should reflect the local identity address */ hci_copy_identity_address(hdev, &conn->src, &conn->src_type); - /* set proper cleanup function */ - if (!bacmp(dst, BDADDR_ANY)) - conn->cleanup = bis_cleanup; - else if (conn->role == HCI_ROLE_MASTER) + if (conn->role == HCI_ROLE_MASTER) conn->cleanup = cis_cleanup; - conn->mtu = hdev->iso_mtu ? hdev->iso_mtu : - hdev->le_mtu ? hdev->le_mtu : hdev->acl_mtu; + conn->mtu = hdev->iso_mtu; + break; + case PA_LINK: + case BIS_LINK: + /* conn->src should reflect the local identity address */ + hci_copy_identity_address(hdev, &conn->src, &conn->src_type); + conn->cleanup = bis_cleanup; + conn->mtu = hdev->iso_mtu; break; case SCO_LINK: if (lmp_esco_capable(hdev)) diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index d37db364acf740..3838b90343d910 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -4218,6 +4218,13 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, void *data, } if (i == ARRAY_SIZE(hci_cc_table)) { + if (!skb->len) { + bt_dev_err(hdev, "Unexpected cc 0x%4.4x with no status", + *opcode); + *status = HCI_ERROR_UNSPECIFIED; + return; + } + /* Unknown opcode, assume byte 0 contains the status, so * that e.g. __hci_cmd_sync() properly returns errors * for vendor specific commands send by HCI drivers. @@ -5836,6 +5843,29 @@ static void hci_le_enh_conn_complete_evt(struct hci_dev *hdev, void *data, le16_to_cpu(ev->supervision_timeout)); } +static void hci_le_pa_sync_lost_evt(struct hci_dev *hdev, void *data, + struct sk_buff *skb) +{ + struct hci_ev_le_pa_sync_lost *ev = data; + u16 handle = le16_to_cpu(ev->handle); + struct hci_conn *conn; + + bt_dev_dbg(hdev, "sync handle 0x%4.4x", handle); + + hci_dev_lock(hdev); + + /* Delete the pa sync connection */ + conn = hci_conn_hash_lookup_pa_sync_handle(hdev, handle); + if (conn) { + clear_bit(HCI_CONN_BIG_SYNC, &conn->flags); + clear_bit(HCI_CONN_PA_SYNC, &conn->flags); + hci_disconn_cfm(conn, HCI_ERROR_REMOTE_USER_TERM); + hci_conn_del(conn); + } + + hci_dev_unlock(hdev); +} + static void hci_le_ext_adv_term_evt(struct hci_dev *hdev, void *data, struct sk_buff *skb) { @@ -6994,14 +7024,9 @@ static void hci_le_big_sync_established_evt(struct hci_dev *hdev, void *data, continue; } - if (ev->status != 0x42) { + if (ev->status != 0x42) /* Mark PA sync as established */ set_bit(HCI_CONN_PA_SYNC, &bis->flags); - /* Reset cleanup callback of PA Sync so it doesn't - * terminate the sync when deleting the connection. - */ - conn->cleanup = NULL; - } bis->sync_handle = conn->sync_handle; bis->iso_qos.bcast.big = ev->handle; @@ -7044,29 +7069,24 @@ static void hci_le_big_sync_lost_evt(struct hci_dev *hdev, void *data, struct sk_buff *skb) { struct hci_evt_le_big_sync_lost *ev = data; - struct hci_conn *bis, *conn; - bool mgmt_conn; + struct hci_conn *bis; + bool mgmt_conn = false; bt_dev_dbg(hdev, "big handle 0x%2.2x", ev->handle); hci_dev_lock(hdev); - /* Delete the pa sync connection */ - bis = hci_conn_hash_lookup_pa_sync_big_handle(hdev, ev->handle); - if (bis) { - conn = hci_conn_hash_lookup_pa_sync_handle(hdev, - bis->sync_handle); - if (conn) - hci_conn_del(conn); - } - /* Delete each bis connection */ while ((bis = hci_conn_hash_lookup_big_state(hdev, ev->handle, BT_CONNECTED, HCI_ROLE_SLAVE))) { - mgmt_conn = test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &bis->flags); - mgmt_device_disconnected(hdev, &bis->dst, bis->type, bis->dst_type, - ev->reason, mgmt_conn); + if (!mgmt_conn) { + mgmt_conn = test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, + &bis->flags); + mgmt_device_disconnected(hdev, &bis->dst, bis->type, + bis->dst_type, ev->reason, + mgmt_conn); + } clear_bit(HCI_CONN_BIG_SYNC, &bis->flags); hci_disconn_cfm(bis, ev->reason); @@ -7180,6 +7200,9 @@ static const struct hci_le_ev { hci_le_per_adv_report_evt, sizeof(struct hci_ev_le_per_adv_report), HCI_MAX_EVENT_SIZE), + /* [0x10 = HCI_EV_LE_PA_SYNC_LOST] */ + HCI_LE_EV(HCI_EV_LE_PA_SYNC_LOST, hci_le_pa_sync_lost_evt, + sizeof(struct hci_ev_le_pa_sync_lost)), /* [0x12 = HCI_EV_LE_EXT_ADV_SET_TERM] */ HCI_LE_EV(HCI_EV_LE_EXT_ADV_SET_TERM, hci_le_ext_adv_term_evt, sizeof(struct hci_evt_le_ext_adv_set_term)), diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c index 73fc41b68b6870..6e76798ec786b1 100644 --- a/net/bluetooth/hci_sync.c +++ b/net/bluetooth/hci_sync.c @@ -6999,7 +6999,7 @@ static void create_pa_complete(struct hci_dev *hdev, void *data, int err) hci_dev_lock(hdev); - if (!hci_conn_valid(hdev, conn)) + if (hci_conn_valid(hdev, conn)) clear_bit(HCI_CONN_CREATE_PA_SYNC, &conn->flags); if (!err) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index d08320380ad67c..35c57657bcf4e8 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -497,6 +497,7 @@ void l2cap_chan_hold(struct l2cap_chan *c) kref_get(&c->kref); } +EXPORT_SYMBOL_GPL(l2cap_chan_hold); struct l2cap_chan *l2cap_chan_hold_unless_zero(struct l2cap_chan *c) { diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 24e335e3a7271f..262bf984d2aafa 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -5395,9 +5395,9 @@ static u8 parse_adv_monitor_pattern(struct adv_monitor *m, u8 pattern_count, for (i = 0; i < pattern_count; i++) { offset = patterns[i].offset; length = patterns[i].length; - if (offset >= HCI_MAX_EXT_AD_LENGTH || - length > HCI_MAX_EXT_AD_LENGTH || - (offset + length) > HCI_MAX_EXT_AD_LENGTH) + if (offset >= HCI_MAX_AD_LENGTH || + length > HCI_MAX_AD_LENGTH || + (offset + length) > HCI_MAX_AD_LENGTH) return MGMT_STATUS_INVALID_PARAMS; p = kmalloc(sizeof(*p), GFP_KERNEL); @@ -9497,6 +9497,7 @@ void mgmt_index_removed(struct hci_dev *hdev) cancel_delayed_work_sync(&hdev->discov_off); cancel_delayed_work_sync(&hdev->service_cache); cancel_delayed_work_sync(&hdev->rpa_expired); + cancel_delayed_work_sync(&hdev->mesh_send_done); } void mgmt_power_on(struct hci_dev *hdev, int err) diff --git a/net/bridge/br_forward.c b/net/bridge/br_forward.c index 870bdf2e082c4d..dea09096ad0fba 100644 --- a/net/bridge/br_forward.c +++ b/net/bridge/br_forward.c @@ -25,7 +25,7 @@ static inline int should_deliver(const struct net_bridge_port *p, vg = nbp_vlan_group_rcu(p); return ((p->flags & BR_HAIRPIN_MODE) || skb->dev != p->dev) && - (br_mst_is_enabled(p->br) || p->state == BR_STATE_FORWARDING) && + (br_mst_is_enabled(p) || p->state == BR_STATE_FORWARDING) && br_allowed_egress(vg, skb) && nbp_switchdev_allowed_egress(p, skb) && !br_skb_isolated(p, skb); } diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index 98c5b9c3145f37..ca3a637d7cca77 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c @@ -386,6 +386,7 @@ void br_dev_delete(struct net_device *dev, struct list_head *head) del_nbp(p); } + br_mst_uninit(br); br_recalculate_neigh_suppress_enabled(br); br_fdb_delete_by_port(br, NULL, 0, 1); diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c index 67b4c905e49a21..777fa869c1a144 100644 --- a/net/bridge/br_input.c +++ b/net/bridge/br_input.c @@ -94,7 +94,7 @@ int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb br = p->br; - if (br_mst_is_enabled(br)) { + if (br_mst_is_enabled(p)) { state = BR_STATE_FORWARDING; } else { if (p->state == BR_STATE_DISABLED) { @@ -429,7 +429,7 @@ static rx_handler_result_t br_handle_frame(struct sk_buff **pskb) return RX_HANDLER_PASS; forward: - if (br_mst_is_enabled(p->br)) + if (br_mst_is_enabled(p)) goto defer_stp_filtering; switch (p->state) { diff --git a/net/bridge/br_mst.c b/net/bridge/br_mst.c index 3f24b4ee49c274..43a300ae6bfafc 100644 --- a/net/bridge/br_mst.c +++ b/net/bridge/br_mst.c @@ -22,6 +22,12 @@ bool br_mst_enabled(const struct net_device *dev) } EXPORT_SYMBOL_GPL(br_mst_enabled); +void br_mst_uninit(struct net_bridge *br) +{ + if (br_opt_get(br, BROPT_MST_ENABLED)) + static_branch_dec(&br_mst_used); +} + int br_mst_get_info(const struct net_device *dev, u16 msti, unsigned long *vids) { const struct net_bridge_vlan_group *vg; @@ -225,9 +231,9 @@ int br_mst_set_enabled(struct net_bridge *br, bool on, return err; if (on) - static_branch_enable(&br_mst_used); + static_branch_inc(&br_mst_used); else - static_branch_disable(&br_mst_used); + static_branch_dec(&br_mst_used); br_opt_toggle(br, BROPT_MST_ENABLED, on); return 0; diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index 16be5d25040230..7280c4e9305f36 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h @@ -1935,10 +1935,12 @@ static inline bool br_vlan_state_allowed(u8 state, bool learn_allow) /* br_mst.c */ #ifdef CONFIG_BRIDGE_VLAN_FILTERING DECLARE_STATIC_KEY_FALSE(br_mst_used); -static inline bool br_mst_is_enabled(struct net_bridge *br) +static inline bool br_mst_is_enabled(const struct net_bridge_port *p) { + /* check the port's vlan group to avoid racing with port deletion */ return static_branch_unlikely(&br_mst_used) && - br_opt_get(br, BROPT_MST_ENABLED); + br_opt_get(p->br, BROPT_MST_ENABLED) && + rcu_access_pointer(p->vlgrp); } int br_mst_set_state(struct net_bridge_port *p, u16 msti, u8 state, @@ -1952,8 +1954,9 @@ int br_mst_fill_info(struct sk_buff *skb, const struct net_bridge_vlan_group *vg); int br_mst_process(struct net_bridge_port *p, const struct nlattr *mst_attr, struct netlink_ext_ack *extack); +void br_mst_uninit(struct net_bridge *br); #else -static inline bool br_mst_is_enabled(struct net_bridge *br) +static inline bool br_mst_is_enabled(const struct net_bridge_port *p) { return false; } @@ -1987,6 +1990,10 @@ static inline int br_mst_process(struct net_bridge_port *p, { return -EOPNOTSUPP; } + +static inline void br_mst_uninit(struct net_bridge *br) +{ +} #endif struct nf_br_ops { diff --git a/net/core/dev_ioctl.c b/net/core/dev_ioctl.c index ad54b12d4b4c80..8bb71a10dba096 100644 --- a/net/core/dev_ioctl.c +++ b/net/core/dev_ioctl.c @@ -443,6 +443,9 @@ static int generic_hwtstamp_ioctl_lower(struct net_device *dev, int cmd, struct ifreq ifrr; int err; + if (!kernel_cfg->ifr) + return -EINVAL; + strscpy_pad(ifrr.ifr_name, dev->name, IFNAMSIZ); ifrr.ifr_ifru = kernel_cfg->ifr->ifr_ifru; diff --git a/net/core/gro_cells.c b/net/core/gro_cells.c index fd57b845de333f..a725d21159a6f1 100644 --- a/net/core/gro_cells.c +++ b/net/core/gro_cells.c @@ -60,9 +60,10 @@ static int gro_cell_poll(struct napi_struct *napi, int budget) struct sk_buff *skb; int work_done = 0; - __local_lock_nested_bh(&cell->bh_lock); while (work_done < budget) { + __local_lock_nested_bh(&cell->bh_lock); skb = __skb_dequeue(&cell->napi_skbs); + __local_unlock_nested_bh(&cell->bh_lock); if (!skb) break; napi_gro_receive(napi, skb); @@ -71,7 +72,6 @@ static int gro_cell_poll(struct napi_struct *napi, int budget) if (work_done < budget) napi_complete_done(napi, work_done); - __local_unlock_nested_bh(&cell->bh_lock); return work_done; } diff --git a/net/core/netpoll.c b/net/core/netpoll.c index 60a05d3b7c2491..331764845e8fa5 100644 --- a/net/core/netpoll.c +++ b/net/core/netpoll.c @@ -228,19 +228,16 @@ static void refill_skbs(struct netpoll *np) { struct sk_buff_head *skb_pool; struct sk_buff *skb; - unsigned long flags; skb_pool = &np->skb_pool; - spin_lock_irqsave(&skb_pool->lock, flags); - while (skb_pool->qlen < MAX_SKBS) { + while (READ_ONCE(skb_pool->qlen) < MAX_SKBS) { skb = alloc_skb(MAX_SKB_SIZE, GFP_ATOMIC); if (!skb) break; - __skb_queue_tail(skb_pool, skb); + skb_queue_tail(skb_pool, skb); } - spin_unlock_irqrestore(&skb_pool->lock, flags); } static void zap_completion_queue(void) @@ -814,6 +811,10 @@ static void __netpoll_cleanup(struct netpoll *np) if (!npinfo) return; + /* At this point, there is a single npinfo instance per netdevice, and + * its refcnt tracks how many netpoll structures are linked to it. We + * only perform npinfo cleanup when the refcnt decrements to zero. + */ if (refcount_dec_and_test(&npinfo->refcnt)) { const struct net_device_ops *ops; @@ -823,8 +824,7 @@ static void __netpoll_cleanup(struct netpoll *np) RCU_INIT_POINTER(np->dev->npinfo, NULL); call_rcu(&npinfo->rcu, rcu_cleanup_netpoll_info); - } else - RCU_INIT_POINTER(np->dev->npinfo, NULL); + } skb_pool_flush(np); } diff --git a/net/devlink/rate.c b/net/devlink/rate.c index 264fb82cba196e..d157a8419bcad4 100644 --- a/net/devlink/rate.c +++ b/net/devlink/rate.c @@ -828,13 +828,15 @@ void devl_rate_nodes_destroy(struct devlink *devlink) if (!devlink_rate->parent) continue; - refcount_dec(&devlink_rate->parent->refcnt); if (devlink_rate_is_leaf(devlink_rate)) ops->rate_leaf_parent_set(devlink_rate, NULL, devlink_rate->priv, NULL, NULL); else if (devlink_rate_is_node(devlink_rate)) ops->rate_node_parent_set(devlink_rate, NULL, devlink_rate->priv, NULL, NULL); + + refcount_dec(&devlink_rate->parent->refcnt); + devlink_rate->parent = NULL; } list_for_each_entry_safe(devlink_rate, tmp, &devlink->rate_list, list) { if (devlink_rate_is_node(devlink_rate)) { diff --git a/net/dsa/tag_brcm.c b/net/dsa/tag_brcm.c index 26bb657ceac36f..eadb358179ce33 100644 --- a/net/dsa/tag_brcm.c +++ b/net/dsa/tag_brcm.c @@ -176,7 +176,8 @@ static struct sk_buff *brcm_tag_rcv_ll(struct sk_buff *skb, /* Remove Broadcom tag and update checksum */ skb_pull_rcsum(skb, BRCM_TAG_LEN); - dsa_default_offload_fwd_mark(skb); + if (likely(!is_link_local_ether_addr(eth_hdr(skb)->h_dest))) + dsa_default_offload_fwd_mark(skb); return skb; } @@ -224,12 +225,14 @@ static struct sk_buff *brcm_leg_tag_rcv(struct sk_buff *skb, { int len = BRCM_LEG_TAG_LEN; int source_port; + __be16 *proto; u8 *brcm_tag; if (unlikely(!pskb_may_pull(skb, BRCM_LEG_TAG_LEN + VLAN_HLEN))) return NULL; brcm_tag = dsa_etype_header_pos_rx(skb); + proto = (__be16 *)(brcm_tag + BRCM_LEG_TAG_LEN); source_port = brcm_tag[5] & BRCM_LEG_PORT_ID; @@ -237,14 +240,19 @@ static struct sk_buff *brcm_leg_tag_rcv(struct sk_buff *skb, if (!skb->dev) return NULL; - /* VLAN tag is added by BCM63xx internal switch */ - if (netdev_uses_dsa(skb->dev)) + /* The internal switch in BCM63XX SoCs always tags on egress on the CPU + * port. We use VID 0 internally for untagged traffic, so strip the tag + * if the TCI field is all 0, and keep it otherwise to also retain + * e.g. 802.1p tagged packets. + */ + if (proto[0] == htons(ETH_P_8021Q) && proto[1] == 0) len += VLAN_HLEN; /* Remove Broadcom tag and update checksum */ skb_pull_rcsum(skb, len); - dsa_default_offload_fwd_mark(skb); + if (likely(!is_link_local_ether_addr(eth_hdr(skb)->h_dest))) + dsa_default_offload_fwd_mark(skb); dsa_strip_etype_header(skb, len); diff --git a/net/handshake/tlshd.c b/net/handshake/tlshd.c index 081093dfd5533b..8f9532a15f43f9 100644 --- a/net/handshake/tlshd.c +++ b/net/handshake/tlshd.c @@ -259,6 +259,7 @@ static int tls_handshake_accept(struct handshake_req *req, out_cancel: genlmsg_cancel(msg, hdr); + nlmsg_free(msg); out: return ret; } diff --git a/net/hsr/hsr_device.c b/net/hsr/hsr_device.c index fbbc3ccf9df64b..492cbc78ab75a0 100644 --- a/net/hsr/hsr_device.c +++ b/net/hsr/hsr_device.c @@ -320,6 +320,9 @@ static void send_hsr_supervision_frame(struct hsr_port *port, } hsr_stag = skb_put(skb, sizeof(struct hsr_sup_tag)); + skb_set_network_header(skb, ETH_HLEN + HSR_HLEN); + skb_reset_mac_len(skb); + set_hsr_stag_path(hsr_stag, (hsr->prot_version ? 0x0 : 0xf)); set_hsr_stag_HSR_ver(hsr_stag, hsr->prot_version); @@ -334,7 +337,7 @@ static void send_hsr_supervision_frame(struct hsr_port *port, } hsr_stag->tlv.HSR_TLV_type = type; - /* TODO: Why 12 in HSRv0? */ + /* HSRv0 has 6 unused bytes after the MAC */ hsr_stag->tlv.HSR_TLV_length = hsr->prot_version ? sizeof(struct hsr_sup_payload) : 12; diff --git a/net/hsr/hsr_forward.c b/net/hsr/hsr_forward.c index c67c0d35921de0..339f0d22021294 100644 --- a/net/hsr/hsr_forward.c +++ b/net/hsr/hsr_forward.c @@ -262,15 +262,23 @@ static struct sk_buff *prp_fill_rct(struct sk_buff *skb, return skb; } -static void hsr_set_path_id(struct hsr_ethhdr *hsr_ethhdr, +static void hsr_set_path_id(struct hsr_frame_info *frame, + struct hsr_ethhdr *hsr_ethhdr, struct hsr_port *port) { int path_id; - if (port->type == HSR_PT_SLAVE_A) - path_id = 0; - else - path_id = 1; + if (port->hsr->prot_version) { + if (port->type == HSR_PT_SLAVE_A) + path_id = 0; + else + path_id = 1; + } else { + if (frame->is_supervision) + path_id = 0xf; + else + path_id = 1; + } set_hsr_tag_path(&hsr_ethhdr->hsr_tag, path_id); } @@ -304,7 +312,7 @@ static struct sk_buff *hsr_fill_tag(struct sk_buff *skb, else hsr_ethhdr = (struct hsr_ethhdr *)pc; - hsr_set_path_id(hsr_ethhdr, port); + hsr_set_path_id(frame, hsr_ethhdr, port); set_hsr_tag_LSDU_size(&hsr_ethhdr->hsr_tag, lsdu_size); hsr_ethhdr->hsr_tag.sequence_nr = htons(frame->sequence_nr); hsr_ethhdr->hsr_tag.encap_proto = hsr_ethhdr->ethhdr.h_proto; @@ -330,7 +338,7 @@ struct sk_buff *hsr_create_tagged_frame(struct hsr_frame_info *frame, (struct hsr_ethhdr *)skb_mac_header(frame->skb_hsr); /* set the lane id properly */ - hsr_set_path_id(hsr_ethhdr, port); + hsr_set_path_id(frame, hsr_ethhdr, port); return skb_clone(frame->skb_hsr, GFP_ATOMIC); } else if (port->dev->features & NETIF_F_HW_HSR_TAG_INS) { return skb_clone(frame->skb_std, GFP_ATOMIC); diff --git a/net/ipv4/esp4_offload.c b/net/ipv4/esp4_offload.c index e0d94270da28a3..05828d4cb6cdbb 100644 --- a/net/ipv4/esp4_offload.c +++ b/net/ipv4/esp4_offload.c @@ -122,8 +122,10 @@ static struct sk_buff *xfrm4_tunnel_gso_segment(struct xfrm_state *x, struct sk_buff *skb, netdev_features_t features) { - __be16 type = x->inner_mode.family == AF_INET6 ? htons(ETH_P_IPV6) - : htons(ETH_P_IP); + const struct xfrm_mode *inner_mode = xfrm_ip2inner_mode(x, + XFRM_MODE_SKB_CB(skb)->protocol); + __be16 type = inner_mode->family == AF_INET6 ? htons(ETH_P_IPV6) + : htons(ETH_P_IP); return skb_eth_gso_segment(skb, features, type); } diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 6d27d3610c1cd2..b549d6a573073b 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -607,6 +607,11 @@ static void fnhe_remove_oldest(struct fnhe_hash_bucket *hash) oldest_p = fnhe_p; } } + + /* Clear oldest->fnhe_daddr to prevent this fnhe from being + * rebound with new dsts in rt_bind_exception(). + */ + oldest->fnhe_daddr = 0; fnhe_flush_routes(oldest); *oldest_p = oldest->fnhe_next; kfree_rcu(oldest, rcu); diff --git a/net/ipv6/esp6_offload.c b/net/ipv6/esp6_offload.c index 7b41fb4f00b587..22410243ebe88d 100644 --- a/net/ipv6/esp6_offload.c +++ b/net/ipv6/esp6_offload.c @@ -158,8 +158,10 @@ static struct sk_buff *xfrm6_tunnel_gso_segment(struct xfrm_state *x, struct sk_buff *skb, netdev_features_t features) { - __be16 type = x->inner_mode.family == AF_INET ? htons(ETH_P_IP) - : htons(ETH_P_IPV6); + const struct xfrm_mode *inner_mode = xfrm_ip2inner_mode(x, + XFRM_MODE_SKB_CB(skb)->protocol); + __be16 type = inner_mode->family == AF_INET ? htons(ETH_P_IP) + : htons(ETH_P_IPV6); return skb_eth_gso_segment(skb, features, type); } diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c index 369a2f2e459cdb..0710281dd95aac 100644 --- a/net/l2tp/l2tp_core.c +++ b/net/l2tp/l2tp_core.c @@ -1246,9 +1246,9 @@ static int l2tp_xmit_core(struct l2tp_session *session, struct sk_buff *skb, uns else l2tp_build_l2tpv3_header(session, __skb_push(skb, session->hdr_len)); - /* Reset skb netfilter state */ - memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); - IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED | IPSKB_REROUTED); + /* Reset control buffer */ + memset(skb->cb, 0, sizeof(skb->cb)); + nf_reset_ct(skb); /* L2TP uses its own lockdep subclass to avoid lockdep splats caused by diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c index 57065714cf8ceb..7f8799fd673eb8 100644 --- a/net/mac80211/chan.c +++ b/net/mac80211/chan.c @@ -1290,7 +1290,7 @@ ieee80211_link_chanctx_reservation_complete(struct ieee80211_link_data *link) &link->csa.finalize_work); break; case NL80211_IFTYPE_STATION: - wiphy_delayed_work_queue(sdata->local->hw.wiphy, + wiphy_hrtimer_work_queue(sdata->local->hw.wiphy, &link->u.mgd.csa.switch_work, 0); break; case NL80211_IFTYPE_UNSPECIFIED: diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 73fd86ec1bce40..878c3b14aeb806 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -612,11 +612,11 @@ struct ieee80211_if_managed { u8 *assoc_req_ies; size_t assoc_req_ies_len; - struct wiphy_delayed_work ml_reconf_work; + struct wiphy_hrtimer_work ml_reconf_work; u16 removed_links; /* TID-to-link mapping support */ - struct wiphy_delayed_work ttlm_work; + struct wiphy_hrtimer_work ttlm_work; struct ieee80211_adv_ttlm_info ttlm_info; struct wiphy_work teardown_ttlm_work; @@ -1017,10 +1017,10 @@ struct ieee80211_link_data_managed { bool operating_11g_mode; struct { - struct wiphy_delayed_work switch_work; + struct wiphy_hrtimer_work switch_work; struct cfg80211_chan_def ap_chandef; struct ieee80211_parsed_tpe tpe; - unsigned long time; + ktime_t time; bool waiting_bcn; bool ignored_same_chan; bool blocked_tx; diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index a7873832d4fa68..0ca55b9655a7fc 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -223,6 +223,10 @@ static int ieee80211_can_powered_addr_change(struct ieee80211_sub_if_data *sdata if (netif_carrier_ok(sdata->dev)) return -EBUSY; + /* if any stations are set known (so they know this vif too), reject */ + if (sta_info_get_by_idx(sdata, 0)) + return -EBUSY; + /* First check no ROC work is happening on this iface */ list_for_each_entry(roc, &local->roc_list, list) { if (roc->sdata != sdata) @@ -242,12 +246,16 @@ static int ieee80211_can_powered_addr_change(struct ieee80211_sub_if_data *sdata ret = -EBUSY; } + /* + * More interface types could be added here but changing the + * address while powered makes the most sense in client modes. + */ switch (sdata->vif.type) { case NL80211_IFTYPE_STATION: case NL80211_IFTYPE_P2P_CLIENT: - /* More interface types could be added here but changing the - * address while powered makes the most sense in client modes. - */ + /* refuse while connecting */ + if (sdata->u.mgd.auth_data || sdata->u.mgd.assoc_data) + return -EBUSY; break; default: ret = -EOPNOTSUPP; diff --git a/net/mac80211/link.c b/net/mac80211/link.c index d71eabe5abf8d8..4a19b765ccb69f 100644 --- a/net/mac80211/link.c +++ b/net/mac80211/link.c @@ -472,10 +472,10 @@ static int _ieee80211_set_active_links(struct ieee80211_sub_if_data *sdata, * from there. */ if (link->conf->csa_active) - wiphy_delayed_work_queue(local->hw.wiphy, + wiphy_hrtimer_work_queue(local->hw.wiphy, &link->u.mgd.csa.switch_work, link->u.mgd.csa.time - - jiffies); + ktime_get_boottime()); } for_each_set_bit(link_id, &add, IEEE80211_MLD_MAX_NUM_LINKS) { diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 3b5827ea438ee8..f3138d15853533 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -45,7 +45,7 @@ #define IEEE80211_ASSOC_TIMEOUT_SHORT (HZ / 10) #define IEEE80211_ASSOC_MAX_TRIES 3 -#define IEEE80211_ADV_TTLM_SAFETY_BUFFER_MS msecs_to_jiffies(100) +#define IEEE80211_ADV_TTLM_SAFETY_BUFFER_MS (100 * USEC_PER_MSEC) #define IEEE80211_ADV_TTLM_ST_UNDERFLOW 0xff00 #define IEEE80211_NEG_TTLM_REQ_TIMEOUT (HZ / 5) @@ -2594,7 +2594,7 @@ void ieee80211_chswitch_done(struct ieee80211_vif *vif, bool success, return; } - wiphy_delayed_work_queue(sdata->local->hw.wiphy, + wiphy_hrtimer_work_queue(sdata->local->hw.wiphy, &link->u.mgd.csa.switch_work, 0); } @@ -2753,7 +2753,8 @@ ieee80211_sta_process_chanswitch(struct ieee80211_link_data *link, .timestamp = timestamp, .device_timestamp = device_timestamp, }; - unsigned long now; + u32 csa_time_tu; + ktime_t now; int res; lockdep_assert_wiphy(local->hw.wiphy); @@ -2983,10 +2984,9 @@ ieee80211_sta_process_chanswitch(struct ieee80211_link_data *link, csa_ie.mode); /* we may have to handle timeout for deactivated link in software */ - now = jiffies; - link->u.mgd.csa.time = now + - TU_TO_JIFFIES((max_t(int, csa_ie.count, 1) - 1) * - link->conf->beacon_int); + now = ktime_get_boottime(); + csa_time_tu = (max_t(int, csa_ie.count, 1) - 1) * link->conf->beacon_int; + link->u.mgd.csa.time = now + us_to_ktime(ieee80211_tu_to_usec(csa_time_tu)); if (ieee80211_vif_link_active(&sdata->vif, link->link_id) && local->ops->channel_switch) { @@ -3001,7 +3001,7 @@ ieee80211_sta_process_chanswitch(struct ieee80211_link_data *link, } /* channel switch handled in software */ - wiphy_delayed_work_queue(local->hw.wiphy, + wiphy_hrtimer_work_queue(local->hw.wiphy, &link->u.mgd.csa.switch_work, link->u.mgd.csa.time - now); return; @@ -4242,14 +4242,14 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, memset(&sdata->u.mgd.ttlm_info, 0, sizeof(sdata->u.mgd.ttlm_info)); - wiphy_delayed_work_cancel(sdata->local->hw.wiphy, &ifmgd->ttlm_work); + wiphy_hrtimer_work_cancel(sdata->local->hw.wiphy, &ifmgd->ttlm_work); memset(&sdata->vif.neg_ttlm, 0, sizeof(sdata->vif.neg_ttlm)); wiphy_delayed_work_cancel(sdata->local->hw.wiphy, &ifmgd->neg_ttlm_timeout_work); sdata->u.mgd.removed_links = 0; - wiphy_delayed_work_cancel(sdata->local->hw.wiphy, + wiphy_hrtimer_work_cancel(sdata->local->hw.wiphy, &sdata->u.mgd.ml_reconf_work); wiphy_work_cancel(sdata->local->hw.wiphy, @@ -6876,7 +6876,7 @@ static void ieee80211_ml_reconfiguration(struct ieee80211_sub_if_data *sdata, /* In case the removal was cancelled, abort it */ if (sdata->u.mgd.removed_links) { sdata->u.mgd.removed_links = 0; - wiphy_delayed_work_cancel(sdata->local->hw.wiphy, + wiphy_hrtimer_work_cancel(sdata->local->hw.wiphy, &sdata->u.mgd.ml_reconf_work); } return; @@ -6906,9 +6906,9 @@ static void ieee80211_ml_reconfiguration(struct ieee80211_sub_if_data *sdata, } sdata->u.mgd.removed_links = removed_links; - wiphy_delayed_work_queue(sdata->local->hw.wiphy, + wiphy_hrtimer_work_queue(sdata->local->hw.wiphy, &sdata->u.mgd.ml_reconf_work, - TU_TO_JIFFIES(delay)); + us_to_ktime(ieee80211_tu_to_usec(delay))); } static int ieee80211_ttlm_set_links(struct ieee80211_sub_if_data *sdata, @@ -7095,7 +7095,7 @@ static void ieee80211_process_adv_ttlm(struct ieee80211_sub_if_data *sdata, /* if a planned TID-to-link mapping was cancelled - * abort it */ - wiphy_delayed_work_cancel(sdata->local->hw.wiphy, + wiphy_hrtimer_work_cancel(sdata->local->hw.wiphy, &sdata->u.mgd.ttlm_work); } else if (sdata->u.mgd.ttlm_info.active) { /* if no TID-to-link element, set to default mapping in @@ -7130,7 +7130,7 @@ static void ieee80211_process_adv_ttlm(struct ieee80211_sub_if_data *sdata, if (ttlm_info.switch_time) { u16 beacon_ts_tu, st_tu, delay; - u32 delay_jiffies; + u64 delay_usec; u64 mask; /* The t2l map switch time is indicated with a partial @@ -7152,23 +7152,23 @@ static void ieee80211_process_adv_ttlm(struct ieee80211_sub_if_data *sdata, if (delay > IEEE80211_ADV_TTLM_ST_UNDERFLOW) return; - delay_jiffies = TU_TO_JIFFIES(delay); + delay_usec = ieee80211_tu_to_usec(delay); /* Link switching can take time, so schedule it * 100ms before to be ready on time */ - if (delay_jiffies > IEEE80211_ADV_TTLM_SAFETY_BUFFER_MS) - delay_jiffies -= + if (delay_usec > IEEE80211_ADV_TTLM_SAFETY_BUFFER_MS) + delay_usec -= IEEE80211_ADV_TTLM_SAFETY_BUFFER_MS; else - delay_jiffies = 0; + delay_usec = 0; sdata->u.mgd.ttlm_info = ttlm_info; - wiphy_delayed_work_cancel(sdata->local->hw.wiphy, + wiphy_hrtimer_work_cancel(sdata->local->hw.wiphy, &sdata->u.mgd.ttlm_work); - wiphy_delayed_work_queue(sdata->local->hw.wiphy, + wiphy_hrtimer_work_queue(sdata->local->hw.wiphy, &sdata->u.mgd.ttlm_work, - delay_jiffies); + us_to_ktime(delay_usec)); return; } } @@ -8793,7 +8793,7 @@ void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata) ieee80211_csa_connection_drop_work); wiphy_delayed_work_init(&ifmgd->tdls_peer_del_work, ieee80211_tdls_peer_del_work); - wiphy_delayed_work_init(&ifmgd->ml_reconf_work, + wiphy_hrtimer_work_init(&ifmgd->ml_reconf_work, ieee80211_ml_reconf_work); wiphy_delayed_work_init(&ifmgd->reconf.wk, ieee80211_ml_sta_reconf_timeout); @@ -8802,7 +8802,7 @@ void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata) timer_setup(&ifmgd->conn_mon_timer, ieee80211_sta_conn_mon_timer, 0); wiphy_delayed_work_init(&ifmgd->tx_tspec_wk, ieee80211_sta_handle_tspec_ac_params_wk); - wiphy_delayed_work_init(&ifmgd->ttlm_work, + wiphy_hrtimer_work_init(&ifmgd->ttlm_work, ieee80211_tid_to_link_map_work); wiphy_delayed_work_init(&ifmgd->neg_ttlm_timeout_work, ieee80211_neg_ttlm_timeout_work); @@ -8849,7 +8849,7 @@ void ieee80211_mgd_setup_link(struct ieee80211_link_data *link) else link->u.mgd.req_smps = IEEE80211_SMPS_OFF; - wiphy_delayed_work_init(&link->u.mgd.csa.switch_work, + wiphy_hrtimer_work_init(&link->u.mgd.csa.switch_work, ieee80211_csa_switch_work); ieee80211_clear_tpe(&link->conf->tpe); @@ -10064,7 +10064,7 @@ void ieee80211_mgd_stop_link(struct ieee80211_link_data *link) &link->u.mgd.request_smps_work); wiphy_work_cancel(link->sdata->local->hw.wiphy, &link->u.mgd.recalc_smps); - wiphy_delayed_work_cancel(link->sdata->local->hw.wiphy, + wiphy_hrtimer_work_cancel(link->sdata->local->hw.wiphy, &link->u.mgd.csa.switch_work); } diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 6af43dfefdd6aa..5b4c3fe9970ad3 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -5360,10 +5360,14 @@ void ieee80211_rx_list(struct ieee80211_hw *hw, struct ieee80211_sta *pubsta, if (WARN_ON(!local->started)) goto drop; - if (likely(!(status->flag & RX_FLAG_FAILED_PLCP_CRC))) { + if (likely(!(status->flag & RX_FLAG_FAILED_PLCP_CRC) && + !(status->flag & RX_FLAG_NO_PSDU && + status->zero_length_psdu_type == + IEEE80211_RADIOTAP_ZERO_LEN_PSDU_NOT_CAPTURED))) { /* - * Validate the rate, unless a PLCP error means that - * we probably can't have a valid rate here anyway. + * Validate the rate, unless there was a PLCP error which may + * have an invalid rate or the PSDU was not capture and may be + * missing rate information. */ switch (status->encoding) { diff --git a/net/mptcp/options.c b/net/mptcp/options.c index 1103b3341a7056..f24ae7d40e883a 100644 --- a/net/mptcp/options.c +++ b/net/mptcp/options.c @@ -838,8 +838,11 @@ bool mptcp_established_options(struct sock *sk, struct sk_buff *skb, opts->suboptions = 0; + /* Force later mptcp_write_options(), but do not use any actual + * option space. + */ if (unlikely(__mptcp_check_fallback(msk) && !mptcp_check_infinite_map(skb))) - return false; + return true; if (unlikely(skb && TCP_SKB_CB(skb)->tcp_flags & TCPHDR_RST)) { if (mptcp_established_options_fastclose(sk, &opt_size, remaining, opts) || @@ -1041,6 +1044,31 @@ static void __mptcp_snd_una_update(struct mptcp_sock *msk, u64 new_snd_una) WRITE_ONCE(msk->snd_una, new_snd_una); } +static void rwin_update(struct mptcp_sock *msk, struct sock *ssk, + struct sk_buff *skb) +{ + struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(ssk); + struct tcp_sock *tp = tcp_sk(ssk); + u64 mptcp_rcv_wnd; + + /* Avoid touching extra cachelines if TCP is going to accept this + * skb without filling the TCP-level window even with a possibly + * outdated mptcp-level rwin. + */ + if (!skb->len || skb->len < tcp_receive_window(tp)) + return; + + mptcp_rcv_wnd = atomic64_read(&msk->rcv_wnd_sent); + if (!after64(mptcp_rcv_wnd, subflow->rcv_wnd_sent)) + return; + + /* Some other subflow grew the mptcp-level rwin since rcv_wup, + * resync. + */ + tp->rcv_wnd += mptcp_rcv_wnd - subflow->rcv_wnd_sent; + subflow->rcv_wnd_sent = mptcp_rcv_wnd; +} + static void ack_update_msk(struct mptcp_sock *msk, struct sock *ssk, struct mptcp_options_received *mp_opt) @@ -1208,6 +1236,7 @@ bool mptcp_incoming_options(struct sock *sk, struct sk_buff *skb) */ if (mp_opt.use_ack) ack_update_msk(msk, sk, &mp_opt); + rwin_update(msk, sk, skb); /* Zero-data-length packets are dropped by the caller and not * propagated to the MPTCP layer, so the skb extension does not @@ -1294,6 +1323,10 @@ static void mptcp_set_rwin(struct tcp_sock *tp, struct tcphdr *th) if (rcv_wnd_new != rcv_wnd_old) { raise_win: + /* The msk-level rcv wnd is after the tcp level one, + * sync the latter. + */ + rcv_wnd_new = rcv_wnd_old; win = rcv_wnd_old - ack_seq; tp->rcv_wnd = min_t(u64, win, U32_MAX); new_win = tp->rcv_wnd; @@ -1317,6 +1350,21 @@ static void mptcp_set_rwin(struct tcp_sock *tp, struct tcphdr *th) update_wspace: WRITE_ONCE(msk->old_wspace, tp->rcv_wnd); + subflow->rcv_wnd_sent = rcv_wnd_new; +} + +static void mptcp_track_rwin(struct tcp_sock *tp) +{ + const struct sock *ssk = (const struct sock *)tp; + struct mptcp_subflow_context *subflow; + struct mptcp_sock *msk; + + if (!ssk) + return; + + subflow = mptcp_subflow_ctx(ssk); + msk = mptcp_sk(subflow->conn); + WRITE_ONCE(msk->old_wspace, tp->rcv_wnd); } __sum16 __mptcp_make_csum(u64 data_seq, u32 subflow_seq, u16 data_len, __wsum sum) @@ -1611,6 +1659,10 @@ void mptcp_write_options(struct tcphdr *th, __be32 *ptr, struct tcp_sock *tp, opts->reset_transient, opts->reset_reason); return; + } else if (unlikely(!opts->suboptions)) { + /* Fallback to TCP */ + mptcp_track_rwin(tp); + return; } if (OPTION_MPTCP_PRIO & opts->suboptions) { diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c index 2ff1b949956834..9604b91902b8bc 100644 --- a/net/mptcp/pm.c +++ b/net/mptcp/pm.c @@ -18,6 +18,7 @@ struct mptcp_pm_add_entry { u8 retrans_times; struct timer_list add_timer; struct mptcp_sock *sock; + struct rcu_head rcu; }; static DEFINE_SPINLOCK(mptcp_pm_list_lock); @@ -155,7 +156,7 @@ bool mptcp_remove_anno_list_by_saddr(struct mptcp_sock *msk, entry = mptcp_pm_del_add_timer(msk, addr, false); ret = entry; - kfree(entry); + kfree_rcu(entry, rcu); return ret; } @@ -345,22 +346,27 @@ mptcp_pm_del_add_timer(struct mptcp_sock *msk, { struct mptcp_pm_add_entry *entry; struct sock *sk = (struct sock *)msk; - struct timer_list *add_timer = NULL; + bool stop_timer = false; + + rcu_read_lock(); spin_lock_bh(&msk->pm.lock); entry = mptcp_lookup_anno_list_by_saddr(msk, addr); if (entry && (!check_id || entry->addr.id == addr->id)) { entry->retrans_times = ADD_ADDR_RETRANS_MAX; - add_timer = &entry->add_timer; + stop_timer = true; } if (!check_id && entry) list_del(&entry->list); spin_unlock_bh(&msk->pm.lock); - /* no lock, because sk_stop_timer_sync() is calling timer_delete_sync() */ - if (add_timer) - sk_stop_timer_sync(sk, add_timer); + /* Note: entry might have been removed by another thread. + * We hold rcu_read_lock() to ensure it is not freed under us. + */ + if (stop_timer) + sk_stop_timer_sync(sk, &entry->add_timer); + rcu_read_unlock(); return entry; } @@ -415,7 +421,7 @@ static void mptcp_pm_free_anno_list(struct mptcp_sock *msk) list_for_each_entry_safe(entry, tmp, &free_list, list) { sk_stop_timer_sync(sk, &entry->add_timer); - kfree(entry); + kfree_rcu(entry, rcu); } } diff --git a/net/mptcp/pm_kernel.c b/net/mptcp/pm_kernel.c index 2ae95476dba35e..0a50fd5edc06db 100644 --- a/net/mptcp/pm_kernel.c +++ b/net/mptcp/pm_kernel.c @@ -672,7 +672,7 @@ static void mptcp_pm_nl_add_addr_received(struct mptcp_sock *msk) void mptcp_pm_nl_rm_addr(struct mptcp_sock *msk, u8 rm_id) { - if (rm_id && WARN_ON_ONCE(msk->pm.add_addr_accepted == 0)) { + if (rm_id && !WARN_ON_ONCE(msk->pm.add_addr_accepted == 0)) { u8 limit_add_addr_accepted = mptcp_pm_get_limit_add_addr_accepted(msk); diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c index 2d6b8de35c4493..33b5dce431c29d 100644 --- a/net/mptcp/protocol.c +++ b/net/mptcp/protocol.c @@ -61,11 +61,13 @@ static u64 mptcp_wnd_end(const struct mptcp_sock *msk) static const struct proto_ops *mptcp_fallback_tcp_ops(const struct sock *sk) { + unsigned short family = READ_ONCE(sk->sk_family); + #if IS_ENABLED(CONFIG_MPTCP_IPV6) - if (sk->sk_prot == &tcpv6_prot) + if (family == AF_INET6) return &inet6_stream_ops; #endif - WARN_ON_ONCE(sk->sk_prot != &tcp_prot); + WARN_ON_ONCE(family != AF_INET); return &inet_stream_ops; } @@ -76,6 +78,13 @@ bool __mptcp_try_fallback(struct mptcp_sock *msk, int fb_mib) if (__mptcp_check_fallback(msk)) return true; + /* The caller possibly is not holding the msk socket lock, but + * in the fallback case only the current subflow is touching + * the OoO queue. + */ + if (!RB_EMPTY_ROOT(&msk->out_of_order_queue)) + return false; + spin_lock_bh(&msk->fallback_lock); if (!msk->allow_infinite_fallback) { spin_unlock_bh(&msk->fallback_lock); @@ -935,14 +944,19 @@ static void mptcp_reset_rtx_timer(struct sock *sk) bool mptcp_schedule_work(struct sock *sk) { - if (inet_sk_state_load(sk) != TCP_CLOSE && - schedule_work(&mptcp_sk(sk)->work)) { - /* each subflow already holds a reference to the sk, and the - * workqueue is invoked by a subflow, so sk can't go away here. - */ - sock_hold(sk); + if (inet_sk_state_load(sk) == TCP_CLOSE) + return false; + + /* Get a reference on this socket, mptcp_worker() will release it. + * As mptcp_worker() might complete before us, we can not avoid + * a sock_hold()/sock_put() if schedule_work() returns false. + */ + sock_hold(sk); + + if (schedule_work(&mptcp_sk(sk)->work)) return true; - } + + sock_put(sk); return false; } @@ -2397,7 +2411,6 @@ bool __mptcp_retransmit_pending_data(struct sock *sk) /* flags for __mptcp_close_ssk() */ #define MPTCP_CF_PUSH BIT(1) -#define MPTCP_CF_FASTCLOSE BIT(2) /* be sure to send a reset only if the caller asked for it, also * clean completely the subflow status when the subflow reaches @@ -2408,7 +2421,7 @@ static void __mptcp_subflow_disconnect(struct sock *ssk, unsigned int flags) { if (((1 << ssk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN)) || - (flags & MPTCP_CF_FASTCLOSE)) { + subflow->send_fastclose) { /* The MPTCP code never wait on the subflow sockets, TCP-level * disconnect should never fail */ @@ -2455,14 +2468,8 @@ static void __mptcp_close_ssk(struct sock *sk, struct sock *ssk, lock_sock_nested(ssk, SINGLE_DEPTH_NESTING); - if ((flags & MPTCP_CF_FASTCLOSE) && !__mptcp_check_fallback(msk)) { - /* be sure to force the tcp_close path - * to generate the egress reset - */ - ssk->sk_lingertime = 0; - sock_set_flag(ssk, SOCK_LINGER); - subflow->send_fastclose = 1; - } + if (subflow->send_fastclose && ssk->sk_state != TCP_CLOSE) + tcp_set_state(ssk, TCP_CLOSE); need_push = (flags & MPTCP_CF_PUSH) && __mptcp_retransmit_pending_data(sk); if (!dispose_it) { @@ -2558,7 +2565,8 @@ static void __mptcp_close_subflow(struct sock *sk) if (ssk_state != TCP_CLOSE && (ssk_state != TCP_CLOSE_WAIT || - inet_sk_state_load(sk) != TCP_ESTABLISHED)) + inet_sk_state_load(sk) != TCP_ESTABLISHED || + __mptcp_check_fallback(msk))) continue; /* 'subflow_data_ready' will re-sched once rx queue is empty */ @@ -2766,9 +2774,26 @@ static void mptcp_do_fastclose(struct sock *sk) struct mptcp_sock *msk = mptcp_sk(sk); mptcp_set_state(sk, TCP_CLOSE); - mptcp_for_each_subflow_safe(msk, subflow, tmp) - __mptcp_close_ssk(sk, mptcp_subflow_tcp_sock(subflow), - subflow, MPTCP_CF_FASTCLOSE); + + /* Explicitly send the fastclose reset as need */ + if (__mptcp_check_fallback(msk)) + return; + + mptcp_for_each_subflow_safe(msk, subflow, tmp) { + struct sock *ssk = mptcp_subflow_tcp_sock(subflow); + + lock_sock(ssk); + + /* Some subflow socket states don't allow/need a reset.*/ + if ((1 << ssk->sk_state) & (TCPF_LISTEN | TCPF_CLOSE)) + goto unlock; + + subflow->send_fastclose = 1; + tcp_send_active_reset(ssk, ssk->sk_allocation, + SK_RST_REASON_TCP_ABORT_ON_CLOSE); +unlock: + release_sock(ssk); + } } static void mptcp_worker(struct work_struct *work) @@ -2795,7 +2820,11 @@ static void mptcp_worker(struct work_struct *work) __mptcp_close_subflow(sk); if (mptcp_close_tout_expired(sk)) { + struct mptcp_subflow_context *subflow, *tmp; + mptcp_do_fastclose(sk); + mptcp_for_each_subflow_safe(msk, subflow, tmp) + __mptcp_close_ssk(sk, subflow->tcp_sock, subflow, 0); mptcp_close_wake_up(sk); } @@ -3220,7 +3249,8 @@ static int mptcp_disconnect(struct sock *sk, int flags) /* msk->subflow is still intact, the following will not free the first * subflow */ - mptcp_destroy_common(msk, MPTCP_CF_FASTCLOSE); + mptcp_do_fastclose(sk); + mptcp_destroy_common(msk); /* The first subflow is already in TCP_CLOSE status, the following * can't overlap with a fallback anymore @@ -3399,7 +3429,7 @@ void mptcp_rcv_space_init(struct mptcp_sock *msk, const struct sock *ssk) msk->rcvq_space.space = TCP_INIT_CWND * TCP_MSS_DEFAULT; } -void mptcp_destroy_common(struct mptcp_sock *msk, unsigned int flags) +void mptcp_destroy_common(struct mptcp_sock *msk) { struct mptcp_subflow_context *subflow, *tmp; struct sock *sk = (struct sock *)msk; @@ -3408,7 +3438,7 @@ void mptcp_destroy_common(struct mptcp_sock *msk, unsigned int flags) /* join list will be eventually flushed (with rst) at sock lock release time */ mptcp_for_each_subflow_safe(msk, subflow, tmp) - __mptcp_close_ssk(sk, mptcp_subflow_tcp_sock(subflow), subflow, flags); + __mptcp_close_ssk(sk, mptcp_subflow_tcp_sock(subflow), subflow, 0); __skb_queue_purge(&sk->sk_receive_queue); skb_rbtree_purge(&msk->out_of_order_queue); @@ -3426,7 +3456,7 @@ static void mptcp_destroy(struct sock *sk) /* allow the following to close even the initial subflow */ msk->free_first = 1; - mptcp_destroy_common(msk, 0); + mptcp_destroy_common(msk); sk_sockets_allocated_dec(sk); } diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h index 379a88e14e8d25..6ca97096607c39 100644 --- a/net/mptcp/protocol.h +++ b/net/mptcp/protocol.h @@ -509,6 +509,7 @@ struct mptcp_subflow_context { u64 remote_key; u64 idsn; u64 map_seq; + u64 rcv_wnd_sent; u32 snd_isn; u32 token; u32 rel_write_seq; @@ -976,7 +977,7 @@ static inline void mptcp_propagate_sndbuf(struct sock *sk, struct sock *ssk) local_bh_enable(); } -void mptcp_destroy_common(struct mptcp_sock *msk, unsigned int flags); +void mptcp_destroy_common(struct mptcp_sock *msk); #define MPTCP_TOKEN_MAX_RETRIES 4 diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c index e8325890a32238..af707ce0f62445 100644 --- a/net/mptcp/subflow.c +++ b/net/mptcp/subflow.c @@ -2144,6 +2144,10 @@ void __init mptcp_subflow_init(void) tcp_prot_override = tcp_prot; tcp_prot_override.release_cb = tcp_release_cb_override; tcp_prot_override.diag_destroy = tcp_abort_override; +#ifdef CONFIG_BPF_SYSCALL + /* Disable sockmap processing for subflows */ + tcp_prot_override.psock_update_sk_prot = NULL; +#endif #if IS_ENABLED(CONFIG_MPTCP_IPV6) /* In struct mptcp_subflow_request_sock, we assume the TCP request sock @@ -2180,6 +2184,10 @@ void __init mptcp_subflow_init(void) tcpv6_prot_override = tcpv6_prot; tcpv6_prot_override.release_cb = tcp_release_cb_override; tcpv6_prot_override.diag_destroy = tcp_abort_override; +#ifdef CONFIG_BPF_SYSCALL + /* Disable sockmap processing for subflows */ + tcpv6_prot_override.psock_update_sk_prot = NULL; +#endif #endif mptcp_diag_subflow_init(&subflow_ulp_ops); diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c index 2832e079419715..792ca44a461da0 100644 --- a/net/openvswitch/actions.c +++ b/net/openvswitch/actions.c @@ -572,69 +572,6 @@ static int set_ipv6(struct sk_buff *skb, struct sw_flow_key *flow_key, return 0; } -static int set_nsh(struct sk_buff *skb, struct sw_flow_key *flow_key, - const struct nlattr *a) -{ - struct nshhdr *nh; - size_t length; - int err; - u8 flags; - u8 ttl; - int i; - - struct ovs_key_nsh key; - struct ovs_key_nsh mask; - - err = nsh_key_from_nlattr(a, &key, &mask); - if (err) - return err; - - /* Make sure the NSH base header is there */ - if (!pskb_may_pull(skb, skb_network_offset(skb) + NSH_BASE_HDR_LEN)) - return -ENOMEM; - - nh = nsh_hdr(skb); - length = nsh_hdr_len(nh); - - /* Make sure the whole NSH header is there */ - err = skb_ensure_writable(skb, skb_network_offset(skb) + - length); - if (unlikely(err)) - return err; - - nh = nsh_hdr(skb); - skb_postpull_rcsum(skb, nh, length); - flags = nsh_get_flags(nh); - flags = OVS_MASKED(flags, key.base.flags, mask.base.flags); - flow_key->nsh.base.flags = flags; - ttl = nsh_get_ttl(nh); - ttl = OVS_MASKED(ttl, key.base.ttl, mask.base.ttl); - flow_key->nsh.base.ttl = ttl; - nsh_set_flags_and_ttl(nh, flags, ttl); - nh->path_hdr = OVS_MASKED(nh->path_hdr, key.base.path_hdr, - mask.base.path_hdr); - flow_key->nsh.base.path_hdr = nh->path_hdr; - switch (nh->mdtype) { - case NSH_M_TYPE1: - for (i = 0; i < NSH_MD1_CONTEXT_SIZE; i++) { - nh->md1.context[i] = - OVS_MASKED(nh->md1.context[i], key.context[i], - mask.context[i]); - } - memcpy(flow_key->nsh.context, nh->md1.context, - sizeof(nh->md1.context)); - break; - case NSH_M_TYPE2: - memset(flow_key->nsh.context, 0, - sizeof(flow_key->nsh.context)); - break; - default: - return -EINVAL; - } - skb_postpush_rcsum(skb, nh, length); - return 0; -} - /* Must follow skb_ensure_writable() since that can move the skb data. */ static void set_tp_port(struct sk_buff *skb, __be16 *port, __be16 new_port, __sum16 *check) @@ -1130,10 +1067,6 @@ static int execute_masked_set_action(struct sk_buff *skb, get_mask(a, struct ovs_key_ethernet *)); break; - case OVS_KEY_ATTR_NSH: - err = set_nsh(skb, flow_key, a); - break; - case OVS_KEY_ATTR_IPV4: err = set_ipv4(skb, flow_key, nla_data(a), get_mask(a, struct ovs_key_ipv4 *)); @@ -1170,6 +1103,7 @@ static int execute_masked_set_action(struct sk_buff *skb, case OVS_KEY_ATTR_CT_LABELS: case OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV4: case OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV6: + case OVS_KEY_ATTR_NSH: err = -EINVAL; break; } diff --git a/net/openvswitch/flow_netlink.c b/net/openvswitch/flow_netlink.c index ad64bb9ab5e256..1cb4f97335d87b 100644 --- a/net/openvswitch/flow_netlink.c +++ b/net/openvswitch/flow_netlink.c @@ -1305,6 +1305,11 @@ static int metadata_from_nlattrs(struct net *net, struct sw_flow_match *match, return 0; } +/* + * Constructs NSH header 'nh' from attributes of OVS_ACTION_ATTR_PUSH_NSH, + * where 'nh' points to a memory block of 'size' bytes. It's assumed that + * attributes were previously validated with validate_push_nsh(). + */ int nsh_hdr_from_nlattr(const struct nlattr *attr, struct nshhdr *nh, size_t size) { @@ -1314,8 +1319,6 @@ int nsh_hdr_from_nlattr(const struct nlattr *attr, u8 ttl = 0; int mdlen = 0; - /* validate_nsh has check this, so we needn't do duplicate check here - */ if (size < NSH_BASE_HDR_LEN) return -ENOBUFS; @@ -1359,46 +1362,6 @@ int nsh_hdr_from_nlattr(const struct nlattr *attr, return 0; } -int nsh_key_from_nlattr(const struct nlattr *attr, - struct ovs_key_nsh *nsh, struct ovs_key_nsh *nsh_mask) -{ - struct nlattr *a; - int rem; - - /* validate_nsh has check this, so we needn't do duplicate check here - */ - nla_for_each_nested(a, attr, rem) { - int type = nla_type(a); - - switch (type) { - case OVS_NSH_KEY_ATTR_BASE: { - const struct ovs_nsh_key_base *base = nla_data(a); - const struct ovs_nsh_key_base *base_mask = base + 1; - - nsh->base = *base; - nsh_mask->base = *base_mask; - break; - } - case OVS_NSH_KEY_ATTR_MD1: { - const struct ovs_nsh_key_md1 *md1 = nla_data(a); - const struct ovs_nsh_key_md1 *md1_mask = md1 + 1; - - memcpy(nsh->context, md1->context, sizeof(*md1)); - memcpy(nsh_mask->context, md1_mask->context, - sizeof(*md1_mask)); - break; - } - case OVS_NSH_KEY_ATTR_MD2: - /* Not supported yet */ - return -ENOTSUPP; - default: - return -EINVAL; - } - } - - return 0; -} - static int nsh_key_put_from_nlattr(const struct nlattr *attr, struct sw_flow_match *match, bool is_mask, bool is_push_nsh, bool log) @@ -2839,17 +2802,13 @@ static int validate_and_copy_set_tun(const struct nlattr *attr, return err; } -static bool validate_nsh(const struct nlattr *attr, bool is_mask, - bool is_push_nsh, bool log) +static bool validate_push_nsh(const struct nlattr *attr, bool log) { struct sw_flow_match match; struct sw_flow_key key; - int ret = 0; ovs_match_init(&match, &key, true, NULL); - ret = nsh_key_put_from_nlattr(attr, &match, is_mask, - is_push_nsh, log); - return !ret; + return !nsh_key_put_from_nlattr(attr, &match, false, true, log); } /* Return false if there are any non-masked bits set. @@ -2997,13 +2956,6 @@ static int validate_set(const struct nlattr *a, break; - case OVS_KEY_ATTR_NSH: - if (eth_type != htons(ETH_P_NSH)) - return -EINVAL; - if (!validate_nsh(nla_data(a), masked, false, log)) - return -EINVAL; - break; - default: return -EINVAL; } @@ -3437,7 +3389,7 @@ static int __ovs_nla_copy_actions(struct net *net, const struct nlattr *attr, return -EINVAL; } mac_proto = MAC_PROTO_NONE; - if (!validate_nsh(nla_data(a), false, true, true)) + if (!validate_push_nsh(nla_data(a), log)) return -EINVAL; break; diff --git a/net/openvswitch/flow_netlink.h b/net/openvswitch/flow_netlink.h index fe7f77fc5f1890..ff8cdecbe34654 100644 --- a/net/openvswitch/flow_netlink.h +++ b/net/openvswitch/flow_netlink.h @@ -65,8 +65,6 @@ int ovs_nla_put_actions(const struct nlattr *attr, void ovs_nla_free_flow_actions(struct sw_flow_actions *); void ovs_nla_free_flow_actions_rcu(struct sw_flow_actions *); -int nsh_key_from_nlattr(const struct nlattr *attr, struct ovs_key_nsh *nsh, - struct ovs_key_nsh *nsh_mask); int nsh_hdr_from_nlattr(const struct nlattr *attr, struct nshhdr *nh, size_t size); diff --git a/net/sched/act_bpf.c b/net/sched/act_bpf.c index 396b576390d00a..c2b5bc19e09118 100644 --- a/net/sched/act_bpf.c +++ b/net/sched/act_bpf.c @@ -47,12 +47,10 @@ TC_INDIRECT_SCOPE int tcf_bpf_act(struct sk_buff *skb, filter = rcu_dereference(prog->filter); if (at_ingress) { __skb_push(skb, skb->mac_len); - bpf_compute_data_pointers(skb); - filter_res = bpf_prog_run(filter, skb); + filter_res = bpf_prog_run_data_pointers(filter, skb); __skb_pull(skb, skb->mac_len); } else { - bpf_compute_data_pointers(skb); - filter_res = bpf_prog_run(filter, skb); + filter_res = bpf_prog_run_data_pointers(filter, skb); } if (unlikely(!skb->tstamp && skb->tstamp_type)) skb->tstamp_type = SKB_CLOCK_REALTIME; diff --git a/net/sched/act_connmark.c b/net/sched/act_connmark.c index 3e89927d711647..26ba8c2d20abf3 100644 --- a/net/sched/act_connmark.c +++ b/net/sched/act_connmark.c @@ -195,13 +195,15 @@ static inline int tcf_connmark_dump(struct sk_buff *skb, struct tc_action *a, const struct tcf_connmark_info *ci = to_connmark(a); unsigned char *b = skb_tail_pointer(skb); const struct tcf_connmark_parms *parms; - struct tc_connmark opt = { - .index = ci->tcf_index, - .refcnt = refcount_read(&ci->tcf_refcnt) - ref, - .bindcnt = atomic_read(&ci->tcf_bindcnt) - bind, - }; + struct tc_connmark opt; struct tcf_t t; + memset(&opt, 0, sizeof(opt)); + + opt.index = ci->tcf_index; + opt.refcnt = refcount_read(&ci->tcf_refcnt) - ref; + opt.bindcnt = atomic_read(&ci->tcf_bindcnt) - bind; + rcu_read_lock(); parms = rcu_dereference(ci->parms); diff --git a/net/sched/act_ife.c b/net/sched/act_ife.c index 107c6d83dc5c4b..7c6975632fc2ec 100644 --- a/net/sched/act_ife.c +++ b/net/sched/act_ife.c @@ -644,13 +644,15 @@ static int tcf_ife_dump(struct sk_buff *skb, struct tc_action *a, int bind, unsigned char *b = skb_tail_pointer(skb); struct tcf_ife_info *ife = to_ife(a); struct tcf_ife_params *p; - struct tc_ife opt = { - .index = ife->tcf_index, - .refcnt = refcount_read(&ife->tcf_refcnt) - ref, - .bindcnt = atomic_read(&ife->tcf_bindcnt) - bind, - }; + struct tc_ife opt; struct tcf_t t; + memset(&opt, 0, sizeof(opt)); + + opt.index = ife->tcf_index, + opt.refcnt = refcount_read(&ife->tcf_refcnt) - ref, + opt.bindcnt = atomic_read(&ife->tcf_bindcnt) - bind, + spin_lock_bh(&ife->tcf_lock); opt.action = ife->tcf_action; p = rcu_dereference_protected(ife->params, diff --git a/net/sched/cls_bpf.c b/net/sched/cls_bpf.c index 7fbe42f0e5c2b7..a32754a2658bb7 100644 --- a/net/sched/cls_bpf.c +++ b/net/sched/cls_bpf.c @@ -97,12 +97,10 @@ TC_INDIRECT_SCOPE int cls_bpf_classify(struct sk_buff *skb, } else if (at_ingress) { /* It is safe to push/pull even if skb_shared() */ __skb_push(skb, skb->mac_len); - bpf_compute_data_pointers(skb); - filter_res = bpf_prog_run(prog->filter, skb); + filter_res = bpf_prog_run_data_pointers(prog->filter, skb); __skb_pull(skb, skb->mac_len); } else { - bpf_compute_data_pointers(skb); - filter_res = bpf_prog_run(prog->filter, skb); + filter_res = bpf_prog_run_data_pointers(prog->filter, skb); } if (unlikely(!skb->tstamp && skb->tstamp_type)) skb->tstamp_type = SKB_CLOCK_REALTIME; diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c index 1e058b46d3e171..f56b18c8aebf73 100644 --- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c @@ -1599,6 +1599,11 @@ static int __tc_modify_qdisc(struct sk_buff *skb, struct nlmsghdr *n, NL_SET_ERR_MSG(extack, "Failed to find specified qdisc"); return -ENOENT; } + if (p->flags & TCQ_F_INGRESS) { + NL_SET_ERR_MSG(extack, + "Cannot add children to ingress/clsact qdisc"); + return -EOPNOTSUPP; + } q = qdisc_leaf(p, clid, extack); if (IS_ERR(q)) return PTR_ERR(q); diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c index 1e008a228ebdf8..7dee9748a56be9 100644 --- a/net/sched/sch_generic.c +++ b/net/sched/sch_generic.c @@ -180,9 +180,10 @@ static inline void dev_requeue_skb(struct sk_buff *skb, struct Qdisc *q) static void try_bulk_dequeue_skb(struct Qdisc *q, struct sk_buff *skb, const struct netdev_queue *txq, - int *packets) + int *packets, int budget) { int bytelimit = qdisc_avail_bulklimit(txq) - skb->len; + int cnt = 0; while (bytelimit > 0) { struct sk_buff *nskb = q->dequeue(q); @@ -193,8 +194,10 @@ static void try_bulk_dequeue_skb(struct Qdisc *q, bytelimit -= nskb->len; /* covers GSO len */ skb->next = nskb; skb = nskb; - (*packets)++; /* GSO counts as one pkt */ + if (++cnt >= budget) + break; } + (*packets) += cnt; skb_mark_not_on_list(skb); } @@ -228,7 +231,7 @@ static void try_bulk_dequeue_skb_slow(struct Qdisc *q, * A requeued skb (via q->gso_skb) can also be a SKB list. */ static struct sk_buff *dequeue_skb(struct Qdisc *q, bool *validate, - int *packets) + int *packets, int budget) { const struct netdev_queue *txq = q->dev_queue; struct sk_buff *skb = NULL; @@ -295,7 +298,7 @@ static struct sk_buff *dequeue_skb(struct Qdisc *q, bool *validate, if (skb) { bulk: if (qdisc_may_bulk(q)) - try_bulk_dequeue_skb(q, skb, txq, packets); + try_bulk_dequeue_skb(q, skb, txq, packets, budget); else try_bulk_dequeue_skb_slow(q, skb, packets); } @@ -387,7 +390,7 @@ bool sch_direct_xmit(struct sk_buff *skb, struct Qdisc *q, * >0 - queue is not empty. * */ -static inline bool qdisc_restart(struct Qdisc *q, int *packets) +static inline bool qdisc_restart(struct Qdisc *q, int *packets, int budget) { spinlock_t *root_lock = NULL; struct netdev_queue *txq; @@ -396,7 +399,7 @@ static inline bool qdisc_restart(struct Qdisc *q, int *packets) bool validate; /* Dequeue packet */ - skb = dequeue_skb(q, &validate, packets); + skb = dequeue_skb(q, &validate, packets, budget); if (unlikely(!skb)) return false; @@ -414,7 +417,7 @@ void __qdisc_run(struct Qdisc *q) int quota = READ_ONCE(net_hotdata.dev_tx_weight); int packets; - while (qdisc_restart(q, &packets)) { + while (qdisc_restart(q, &packets, quota)) { quota -= packets; if (quota <= 0) { if (q->flags & TCQ_F_NOLOCK) diff --git a/net/sctp/diag.c b/net/sctp/diag.c index 996c2018f0e611..2afb376299fe47 100644 --- a/net/sctp/diag.c +++ b/net/sctp/diag.c @@ -73,19 +73,26 @@ static int inet_diag_msg_sctpladdrs_fill(struct sk_buff *skb, struct nlattr *attr; void *info = NULL; + rcu_read_lock(); list_for_each_entry_rcu(laddr, address_list, list) addrcnt++; + rcu_read_unlock(); attr = nla_reserve(skb, INET_DIAG_LOCALS, addrlen * addrcnt); if (!attr) return -EMSGSIZE; info = nla_data(attr); + rcu_read_lock(); list_for_each_entry_rcu(laddr, address_list, list) { memcpy(info, &laddr->a, sizeof(laddr->a)); memset(info + sizeof(laddr->a), 0, addrlen - sizeof(laddr->a)); info += addrlen; + + if (!--addrcnt) + break; } + rcu_read_unlock(); return 0; } @@ -223,14 +230,15 @@ struct sctp_comm_param { bool net_admin; }; -static size_t inet_assoc_attr_size(struct sctp_association *asoc) +static size_t inet_assoc_attr_size(struct sock *sk, + struct sctp_association *asoc) { int addrlen = sizeof(struct sockaddr_storage); int addrcnt = 0; struct sctp_sockaddr_entry *laddr; list_for_each_entry_rcu(laddr, &asoc->base.bind_addr.address_list, - list) + list, lockdep_sock_is_held(sk)) addrcnt++; return nla_total_size(sizeof(struct sctp_info)) @@ -256,11 +264,14 @@ static int sctp_sock_dump_one(struct sctp_endpoint *ep, struct sctp_transport *t if (err) return err; - rep = nlmsg_new(inet_assoc_attr_size(assoc), GFP_KERNEL); - if (!rep) + lock_sock(sk); + + rep = nlmsg_new(inet_assoc_attr_size(sk, assoc), GFP_KERNEL); + if (!rep) { + release_sock(sk); return -ENOMEM; + } - lock_sock(sk); if (ep != assoc->ep) { err = -EAGAIN; goto out; diff --git a/net/sctp/transport.c b/net/sctp/transport.c index 4d258a6e8033cb..0c56d9673cc137 100644 --- a/net/sctp/transport.c +++ b/net/sctp/transport.c @@ -37,10 +37,10 @@ /* 1st Level Abstractions. */ /* Initialize a new transport from provided memory. */ -static struct sctp_transport *sctp_transport_init(struct net *net, - struct sctp_transport *peer, - const union sctp_addr *addr, - gfp_t gfp) +static void sctp_transport_init(struct net *net, + struct sctp_transport *peer, + const union sctp_addr *addr, + gfp_t gfp) { /* Copy in the address. */ peer->af_specific = sctp_get_af_specific(addr->sa.sa_family); @@ -83,8 +83,6 @@ static struct sctp_transport *sctp_transport_init(struct net *net, get_random_bytes(&peer->hb_nonce, sizeof(peer->hb_nonce)); refcount_set(&peer->refcnt, 1); - - return peer; } /* Allocate and initialize a new transport. */ @@ -96,20 +94,13 @@ struct sctp_transport *sctp_transport_new(struct net *net, transport = kzalloc(sizeof(*transport), gfp); if (!transport) - goto fail; + return NULL; - if (!sctp_transport_init(net, transport, addr, gfp)) - goto fail_init; + sctp_transport_init(net, transport, addr, gfp); SCTP_DBG_OBJCNT_INC(transport); return transport; - -fail_init: - kfree(transport); - -fail: - return NULL; } /* This transport is no longer needed. Free up if possible, or @@ -495,6 +486,7 @@ void sctp_transport_update_rto(struct sctp_transport *tp, __u32 rtt) if (tp->rttvar || tp->srtt) { struct net *net = tp->asoc->base.net; + unsigned int rto_beta, rto_alpha; /* 6.3.1 C3) When a new RTT measurement R' is made, set * RTTVAR <- (1 - RTO.Beta) * RTTVAR + RTO.Beta * |SRTT - R'| * SRTT <- (1 - RTO.Alpha) * SRTT + RTO.Alpha * R' @@ -506,10 +498,14 @@ void sctp_transport_update_rto(struct sctp_transport *tp, __u32 rtt) * For example, assuming the default value of RTO.Alpha of * 1/8, rto_alpha would be expressed as 3. */ - tp->rttvar = tp->rttvar - (tp->rttvar >> net->sctp.rto_beta) - + (((__u32)abs((__s64)tp->srtt - (__s64)rtt)) >> net->sctp.rto_beta); - tp->srtt = tp->srtt - (tp->srtt >> net->sctp.rto_alpha) - + (rtt >> net->sctp.rto_alpha); + rto_beta = READ_ONCE(net->sctp.rto_beta); + if (rto_beta < 32) + tp->rttvar = tp->rttvar - (tp->rttvar >> rto_beta) + + (((__u32)abs((__s64)tp->srtt - (__s64)rtt)) >> rto_beta); + rto_alpha = READ_ONCE(net->sctp.rto_alpha); + if (rto_alpha < 32) + tp->srtt = tp->srtt - (tp->srtt >> rto_alpha) + + (rtt >> rto_alpha); } else { /* 6.3.1 C2) When the first RTT measurement R is made, set * SRTT <- R, RTTVAR <- R/2. diff --git a/net/smc/smc_clc.c b/net/smc/smc_clc.c index 157aace169d496..87c87edadde719 100644 --- a/net/smc/smc_clc.c +++ b/net/smc/smc_clc.c @@ -890,6 +890,7 @@ int smc_clc_send_proposal(struct smc_sock *smc, struct smc_init_info *ini) return SMC_CLC_DECL_CNFERR; } pclc_base->hdr.typev1 = SMC_TYPE_N; + ini->smc_type_v1 = SMC_TYPE_N; } else { pclc_base->iparea_offset = htons(sizeof(*pclc_smcd)); plen += sizeof(*pclc_prfx) + diff --git a/net/strparser/strparser.c b/net/strparser/strparser.c index 43b1f558b33dbd..e659fea2da70f8 100644 --- a/net/strparser/strparser.c +++ b/net/strparser/strparser.c @@ -238,7 +238,7 @@ static int __strp_recv(read_descriptor_t *desc, struct sk_buff *orig_skb, strp_parser_err(strp, -EMSGSIZE, desc); break; } else if (len <= (ssize_t)head->len - - skb->len - stm->strp.offset) { + (ssize_t)skb->len - stm->strp.offset) { /* Length must be into new skb (and also * greater than zero) */ diff --git a/net/sunrpc/Kconfig b/net/sunrpc/Kconfig index 984e0cf9bf8aa9..a570e7adf270fb 100644 --- a/net/sunrpc/Kconfig +++ b/net/sunrpc/Kconfig @@ -18,10 +18,9 @@ config SUNRPC_SWAP config RPCSEC_GSS_KRB5 tristate "Secure RPC: Kerberos V mechanism" - depends on SUNRPC + depends on SUNRPC && CRYPTO default y select SUNRPC_GSS - select CRYPTO select CRYPTO_SKCIPHER select CRYPTO_HASH help diff --git a/net/tipc/net.c b/net/tipc/net.c index 0e95572e56b41e..7e65d0b0c4a8d1 100644 --- a/net/tipc/net.c +++ b/net/tipc/net.c @@ -145,7 +145,9 @@ void tipc_net_finalize_work(struct work_struct *work) { struct tipc_net *tn = container_of(work, struct tipc_net, work); + rtnl_lock(); tipc_net_finalize(tipc_link_net(tn->bcl), tn->trial_addr); + rtnl_unlock(); } void tipc_net_stop(struct net *net) diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 768098dec23100..833c3616d2a2b4 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -2954,6 +2954,7 @@ static int unix_stream_read_generic(struct unix_stream_read_state *state, u = unix_sk(sk); +redo: /* Lock the socket to prevent queue disordering * while sleeps in memcpy_tomsg */ @@ -2965,7 +2966,6 @@ static int unix_stream_read_generic(struct unix_stream_read_state *state, struct sk_buff *skb, *last; int chunk; -redo: unix_state_lock(sk); if (sock_flag(sk, SOCK_DEAD)) { err = -ECONNRESET; @@ -3015,7 +3015,6 @@ static int unix_stream_read_generic(struct unix_stream_read_state *state, goto out; } - mutex_lock(&u->iolock); goto redo; unlock: unix_state_unlock(sk); diff --git a/net/unix/garbage.c b/net/unix/garbage.c index 684ab03137b6c6..65396a4e1b07e6 100644 --- a/net/unix/garbage.c +++ b/net/unix/garbage.c @@ -145,6 +145,7 @@ enum unix_vertex_index { }; static unsigned long unix_vertex_unvisited_index = UNIX_VERTEX_INDEX_MARK1; +static unsigned long unix_vertex_max_scc_index = UNIX_VERTEX_INDEX_START; static void unix_add_edge(struct scm_fp_list *fpl, struct unix_edge *edge) { @@ -153,6 +154,7 @@ static void unix_add_edge(struct scm_fp_list *fpl, struct unix_edge *edge) if (!vertex) { vertex = list_first_entry(&fpl->vertices, typeof(*vertex), entry); vertex->index = unix_vertex_unvisited_index; + vertex->scc_index = ++unix_vertex_max_scc_index; vertex->out_degree = 0; INIT_LIST_HEAD(&vertex->edges); INIT_LIST_HEAD(&vertex->scc_entry); @@ -489,10 +491,15 @@ static void __unix_walk_scc(struct unix_vertex *vertex, unsigned long *last_inde scc_dead = unix_vertex_dead(v); } - if (scc_dead) + if (scc_dead) { unix_collect_skb(&scc, hitlist); - else if (!unix_graph_maybe_cyclic) - unix_graph_maybe_cyclic = unix_scc_cyclic(&scc); + } else { + if (unix_vertex_max_scc_index < vertex->scc_index) + unix_vertex_max_scc_index = vertex->scc_index; + + if (!unix_graph_maybe_cyclic) + unix_graph_maybe_cyclic = unix_scc_cyclic(&scc); + } list_del(&scc); } @@ -507,6 +514,7 @@ static void unix_walk_scc(struct sk_buff_head *hitlist) unsigned long last_index = UNIX_VERTEX_INDEX_START; unix_graph_maybe_cyclic = false; + unix_vertex_max_scc_index = UNIX_VERTEX_INDEX_START; /* Visit every vertex exactly once. * __unix_walk_scc() moves visited vertices to unix_visited_vertices. diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c index 76763247a377a6..a9ca9c3b87b31a 100644 --- a/net/vmw_vsock/af_vsock.c +++ b/net/vmw_vsock/af_vsock.c @@ -1661,18 +1661,40 @@ static int vsock_connect(struct socket *sock, struct sockaddr *addr, timeout = schedule_timeout(timeout); lock_sock(sk); - if (signal_pending(current)) { - err = sock_intr_errno(timeout); - sk->sk_state = sk->sk_state == TCP_ESTABLISHED ? TCP_CLOSING : TCP_CLOSE; - sock->state = SS_UNCONNECTED; - vsock_transport_cancel_pkt(vsk); - vsock_remove_connected(vsk); - goto out_wait; - } else if ((sk->sk_state != TCP_ESTABLISHED) && (timeout == 0)) { - err = -ETIMEDOUT; + /* Connection established. Whatever happens to socket once we + * release it, that's not connect()'s concern. No need to go + * into signal and timeout handling. Call it a day. + * + * Note that allowing to "reset" an already established socket + * here is racy and insecure. + */ + if (sk->sk_state == TCP_ESTABLISHED) + break; + + /* If connection was _not_ established and a signal/timeout came + * to be, we want the socket's state reset. User space may want + * to retry. + * + * sk_state != TCP_ESTABLISHED implies that socket is not on + * vsock_connected_table. We keep the binding and the transport + * assigned. + */ + if (signal_pending(current) || timeout == 0) { + err = timeout == 0 ? -ETIMEDOUT : sock_intr_errno(timeout); + + /* Listener might have already responded with + * VIRTIO_VSOCK_OP_RESPONSE. Its handling expects our + * sk_state == TCP_SYN_SENT, which hereby we break. + * In such case VIRTIO_VSOCK_OP_RST will follow. + */ sk->sk_state = TCP_CLOSE; sock->state = SS_UNCONNECTED; + + /* Try to cancel VIRTIO_VSOCK_OP_REQUEST skb sent out by + * transport->connect(). + */ vsock_transport_cancel_pkt(vsk); + goto out_wait; } diff --git a/net/wireless/core.c b/net/wireless/core.c index 797f9f2004a694..54a34d8d356e04 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c @@ -1787,6 +1787,62 @@ bool wiphy_delayed_work_pending(struct wiphy *wiphy, } EXPORT_SYMBOL_GPL(wiphy_delayed_work_pending); +enum hrtimer_restart wiphy_hrtimer_work_timer(struct hrtimer *t) +{ + struct wiphy_hrtimer_work *hrwork = + container_of(t, struct wiphy_hrtimer_work, timer); + + wiphy_work_queue(hrwork->wiphy, &hrwork->work); + + return HRTIMER_NORESTART; +} +EXPORT_SYMBOL_GPL(wiphy_hrtimer_work_timer); + +void wiphy_hrtimer_work_queue(struct wiphy *wiphy, + struct wiphy_hrtimer_work *hrwork, + ktime_t delay) +{ + trace_wiphy_hrtimer_work_queue(wiphy, &hrwork->work, delay); + + if (!delay) { + hrtimer_cancel(&hrwork->timer); + wiphy_work_queue(wiphy, &hrwork->work); + return; + } + + hrwork->wiphy = wiphy; + hrtimer_start_range_ns(&hrwork->timer, delay, + 1000 * NSEC_PER_USEC, HRTIMER_MODE_REL); +} +EXPORT_SYMBOL_GPL(wiphy_hrtimer_work_queue); + +void wiphy_hrtimer_work_cancel(struct wiphy *wiphy, + struct wiphy_hrtimer_work *hrwork) +{ + lockdep_assert_held(&wiphy->mtx); + + hrtimer_cancel(&hrwork->timer); + wiphy_work_cancel(wiphy, &hrwork->work); +} +EXPORT_SYMBOL_GPL(wiphy_hrtimer_work_cancel); + +void wiphy_hrtimer_work_flush(struct wiphy *wiphy, + struct wiphy_hrtimer_work *hrwork) +{ + lockdep_assert_held(&wiphy->mtx); + + hrtimer_cancel(&hrwork->timer); + wiphy_work_flush(wiphy, &hrwork->work); +} +EXPORT_SYMBOL_GPL(wiphy_hrtimer_work_flush); + +bool wiphy_hrtimer_work_pending(struct wiphy *wiphy, + struct wiphy_hrtimer_work *hrwork) +{ + return hrtimer_is_queued(&hrwork->timer); +} +EXPORT_SYMBOL_GPL(wiphy_hrtimer_work_pending); + static int __init cfg80211_init(void) { int err; diff --git a/net/wireless/trace.h b/net/wireless/trace.h index 8a4c34112eb5ff..2b71f1d867a08b 100644 --- a/net/wireless/trace.h +++ b/net/wireless/trace.h @@ -304,6 +304,27 @@ TRACE_EVENT(wiphy_delayed_work_queue, __entry->delay) ); +TRACE_EVENT(wiphy_hrtimer_work_queue, + TP_PROTO(struct wiphy *wiphy, struct wiphy_work *work, + ktime_t delay), + TP_ARGS(wiphy, work, delay), + TP_STRUCT__entry( + WIPHY_ENTRY + __field(void *, instance) + __field(void *, func) + __field(ktime_t, delay) + ), + TP_fast_assign( + WIPHY_ASSIGN; + __entry->instance = work; + __entry->func = work->func; + __entry->delay = delay; + ), + TP_printk(WIPHY_PR_FMT " instance=%p func=%pS delay=%llu", + WIPHY_PR_ARG, __entry->instance, __entry->func, + __entry->delay) +); + TRACE_EVENT(wiphy_work_worker_start, TP_PROTO(struct wiphy *wiphy), TP_ARGS(wiphy), diff --git a/net/xfrm/xfrm_device.c b/net/xfrm/xfrm_device.c index 44b9de6e4e7788..52ae0e034d29e2 100644 --- a/net/xfrm/xfrm_device.c +++ b/net/xfrm/xfrm_device.c @@ -438,7 +438,7 @@ bool xfrm_dev_offload_ok(struct sk_buff *skb, struct xfrm_state *x) check_tunnel_size = x->xso.type == XFRM_DEV_OFFLOAD_PACKET && x->props.mode == XFRM_MODE_TUNNEL; - switch (x->inner_mode.family) { + switch (skb_dst(skb)->ops->family) { case AF_INET: /* Check for IPv4 options */ if (ip_hdr(skb)->ihl != 5) diff --git a/net/xfrm/xfrm_output.c b/net/xfrm/xfrm_output.c index 9077730ff7d0ea..54222fcbd7fd81 100644 --- a/net/xfrm/xfrm_output.c +++ b/net/xfrm/xfrm_output.c @@ -698,7 +698,7 @@ static void xfrm_get_inner_ipproto(struct sk_buff *skb, struct xfrm_state *x) return; if (x->outer_mode.encap == XFRM_MODE_TUNNEL) { - switch (x->outer_mode.family) { + switch (skb_dst(skb)->ops->family) { case AF_INET: xo->inner_ipproto = ip_hdr(skb)->protocol; break; @@ -772,8 +772,12 @@ int xfrm_output(struct sock *sk, struct sk_buff *skb) /* Exclusive direct xmit for tunnel mode, as * some filtering or matching rules may apply * in transport mode. + * Locally generated packets also require + * the normal XFRM path for L2 header setup, + * as the hardware needs the L2 header to match + * for encryption, so skip direct output as well. */ - if (x->props.mode == XFRM_MODE_TUNNEL) + if (x->props.mode == XFRM_MODE_TUNNEL && !skb->sk) return xfrm_dev_direct_output(sk, x, skb); return xfrm_output_resume(sk, skb, 0); diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index d213ca3653a8f2..9e14e453b55cc9 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c @@ -592,6 +592,7 @@ void xfrm_state_free(struct xfrm_state *x) } EXPORT_SYMBOL(xfrm_state_free); +static void xfrm_state_delete_tunnel(struct xfrm_state *x); static void xfrm_state_gc_destroy(struct xfrm_state *x) { if (x->mode_cbs && x->mode_cbs->destroy_state) @@ -607,6 +608,7 @@ static void xfrm_state_gc_destroy(struct xfrm_state *x) kfree(x->replay_esn); kfree(x->preplay_esn); xfrm_unset_type_offload(x); + xfrm_state_delete_tunnel(x); if (x->type) { x->type->destructor(x); xfrm_put_type(x->type); @@ -806,7 +808,6 @@ void __xfrm_state_destroy(struct xfrm_state *x) } EXPORT_SYMBOL(__xfrm_state_destroy); -static void xfrm_state_delete_tunnel(struct xfrm_state *x); int __xfrm_state_delete(struct xfrm_state *x) { struct net *net = xs_net(x); @@ -2073,6 +2074,7 @@ static struct xfrm_state *xfrm_state_clone_and_setup(struct xfrm_state *orig, return x; error: + x->km.state = XFRM_STATE_DEAD; xfrm_state_put(x); out: return NULL; @@ -2157,11 +2159,15 @@ struct xfrm_state *xfrm_state_migrate(struct xfrm_state *x, xfrm_state_insert(xc); } else { if (xfrm_state_add(xc) < 0) - goto error; + goto error_add; } return xc; +error_add: + if (xuo) + xfrm_dev_state_delete(xc); error: + xc->km.state = XFRM_STATE_DEAD; xfrm_state_put(xc); return NULL; } @@ -2191,14 +2197,18 @@ int xfrm_state_update(struct xfrm_state *x) } if (x1->km.state == XFRM_STATE_ACQ) { - if (x->dir && x1->dir != x->dir) + if (x->dir && x1->dir != x->dir) { + to_put = x1; goto out; + } __xfrm_state_insert(x); x = NULL; } else { - if (x1->dir != x->dir) + if (x1->dir != x->dir) { + to_put = x1; goto out; + } } err = 0; @@ -3298,6 +3308,7 @@ int __net_init xfrm_state_init(struct net *net) void xfrm_state_fini(struct net *net) { unsigned int sz; + int i; flush_work(&net->xfrm.state_hash_work); xfrm_state_flush(net, 0, false); @@ -3305,14 +3316,17 @@ void xfrm_state_fini(struct net *net) WARN_ON(!list_empty(&net->xfrm.state_all)); + for (i = 0; i <= net->xfrm.state_hmask; i++) { + WARN_ON(!hlist_empty(net->xfrm.state_byseq + i)); + WARN_ON(!hlist_empty(net->xfrm.state_byspi + i)); + WARN_ON(!hlist_empty(net->xfrm.state_bysrc + i)); + WARN_ON(!hlist_empty(net->xfrm.state_bydst + i)); + } + sz = (net->xfrm.state_hmask + 1) * sizeof(struct hlist_head); - WARN_ON(!hlist_empty(net->xfrm.state_byseq)); xfrm_hash_free(net->xfrm.state_byseq, sz); - WARN_ON(!hlist_empty(net->xfrm.state_byspi)); xfrm_hash_free(net->xfrm.state_byspi, sz); - WARN_ON(!hlist_empty(net->xfrm.state_bysrc)); xfrm_hash_free(net->xfrm.state_bysrc, sz); - WARN_ON(!hlist_empty(net->xfrm.state_bydst)); xfrm_hash_free(net->xfrm.state_bydst, sz); free_percpu(net->xfrm.state_cache_input); } diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index 010c9e6638c0cd..403b5ecac2c544 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c @@ -947,8 +947,11 @@ static struct xfrm_state *xfrm_state_construct(struct net *net, if (attrs[XFRMA_SA_PCPU]) { x->pcpu_num = nla_get_u32(attrs[XFRMA_SA_PCPU]); - if (x->pcpu_num >= num_possible_cpus()) + if (x->pcpu_num >= num_possible_cpus()) { + err = -ERANGE; + NL_SET_ERR_MSG(extack, "pCPU number too big"); goto error; + } } err = __xfrm_init_state(x, extack); @@ -3035,6 +3038,9 @@ static int xfrm_add_acquire(struct sk_buff *skb, struct nlmsghdr *nlh, } xfrm_state_free(x); + xfrm_dev_policy_delete(xp); + xfrm_dev_policy_free(xp); + security_xfrm_policy_free(xp->security); kfree(xp); return 0; diff --git a/rust/Makefile b/rust/Makefile index 23c7ae905bd2f0..7842ad0a4ea726 100644 --- a/rust/Makefile +++ b/rust/Makefile @@ -69,6 +69,9 @@ core-edition := $(if $(call rustc-min-version,108700),2024,2021) # the time being (https://github.com/rust-lang/rust/issues/144521). rustdoc_modifiers_workaround := $(if $(call rustc-min-version,108800),-Cunsafe-allow-abi-mismatch=fixed-x18) +# Similarly, for doctests (https://github.com/rust-lang/rust/issues/146465). +doctests_modifiers_workaround := $(rustdoc_modifiers_workaround)$(if $(call rustc-min-version,109100),$(comma)sanitizer) + # `rustc` recognizes `--remap-path-prefix` since 1.26.0, but `rustdoc` only # since Rust 1.81.0. Moreover, `rustdoc` ICEs on out-of-tree builds since Rust # 1.82.0 (https://github.com/rust-lang/rust/issues/138520). Thus workaround both @@ -127,9 +130,14 @@ rustdoc-core: private rustc_target_flags = --edition=$(core-edition) $(core-cfgs rustdoc-core: $(RUST_LIB_SRC)/core/src/lib.rs rustdoc-clean FORCE +$(call if_changed,rustdoc) +# Even if `rustdoc` targets are not kernel objects, they should still be +# treated as such so that we pass the same flags. Otherwise, for instance, +# `rustdoc` will complain about missing sanitizer flags causing an ABI mismatch. +rustdoc-compiler_builtins: private is-kernel-object := y rustdoc-compiler_builtins: $(src)/compiler_builtins.rs rustdoc-core FORCE +$(call if_changed,rustdoc) +rustdoc-ffi: private is-kernel-object := y rustdoc-ffi: $(src)/ffi.rs rustdoc-core FORCE +$(call if_changed,rustdoc) @@ -147,6 +155,7 @@ rustdoc-pin_init: $(src)/pin-init/src/lib.rs rustdoc-pin_init_internal \ rustdoc-macros FORCE +$(call if_changed,rustdoc) +rustdoc-kernel: private is-kernel-object := y rustdoc-kernel: private rustc_target_flags = --extern ffi --extern pin_init \ --extern build_error --extern macros \ --extern bindings --extern uapi @@ -230,7 +239,7 @@ quiet_cmd_rustdoc_test_kernel = RUSTDOC TK $< --extern bindings --extern uapi \ --no-run --crate-name kernel -Zunstable-options \ --sysroot=/dev/null \ - $(rustdoc_modifiers_workaround) \ + $(doctests_modifiers_workaround) \ --test-builder $(objtree)/scripts/rustdoc_test_builder \ $< $(rustdoc_test_kernel_quiet); \ $(objtree)/scripts/rustdoc_test_gen @@ -289,7 +298,7 @@ bindgen_skip_c_flags := -mno-fp-ret-in-387 -mpreferred-stack-boundary=% \ -fno-inline-functions-called-once -fsanitize=bounds-strict \ -fstrict-flex-arrays=% -fmin-function-alignment=% \ -fzero-init-padding-bits=% -mno-fdpic \ - --param=% --param asan-% + --param=% --param asan-% -fno-isolate-erroneous-paths-dereference # Derived from `scripts/Makefile.clang`. BINDGEN_TARGET_x86 := x86_64-linux-gnu @@ -522,6 +531,10 @@ $(obj)/pin_init.o: $(src)/pin-init/src/lib.rs $(obj)/compiler_builtins.o \ $(obj)/$(libpin_init_internal_name) $(obj)/$(libmacros_name) FORCE +$(call if_changed_rule,rustc_library) +# Even if normally `build_error` is not a kernel object, it should still be +# treated as such so that we pass the same flags. Otherwise, for instance, +# `rustc` will complain about missing sanitizer flags causing an ABI mismatch. +$(obj)/build_error.o: private is-kernel-object := y $(obj)/build_error.o: private skip_gendwarfksyms = 1 $(obj)/build_error.o: $(src)/build_error.rs $(obj)/compiler_builtins.o FORCE +$(call if_changed_rule,rustc_library) diff --git a/rust/kernel/devres.rs b/rust/kernel/devres.rs index 10a6a17898541d..2392c281459eff 100644 --- a/rust/kernel/devres.rs +++ b/rust/kernel/devres.rs @@ -103,7 +103,7 @@ struct Inner { /// /// # Invariants /// -/// [`Self::inner`] is guaranteed to be initialized and is always accessed read-only. +/// `Self::inner` is guaranteed to be initialized and is always accessed read-only. #[pin_data(PinnedDrop)] pub struct Devres { dev: ARef, diff --git a/rust/kernel/sync/condvar.rs b/rust/kernel/sync/condvar.rs index c6ec64295c9ffb..aa5b9a7a726dd0 100644 --- a/rust/kernel/sync/condvar.rs +++ b/rust/kernel/sync/condvar.rs @@ -36,7 +36,7 @@ pub use new_condvar; /// spuriously. /// /// Instances of [`CondVar`] need a lock class and to be pinned. The recommended way to create such -/// instances is with the [`pin_init`](crate::pin_init!) and [`new_condvar`] macros. +/// instances is with the [`pin_init`](pin_init::pin_init!) and [`new_condvar`] macros. /// /// # Examples /// diff --git a/samples/vfs/test-statx.c b/samples/vfs/test-statx.c index 49c7a46cee0739..424a6fa15723cb 100644 --- a/samples/vfs/test-statx.c +++ b/samples/vfs/test-statx.c @@ -19,6 +19,12 @@ #include #include #include + +// Work around glibc header silliness +#undef AT_RENAME_NOREPLACE +#undef AT_RENAME_EXCHANGE +#undef AT_RENAME_WHITEOUT + #include #include #define statx foo diff --git a/samples/watch_queue/watch_test.c b/samples/watch_queue/watch_test.c index 8c6cb57d5cfc5b..24cf7d7a197258 100644 --- a/samples/watch_queue/watch_test.c +++ b/samples/watch_queue/watch_test.c @@ -16,6 +16,12 @@ #include #include #include + +// Work around glibc header silliness +#undef AT_RENAME_NOREPLACE +#undef AT_RENAME_EXCHANGE +#undef AT_RENAME_WHITEOUT + #include #include #include diff --git a/scripts/Makefile.build b/scripts/Makefile.build index d0ee33a487be95..52c08c4eb0b9af 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -167,7 +167,7 @@ else ifeq ($(KBUILD_CHECKSRC),2) endif ifneq ($(KBUILD_EXTRA_WARN),) - cmd_checkdoc = PYTHONDONTWRITEBYTECODE=1 $(KERNELDOC) -none $(KDOCFLAGS) \ + cmd_checkdoc = PYTHONDONTWRITEBYTECODE=1 $(PYTHON3) $(KERNELDOC) -none $(KDOCFLAGS) \ $(if $(findstring 2, $(KBUILD_EXTRA_WARN)), -Wall) \ $< endif diff --git a/scripts/Makefile.vmlinux b/scripts/Makefile.vmlinux index ced4379550d766..cd788cac9d91da 100644 --- a/scripts/Makefile.vmlinux +++ b/scripts/Makefile.vmlinux @@ -102,11 +102,24 @@ vmlinux: vmlinux.unstripped FORCE # modules.builtin.modinfo # --------------------------------------------------------------------------- +# .modinfo in vmlinux.unstripped is aligned to 8 bytes for compatibility with +# tools that expect vmlinux to have sufficiently aligned sections but the +# additional bytes used for padding .modinfo to satisfy this requirement break +# certain versions of kmod with +# +# depmod: ERROR: kmod_builtin_iter_next: unexpected string without modname prefix +# +# Strip the trailing padding bytes after extracting .modinfo to comply with +# what kmod expects to parse. +quiet_cmd_modules_builtin_modinfo = GEN $@ + cmd_modules_builtin_modinfo = $(cmd_objcopy); \ + sed -i 's/\x00\+$$/\x00/g' $@ + OBJCOPYFLAGS_modules.builtin.modinfo := -j .modinfo -O binary targets += modules.builtin.modinfo modules.builtin.modinfo: vmlinux.unstripped FORCE - $(call if_changed,objcopy) + $(call if_changed,modules_builtin_modinfo) # modules.builtin # --------------------------------------------------------------------------- diff --git a/scripts/decode_stacktrace.sh b/scripts/decode_stacktrace.sh index c73cb802a0a3fc..8d01b741de624c 100755 --- a/scripts/decode_stacktrace.sh +++ b/scripts/decode_stacktrace.sh @@ -277,12 +277,6 @@ handle_line() { fi done - if [[ ${words[$last]} =~ ^[0-9a-f]+\] ]]; then - words[$last-1]="${words[$last-1]} ${words[$last]}" - unset words[$last] spaces[$last] - last=$(( $last - 1 )) - fi - # Extract info after the symbol if present. E.g.: # func_name+0x54/0x80 (P) # ^^^ @@ -295,6 +289,14 @@ handle_line() { last=$(( $last - 1 )) fi + # Join module name with its build id if present, as these were + # split during tokenization (e.g. "[module" and "modbuildid]"). + if [[ ${words[$last]} =~ ^[0-9a-f]+\] ]]; then + words[$last-1]="${words[$last-1]} ${words[$last]}" + unset words[$last] spaces[$last] + last=$(( $last - 1 )) + fi + if [[ ${words[$last]} =~ \[([^]]+)\] ]]; then module=${words[$last]} # some traces format is "(%pS)", which like "(foo+0x0/0x1 [bar])" diff --git a/scripts/gendwarfksyms/gendwarfksyms.c b/scripts/gendwarfksyms/gendwarfksyms.c index 08ae61eb327eac..f5203d1640ee69 100644 --- a/scripts/gendwarfksyms/gendwarfksyms.c +++ b/scripts/gendwarfksyms/gendwarfksyms.c @@ -138,7 +138,8 @@ int main(int argc, char **argv) error("no input files?"); } - symbol_read_exports(stdin); + if (!symbol_read_exports(stdin)) + return 0; if (symtypes_file) { symfile = fopen(symtypes_file, "w"); diff --git a/scripts/gendwarfksyms/gendwarfksyms.h b/scripts/gendwarfksyms/gendwarfksyms.h index d9c06d2cb1dfc0..32cec8f7695a80 100644 --- a/scripts/gendwarfksyms/gendwarfksyms.h +++ b/scripts/gendwarfksyms/gendwarfksyms.h @@ -123,7 +123,7 @@ struct symbol { typedef void (*symbol_callback_t)(struct symbol *, void *arg); bool is_symbol_ptr(const char *name); -void symbol_read_exports(FILE *file); +int symbol_read_exports(FILE *file); void symbol_read_symtab(int fd); struct symbol *symbol_get(const char *name); void symbol_set_ptr(struct symbol *sym, Dwarf_Die *ptr); diff --git a/scripts/gendwarfksyms/symbols.c b/scripts/gendwarfksyms/symbols.c index 35ed594f0749b7..ecddcb5ffcdfb9 100644 --- a/scripts/gendwarfksyms/symbols.c +++ b/scripts/gendwarfksyms/symbols.c @@ -128,7 +128,7 @@ static bool is_exported(const char *name) return for_each(name, NULL, NULL) > 0; } -void symbol_read_exports(FILE *file) +int symbol_read_exports(FILE *file) { struct symbol *sym; char *line = NULL; @@ -159,6 +159,8 @@ void symbol_read_exports(FILE *file) free(line); debug("%d exported symbols", nsym); + + return nsym; } static void get_symbol(struct symbol *sym, void *arg) diff --git a/security/landlock/fs.c b/security/landlock/fs.c index 0bade2c5aa1d00..d9c12b993fa7dd 100644 --- a/security/landlock/fs.c +++ b/security/landlock/fs.c @@ -1335,11 +1335,10 @@ static void hook_sb_delete(struct super_block *const sb) * At this point, we own the ihold() reference that was * originally set up by get_inode_object() and the * __iget() reference that we just set in this loop - * walk. Therefore the following call to iput() will - * not sleep nor drop the inode because there is now at - * least two references to it. + * walk. Therefore there are at least two references + * on the inode. */ - iput(inode); + iput_not_last(inode); } else { spin_unlock(&object->lock); rcu_read_unlock(); diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index dfc22da42f307d..e713291db873ca 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -210,12 +210,12 @@ static int selinux_lsm_notifier_avc_callback(u32 event) */ static void cred_init_security(void) { - struct task_security_struct *tsec; + struct cred_security_struct *crsec; /* NOTE: the lsm framework zeros out the buffer on allocation */ - tsec = selinux_cred(unrcu_pointer(current->real_cred)); - tsec->osid = tsec->sid = tsec->avdcache.sid = SECINITSID_KERNEL; + crsec = selinux_cred(unrcu_pointer(current->real_cred)); + crsec->osid = crsec->sid = SECINITSID_KERNEL; } /* @@ -223,10 +223,10 @@ static void cred_init_security(void) */ static inline u32 cred_sid(const struct cred *cred) { - const struct task_security_struct *tsec; + const struct cred_security_struct *crsec; - tsec = selinux_cred(cred); - return tsec->sid; + crsec = selinux_cred(cred); + return crsec->sid; } static void __ad_net_init(struct common_audit_data *ad, @@ -437,15 +437,15 @@ static int may_context_mount_sb_relabel(u32 sid, struct superblock_security_struct *sbsec, const struct cred *cred) { - const struct task_security_struct *tsec = selinux_cred(cred); + const struct cred_security_struct *crsec = selinux_cred(cred); int rc; - rc = avc_has_perm(tsec->sid, sbsec->sid, SECCLASS_FILESYSTEM, + rc = avc_has_perm(crsec->sid, sbsec->sid, SECCLASS_FILESYSTEM, FILESYSTEM__RELABELFROM, NULL); if (rc) return rc; - rc = avc_has_perm(tsec->sid, sid, SECCLASS_FILESYSTEM, + rc = avc_has_perm(crsec->sid, sid, SECCLASS_FILESYSTEM, FILESYSTEM__RELABELTO, NULL); return rc; } @@ -454,9 +454,9 @@ static int may_context_mount_inode_relabel(u32 sid, struct superblock_security_struct *sbsec, const struct cred *cred) { - const struct task_security_struct *tsec = selinux_cred(cred); + const struct cred_security_struct *crsec = selinux_cred(cred); int rc; - rc = avc_has_perm(tsec->sid, sbsec->sid, SECCLASS_FILESYSTEM, + rc = avc_has_perm(crsec->sid, sbsec->sid, SECCLASS_FILESYSTEM, FILESYSTEM__RELABELFROM, NULL); if (rc) return rc; @@ -1788,7 +1788,7 @@ static int file_has_perm(const struct cred *cred, * Determine the label for an inode that might be unioned. */ static int -selinux_determine_inode_label(const struct task_security_struct *tsec, +selinux_determine_inode_label(const struct cred_security_struct *crsec, struct inode *dir, const struct qstr *name, u16 tclass, u32 *_new_isid) @@ -1800,11 +1800,11 @@ selinux_determine_inode_label(const struct task_security_struct *tsec, (sbsec->behavior == SECURITY_FS_USE_MNTPOINT)) { *_new_isid = sbsec->mntpoint_sid; } else if ((sbsec->flags & SBLABEL_MNT) && - tsec->create_sid) { - *_new_isid = tsec->create_sid; + crsec->create_sid) { + *_new_isid = crsec->create_sid; } else { const struct inode_security_struct *dsec = inode_security(dir); - return security_transition_sid(tsec->sid, + return security_transition_sid(crsec->sid, dsec->sid, tclass, name, _new_isid); } @@ -1817,7 +1817,7 @@ static int may_create(struct inode *dir, struct dentry *dentry, u16 tclass) { - const struct task_security_struct *tsec = selinux_cred(current_cred()); + const struct cred_security_struct *crsec = selinux_cred(current_cred()); struct inode_security_struct *dsec; struct superblock_security_struct *sbsec; u32 sid, newsid; @@ -1827,7 +1827,7 @@ static int may_create(struct inode *dir, dsec = inode_security(dir); sbsec = selinux_superblock(dir->i_sb); - sid = tsec->sid; + sid = crsec->sid; ad.type = LSM_AUDIT_DATA_DENTRY; ad.u.dentry = dentry; @@ -1838,7 +1838,7 @@ static int may_create(struct inode *dir, if (rc) return rc; - rc = selinux_determine_inode_label(tsec, dir, &dentry->d_name, tclass, + rc = selinux_determine_inode_label(crsec, dir, &dentry->d_name, tclass, &newsid); if (rc) return rc; @@ -2251,8 +2251,8 @@ static u32 ptrace_parent_sid(void) } static int check_nnp_nosuid(const struct linux_binprm *bprm, - const struct task_security_struct *old_tsec, - const struct task_security_struct *new_tsec) + const struct cred_security_struct *old_crsec, + const struct cred_security_struct *new_crsec) { int nnp = (bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS); int nosuid = !mnt_may_suid(bprm->file->f_path.mnt); @@ -2262,7 +2262,7 @@ static int check_nnp_nosuid(const struct linux_binprm *bprm, if (!nnp && !nosuid) return 0; /* neither NNP nor nosuid */ - if (new_tsec->sid == old_tsec->sid) + if (new_crsec->sid == old_crsec->sid) return 0; /* No change in credentials */ /* @@ -2277,7 +2277,7 @@ static int check_nnp_nosuid(const struct linux_binprm *bprm, av |= PROCESS2__NNP_TRANSITION; if (nosuid) av |= PROCESS2__NOSUID_TRANSITION; - rc = avc_has_perm(old_tsec->sid, new_tsec->sid, + rc = avc_has_perm(old_crsec->sid, new_crsec->sid, SECCLASS_PROCESS2, av, NULL); if (!rc) return 0; @@ -2288,8 +2288,8 @@ static int check_nnp_nosuid(const struct linux_binprm *bprm, * i.e. SIDs that are guaranteed to only be allowed a subset * of the permissions of the current SID. */ - rc = security_bounded_transition(old_tsec->sid, - new_tsec->sid); + rc = security_bounded_transition(old_crsec->sid, + new_crsec->sid); if (!rc) return 0; @@ -2305,8 +2305,8 @@ static int check_nnp_nosuid(const struct linux_binprm *bprm, static int selinux_bprm_creds_for_exec(struct linux_binprm *bprm) { - const struct task_security_struct *old_tsec; - struct task_security_struct *new_tsec; + const struct cred_security_struct *old_crsec; + struct cred_security_struct *new_crsec; struct inode_security_struct *isec; struct common_audit_data ad; struct inode *inode = file_inode(bprm->file); @@ -2315,18 +2315,18 @@ static int selinux_bprm_creds_for_exec(struct linux_binprm *bprm) /* SELinux context only depends on initial program or script and not * the script interpreter */ - old_tsec = selinux_cred(current_cred()); - new_tsec = selinux_cred(bprm->cred); + old_crsec = selinux_cred(current_cred()); + new_crsec = selinux_cred(bprm->cred); isec = inode_security(inode); /* Default to the current task SID. */ - new_tsec->sid = old_tsec->sid; - new_tsec->osid = old_tsec->sid; + new_crsec->sid = old_crsec->sid; + new_crsec->osid = old_crsec->sid; /* Reset fs, key, and sock SIDs on execve. */ - new_tsec->create_sid = 0; - new_tsec->keycreate_sid = 0; - new_tsec->sockcreate_sid = 0; + new_crsec->create_sid = 0; + new_crsec->keycreate_sid = 0; + new_crsec->sockcreate_sid = 0; /* * Before policy is loaded, label any task outside kernel space @@ -2335,26 +2335,26 @@ static int selinux_bprm_creds_for_exec(struct linux_binprm *bprm) * (if the policy chooses to set SECINITSID_INIT != SECINITSID_KERNEL). */ if (!selinux_initialized()) { - new_tsec->sid = SECINITSID_INIT; + new_crsec->sid = SECINITSID_INIT; /* also clear the exec_sid just in case */ - new_tsec->exec_sid = 0; + new_crsec->exec_sid = 0; return 0; } - if (old_tsec->exec_sid) { - new_tsec->sid = old_tsec->exec_sid; + if (old_crsec->exec_sid) { + new_crsec->sid = old_crsec->exec_sid; /* Reset exec SID on execve. */ - new_tsec->exec_sid = 0; + new_crsec->exec_sid = 0; /* Fail on NNP or nosuid if not an allowed transition. */ - rc = check_nnp_nosuid(bprm, old_tsec, new_tsec); + rc = check_nnp_nosuid(bprm, old_crsec, new_crsec); if (rc) return rc; } else { /* Check for a default transition on this program. */ - rc = security_transition_sid(old_tsec->sid, + rc = security_transition_sid(old_crsec->sid, isec->sid, SECCLASS_PROCESS, NULL, - &new_tsec->sid); + &new_crsec->sid); if (rc) return rc; @@ -2362,34 +2362,34 @@ static int selinux_bprm_creds_for_exec(struct linux_binprm *bprm) * Fallback to old SID on NNP or nosuid if not an allowed * transition. */ - rc = check_nnp_nosuid(bprm, old_tsec, new_tsec); + rc = check_nnp_nosuid(bprm, old_crsec, new_crsec); if (rc) - new_tsec->sid = old_tsec->sid; + new_crsec->sid = old_crsec->sid; } ad.type = LSM_AUDIT_DATA_FILE; ad.u.file = bprm->file; - if (new_tsec->sid == old_tsec->sid) { - rc = avc_has_perm(old_tsec->sid, isec->sid, + if (new_crsec->sid == old_crsec->sid) { + rc = avc_has_perm(old_crsec->sid, isec->sid, SECCLASS_FILE, FILE__EXECUTE_NO_TRANS, &ad); if (rc) return rc; } else { /* Check permissions for the transition. */ - rc = avc_has_perm(old_tsec->sid, new_tsec->sid, + rc = avc_has_perm(old_crsec->sid, new_crsec->sid, SECCLASS_PROCESS, PROCESS__TRANSITION, &ad); if (rc) return rc; - rc = avc_has_perm(new_tsec->sid, isec->sid, + rc = avc_has_perm(new_crsec->sid, isec->sid, SECCLASS_FILE, FILE__ENTRYPOINT, &ad); if (rc) return rc; /* Check for shared state */ if (bprm->unsafe & LSM_UNSAFE_SHARE) { - rc = avc_has_perm(old_tsec->sid, new_tsec->sid, + rc = avc_has_perm(old_crsec->sid, new_crsec->sid, SECCLASS_PROCESS, PROCESS__SHARE, NULL); if (rc) @@ -2401,7 +2401,7 @@ static int selinux_bprm_creds_for_exec(struct linux_binprm *bprm) if (bprm->unsafe & LSM_UNSAFE_PTRACE) { u32 ptsid = ptrace_parent_sid(); if (ptsid != 0) { - rc = avc_has_perm(ptsid, new_tsec->sid, + rc = avc_has_perm(ptsid, new_crsec->sid, SECCLASS_PROCESS, PROCESS__PTRACE, NULL); if (rc) @@ -2415,7 +2415,7 @@ static int selinux_bprm_creds_for_exec(struct linux_binprm *bprm) /* Enable secure mode for SIDs transitions unless the noatsecure permission is granted between the two SIDs, i.e. ahp returns 0. */ - rc = avc_has_perm(old_tsec->sid, new_tsec->sid, + rc = avc_has_perm(old_crsec->sid, new_crsec->sid, SECCLASS_PROCESS, PROCESS__NOATSECURE, NULL); bprm->secureexec |= !!rc; @@ -2483,12 +2483,12 @@ static inline void flush_unauthorized_files(const struct cred *cred, */ static void selinux_bprm_committing_creds(const struct linux_binprm *bprm) { - struct task_security_struct *new_tsec; + struct cred_security_struct *new_crsec; struct rlimit *rlim, *initrlim; int rc, i; - new_tsec = selinux_cred(bprm->cred); - if (new_tsec->sid == new_tsec->osid) + new_crsec = selinux_cred(bprm->cred); + if (new_crsec->sid == new_crsec->osid) return; /* Close files for which the new task SID is not authorized. */ @@ -2507,7 +2507,7 @@ static void selinux_bprm_committing_creds(const struct linux_binprm *bprm) * higher than the default soft limit for cases where the default is * lower than the hard limit, e.g. RLIMIT_CORE or RLIMIT_STACK. */ - rc = avc_has_perm(new_tsec->osid, new_tsec->sid, SECCLASS_PROCESS, + rc = avc_has_perm(new_crsec->osid, new_crsec->sid, SECCLASS_PROCESS, PROCESS__RLIMITINH, NULL); if (rc) { /* protect against do_prlimit() */ @@ -2529,12 +2529,12 @@ static void selinux_bprm_committing_creds(const struct linux_binprm *bprm) */ static void selinux_bprm_committed_creds(const struct linux_binprm *bprm) { - const struct task_security_struct *tsec = selinux_cred(current_cred()); + const struct cred_security_struct *crsec = selinux_cred(current_cred()); u32 osid, sid; int rc; - osid = tsec->osid; - sid = tsec->sid; + osid = crsec->osid; + sid = crsec->sid; if (sid == osid) return; @@ -2911,7 +2911,7 @@ static int selinux_dentry_create_files_as(struct dentry *dentry, int mode, { u32 newsid; int rc; - struct task_security_struct *tsec; + struct cred_security_struct *crsec; rc = selinux_determine_inode_label(selinux_cred(old), d_inode(dentry->d_parent), name, @@ -2920,8 +2920,8 @@ static int selinux_dentry_create_files_as(struct dentry *dentry, int mode, if (rc) return rc; - tsec = selinux_cred(new); - tsec->create_sid = newsid; + crsec = selinux_cred(new); + crsec->create_sid = newsid; return 0; } @@ -2929,7 +2929,7 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir, const struct qstr *qstr, struct xattr *xattrs, int *xattr_count) { - const struct task_security_struct *tsec = selinux_cred(current_cred()); + const struct cred_security_struct *crsec = selinux_cred(current_cred()); struct superblock_security_struct *sbsec; struct xattr *xattr = lsm_get_xattr_slot(xattrs, xattr_count); u32 newsid, clen; @@ -2939,9 +2939,9 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir, sbsec = selinux_superblock(dir->i_sb); - newsid = tsec->create_sid; + newsid = crsec->create_sid; newsclass = inode_mode_to_security_class(inode->i_mode); - rc = selinux_determine_inode_label(tsec, dir, qstr, newsclass, &newsid); + rc = selinux_determine_inode_label(crsec, dir, qstr, newsclass, &newsid); if (rc) return rc; @@ -3113,7 +3113,7 @@ static noinline int audit_inode_permission(struct inode *inode, static inline void task_avdcache_reset(struct task_security_struct *tsec) { memset(&tsec->avdcache.dir, 0, sizeof(tsec->avdcache.dir)); - tsec->avdcache.sid = tsec->sid; + tsec->avdcache.sid = current_sid(); tsec->avdcache.seqno = avc_policy_seqno(); tsec->avdcache.dir_spot = TSEC_AVDC_DIR_SIZE - 1; } @@ -3137,7 +3137,7 @@ static inline int task_avdcache_search(struct task_security_struct *tsec, if (isec->sclass != SECCLASS_DIR) return -ENOENT; - if (unlikely(tsec->sid != tsec->avdcache.sid || + if (unlikely(current_sid() != tsec->avdcache.sid || tsec->avdcache.seqno != avc_policy_seqno())) { task_avdcache_reset(tsec); return -ENOENT; @@ -3201,6 +3201,7 @@ static int selinux_inode_permission(struct inode *inode, int requested) { int mask; u32 perms; + u32 sid = current_sid(); struct task_security_struct *tsec; struct inode_security_struct *isec; struct avdc_entry *avdc; @@ -3213,8 +3214,8 @@ static int selinux_inode_permission(struct inode *inode, int requested) if (!mask) return 0; - tsec = selinux_cred(current_cred()); - if (task_avdcache_permnoaudit(tsec)) + tsec = selinux_task(current); + if (task_avdcache_permnoaudit(tsec, sid)) return 0; isec = inode_security_rcu(inode, requested & MAY_NOT_BLOCK); @@ -3234,7 +3235,7 @@ static int selinux_inode_permission(struct inode *inode, int requested) struct av_decision avd; /* Cache miss. */ - rc = avc_has_perm_noaudit(tsec->sid, isec->sid, isec->sclass, + rc = avc_has_perm_noaudit(sid, isec->sid, isec->sclass, perms, 0, &avd); audited = avc_audit_required(perms, &avd, rc, (requested & MAY_ACCESS) ? FILE__AUDIT_ACCESS : 0, @@ -3285,9 +3286,9 @@ static int selinux_inode_getattr(const struct path *path) { struct task_security_struct *tsec; - tsec = selinux_cred(current_cred()); + tsec = selinux_task(current); - if (task_avdcache_permnoaudit(tsec)) + if (task_avdcache_permnoaudit(tsec, current_sid())) return 0; return path_has_perm(current_cred(), path, FILE__GETATTR); @@ -3659,7 +3660,7 @@ static void selinux_inode_getlsmprop(struct inode *inode, struct lsm_prop *prop) static int selinux_inode_copy_up(struct dentry *src, struct cred **new) { struct lsm_prop prop; - struct task_security_struct *tsec; + struct cred_security_struct *crsec; struct cred *new_creds = *new; if (new_creds == NULL) { @@ -3668,10 +3669,10 @@ static int selinux_inode_copy_up(struct dentry *src, struct cred **new) return -ENOMEM; } - tsec = selinux_cred(new_creds); + crsec = selinux_cred(new_creds); /* Get label from overlay inode and set it in create_sid */ selinux_inode_getlsmprop(d_inode(src), &prop); - tsec->create_sid = prop.selinux.secid; + crsec->create_sid = prop.selinux.secid; *new = new_creds; return 0; } @@ -3697,7 +3698,7 @@ static int selinux_inode_copy_up_xattr(struct dentry *dentry, const char *name) static int selinux_kernfs_init_security(struct kernfs_node *kn_dir, struct kernfs_node *kn) { - const struct task_security_struct *tsec = selinux_cred(current_cred()); + const struct cred_security_struct *crsec = selinux_cred(current_cred()); u32 parent_sid, newsid, clen; int rc; char *context; @@ -3725,8 +3726,8 @@ static int selinux_kernfs_init_security(struct kernfs_node *kn_dir, if (rc) return rc; - if (tsec->create_sid) { - newsid = tsec->create_sid; + if (crsec->create_sid) { + newsid = crsec->create_sid; } else { u16 secclass = inode_mode_to_security_class(kn->mode); const char *kn_name; @@ -3737,7 +3738,7 @@ static int selinux_kernfs_init_security(struct kernfs_node *kn_dir, q.name = kn_name; q.hash_len = hashlen_string(kn_dir, kn_name); - rc = security_transition_sid(tsec->sid, + rc = security_transition_sid(crsec->sid, parent_sid, secclass, &q, &newsid); if (rc) @@ -4151,7 +4152,10 @@ static int selinux_task_alloc(struct task_struct *task, u64 clone_flags) { u32 sid = current_sid(); + struct task_security_struct *old_tsec = selinux_task(current); + struct task_security_struct *new_tsec = selinux_task(task); + *new_tsec = *old_tsec; return avc_has_perm(sid, sid, SECCLASS_PROCESS, PROCESS__FORK, NULL); } @@ -4161,10 +4165,10 @@ static int selinux_task_alloc(struct task_struct *task, static int selinux_cred_prepare(struct cred *new, const struct cred *old, gfp_t gfp) { - const struct task_security_struct *old_tsec = selinux_cred(old); - struct task_security_struct *tsec = selinux_cred(new); + const struct cred_security_struct *old_crsec = selinux_cred(old); + struct cred_security_struct *crsec = selinux_cred(new); - *tsec = *old_tsec; + *crsec = *old_crsec; return 0; } @@ -4173,10 +4177,10 @@ static int selinux_cred_prepare(struct cred *new, const struct cred *old, */ static void selinux_cred_transfer(struct cred *new, const struct cred *old) { - const struct task_security_struct *old_tsec = selinux_cred(old); - struct task_security_struct *tsec = selinux_cred(new); + const struct cred_security_struct *old_crsec = selinux_cred(old); + struct cred_security_struct *crsec = selinux_cred(new); - *tsec = *old_tsec; + *crsec = *old_crsec; } static void selinux_cred_getsecid(const struct cred *c, u32 *secid) @@ -4195,7 +4199,7 @@ static void selinux_cred_getlsmprop(const struct cred *c, struct lsm_prop *prop) */ static int selinux_kernel_act_as(struct cred *new, u32 secid) { - struct task_security_struct *tsec = selinux_cred(new); + struct cred_security_struct *crsec = selinux_cred(new); u32 sid = current_sid(); int ret; @@ -4204,10 +4208,10 @@ static int selinux_kernel_act_as(struct cred *new, u32 secid) KERNEL_SERVICE__USE_AS_OVERRIDE, NULL); if (ret == 0) { - tsec->sid = secid; - tsec->create_sid = 0; - tsec->keycreate_sid = 0; - tsec->sockcreate_sid = 0; + crsec->sid = secid; + crsec->create_sid = 0; + crsec->keycreate_sid = 0; + crsec->sockcreate_sid = 0; } return ret; } @@ -4219,7 +4223,7 @@ static int selinux_kernel_act_as(struct cred *new, u32 secid) static int selinux_kernel_create_files_as(struct cred *new, struct inode *inode) { struct inode_security_struct *isec = inode_security(inode); - struct task_security_struct *tsec = selinux_cred(new); + struct cred_security_struct *crsec = selinux_cred(new); u32 sid = current_sid(); int ret; @@ -4229,7 +4233,7 @@ static int selinux_kernel_create_files_as(struct cred *new, struct inode *inode) NULL); if (ret == 0) - tsec->create_sid = isec->sid; + crsec->create_sid = isec->sid; return ret; } @@ -4744,15 +4748,15 @@ static int selinux_conn_sid(u32 sk_sid, u32 skb_sid, u32 *conn_sid) /* socket security operations */ -static int socket_sockcreate_sid(const struct task_security_struct *tsec, +static int socket_sockcreate_sid(const struct cred_security_struct *crsec, u16 secclass, u32 *socksid) { - if (tsec->sockcreate_sid > SECSID_NULL) { - *socksid = tsec->sockcreate_sid; + if (crsec->sockcreate_sid > SECSID_NULL) { + *socksid = crsec->sockcreate_sid; return 0; } - return security_transition_sid(tsec->sid, tsec->sid, + return security_transition_sid(crsec->sid, crsec->sid, secclass, NULL, socksid); } @@ -4797,7 +4801,7 @@ static int sock_has_perm(struct sock *sk, u32 perms) static int selinux_socket_create(int family, int type, int protocol, int kern) { - const struct task_security_struct *tsec = selinux_cred(current_cred()); + const struct cred_security_struct *crsec = selinux_cred(current_cred()); u32 newsid; u16 secclass; int rc; @@ -4806,17 +4810,17 @@ static int selinux_socket_create(int family, int type, return 0; secclass = socket_type_to_security_class(family, type, protocol); - rc = socket_sockcreate_sid(tsec, secclass, &newsid); + rc = socket_sockcreate_sid(crsec, secclass, &newsid); if (rc) return rc; - return avc_has_perm(tsec->sid, newsid, secclass, SOCKET__CREATE, NULL); + return avc_has_perm(crsec->sid, newsid, secclass, SOCKET__CREATE, NULL); } static int selinux_socket_post_create(struct socket *sock, int family, int type, int protocol, int kern) { - const struct task_security_struct *tsec = selinux_cred(current_cred()); + const struct cred_security_struct *crsec = selinux_cred(current_cred()); struct inode_security_struct *isec = inode_security_novalidate(SOCK_INODE(sock)); struct sk_security_struct *sksec; u16 sclass = socket_type_to_security_class(family, type, protocol); @@ -4824,7 +4828,7 @@ static int selinux_socket_post_create(struct socket *sock, int family, int err = 0; if (!kern) { - err = socket_sockcreate_sid(tsec, sclass, &sid); + err = socket_sockcreate_sid(crsec, sclass, &sid); if (err) return err; } @@ -6526,37 +6530,37 @@ static void selinux_d_instantiate(struct dentry *dentry, struct inode *inode) static int selinux_lsm_getattr(unsigned int attr, struct task_struct *p, char **value) { - const struct task_security_struct *tsec; + const struct cred_security_struct *crsec; int error; u32 sid; u32 len; rcu_read_lock(); - tsec = selinux_cred(__task_cred(p)); + crsec = selinux_cred(__task_cred(p)); if (p != current) { - error = avc_has_perm(current_sid(), tsec->sid, + error = avc_has_perm(current_sid(), crsec->sid, SECCLASS_PROCESS, PROCESS__GETATTR, NULL); if (error) goto err_unlock; } switch (attr) { case LSM_ATTR_CURRENT: - sid = tsec->sid; + sid = crsec->sid; break; case LSM_ATTR_PREV: - sid = tsec->osid; + sid = crsec->osid; break; case LSM_ATTR_EXEC: - sid = tsec->exec_sid; + sid = crsec->exec_sid; break; case LSM_ATTR_FSCREATE: - sid = tsec->create_sid; + sid = crsec->create_sid; break; case LSM_ATTR_KEYCREATE: - sid = tsec->keycreate_sid; + sid = crsec->keycreate_sid; break; case LSM_ATTR_SOCKCREATE: - sid = tsec->sockcreate_sid; + sid = crsec->sockcreate_sid; break; default: error = -EOPNOTSUPP; @@ -6581,7 +6585,7 @@ static int selinux_lsm_getattr(unsigned int attr, struct task_struct *p, static int selinux_lsm_setattr(u64 attr, void *value, size_t size) { - struct task_security_struct *tsec; + struct cred_security_struct *crsec; struct cred *new; u32 mysid = current_sid(), sid = 0, ptsid; int error; @@ -6667,11 +6671,11 @@ static int selinux_lsm_setattr(u64 attr, void *value, size_t size) operation. See selinux_bprm_creds_for_exec for the execve checks and may_create for the file creation checks. The operation will then fail if the context is not permitted. */ - tsec = selinux_cred(new); + crsec = selinux_cred(new); if (attr == LSM_ATTR_EXEC) { - tsec->exec_sid = sid; + crsec->exec_sid = sid; } else if (attr == LSM_ATTR_FSCREATE) { - tsec->create_sid = sid; + crsec->create_sid = sid; } else if (attr == LSM_ATTR_KEYCREATE) { if (sid) { error = avc_has_perm(mysid, sid, @@ -6679,22 +6683,22 @@ static int selinux_lsm_setattr(u64 attr, void *value, size_t size) if (error) goto abort_change; } - tsec->keycreate_sid = sid; + crsec->keycreate_sid = sid; } else if (attr == LSM_ATTR_SOCKCREATE) { - tsec->sockcreate_sid = sid; + crsec->sockcreate_sid = sid; } else if (attr == LSM_ATTR_CURRENT) { error = -EINVAL; if (sid == 0) goto abort_change; if (!current_is_single_threaded()) { - error = security_bounded_transition(tsec->sid, sid); + error = security_bounded_transition(crsec->sid, sid); if (error) goto abort_change; } /* Check permissions for the transition. */ - error = avc_has_perm(tsec->sid, sid, SECCLASS_PROCESS, + error = avc_has_perm(crsec->sid, sid, SECCLASS_PROCESS, PROCESS__DYNTRANSITION, NULL); if (error) goto abort_change; @@ -6709,7 +6713,7 @@ static int selinux_lsm_setattr(u64 attr, void *value, size_t size) goto abort_change; } - tsec->sid = sid; + crsec->sid = sid; } else { error = -EINVAL; goto abort_change; @@ -6876,14 +6880,14 @@ static int selinux_inode_getsecctx(struct inode *inode, struct lsm_context *cp) static int selinux_key_alloc(struct key *k, const struct cred *cred, unsigned long flags) { - const struct task_security_struct *tsec; + const struct cred_security_struct *crsec; struct key_security_struct *ksec = selinux_key(k); - tsec = selinux_cred(cred); - if (tsec->keycreate_sid) - ksec->sid = tsec->keycreate_sid; + crsec = selinux_cred(cred); + if (crsec->keycreate_sid) + ksec->sid = crsec->keycreate_sid; else - ksec->sid = tsec->sid; + ksec->sid = crsec->sid; return 0; } @@ -7137,7 +7141,8 @@ static int selinux_bpf_token_create(struct bpf_token *token, union bpf_attr *att #endif struct lsm_blob_sizes selinux_blob_sizes __ro_after_init = { - .lbs_cred = sizeof(struct task_security_struct), + .lbs_cred = sizeof(struct cred_security_struct), + .lbs_task = sizeof(struct task_security_struct), .lbs_file = sizeof(struct file_security_struct), .lbs_inode = sizeof(struct inode_security_struct), .lbs_ipc = sizeof(struct ipc_security_struct), diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h index 2d5139c6d45b30..8fc3de5234acd8 100644 --- a/security/selinux/include/objsec.h +++ b/security/selinux/include/objsec.h @@ -37,13 +37,16 @@ struct avdc_entry { bool permissive; /* AVC permissive flag */ }; -struct task_security_struct { +struct cred_security_struct { u32 osid; /* SID prior to last execve */ u32 sid; /* current SID */ u32 exec_sid; /* exec SID */ u32 create_sid; /* fscreate SID */ u32 keycreate_sid; /* keycreate SID */ u32 sockcreate_sid; /* fscreate SID */ +} __randomize_layout; + +struct task_security_struct { #define TSEC_AVDC_DIR_SIZE (1 << 2) struct { u32 sid; /* current SID for cached entries */ @@ -54,10 +57,11 @@ struct task_security_struct { } avdcache; } __randomize_layout; -static inline bool task_avdcache_permnoaudit(struct task_security_struct *tsec) +static inline bool task_avdcache_permnoaudit(struct task_security_struct *tsec, + u32 sid) { return (tsec->avdcache.permissive_neveraudit && - tsec->sid == tsec->avdcache.sid && + sid == tsec->avdcache.sid && tsec->avdcache.seqno == avc_policy_seqno()); } @@ -172,11 +176,17 @@ struct perf_event_security_struct { }; extern struct lsm_blob_sizes selinux_blob_sizes; -static inline struct task_security_struct *selinux_cred(const struct cred *cred) +static inline struct cred_security_struct *selinux_cred(const struct cred *cred) { return cred->security + selinux_blob_sizes.lbs_cred; } +static inline struct task_security_struct * +selinux_task(const struct task_struct *task) +{ + return task->security + selinux_blob_sizes.lbs_task; +} + static inline struct file_security_struct *selinux_file(const struct file *file) { return file->f_security + selinux_blob_sizes.lbs_file; @@ -207,9 +217,9 @@ selinux_ipc(const struct kern_ipc_perm *ipc) */ static inline u32 current_sid(void) { - const struct task_security_struct *tsec = selinux_cred(current_cred()); + const struct cred_security_struct *crsec = selinux_cred(current_cred()); - return tsec->sid; + return crsec->sid; } static inline struct superblock_security_struct * diff --git a/sound/core/pcm_drm_eld.c b/sound/core/pcm_drm_eld.c index 688eefce82fa3d..cb2eebaac85fdb 100644 --- a/sound/core/pcm_drm_eld.c +++ b/sound/core/pcm_drm_eld.c @@ -379,7 +379,7 @@ int snd_parse_eld(struct device *dev, struct snd_parsed_hdmi_eld *e, * in console or for audio devices. Assume the highest speakers * configuration, to _not_ prohibit multi-channel audio playback. */ - if (!e->spk_alloc) + if (!e->spk_alloc && e->sad_count) e->spk_alloc = 0xffff; return 0; diff --git a/sound/drivers/pcmtest.c b/sound/drivers/pcmtest.c index 19b3f306c56456..b8474631f0b576 100644 --- a/sound/drivers/pcmtest.c +++ b/sound/drivers/pcmtest.c @@ -696,10 +696,10 @@ static int setup_patt_bufs(void) size_t i; for (i = 0; i < ARRAY_SIZE(patt_bufs); i++) { - patt_bufs[i].buf = kzalloc(MAX_PATTERN_LEN, GFP_KERNEL); + patt_bufs[i].buf = kmalloc(MAX_PATTERN_LEN, GFP_KERNEL); if (!patt_bufs[i].buf) break; - strcpy(patt_bufs[i].buf, DEFAULT_PATTERN); + strscpy_pad(patt_bufs[i].buf, DEFAULT_PATTERN, MAX_PATTERN_LEN); patt_bufs[i].len = DEFAULT_PATTERN_LEN; } diff --git a/sound/hda/codecs/cirrus/cs420x.c b/sound/hda/codecs/cirrus/cs420x.c index 823220d5cadaca..13f5f1711fa47a 100644 --- a/sound/hda/codecs/cirrus/cs420x.c +++ b/sound/hda/codecs/cirrus/cs420x.c @@ -585,6 +585,7 @@ static const struct hda_quirk cs4208_mac_fixup_tbl[] = { SND_PCI_QUIRK(0x106b, 0x6c00, "MacMini 7,1", CS4208_MACMINI), SND_PCI_QUIRK(0x106b, 0x7100, "MacBookAir 6,1", CS4208_MBA6), SND_PCI_QUIRK(0x106b, 0x7200, "MacBookAir 6,2", CS4208_MBA6), + SND_PCI_QUIRK(0x106b, 0x7800, "MacPro 6,1", CS4208_MACMINI), SND_PCI_QUIRK(0x106b, 0x7b00, "MacBookPro 12,1", CS4208_MBP11), {} /* terminator */ }; diff --git a/sound/hda/codecs/hdmi/nvhdmi-mcp.c b/sound/hda/codecs/hdmi/nvhdmi-mcp.c index 8fd8d76fa72f85..1c5fdfe872f2b1 100644 --- a/sound/hda/codecs/hdmi/nvhdmi-mcp.c +++ b/sound/hda/codecs/hdmi/nvhdmi-mcp.c @@ -350,8 +350,8 @@ static int nvhdmi_mcp_probe(struct hda_codec *codec, static const struct hda_codec_ops nvhdmi_mcp_codec_ops = { .probe = nvhdmi_mcp_probe, .remove = snd_hda_hdmi_simple_remove, - .build_controls = nvhdmi_mcp_build_pcms, - .build_pcms = nvhdmi_mcp_build_controls, + .build_pcms = nvhdmi_mcp_build_pcms, + .build_controls = nvhdmi_mcp_build_controls, .init = nvhdmi_mcp_init, .unsol_event = snd_hda_hdmi_simple_unsol_event, }; diff --git a/sound/hda/codecs/realtek/alc269.c b/sound/hda/codecs/realtek/alc269.c index 2a94884a7a5bb3..c0a6acd7d42dc0 100644 --- a/sound/hda/codecs/realtek/alc269.c +++ b/sound/hda/codecs/realtek/alc269.c @@ -3406,7 +3406,42 @@ static void alc287_fixup_lenovo_thinkpad_with_alc1318(struct hda_codec *codec, spec->power_hook = alc287_s4_power_gpio3_default; spec->gen.pcm_playback_hook = alc287_alc1318_playback_pcm_hook; } +/* GPIO2: mute led GPIO3: micmute led */ +static void alc245_tas2781_spi_hp_fixup_muteled(struct hda_codec *codec, + const struct hda_fixup *fix, int action) +{ + struct alc_spec *spec = codec->spec; + static const hda_nid_t conn[] = { 0x02 }; + + switch (action) { + case HDA_FIXUP_ACT_PRE_PROBE: + spec->gen.auto_mute_via_amp = 1; + snd_hda_override_conn_list(codec, 0x17, ARRAY_SIZE(conn), conn); + break; + } + + tas2781_fixup_spi(codec, fix, action); + alc_fixup_hp_gpio_led(codec, action, 0x04, 0x0); + alc285_fixup_hp_coef_micmute_led(codec, fix, action); +} +/* JD2: mute led GPIO3: micmute led */ +static void alc245_tas2781_i2c_hp_fixup_muteled(struct hda_codec *codec, + const struct hda_fixup *fix, int action) +{ + struct alc_spec *spec = codec->spec; + static const hda_nid_t conn[] = { 0x02 }; + + switch (action) { + case HDA_FIXUP_ACT_PRE_PROBE: + spec->gen.auto_mute_via_amp = 1; + snd_hda_override_conn_list(codec, 0x17, ARRAY_SIZE(conn), conn); + break; + } + tas2781_fixup_txnw_i2c(codec, fix, action); + alc245_fixup_hp_mute_led_coefbit(codec, fix, action); + alc285_fixup_hp_coef_micmute_led(codec, fix, action); +} /* * Clear COEF 0x0d (PCBEEP passthrough) bit 0x40 where BIOS sets it wrongly * at PM resume @@ -3418,6 +3453,21 @@ static void alc283_fixup_dell_hp_resume(struct hda_codec *codec, alc_write_coef_idx(codec, 0xd, 0x2800); } +/* Swap DAC assignments for HP and speaker */ +static void alc288_fixup_surface_swap_dacs(struct hda_codec *codec, + const struct hda_fixup *fix, int action) +{ + struct alc_spec *spec = codec->spec; + static hda_nid_t preferred_pairs[] = { + 0x21, 0x03, 0x14, 0x02, 0 + }; + + if (action != HDA_FIXUP_ACT_PRE_PROBE) + return; + + spec->gen.preferred_dacs = preferred_pairs; +} + enum { ALC269_FIXUP_GPIO2, ALC269_FIXUP_SONY_VAIO, @@ -3737,6 +3787,10 @@ enum { ALC269_FIXUP_POSITIVO_P15X_HEADSET_MIC, ALC289_FIXUP_ASUS_ZEPHYRUS_DUAL_SPK, ALC256_FIXUP_VAIO_RPL_MIC_NO_PRESENCE, + ALC245_FIXUP_HP_TAS2781_SPI_MUTE_LED, + ALC245_FIXUP_HP_TAS2781_I2C_MUTE_LED, + ALC288_FIXUP_SURFACE_SWAP_DACS, + ALC236_FIXUP_HP_MUTE_LED_MICMUTE_GPIO, }; /* A special fixup for Lenovo C940 and Yoga Duet 7; @@ -5270,6 +5324,12 @@ static const struct hda_fixup alc269_fixups[] = { .type = HDA_FIXUP_FUNC, .v.func = alc236_fixup_hp_mute_led_micmute_vref, }, + [ALC236_FIXUP_HP_MUTE_LED_MICMUTE_GPIO] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc236_fixup_hp_mute_led_coefbit2, + .chained = true, + .chain_id = ALC236_FIXUP_HP_GPIO_LED, + }, [ALC236_FIXUP_LENOVO_INV_DMIC] = { .type = HDA_FIXUP_FUNC, .v.func = alc_fixup_inv_dmic, @@ -6183,7 +6243,19 @@ static const struct hda_fixup alc269_fixups[] = { }, .chained = true, .chain_id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST - } + }, + [ALC245_FIXUP_HP_TAS2781_SPI_MUTE_LED] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc245_tas2781_spi_hp_fixup_muteled, + }, + [ALC245_FIXUP_HP_TAS2781_I2C_MUTE_LED] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc245_tas2781_i2c_hp_fixup_muteled, + }, + [ALC288_FIXUP_SURFACE_SWAP_DACS] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc288_fixup_surface_swap_dacs, + }, }; static const struct hda_quirk alc269_fixup_tbl[] = { @@ -6694,6 +6766,19 @@ static const struct hda_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x103c, 0x8e60, "HP Trekker ", ALC287_FIXUP_CS35L41_I2C_2), SND_PCI_QUIRK(0x103c, 0x8e61, "HP Trekker ", ALC287_FIXUP_CS35L41_I2C_2), SND_PCI_QUIRK(0x103c, 0x8e62, "HP Trekker ", ALC287_FIXUP_CS35L41_I2C_2), + SND_PCI_QUIRK(0x103c, 0x8ec1, "HP 200 G2i", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_GPIO), + SND_PCI_QUIRK(0x103c, 0x8ed5, "HP EliteBook 8 Flip G2i 13", ALC245_FIXUP_HP_TAS2781_SPI_MUTE_LED), + SND_PCI_QUIRK(0x103c, 0x8ed6, "HP EliteBook 8 G2i 13", ALC245_FIXUP_HP_TAS2781_SPI_MUTE_LED), + SND_PCI_QUIRK(0x103c, 0x8ed7, "HP EliteBook 8 G2i 14", ALC245_FIXUP_HP_TAS2781_SPI_MUTE_LED), + SND_PCI_QUIRK(0x103c, 0x8ed8, "HP EliteBook 8 G2i 16", ALC245_FIXUP_HP_TAS2781_SPI_MUTE_LED), + SND_PCI_QUIRK(0x103c, 0x8ed9, "HP ZBook Firefly 14W", ALC245_FIXUP_HP_TAS2781_SPI_MUTE_LED), + SND_PCI_QUIRK(0x103c, 0x8eda, "HP ZBook Firefly 16W", ALC245_FIXUP_HP_TAS2781_SPI_MUTE_LED), + SND_PCI_QUIRK(0x103c, 0x8f0c, "HP ZBook X G2i 16W", ALC236_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8f0e, "HP ZBook X G2i 16W", ALC236_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8f40, "HP ZBook 8 G2a 14", ALC245_FIXUP_HP_TAS2781_I2C_MUTE_LED), + SND_PCI_QUIRK(0x103c, 0x8f41, "HP ZBook 8 G2a 16", ALC245_FIXUP_HP_TAS2781_I2C_MUTE_LED), + SND_PCI_QUIRK(0x103c, 0x8f42, "HP ZBook 8 G2a 14W", ALC245_FIXUP_HP_TAS2781_I2C_MUTE_LED), + SND_PCI_QUIRK(0x103c, 0x8f62, "HP ZBook 8 G2a 16W", ALC245_FIXUP_HP_TAS2781_I2C_MUTE_LED), SND_PCI_QUIRK(0x1043, 0x1032, "ASUS VivoBook X513EA", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1043, 0x1034, "ASUS GU605C", ALC285_FIXUP_ASUS_GU605_SPI_SPEAKER2_TO_DAC1), SND_PCI_QUIRK(0x1043, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC), @@ -6725,6 +6810,8 @@ static const struct hda_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x1043, 0x12f0, "ASUS X541UV", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1043, 0x1313, "Asus K42JZ", ALC269VB_FIXUP_ASUS_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1043, 0x1314, "ASUS GA605K", ALC285_FIXUP_ASUS_GA605K_HEADSET_MIC), + SND_PCI_QUIRK(0x1043, 0x1384, "ASUS RC73XA", ALC287_FIXUP_TXNW2781_I2C), + SND_PCI_QUIRK(0x1043, 0x1394, "ASUS RC73YA", ALC287_FIXUP_TXNW2781_I2C), SND_PCI_QUIRK(0x1043, 0x13b0, "ASUS Z550SA", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_ASUS_ZENBOOK), SND_PCI_QUIRK(0x1043, 0x1433, "ASUS GX650PY/PZ/PV/PU/PYV/PZV/PIV/PVV", ALC285_FIXUP_ASUS_I2C_HEADSET_MIC), @@ -6873,6 +6960,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x10ec, 0x12f6, "Intel Reference board", ALC295_FIXUP_CHROME_BOOK), SND_PCI_QUIRK(0x10ec, 0x1310, "Intel Reference board", ALC295_FIXUP_CHROME_BOOK), SND_PCI_QUIRK(0x10f7, 0x8338, "Panasonic CF-SZ6", ALC269_FIXUP_ASPIRE_HEADSET_MIC), + SND_PCI_QUIRK(0x1414, 0x9c20, "Microsoft Surface Pro 2/3", ALC288_FIXUP_SURFACE_SWAP_DACS), SND_PCI_QUIRK(0x144d, 0xc109, "Samsung Ativ book 9 (NP900X3G)", ALC269_FIXUP_INV_DMIC), SND_PCI_QUIRK(0x144d, 0xc169, "Samsung Notebook 9 Pen (NP930SBE-K01US)", ALC298_FIXUP_SAMSUNG_AMP), SND_PCI_QUIRK(0x144d, 0xc176, "Samsung Notebook 9 Pro (NP930MBE-K04US)", ALC298_FIXUP_SAMSUNG_AMP), diff --git a/sound/hda/codecs/side-codecs/tas2781_hda_i2c.c b/sound/hda/codecs/side-codecs/tas2781_hda_i2c.c index 0357401a602349..c8619995b1d78c 100644 --- a/sound/hda/codecs/side-codecs/tas2781_hda_i2c.c +++ b/sound/hda/codecs/side-codecs/tas2781_hda_i2c.c @@ -87,6 +87,7 @@ static const struct acpi_gpio_mapping tas2781_speaker_id_gpios[] = { static int tas2781_read_acpi(struct tasdevice_priv *p, const char *hid) { + struct gpio_desc *speaker_id; struct acpi_device *adev; struct device *physdev; LIST_HEAD(resources); @@ -119,19 +120,31 @@ static int tas2781_read_acpi(struct tasdevice_priv *p, const char *hid) /* Speaker id was needed for ASUS projects. */ ret = kstrtou32(sub, 16, &subid); if (!ret && upper_16_bits(subid) == PCI_VENDOR_ID_ASUSTEK) { - ret = devm_acpi_dev_add_driver_gpios(p->dev, - tas2781_speaker_id_gpios); - if (ret < 0) + ret = acpi_dev_add_driver_gpios(adev, tas2781_speaker_id_gpios); + if (ret < 0) { dev_err(p->dev, "Failed to add driver gpio %d.\n", ret); - p->speaker_id = devm_gpiod_get(p->dev, "speakerid", GPIOD_IN); - if (IS_ERR(p->speaker_id)) { - dev_err(p->dev, "Failed to get Speaker id.\n"); - ret = PTR_ERR(p->speaker_id); - goto err; + p->speaker_id = -1; + goto end_2563; + } + + speaker_id = fwnode_gpiod_get_index(acpi_fwnode_handle(adev), + "speakerid", 0, GPIOD_IN, NULL); + if (!IS_ERR(speaker_id)) { + p->speaker_id = gpiod_get_value_cansleep(speaker_id); + dev_dbg(p->dev, "Got speaker id gpio from ACPI: %d.\n", + p->speaker_id); + gpiod_put(speaker_id); + } else { + p->speaker_id = -1; + ret = PTR_ERR(speaker_id); + dev_err(p->dev, "Get speaker id gpio failed %d.\n", + ret); } + + acpi_dev_remove_driver_gpios(adev); } else { - p->speaker_id = NULL; + p->speaker_id = -1; } end_2563: @@ -432,23 +445,16 @@ static void tasdevice_dspfw_init(void *context) struct tas2781_hda *tas_hda = dev_get_drvdata(tas_priv->dev); struct tas2781_hda_i2c_priv *hda_priv = tas_hda->hda_priv; struct hda_codec *codec = tas_priv->codec; - int ret, spk_id; + int ret; tasdevice_dsp_remove(tas_priv); tas_priv->fw_state = TASDEVICE_DSP_FW_PENDING; - if (tas_priv->speaker_id != NULL) { - // Speaker id need to be checked for ASUS only. - spk_id = gpiod_get_value(tas_priv->speaker_id); - if (spk_id < 0) { - // Speaker id is not valid, use default. - dev_dbg(tas_priv->dev, "Wrong spk_id = %d\n", spk_id); - spk_id = 0; - } + if (tas_priv->speaker_id >= 0) { snprintf(tas_priv->coef_binaryname, sizeof(tas_priv->coef_binaryname), "TAS2XXX%04X%d.bin", lower_16_bits(codec->core.subsystem_id), - spk_id); + tas_priv->speaker_id); } else { snprintf(tas_priv->coef_binaryname, sizeof(tas_priv->coef_binaryname), diff --git a/sound/isa/gus/gus_reset.c b/sound/isa/gus/gus_reset.c index 5cbace8369f8e8..a7a3e764bb77cf 100644 --- a/sound/isa/gus/gus_reset.c +++ b/sound/isa/gus/gus_reset.c @@ -9,9 +9,6 @@ #include #include -extern int snd_gf1_synth_init(struct snd_gus_card * gus); -extern void snd_gf1_synth_done(struct snd_gus_card * gus); - /* * ok.. default interrupt handlers... */ diff --git a/sound/pci/au88x0/au88x0.c b/sound/pci/au88x0/au88x0.c index de56e83d8e10c2..bb02945793f0c3 100644 --- a/sound/pci/au88x0/au88x0.c +++ b/sound/pci/au88x0/au88x0.c @@ -280,11 +280,11 @@ __snd_vortex_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) // (5) err = pci_read_config_word(pci, PCI_DEVICE_ID, &chip->device); - if (err < 0) - return err; + if (err) + return pcibios_err_to_errno(err); err = pci_read_config_word(pci, PCI_VENDOR_ID, &chip->vendor); - if (err < 0) - return err; + if (err) + return pcibios_err_to_errno(err); chip->rev = pci->revision; #ifdef CHIP_AU8830 if ((chip->rev) != 0xfe && (chip->rev) != 0xfa) { diff --git a/sound/pci/ctxfi/ctatc.c b/sound/pci/ctxfi/ctatc.c index 14779b383d9ea3..227d8c8490e1f5 100644 --- a/sound/pci/ctxfi/ctatc.c +++ b/sound/pci/ctxfi/ctatc.c @@ -25,6 +25,9 @@ #include #include +#define NUM_ATC_SRCS 6 +#define NUM_ATC_PCM (2 * 4) + #define MONO_SUM_SCALE 0x19a8 /* 2^(-0.5) in 14-bit floating format */ #define MAX_MULTI_CHN 8 @@ -60,6 +63,7 @@ static const struct snd_pci_quirk subsys_20k2_list[] = { SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_CREATIVE, 0xf000, PCI_SUBDEVICE_ID_CREATIVE_HENDRIX, "HENDRIX", CTHENDRIX), + SND_PCI_QUIRK(0x160b, 0x0101, "OK0010", CTOK0010), { } /* terminator */ }; @@ -75,6 +79,7 @@ static const char *ct_subsys_name[NUM_CTCARDS] = { [CTHENDRIX] = "Hendrix", [CTSB0880] = "SB0880", [CTSB1270] = "SB1270", + [CTOK0010] = "OK0010", [CT20K2_UNKNOWN] = "Unknown", }; @@ -984,6 +989,24 @@ static struct capabilities atc_capabilities(struct ct_atc *atc) return hw->capabilities(hw); } +static void atc_dedicated_rca_select(struct ct_atc *atc) +{ + struct dao *dao; + struct ct_mixer *mixer = atc->mixer; + struct rsc *rscs[2] = {NULL}; + + dao = container_of(atc->daios[atc->rca_state ? RCA : LINEO1], + struct dao, daio); + dao->ops->clear_left_input(dao); + dao->ops->clear_right_input(dao); + + mixer->get_output_ports(mixer, MIX_WAVE_FRONT, &rscs[0], &rscs[1]); + dao = container_of(atc->daios[atc->rca_state ? LINEO1 : RCA], + struct dao, daio); + dao->ops->set_left_input(dao, rscs[0]); + dao->ops->set_right_input(dao, rscs[1]); +} + static int atc_output_switch_get(struct ct_atc *atc) { struct hw *hw = atc->hw; @@ -1085,6 +1108,11 @@ static int atc_mic_unmute(struct ct_atc *atc, unsigned char state) return atc_daio_unmute(atc, state, MIC); } +static int atc_rca_unmute(struct ct_atc *atc, unsigned char state) +{ + return atc_daio_unmute(atc, state, RCA); +} + static int atc_spdif_out_unmute(struct ct_atc *atc, unsigned char state) { return atc_daio_unmute(atc, state, SPDIFOO); @@ -1161,9 +1189,11 @@ static int atc_release_resources(struct ct_atc *atc) if (atc->daios) { daio_mgr = (struct daio_mgr *)atc->rsc_mgrs[DAIO]; - for (i = 0; i < atc->n_daio; i++) { + for (i = 0; i < NUM_DAIOTYP; i++) { daio = atc->daios[i]; - if (daio->type < LINEIM) { + if (!daio) + continue; + if (daio->output) { dao = container_of(daio, struct dao, daio); dao->ops->clear_left_input(dao); dao->ops->clear_right_input(dao); @@ -1176,8 +1206,9 @@ static int atc_release_resources(struct ct_atc *atc) if (atc->pcm) { sum_mgr = atc->rsc_mgrs[SUM]; - for (i = 0; i < atc->n_pcm; i++) - sum_mgr->put_sum(sum_mgr, atc->pcm[i]); + for (i = 0; i < NUM_ATC_PCM; i++) + if (atc->pcm[i]) + sum_mgr->put_sum(sum_mgr, atc->pcm[i]); kfree(atc->pcm); atc->pcm = NULL; @@ -1185,8 +1216,9 @@ static int atc_release_resources(struct ct_atc *atc) if (atc->srcs) { src_mgr = atc->rsc_mgrs[SRC]; - for (i = 0; i < atc->n_src; i++) - src_mgr->put_src(src_mgr, atc->srcs[i]); + for (i = 0; i < NUM_ATC_SRCS; i++) + if (atc->srcs[i]) + src_mgr->put_src(src_mgr, atc->srcs[i]); kfree(atc->srcs); atc->srcs = NULL; @@ -1194,7 +1226,9 @@ static int atc_release_resources(struct ct_atc *atc) if (atc->srcimps) { srcimp_mgr = atc->rsc_mgrs[SRCIMP]; - for (i = 0; i < atc->n_srcimp; i++) { + for (i = 0; i < NUM_ATC_SRCS; i++) { + if (!atc->srcimps[i]) + continue; srcimp = atc->srcimps[i]; srcimp->ops->unmap(srcimp); srcimp_mgr->put_srcimp(srcimp_mgr, atc->srcimps[i]); @@ -1294,6 +1328,7 @@ static int atc_identify_card(struct ct_atc *atc, unsigned int ssid) dev_info(atc->card->dev, "chip %s model %s (%04x:%04x) is found\n", atc->chip_name, atc->model_name, vendor_id, device_id); + atc->rca_state = 0; return 0; } @@ -1367,32 +1402,35 @@ static int atc_get_resources(struct ct_atc *atc) struct srcimp_mgr *srcimp_mgr; struct sum_desc sum_dsc = {0}; struct sum_mgr *sum_mgr; - int err, i, num_srcs, num_daios; + struct capabilities cap; + int err, i; - num_daios = ((atc->model == CTSB1270) ? 8 : 7); - num_srcs = ((atc->model == CTSB1270) ? 6 : 4); + cap = atc->capabilities(atc); - atc->daios = kcalloc(num_daios, sizeof(void *), GFP_KERNEL); + atc->daios = kcalloc(NUM_DAIOTYP, sizeof(void *), GFP_KERNEL); if (!atc->daios) return -ENOMEM; - atc->srcs = kcalloc(num_srcs, sizeof(void *), GFP_KERNEL); + atc->srcs = kcalloc(NUM_ATC_SRCS, sizeof(void *), GFP_KERNEL); if (!atc->srcs) return -ENOMEM; - atc->srcimps = kcalloc(num_srcs, sizeof(void *), GFP_KERNEL); + atc->srcimps = kcalloc(NUM_ATC_SRCS, sizeof(void *), GFP_KERNEL); if (!atc->srcimps) return -ENOMEM; - atc->pcm = kcalloc(2 * 4, sizeof(void *), GFP_KERNEL); + atc->pcm = kcalloc(NUM_ATC_PCM, sizeof(void *), GFP_KERNEL); if (!atc->pcm) return -ENOMEM; daio_mgr = (struct daio_mgr *)atc->rsc_mgrs[DAIO]; da_desc.msr = atc->msr; - for (i = 0, atc->n_daio = 0; i < num_daios; i++) { + for (i = 0; i < NUM_DAIOTYP; i++) { + if (((i == MIC) && !cap.dedicated_mic) || ((i == RCA) && !cap.dedicated_rca)) + continue; da_desc.type = (atc->model != CTSB073X) ? i : ((i == SPDIFIO) ? SPDIFI1 : i); + da_desc.output = (i < LINEIM) || (i == RCA); err = daio_mgr->get_daio(daio_mgr, &da_desc, (struct daio **)&atc->daios[i]); if (err) { @@ -1401,42 +1439,39 @@ static int atc_get_resources(struct ct_atc *atc) i); return err; } - atc->n_daio++; } src_mgr = atc->rsc_mgrs[SRC]; src_dsc.multi = 1; src_dsc.msr = atc->msr; src_dsc.mode = ARCRW; - for (i = 0, atc->n_src = 0; i < num_srcs; i++) { + for (i = 0; i < NUM_ATC_SRCS; i++) { + if (((i > 3) && !cap.dedicated_mic)) + continue; err = src_mgr->get_src(src_mgr, &src_dsc, (struct src **)&atc->srcs[i]); if (err) return err; - - atc->n_src++; } srcimp_mgr = atc->rsc_mgrs[SRCIMP]; srcimp_dsc.msr = 8; - for (i = 0, atc->n_srcimp = 0; i < num_srcs; i++) { + for (i = 0; i < NUM_ATC_SRCS; i++) { + if (((i > 3) && !cap.dedicated_mic)) + continue; err = srcimp_mgr->get_srcimp(srcimp_mgr, &srcimp_dsc, (struct srcimp **)&atc->srcimps[i]); if (err) return err; - - atc->n_srcimp++; } sum_mgr = atc->rsc_mgrs[SUM]; sum_dsc.msr = atc->msr; - for (i = 0, atc->n_pcm = 0; i < (2*4); i++) { + for (i = 0; i < NUM_ATC_PCM; i++) { err = sum_mgr->get_sum(sum_mgr, &sum_dsc, (struct sum **)&atc->pcm[i]); if (err) return err; - - atc->n_pcm++; } return 0; @@ -1489,9 +1524,11 @@ static void atc_connect_resources(struct ct_atc *atc) struct sum *sum; struct ct_mixer *mixer; struct rsc *rscs[2] = {NULL}; + struct capabilities cap; int i, j; mixer = atc->mixer; + cap = atc->capabilities(atc); for (i = MIX_WAVE_FRONT, j = LINEO1; i <= MIX_SPDIF_OUT; i++, j++) { mixer->get_output_ports(mixer, i, &rscs[0], &rscs[1]); @@ -1500,6 +1537,11 @@ static void atc_connect_resources(struct ct_atc *atc) dao->ops->set_right_input(dao, rscs[1]); } + if (cap.dedicated_rca) { + /* SE-300PCIE has a dedicated DAC for the RCA. */ + atc_dedicated_rca_select(atc); + } + dai = container_of(atc->daios[LINEIM], struct dai, daio); atc_connect_dai(atc->rsc_mgrs[SRC], dai, (struct src **)&atc->srcs[2], @@ -1509,8 +1551,9 @@ static void atc_connect_resources(struct ct_atc *atc) src = atc->srcs[3]; mixer->set_input_right(mixer, MIX_LINE_IN, &src->rsc); - if (atc->model == CTSB1270) { + if (cap.dedicated_mic) { /* Titanium HD has a dedicated ADC for the Mic. */ + /* SE-300PCIE has a 4-channel ADC. */ dai = container_of(atc->daios[MIC], struct dai, daio); atc_connect_dai(atc->rsc_mgrs[SRC], dai, (struct src **)&atc->srcs[4], @@ -1632,12 +1675,14 @@ static const struct ct_atc atc_preset = { .line_rear_unmute = atc_line_rear_unmute, .line_in_unmute = atc_line_in_unmute, .mic_unmute = atc_mic_unmute, + .rca_unmute = atc_rca_unmute, .spdif_out_unmute = atc_spdif_out_unmute, .spdif_in_unmute = atc_spdif_in_unmute, .spdif_out_get_status = atc_spdif_out_get_status, .spdif_out_set_status = atc_spdif_out_set_status, .spdif_out_passthru = atc_spdif_out_passthru, .capabilities = atc_capabilities, + .dedicated_rca_select = atc_dedicated_rca_select, .output_switch_get = atc_output_switch_get, .output_switch_put = atc_output_switch_put, .mic_source_switch_get = atc_mic_source_switch_get, diff --git a/sound/pci/ctxfi/ctatc.h b/sound/pci/ctxfi/ctatc.h index 0bc7b71d910b05..ca0a9d5b86d85c 100644 --- a/sound/pci/ctxfi/ctatc.h +++ b/sound/pci/ctxfi/ctatc.h @@ -82,6 +82,8 @@ struct ct_atc { const char *chip_name; const char *model_name; + unsigned char rca_state; /* 0 = dedicated RCA, 1 = 7.1ch Front */ + struct ct_vm *vm; /* device virtual memory manager for this card */ int (*map_audio_buffer)(struct ct_atc *atc, struct ct_atc_pcm *apcm); void (*unmap_audio_buffer)(struct ct_atc *atc, struct ct_atc_pcm *apcm); @@ -113,12 +115,14 @@ struct ct_atc { int (*line_rear_unmute)(struct ct_atc *atc, unsigned char state); int (*line_in_unmute)(struct ct_atc *atc, unsigned char state); int (*mic_unmute)(struct ct_atc *atc, unsigned char state); + int (*rca_unmute)(struct ct_atc *atc, unsigned char state); int (*spdif_out_unmute)(struct ct_atc *atc, unsigned char state); int (*spdif_in_unmute)(struct ct_atc *atc, unsigned char state); int (*spdif_out_get_status)(struct ct_atc *atc, unsigned int *status); int (*spdif_out_set_status)(struct ct_atc *atc, unsigned int status); int (*spdif_out_passthru)(struct ct_atc *atc, unsigned char state); struct capabilities (*capabilities)(struct ct_atc *atc); + void (*dedicated_rca_select)(struct ct_atc *atc); int (*output_switch_get)(struct ct_atc *atc); int (*output_switch_put)(struct ct_atc *atc, int position); int (*mic_source_switch_get)(struct ct_atc *atc); @@ -132,10 +136,6 @@ struct ct_atc { void **pcm; /* SUMs for collecting all pcm stream */ void **srcs; /* Sample Rate Converters for input signal */ void **srcimps; /* input mappers for SRCs */ - unsigned char n_daio; - unsigned char n_src; - unsigned char n_srcimp; - unsigned char n_pcm; struct ct_timer *timer; diff --git a/sound/pci/ctxfi/ctdaio.c b/sound/pci/ctxfi/ctdaio.c index c0c3f8ab84677d..1c8f8efd836ceb 100644 --- a/sound/pci/ctxfi/ctdaio.c +++ b/sound/pci/ctxfi/ctdaio.c @@ -18,8 +18,6 @@ #include #include -#define DAIO_OUT_MAX SPDIFOO - struct daio_usage { unsigned short data; }; @@ -47,6 +45,7 @@ static const struct daio_rsc_idx idx_20k2[NUM_DAIOTYP] = { [LINEO4] = {.left = 0x70, .right = 0x71}, [LINEIM] = {.left = 0x45, .right = 0xc5}, [MIC] = {.left = 0x55, .right = 0xd5}, + [RCA] = {.left = 0x30, .right = 0x31}, [SPDIFOO] = {.left = 0x00, .right = 0x01}, [SPDIFIO] = {.left = 0x05, .right = 0x85}, }; @@ -125,6 +124,7 @@ static unsigned int daio_device_index(enum DAIOTYP type, struct hw *hw) case LINEO4: return 6; case LINEIM: return 4; case MIC: return 5; + case RCA: return 3; default: return -EINVAL; } default: @@ -329,7 +329,7 @@ static int daio_rsc_init(struct daio *daio, goto error1; /* Set daio->rscl/r->ops to daio specific ones */ - if (desc->type <= DAIO_OUT_MAX) { + if (desc->output) { daio->rscl.ops = daio->rscr.ops = &daio_out_rsc_ops; } else { switch (hw->chip_type) { @@ -344,6 +344,7 @@ static int daio_rsc_init(struct daio *daio, } } daio->type = desc->type; + daio->output = desc->output; return 0; @@ -390,7 +391,7 @@ static int dao_rsc_init(struct dao *dao, hw->daio_mgr_commit_write(hw, mgr->mgr.ctrl_blk); conf = (desc->msr & 0x7) | (desc->passthru << 3); - hw->daio_mgr_dao_init(mgr->mgr.ctrl_blk, + hw->daio_mgr_dao_init(hw, mgr->mgr.ctrl_blk, daio_device_index(dao->daio.type, hw), conf); hw->daio_mgr_enb_dao(mgr->mgr.ctrl_blk, daio_device_index(dao->daio.type, hw)); @@ -433,6 +434,7 @@ static int dao_rsc_reinit(struct dao *dao, const struct dao_desc *desc) dsc.type = dao->daio.type; dsc.msr = desc->msr; dsc.passthru = desc->passthru; + dsc.output = dao->daio.output; dao_rsc_uninit(dao); return dao_rsc_init(dao, &dsc, mgr); } @@ -518,7 +520,7 @@ static int get_daio_rsc(struct daio_mgr *mgr, err = -ENOMEM; /* Allocate mem for daio resource */ - if (desc->type <= DAIO_OUT_MAX) { + if (desc->output) { struct dao *dao = kzalloc(sizeof(*dao), GFP_KERNEL); if (!dao) goto error; @@ -565,7 +567,7 @@ static int put_daio_rsc(struct daio_mgr *mgr, struct daio *daio) daio_mgr_put_rsc(&mgr->mgr, daio->type); } - if (daio->type <= DAIO_OUT_MAX) { + if (daio->output) { dao_rsc_uninit(container_of(daio, struct dao, daio)); kfree(container_of(daio, struct dao, daio)); } else { @@ -580,7 +582,7 @@ static int daio_mgr_enb_daio(struct daio_mgr *mgr, struct daio *daio) { struct hw *hw = mgr->mgr.hw; - if (DAIO_OUT_MAX >= daio->type) { + if (daio->output) { hw->daio_mgr_enb_dao(mgr->mgr.ctrl_blk, daio_device_index(daio->type, hw)); } else { @@ -594,7 +596,7 @@ static int daio_mgr_dsb_daio(struct daio_mgr *mgr, struct daio *daio) { struct hw *hw = mgr->mgr.hw; - if (DAIO_OUT_MAX >= daio->type) { + if (daio->output) { hw->daio_mgr_dsb_dao(mgr->mgr.ctrl_blk, daio_device_index(daio->type, hw)); } else { diff --git a/sound/pci/ctxfi/ctdaio.h b/sound/pci/ctxfi/ctdaio.h index 15147fe5f74a0b..ff77d55539a560 100644 --- a/sound/pci/ctxfi/ctdaio.h +++ b/sound/pci/ctxfi/ctdaio.h @@ -31,6 +31,7 @@ enum DAIOTYP { LINEIM, SPDIFIO, /* S/PDIF In (Flexijack/Optical) on the card */ MIC, /* Dedicated mic on Titanium HD */ + RCA, /* Dedicated RCA on SE-300PCIE */ SPDIFI1, /* S/PDIF In on internal Drive Bay */ NUM_DAIOTYP }; @@ -43,6 +44,7 @@ struct daio { struct rsc rscl; /* Basic resource info for left TX/RX */ struct rsc rscr; /* Basic resource info for right TX/RX */ enum DAIOTYP type; + unsigned char output; }; struct dao { @@ -91,6 +93,7 @@ struct daio_desc { unsigned int type:4; unsigned int msr:4; unsigned int passthru:1; + unsigned int output:1; }; struct daio_mgr { diff --git a/sound/pci/ctxfi/cthardware.h b/sound/pci/ctxfi/cthardware.h index 2875cec83b8f24..a3051fdd31f614 100644 --- a/sound/pci/ctxfi/cthardware.h +++ b/sound/pci/ctxfi/cthardware.h @@ -38,6 +38,7 @@ enum CTCARDS { CTHENDRIX, CTSB0880, CTSB1270, + CTOK0010, CT20K2_UNKNOWN, NUM_CTCARDS /* This should always be the last */ }; @@ -62,6 +63,7 @@ struct card_conf { struct capabilities { unsigned int digit_io_switch:1; unsigned int dedicated_mic:1; + unsigned int dedicated_rca:1; unsigned int output_switch:1; unsigned int mic_source_switch:1; }; @@ -167,7 +169,7 @@ struct hw { int (*daio_mgr_dsb_dai)(void *blk, unsigned int idx); int (*daio_mgr_enb_dao)(void *blk, unsigned int idx); int (*daio_mgr_dsb_dao)(void *blk, unsigned int idx); - int (*daio_mgr_dao_init)(void *blk, unsigned int idx, + int (*daio_mgr_dao_init)(struct hw *hw, void *blk, unsigned int idx, unsigned int conf); int (*daio_mgr_set_imaparc)(void *blk, unsigned int slot); int (*daio_mgr_set_imapnxt)(void *blk, unsigned int next); diff --git a/sound/pci/ctxfi/cthw20k1.c b/sound/pci/ctxfi/cthw20k1.c index 42b90c9b2ee9f1..ea0a928937b6fc 100644 --- a/sound/pci/ctxfi/cthw20k1.c +++ b/sound/pci/ctxfi/cthw20k1.c @@ -1031,7 +1031,7 @@ static int daio_mgr_dsb_dao(void *blk, unsigned int idx) return 0; } -static int daio_mgr_dao_init(void *blk, unsigned int idx, unsigned int conf) +static int daio_mgr_dao_init(struct hw *hw __maybe_unused, void *blk, unsigned int idx, unsigned int conf) { struct daio_mgr_ctrl_blk *ctl = blk; @@ -1775,6 +1775,7 @@ static struct capabilities hw_capabilities(struct hw *hw) /* SB073x and Vista compatible cards have no digit IO switch */ cap.digit_io_switch = !(hw->model == CTSB073X || hw->model == CTUAA); cap.dedicated_mic = 0; + cap.dedicated_rca = 0; cap.output_switch = 0; cap.mic_source_switch = 0; diff --git a/sound/pci/ctxfi/cthw20k2.c b/sound/pci/ctxfi/cthw20k2.c index 55af8ef2983836..fac88f5590c970 100644 --- a/sound/pci/ctxfi/cthw20k2.c +++ b/sound/pci/ctxfi/cthw20k2.c @@ -910,7 +910,7 @@ static int dao_commit_write(struct hw *hw, unsigned int idx, void *blk) struct dao_ctrl_blk *ctl = blk; if (ctl->dirty.bf.atxcsl) { - if (idx < 4) { + if ((idx < 4) && ((hw->model != CTOK0010) || (idx < 3))) { /* S/PDIF SPOSx */ hw_write_20kx(hw, AUDIO_IO_TX_CSTAT_L+0x40*idx, ctl->atxcsl); @@ -985,11 +985,12 @@ static int daio_mgr_dsb_dao(void *blk, unsigned int idx) return 0; } -static int daio_mgr_dao_init(void *blk, unsigned int idx, unsigned int conf) +static int daio_mgr_dao_init(struct hw *hw, void *blk, unsigned int idx, unsigned int conf) { struct daio_mgr_ctrl_blk *ctl = blk; - if (idx < 4) { + /* Port 3 is dedicated to RCA on SE-300PCIE */ + if ((idx < 4) && ((hw->model != CTOK0010) || (idx < 3))) { /* S/PDIF output */ switch ((conf & 0xf)) { case 1: @@ -1176,6 +1177,10 @@ static int hw_daio_init(struct hw *hw, const struct daio_conf *info) hw_write_20kx(hw, AUDIO_IO_MCLK, 0x21011111); hw_write_20kx(hw, AUDIO_IO_TX_BLRCLK, 0x21212121); hw_write_20kx(hw, AUDIO_IO_RX_BLRCLK, 0); + } else if ((4 == info->msr) && (hw->model == CTOK0010)) { + hw_write_20kx(hw, AUDIO_IO_MCLK, 0x21212121); + hw_write_20kx(hw, AUDIO_IO_TX_BLRCLK, 0x21212121); + hw_write_20kx(hw, AUDIO_IO_RX_BLRCLK, 0); } else { dev_alert(hw->card->dev, "ERROR!!! Invalid sampling rate!!!\n"); @@ -1183,7 +1188,8 @@ static int hw_daio_init(struct hw *hw, const struct daio_conf *info) } for (i = 0; i < 8; i++) { - if (i <= 3) { + /* Port 3 is configured as I2S on SE-300PCIE */ + if ((i < 4) && ((hw->model != CTOK0010) || (i < 3))) { /* This comment looks wrong since loop is over 4 */ /* channels and emu20k2 supports 4 spdif IOs. */ /* 1st 3 channels are SPDIFs (SB0960) */ @@ -1637,6 +1643,13 @@ static int hw_dac_init(struct hw *hw, const struct dac_conf *info) hw_write_20kx(hw, GPIO_DATA, data); hw_dac_start(hw); return 0; + } else if (hw->model == CTOK0010) { + hw_dac_stop(hw); + data = hw_read_20kx(hw, GPIO_DATA); + data |= 0x1000; + hw_write_20kx(hw, GPIO_DATA, data); + hw_dac_start(hw); + return 0; } /* Set DAC reset bit as output */ @@ -1756,9 +1769,11 @@ static int hw_dac_init(struct hw *hw, const struct dac_conf *info) static int hw_is_adc_input_selected(struct hw *hw, enum ADCSRC type) { u32 data; - if (hw->model == CTSB1270) { + if ((hw->model == CTSB1270) || (hw->model == CTOK0010)) { /* Titanium HD has two ADC chips, one for line in and one */ - /* for MIC. We don't need to switch the ADC input. */ + /* for MIC. Also, SE-300PCIE has a single ADC chip that */ + /* simultaneously supports 4-channel input. We don't need */ + /* to switch the ADC input. */ return 1; } data = hw_read_20kx(hw, GPIO_DATA); @@ -1826,6 +1841,32 @@ static int hw_adc_input_select(struct hw *hw, enum ADCSRC type) return 0; } +static void hw_adc_stop(struct hw *hw) +{ + u32 data; + /* Reset the ADC (reset is active low). */ + data = hw_read_20kx(hw, GPIO_DATA); + data &= ~(0x1 << 15); + hw_write_20kx(hw, GPIO_DATA, data); + usleep_range(10000, 11000); +} + +static void hw_adc_start(struct hw *hw) +{ + u32 data; + /* Return the ADC to normal operation. */ + data = hw_read_20kx(hw, GPIO_DATA); + data |= (0x1 << 15); + hw_write_20kx(hw, GPIO_DATA, data); + msleep(50); +} + +static void hw_adc_reset(struct hw *hw) +{ + hw_adc_stop(hw); + hw_adc_start(hw); +} + static int hw_adc_init(struct hw *hw, const struct adc_conf *info) { int err; @@ -1836,6 +1877,12 @@ static int hw_adc_init(struct hw *hw, const struct adc_conf *info) data |= (0x1 << 15); hw_write_20kx(hw, GPIO_CTRL, data); + if (hw->model == CTOK0010) { + /* Manual ADC setup for SE-300PCIE is not needed. */ + hw_adc_reset(hw); + return 0; + } + /* Initialize I2C */ err = hw20k2_i2c_init(hw, 0x1A, 1, 1); if (err < 0) { @@ -1843,10 +1890,7 @@ static int hw_adc_init(struct hw *hw, const struct adc_conf *info) goto error; } - /* Reset the ADC (reset is active low). */ - data = hw_read_20kx(hw, GPIO_DATA); - data &= ~(0x1 << 15); - hw_write_20kx(hw, GPIO_DATA, data); + hw_adc_stop(hw); if (hw->model == CTSB1270) { /* Set up the PCM4220 ADC on Titanium HD */ @@ -1860,11 +1904,7 @@ static int hw_adc_init(struct hw *hw, const struct adc_conf *info) hw_write_20kx(hw, GPIO_DATA, data); } - usleep_range(10000, 11000); - /* Return the ADC to normal operation. */ - data |= (0x1 << 15); - hw_write_20kx(hw, GPIO_DATA, data); - msleep(50); + hw_adc_start(hw); /* I2C write to register offset 0x0B to set ADC LRCLK polarity */ /* invert bit, interface format to I2S, word length to 24-bit, */ @@ -1910,7 +1950,8 @@ static struct capabilities hw_capabilities(struct hw *hw) struct capabilities cap; cap.digit_io_switch = 0; - cap.dedicated_mic = hw->model == CTSB1270; + cap.dedicated_mic = (hw->model == CTSB1270) || (hw->model == CTOK0010); + cap.dedicated_rca = hw->model == CTOK0010; cap.output_switch = hw->model == CTSB1270; cap.mic_source_switch = hw->model == CTSB1270; @@ -2147,15 +2188,17 @@ static int hw_card_init(struct hw *hw, struct card_conf *info) /* Reset all SRC pending interrupts */ hw_write_20kx(hw, SRC_IP, 0); - if (hw->model != CTSB1270) { + if (hw->model == CTSB1270) { + hw_write_20kx(hw, GPIO_CTRL, 0x9E5F); + } else if (hw->model == CTOK0010) { + hw_write_20kx(hw, GPIO_CTRL, 0x9902); + } else { /* TODO: detect the card ID and configure GPIO accordingly. */ /* Configures GPIO (0xD802 0x98028) */ /*hw_write_20kx(hw, GPIO_CTRL, 0x7F07);*/ /* Configures GPIO (SB0880) */ /*hw_write_20kx(hw, GPIO_CTRL, 0xFF07);*/ hw_write_20kx(hw, GPIO_CTRL, 0xD802); - } else { - hw_write_20kx(hw, GPIO_CTRL, 0x9E5F); } /* Enable audio ring */ hw_write_20kx(hw, MIXER_AR_ENABLE, 0x01); diff --git a/sound/pci/ctxfi/ctmixer.c b/sound/pci/ctxfi/ctmixer.c index 496682613db57a..fc9fde284fb39e 100644 --- a/sound/pci/ctxfi/ctmixer.c +++ b/sound/pci/ctxfi/ctmixer.c @@ -547,8 +547,14 @@ static void do_switch(struct ct_atc *atc, enum CTALSA_MIXER_CTL type, int state) atc->mic_unmute(atc, state); else if (MIXER_SPDIFI_C_S == type) atc->spdif_in_unmute(atc, state); - else if (MIXER_WAVEF_P_S == type) - atc->line_front_unmute(atc, state); + else if (MIXER_WAVEF_P_S == type) { + if (cap.dedicated_rca) { + atc->rca_unmute(atc, atc->rca_state ? 0 : state); + atc->line_front_unmute(atc, atc->rca_state ? state : 0); + } else { + atc->line_front_unmute(atc, state); + } + } else if (MIXER_WAVES_P_S == type) atc->line_surround_unmute(atc, state); else if (MIXER_WAVEC_P_S == type) @@ -612,6 +618,57 @@ static struct snd_kcontrol_new swh_ctl = { .put = ct_alsa_mix_switch_put }; +static int dedicated_rca_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *info) +{ + static const char *const names[2] = { + "RCA", "Front" + }; + + return snd_ctl_enum_info(info, 1, 2, names); +} + +static int dedicated_rca_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct ct_atc *atc = snd_kcontrol_chip(kcontrol); + + ucontrol->value.enumerated.item[0] = atc->rca_state; + return 0; +} + +static int dedicated_rca_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct ct_atc *atc = snd_kcontrol_chip(kcontrol); + unsigned int rca_state = ucontrol->value.enumerated.item[0]; + unsigned char state; + + if (rca_state > 1) + return -EINVAL; + + if (rca_state == atc->rca_state) + return 0; + + state = get_switch_state(atc->mixer, MIXER_WAVEF_P_S); + do_switch(atc, MIXER_WAVEF_P_S, 0); + + atc->rca_state = rca_state; + atc->dedicated_rca_select(atc); + + do_switch(atc, MIXER_WAVEF_P_S, state); + + return 1; +} + +static struct snd_kcontrol_new rca_ctl = { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Analog Playback Route", + .info = dedicated_rca_info, + .get = dedicated_rca_get, + .put = dedicated_rca_put, +}; + static int ct_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { @@ -784,7 +841,17 @@ static int ct_mixer_kcontrols_create(struct ct_mixer *mixer) if (err) return err; } - atc->line_front_unmute(atc, 1); + + if (cap.dedicated_rca) { + err = ct_mixer_kcontrol_new(mixer, &rca_ctl); + if (err) + return err; + + atc->line_front_unmute(atc, 0); + atc->rca_unmute(atc, 1); + } else { + atc->line_front_unmute(atc, 1); + } set_switch_state(mixer, MIXER_WAVEF_P_S, 1); atc->line_surround_unmute(atc, 0); set_switch_state(mixer, MIXER_WAVES_P_S, 0); diff --git a/sound/soc/amd/acp/acp-mach-common.c b/sound/soc/amd/acp/acp-mach-common.c index c4bc8e849284c2..4d99472c75baf0 100644 --- a/sound/soc/amd/acp/acp-mach-common.c +++ b/sound/soc/amd/acp/acp-mach-common.c @@ -116,6 +116,7 @@ static const struct snd_soc_dapm_route rt5682_map[] = { static int acp_card_rt5682_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_card *card = rtd->card; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); struct acp_card_drvdata *drvdata = card->drvdata; struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); struct snd_soc_component *component = codec_dai->component; @@ -129,7 +130,7 @@ static int acp_card_rt5682_init(struct snd_soc_pcm_runtime *rtd) drvdata->wclk = clk_get(component->dev, "rt5682-dai-wclk"); drvdata->bclk = clk_get(component->dev, "rt5682-dai-bclk"); - ret = snd_soc_dapm_new_controls(&card->dapm, rt5682_widgets, + ret = snd_soc_dapm_new_controls(dapm, rt5682_widgets, ARRAY_SIZE(rt5682_widgets)); if (ret) { dev_err(rtd->dev, "unable to add widget dapm controls, ret %d\n", ret); @@ -166,7 +167,7 @@ static int acp_card_rt5682_init(struct snd_soc_pcm_runtime *rtd) return ret; } - return snd_soc_dapm_add_routes(&rtd->card->dapm, rt5682_map, ARRAY_SIZE(rt5682_map)); + return snd_soc_dapm_add_routes(dapm, rt5682_map, ARRAY_SIZE(rt5682_map)); } static int acp_card_hs_startup(struct snd_pcm_substream *substream) @@ -357,6 +358,7 @@ static const struct snd_soc_dapm_route rt5682s_map[] = { static int acp_card_rt5682s_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_card *card = rtd->card; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); struct acp_card_drvdata *drvdata = card->drvdata; struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); struct snd_soc_component *component = codec_dai->component; @@ -372,7 +374,7 @@ static int acp_card_rt5682s_init(struct snd_soc_pcm_runtime *rtd) drvdata->bclk = clk_get(component->dev, "rt5682-dai-bclk"); } - ret = snd_soc_dapm_new_controls(&card->dapm, rt5682s_widgets, + ret = snd_soc_dapm_new_controls(dapm, rt5682s_widgets, ARRAY_SIZE(rt5682s_widgets)); if (ret) { dev_err(rtd->dev, "unable to add widget dapm controls, ret %d\n", ret); @@ -409,7 +411,7 @@ static int acp_card_rt5682s_init(struct snd_soc_pcm_runtime *rtd) return ret; } - return snd_soc_dapm_add_routes(&rtd->card->dapm, rt5682s_map, ARRAY_SIZE(rt5682s_map)); + return snd_soc_dapm_add_routes(dapm, rt5682s_map, ARRAY_SIZE(rt5682s_map)); } static int acp_card_rt5682s_hw_params(struct snd_pcm_substream *substream, @@ -581,13 +583,14 @@ static struct snd_soc_codec_conf rt1019_conf[] = { static int acp_card_rt1019_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_card *card = rtd->card; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); struct acp_card_drvdata *drvdata = card->drvdata; int ret; if (drvdata->amp_codec_id != RT1019) return -EINVAL; - ret = snd_soc_dapm_new_controls(&card->dapm, rt1019_widgets, + ret = snd_soc_dapm_new_controls(dapm, rt1019_widgets, ARRAY_SIZE(rt1019_widgets)); if (ret) { dev_err(rtd->dev, "unable to add widget dapm controls, ret %d\n", ret); @@ -601,7 +604,7 @@ static int acp_card_rt1019_init(struct snd_soc_pcm_runtime *rtd) return ret; } - return snd_soc_dapm_add_routes(&rtd->card->dapm, rt1019_map_lr, + return snd_soc_dapm_add_routes(dapm, rt1019_map_lr, ARRAY_SIZE(rt1019_map_lr)); } @@ -746,13 +749,14 @@ static const struct snd_soc_dapm_route max98360a_map[] = { static int acp_card_maxim_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_card *card = rtd->card; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); struct acp_card_drvdata *drvdata = card->drvdata; int ret; if (drvdata->amp_codec_id != MAX98360A) return -EINVAL; - ret = snd_soc_dapm_new_controls(&card->dapm, max98360a_widgets, + ret = snd_soc_dapm_new_controls(dapm, max98360a_widgets, ARRAY_SIZE(max98360a_widgets)); if (ret) { dev_err(rtd->dev, "unable to add widget dapm controls, ret %d\n", ret); @@ -766,7 +770,7 @@ static int acp_card_maxim_init(struct snd_soc_pcm_runtime *rtd) return ret; } - return snd_soc_dapm_add_routes(&rtd->card->dapm, max98360a_map, + return snd_soc_dapm_add_routes(dapm, max98360a_map, ARRAY_SIZE(max98360a_map)); } @@ -882,13 +886,14 @@ static int acp_card_max98388_startup(struct snd_pcm_substream *substream) static int acp_card_max98388_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_card *card = rtd->card; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); struct acp_card_drvdata *drvdata = card->drvdata; int ret; if (drvdata->amp_codec_id != MAX98388) return -EINVAL; - ret = snd_soc_dapm_new_controls(&card->dapm, max98388_widgets, + ret = snd_soc_dapm_new_controls(dapm, max98388_widgets, ARRAY_SIZE(max98388_widgets)); if (ret) { @@ -904,7 +909,7 @@ static int acp_card_max98388_init(struct snd_soc_pcm_runtime *rtd) return ret; } - return snd_soc_dapm_add_routes(&rtd->card->dapm, max98388_map, + return snd_soc_dapm_add_routes(dapm, max98388_map, ARRAY_SIZE(max98388_map)); } @@ -966,6 +971,7 @@ static const struct snd_soc_dapm_route nau8825_map[] = { static int acp_card_nau8825_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_card *card = rtd->card; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); struct acp_card_drvdata *drvdata = card->drvdata; struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); struct snd_soc_component *component = codec_dai->component; @@ -976,7 +982,7 @@ static int acp_card_nau8825_init(struct snd_soc_pcm_runtime *rtd) if (drvdata->hs_codec_id != NAU8825) return -EINVAL; - ret = snd_soc_dapm_new_controls(&card->dapm, nau8825_widgets, + ret = snd_soc_dapm_new_controls(dapm, nau8825_widgets, ARRAY_SIZE(nau8825_widgets)); if (ret) { dev_err(rtd->dev, "unable to add widget dapm controls, ret %d\n", ret); @@ -1013,7 +1019,7 @@ static int acp_card_nau8825_init(struct snd_soc_pcm_runtime *rtd) return ret; } - return snd_soc_dapm_add_routes(&rtd->card->dapm, nau8825_map, ARRAY_SIZE(nau8825_map)); + return snd_soc_dapm_add_routes(dapm, nau8825_map, ARRAY_SIZE(nau8825_map)); } static int acp_nau8825_hw_params(struct snd_pcm_substream *substream, @@ -1102,8 +1108,7 @@ static const struct snd_soc_ops acp_card_nau8825_ops = { static int platform_clock_control(struct snd_soc_dapm_widget *w, struct snd_kcontrol *k, int event) { - struct snd_soc_dapm_context *dapm = w->dapm; - struct snd_soc_card *card = dapm->card; + struct snd_soc_card *card = snd_soc_dapm_to_card(w->dapm); struct snd_soc_dai *codec_dai; int ret = 0; @@ -1181,13 +1186,14 @@ static struct snd_pcm_hw_constraint_list constraints_sample_bits = { static int acp_8821_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_card *card = rtd->card; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); struct snd_soc_component *component = codec_dai->component; int ret; dev_info(rtd->dev, "codec dai name = %s\n", codec_dai->name); - ret = snd_soc_dapm_new_controls(&card->dapm, nau8821_widgets, + ret = snd_soc_dapm_new_controls(dapm, nau8821_widgets, ARRAY_SIZE(nau8821_widgets)); if (ret) { dev_err(rtd->dev, "unable to add widget dapm controls, ret %d\n", ret); @@ -1221,7 +1227,7 @@ static int acp_8821_init(struct snd_soc_pcm_runtime *rtd) nau8821_enable_jack_detect(component, &nau8821_jack); - return snd_soc_dapm_add_routes(&rtd->card->dapm, nau8821_audio_route, + return snd_soc_dapm_add_routes(dapm, nau8821_audio_route, ARRAY_SIZE(nau8821_audio_route)); } @@ -1340,7 +1346,7 @@ static int acp_rtk_set_bias_level(struct snd_soc_card *card, struct snd_soc_dapm_context *dapm, enum snd_soc_bias_level level) { - struct snd_soc_component *component = dapm->component; + struct snd_soc_component *component = snd_soc_dapm_to_component(dapm); struct acp_card_drvdata *drvdata = card->drvdata; int ret = 0; diff --git a/sound/soc/amd/acp/acp-sdw-legacy-mach.c b/sound/soc/amd/acp/acp-sdw-legacy-mach.c index 54f823f7cecffd..fae94b9edd5a3f 100644 --- a/sound/soc/amd/acp/acp-sdw-legacy-mach.c +++ b/sound/soc/amd/acp/acp-sdw-legacy-mach.c @@ -360,20 +360,25 @@ static int soc_card_dai_links_create(struct snd_soc_card *card) struct snd_soc_acpi_mach_params *mach_params = &mach->mach_params; struct asoc_sdw_endpoint *soc_ends __free(kfree) = NULL; struct asoc_sdw_dailink *soc_dais __free(kfree) = NULL; + struct snd_soc_aux_dev *soc_aux; struct snd_soc_codec_conf *codec_conf; struct snd_soc_dai_link *dai_links; int num_devs = 0; int num_ends = 0; + int num_aux = 0; + int num_confs; int num_links; int be_id = 0; int ret; - ret = asoc_sdw_count_sdw_endpoints(card, &num_devs, &num_ends); + ret = asoc_sdw_count_sdw_endpoints(card, &num_devs, &num_ends, &num_aux); if (ret < 0) { dev_err(dev, "failed to count devices/endpoints: %d\n", ret); return ret; } + num_confs = num_ends; + /* One per DAI link, worst case is a DAI link for every endpoint */ soc_dais = kcalloc(num_ends, sizeof(*soc_dais), GFP_KERNEL); if (!soc_dais) @@ -384,7 +389,11 @@ static int soc_card_dai_links_create(struct snd_soc_card *card) if (!soc_ends) return -ENOMEM; - ret = asoc_sdw_parse_sdw_endpoints(card, soc_dais, soc_ends, &num_devs); + soc_aux = devm_kcalloc(dev, num_aux, sizeof(*soc_aux), GFP_KERNEL); + if (!soc_aux) + return -ENOMEM; + + ret = asoc_sdw_parse_sdw_endpoints(card, soc_aux, soc_dais, soc_ends, &num_confs); if (ret < 0) return ret; @@ -396,7 +405,7 @@ static int soc_card_dai_links_create(struct snd_soc_card *card) dev_dbg(dev, "sdw %d, dmic %d", sdw_be_num, dmic_num); - codec_conf = devm_kcalloc(dev, num_devs, sizeof(*codec_conf), GFP_KERNEL); + codec_conf = devm_kcalloc(dev, num_confs, sizeof(*codec_conf), GFP_KERNEL); if (!codec_conf) return -ENOMEM; @@ -407,9 +416,11 @@ static int soc_card_dai_links_create(struct snd_soc_card *card) return -ENOMEM; card->codec_conf = codec_conf; - card->num_configs = num_devs; + card->num_configs = num_confs; card->dai_link = dai_links; card->num_links = num_links; + card->aux_dev = soc_aux; + card->num_aux_devs = num_aux; /* SDW */ if (sdw_be_num) { diff --git a/sound/soc/amd/acp/acp-sdw-sof-mach.c b/sound/soc/amd/acp/acp-sdw-sof-mach.c index d055582a3bf1ad..5677ae63fca921 100644 --- a/sound/soc/amd/acp/acp-sdw-sof-mach.c +++ b/sound/soc/amd/acp/acp-sdw-sof-mach.c @@ -272,15 +272,17 @@ static int sof_card_dai_links_create(struct snd_soc_card *card) struct snd_soc_acpi_mach_params *mach_params = &mach->mach_params; struct asoc_sdw_endpoint *sof_ends __free(kfree) = NULL; struct asoc_sdw_dailink *sof_dais __free(kfree) = NULL; + struct snd_soc_aux_dev *sof_aux; struct snd_soc_codec_conf *codec_conf; struct snd_soc_dai_link *dai_links; int num_devs = 0; int num_ends = 0; + int num_aux = 0; int num_links; int be_id = 0; int ret; - ret = asoc_sdw_count_sdw_endpoints(card, &num_devs, &num_ends); + ret = asoc_sdw_count_sdw_endpoints(card, &num_devs, &num_ends, &num_aux); if (ret < 0) { dev_err(dev, "failed to count devices/endpoints: %d\n", ret); return ret; @@ -296,7 +298,11 @@ static int sof_card_dai_links_create(struct snd_soc_card *card) if (!sof_ends) return -ENOMEM; - ret = asoc_sdw_parse_sdw_endpoints(card, sof_dais, sof_ends, &num_devs); + sof_aux = devm_kcalloc(dev, num_aux, sizeof(*sof_aux), GFP_KERNEL); + if (!sof_aux) + return -ENOMEM; + + ret = asoc_sdw_parse_sdw_endpoints(card, sof_aux, sof_dais, sof_ends, &num_devs); if (ret < 0) return ret; @@ -322,6 +328,8 @@ static int sof_card_dai_links_create(struct snd_soc_card *card) card->num_configs = num_devs; card->dai_link = dai_links; card->num_links = num_links; + card->aux_dev = sof_aux; + card->num_aux_devs = num_aux; /* SDW */ if (sdw_be_num) { diff --git a/sound/soc/amd/acp/acp3x-es83xx/acp3x-es83xx.c b/sound/soc/amd/acp/acp3x-es83xx/acp3x-es83xx.c index eb5d4a5baef241..141ea4787d999a 100644 --- a/sound/soc/amd/acp/acp3x-es83xx/acp3x-es83xx.c +++ b/sound/soc/amd/acp/acp3x-es83xx/acp3x-es83xx.c @@ -159,7 +159,8 @@ static int acp3x_es83xx_configure_widgets(struct snd_soc_card *card) static int acp3x_es83xx_headphone_power_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct acp3x_es83xx_private *priv = get_mach_priv(w->dapm->card); + struct snd_soc_card *card = snd_soc_dapm_to_card(w->dapm); + struct acp3x_es83xx_private *priv = get_mach_priv(card); dev_dbg(priv->codec_dev, "headphone power event = %d\n", event); if (SND_SOC_DAPM_EVENT_ON(event)) @@ -176,7 +177,8 @@ static int acp3x_es83xx_headphone_power_event(struct snd_soc_dapm_widget *w, static int acp3x_es83xx_speaker_power_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct acp3x_es83xx_private *priv = get_mach_priv(w->dapm->card); + struct snd_soc_card *card = snd_soc_dapm_to_card(w->dapm); + struct acp3x_es83xx_private *priv = get_mach_priv(card); dev_dbg(priv->codec_dev, "speaker power event: %d\n", event); if (SND_SOC_DAPM_EVENT_ON(event)) @@ -314,7 +316,9 @@ static int acp3x_es83xx_init(struct snd_soc_pcm_runtime *runtime) num_routes = acp3x_es83xx_configure_mics(priv); if (num_routes > 0) { - ret = snd_soc_dapm_add_routes(&card->dapm, priv->mic_map, num_routes); + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); + + ret = snd_soc_dapm_add_routes(dapm, priv->mic_map, num_routes); if (ret != 0) device_remove_software_node(priv->codec_dev); } diff --git a/sound/soc/amd/vangogh/acp5x-mach.c b/sound/soc/amd/vangogh/acp5x-mach.c index 2ca904db82abe1..5454de24fbcc7e 100644 --- a/sound/soc/amd/vangogh/acp5x-mach.c +++ b/sound/soc/amd/vangogh/acp5x-mach.c @@ -61,8 +61,7 @@ static const struct snd_kcontrol_new acp5x_8821_controls[] = { static int platform_clock_control(struct snd_soc_dapm_widget *w, struct snd_kcontrol *k, int event) { - struct snd_soc_dapm_context *dapm = w->dapm; - struct snd_soc_card *card = dapm->card; + struct snd_soc_card *card = snd_soc_dapm_to_card(w->dapm); struct snd_soc_dai *dai; int ret = 0; diff --git a/sound/soc/atmel/sam9g20_wm8731.c b/sound/soc/atmel/sam9g20_wm8731.c index 335e216ea7b403..be54a63f43d560 100644 --- a/sound/soc/atmel/sam9g20_wm8731.c +++ b/sound/soc/atmel/sam9g20_wm8731.c @@ -80,7 +80,7 @@ static int at91sam9g20ek_wm8731_init(struct snd_soc_pcm_runtime *rtd) } #ifndef ENABLE_MIC_INPUT - snd_soc_dapm_nc_pin(&rtd->card->dapm, "Int Mic"); + snd_soc_dapm_disable_pin(snd_soc_card_to_dapm(rtd->card), "Int Mic"); #endif return 0; diff --git a/sound/soc/atmel/tse850-pcm5142.c b/sound/soc/atmel/tse850-pcm5142.c index 2a1d0408a4cf19..0b4927d07f25c8 100644 --- a/sound/soc/atmel/tse850-pcm5142.c +++ b/sound/soc/atmel/tse850-pcm5142.c @@ -58,8 +58,8 @@ struct tse850_priv { static int tse850_get_mux1(struct snd_kcontrol *kctrl, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kctrl); - struct snd_soc_card *card = dapm->card; + struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kctrl); + struct snd_soc_card *card = snd_soc_dapm_to_card(dapm); struct tse850_priv *tse850 = snd_soc_card_get_drvdata(card); ucontrol->value.enumerated.item[0] = tse850->loop1_cache; @@ -70,8 +70,8 @@ static int tse850_get_mux1(struct snd_kcontrol *kctrl, static int tse850_put_mux1(struct snd_kcontrol *kctrl, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kctrl); - struct snd_soc_card *card = dapm->card; + struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kctrl); + struct snd_soc_card *card = snd_soc_dapm_to_card(dapm); struct tse850_priv *tse850 = snd_soc_card_get_drvdata(card); struct soc_enum *e = (struct soc_enum *)kctrl->private_value; unsigned int val = ucontrol->value.enumerated.item[0]; @@ -88,8 +88,8 @@ static int tse850_put_mux1(struct snd_kcontrol *kctrl, static int tse850_get_mux2(struct snd_kcontrol *kctrl, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kctrl); - struct snd_soc_card *card = dapm->card; + struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kctrl); + struct snd_soc_card *card = snd_soc_dapm_to_card(dapm); struct tse850_priv *tse850 = snd_soc_card_get_drvdata(card); ucontrol->value.enumerated.item[0] = tse850->loop2_cache; @@ -100,8 +100,8 @@ static int tse850_get_mux2(struct snd_kcontrol *kctrl, static int tse850_put_mux2(struct snd_kcontrol *kctrl, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kctrl); - struct snd_soc_card *card = dapm->card; + struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kctrl); + struct snd_soc_card *card = snd_soc_dapm_to_card(dapm); struct tse850_priv *tse850 = snd_soc_card_get_drvdata(card); struct soc_enum *e = (struct soc_enum *)kctrl->private_value; unsigned int val = ucontrol->value.enumerated.item[0]; @@ -118,8 +118,8 @@ static int tse850_put_mux2(struct snd_kcontrol *kctrl, static int tse850_get_mix(struct snd_kcontrol *kctrl, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kctrl); - struct snd_soc_card *card = dapm->card; + struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kctrl); + struct snd_soc_card *card = snd_soc_dapm_to_card(dapm); struct tse850_priv *tse850 = snd_soc_card_get_drvdata(card); ucontrol->value.enumerated.item[0] = tse850->add_cache; @@ -130,8 +130,8 @@ static int tse850_get_mix(struct snd_kcontrol *kctrl, static int tse850_put_mix(struct snd_kcontrol *kctrl, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kctrl); - struct snd_soc_card *card = dapm->card; + struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kctrl); + struct snd_soc_card *card = snd_soc_dapm_to_card(dapm); struct tse850_priv *tse850 = snd_soc_card_get_drvdata(card); int connect = !!ucontrol->value.integer.value[0]; @@ -152,8 +152,8 @@ static int tse850_put_mix(struct snd_kcontrol *kctrl, static int tse850_get_ana(struct snd_kcontrol *kctrl, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kctrl); - struct snd_soc_card *card = dapm->card; + struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kctrl); + struct snd_soc_card *card = snd_soc_dapm_to_card(dapm); struct tse850_priv *tse850 = snd_soc_card_get_drvdata(card); int ret; @@ -185,8 +185,8 @@ static int tse850_get_ana(struct snd_kcontrol *kctrl, static int tse850_put_ana(struct snd_kcontrol *kctrl, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kctrl); - struct snd_soc_card *card = dapm->card; + struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kctrl); + struct snd_soc_card *card = snd_soc_dapm_to_card(dapm); struct tse850_priv *tse850 = snd_soc_card_get_drvdata(card); struct soc_enum *e = (struct soc_enum *)kctrl->private_value; unsigned int uV = ucontrol->value.enumerated.item[0]; diff --git a/sound/soc/codecs/88pm860x-codec.c b/sound/soc/codecs/88pm860x-codec.c index 58e35da2f85e2c..b4f5b24cde4562 100644 --- a/sound/soc/codecs/88pm860x-codec.c +++ b/sound/soc/codecs/88pm860x-codec.c @@ -1106,6 +1106,7 @@ static int pm860x_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { struct pm860x_priv *pm860x = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); int data; switch (level) { @@ -1116,7 +1117,7 @@ static int pm860x_set_bias_level(struct snd_soc_component *component, break; case SND_SOC_BIAS_STANDBY: - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) { /* Enable Audio PLL & Audio section */ data = AUDIO_PLL | AUDIO_SECTION_ON; pm860x_reg_write(pm860x->i2c, REG_MISC2, data); diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 6da2fff9323c25..6087ebde9523eb 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -171,6 +171,7 @@ config SND_SOC_ALL_CODECS imply SND_SOC_MT6359 imply SND_SOC_MT6660 imply SND_SOC_NAU8315 + imply SND_SOC_NAU8325 imply SND_SOC_NAU8540 imply SND_SOC_NAU8810 imply SND_SOC_NAU8821 @@ -912,6 +913,20 @@ config SND_SOC_CS35L56_CAL_DEBUGFS Create debugfs entries used during factory-line manufacture for factory calibration. + If unsure select "N". + +config SND_SOC_CS35L56_CAL_SET_CTRL + bool "CS35L56 ALSA control to restore factory calibration" + default N + select SND_SOC_CS35L56_CAL_SYSFS_COMMON + help + Allow restoring factory calibration data through an ALSA + control. This is only needed on platforms without UEFI or + some other method of non-volatile storage that the driver + can access directly. + + On most platforms this is not needed. + If unsure select "N". endmenu @@ -2340,6 +2355,7 @@ config SND_SOC_WCD934X tristate "WCD9340/WCD9341 Codec" depends on COMMON_CLK depends on SLIMBUS + depends on SOUNDWIRE || !SOUNDWIRE select REGMAP_IRQ select REGMAP_SLIMBUS select SND_SOC_WCD_CLASSH @@ -2745,6 +2761,10 @@ config SND_SOC_MT6660 config SND_SOC_NAU8315 tristate "Nuvoton Technology Corporation NAU8315 CODEC" +config SND_SOC_NAU8325 + tristate "Nuvoton Technology Corporation NAU8325 CODEC" + depends on I2C + config SND_SOC_NAU8540 tristate "Nuvoton Technology Corporation NAU85L40 CODEC" depends on I2C diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 39138d96a7205d..d687d4f743639b 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -50,9 +50,9 @@ snd-soc-audio-iio-aux-y := audio-iio-aux.o snd-soc-aw8738-y := aw8738.o snd-soc-aw87390-y := aw87390.o snd-soc-aw88081-y := aw88081.o -snd-soc-aw88395-lib-y := aw88395/aw88395_lib.o -snd-soc-aw88395-y := aw88395/aw88395.o \ +snd-soc-aw88395-lib-y := aw88395/aw88395_lib.o \ aw88395/aw88395_device.o +snd-soc-aw88395-y := aw88395/aw88395.o snd-soc-aw88166-y := aw88166.o snd-soc-aw88261-y := aw88261.o snd-soc-aw88399-y := aw88399.o @@ -193,6 +193,7 @@ snd-soc-mt6359-y := mt6359.o snd-soc-mt6359-accdet-y := mt6359-accdet.o snd-soc-mt6660-y := mt6660.o snd-soc-nau8315-y := nau8315.o +snd-soc-nau8325-y := nau8325.o snd-soc-nau8540-y := nau8540.o snd-soc-nau8810-y := nau8810.o snd-soc-nau8821-y := nau8821.o @@ -620,6 +621,7 @@ obj-$(CONFIG_SND_SOC_MT6359) += snd-soc-mt6359.o obj-$(CONFIG_SND_SOC_MT6359_ACCDET) += mt6359-accdet.o obj-$(CONFIG_SND_SOC_MT6660) += snd-soc-mt6660.o obj-$(CONFIG_SND_SOC_NAU8315) += snd-soc-nau8315.o +obj-$(CONFIG_SND_SOC_NAU8325) += snd-soc-nau8325.o obj-$(CONFIG_SND_SOC_NAU8540) += snd-soc-nau8540.o obj-$(CONFIG_SND_SOC_NAU8810) += snd-soc-nau8810.o obj-$(CONFIG_SND_SOC_NAU8821) += snd-soc-nau8821.o diff --git a/sound/soc/codecs/ab8500-codec.c b/sound/soc/codecs/ab8500-codec.c index 14d0378bfe7255..fdda1b747bf7e5 100644 --- a/sound/soc/codecs/ab8500-codec.c +++ b/sound/soc/codecs/ab8500-codec.c @@ -1197,7 +1197,7 @@ static int anc_status_control_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(component->dev); struct device *dev = component->dev; bool apply_fir, apply_iir; @@ -1934,7 +1934,7 @@ static int ab8500_audio_init_audioblock(struct snd_soc_component *component) static int ab8500_audio_setup_mics(struct snd_soc_component *component, struct amic_settings *amics) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); u8 value8; unsigned int value; int status; @@ -2449,7 +2449,7 @@ static void ab8500_codec_of_probe(struct device *dev, struct device_node *np, static int ab8500_codec_probe(struct snd_soc_component *component) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct device *dev = component->dev; struct device_node *np = dev->of_node; struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(dev); diff --git a/sound/soc/codecs/ad1836.c b/sound/soc/codecs/ad1836.c index 949077108bef4f..8afeadcaf8b09f 100644 --- a/sound/soc/codecs/ad1836.c +++ b/sound/soc/codecs/ad1836.c @@ -250,7 +250,7 @@ static int ad1836_resume(struct snd_soc_component *component) static int ad1836_probe(struct snd_soc_component *component) { struct ad1836_priv *ad1836 = snd_soc_component_get_drvdata(component); - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); int num_dacs, num_adcs; int ret = 0; int i; diff --git a/sound/soc/codecs/ad193x.c b/sound/soc/codecs/ad193x.c index 1d3c4d94b4ae91..b93531c3a9a401 100644 --- a/sound/soc/codecs/ad193x.c +++ b/sound/soc/codecs/ad193x.c @@ -282,7 +282,7 @@ static int ad193x_set_dai_sysclk(struct snd_soc_dai *codec_dai, int clk_id, unsigned int freq, int dir) { struct snd_soc_component *component = codec_dai->component; - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct ad193x_priv *ad193x = snd_soc_component_get_drvdata(component); if (clk_id == AD193X_SYSCLK_MCLK) { @@ -476,7 +476,7 @@ static void ad193x_reg_default_init(struct ad193x_priv *ad193x) static int ad193x_component_probe(struct snd_soc_component *component) { struct ad193x_priv *ad193x = snd_soc_component_get_drvdata(component); - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); int num, ret; /* default setting for ad193x */ diff --git a/sound/soc/codecs/adau1761.c b/sound/soc/codecs/adau1761.c index 1f09ea385f8af9..a70c46dd5d76fd 100644 --- a/sound/soc/codecs/adau1761.c +++ b/sound/soc/codecs/adau1761.c @@ -621,6 +621,7 @@ static int adau1761_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { struct adau *adau = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); switch (level) { case SND_SOC_BIAS_ON: @@ -632,7 +633,7 @@ static int adau1761_set_bias_level(struct snd_soc_component *component, regmap_update_bits(adau->regmap, ADAU17X1_CLOCK_CONTROL, ADAU17X1_CLOCK_CONTROL_SYSCLK_EN, ADAU17X1_CLOCK_CONTROL_SYSCLK_EN); - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) regcache_sync(adau->regmap); break; case SND_SOC_BIAS_OFF: @@ -658,7 +659,7 @@ static enum adau1761_output_mode adau1761_get_lineout_mode( static int adau1761_setup_digmic_jackdetect(struct snd_soc_component *component) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct adau1761_platform_data *pdata = component->dev->platform_data; struct adau *adau = snd_soc_component_get_drvdata(component); enum adau1761_digmic_jackdet_pin_mode mode; @@ -721,7 +722,7 @@ static int adau1761_setup_digmic_jackdetect(struct snd_soc_component *component) static int adau1761_setup_headphone_mode(struct snd_soc_component *component) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct adau *adau = snd_soc_component_get_drvdata(component); struct adau1761_platform_data *pdata = component->dev->platform_data; enum adau1761_output_mode mode; @@ -819,7 +820,7 @@ static bool adau1761_readable_register(struct device *dev, unsigned int reg) static int adau1761_component_probe(struct snd_soc_component *component) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct adau1761_platform_data *pdata = component->dev->platform_data; struct adau *adau = snd_soc_component_get_drvdata(component); int ret; diff --git a/sound/soc/codecs/adau1781.c b/sound/soc/codecs/adau1781.c index faad2f9f8dd2b2..38cc0b6e41227e 100644 --- a/sound/soc/codecs/adau1781.c +++ b/sound/soc/codecs/adau1781.c @@ -381,7 +381,7 @@ static int adau1781_set_input_mode(struct adau *adau, unsigned int reg, static int adau1781_component_probe(struct snd_soc_component *component) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct adau1781_platform_data *pdata = dev_get_platdata(component->dev); struct adau *adau = snd_soc_component_get_drvdata(component); int ret; diff --git a/sound/soc/codecs/adau17x1.c b/sound/soc/codecs/adau17x1.c index 0b6b0d2115eb07..26d7eb437ad183 100644 --- a/sound/soc/codecs/adau17x1.c +++ b/sound/soc/codecs/adau17x1.c @@ -185,8 +185,8 @@ static const struct snd_soc_dapm_route adau17x1_dapm_pll_route = { static int adau17x1_dsp_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_component *component = snd_soc_dapm_kcontrol_component(kcontrol); - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_component *component = snd_soc_dapm_kcontrol_to_component(kcontrol); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct adau *adau = snd_soc_component_get_drvdata(component); struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; struct snd_soc_dapm_update update = {}; @@ -230,7 +230,7 @@ static int adau17x1_dsp_mux_enum_put(struct snd_kcontrol *kcontrol, static int adau17x1_dsp_mux_enum_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_component *component = snd_soc_dapm_kcontrol_component(kcontrol); + struct snd_soc_component *component = snd_soc_dapm_kcontrol_to_component(kcontrol); struct adau *adau = snd_soc_component_get_drvdata(component); struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; unsigned int stream = e->shift_l; @@ -383,7 +383,7 @@ static int adau17x1_set_dai_pll(struct snd_soc_dai *dai, int pll_id, static int adau17x1_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id, unsigned int freq, int dir) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(dai->component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(dai->component); struct adau *adau = snd_soc_component_get_drvdata(dai->component); bool is_pll; bool was_pll; @@ -881,7 +881,7 @@ static int adau17x1_setup_firmware(struct snd_soc_component *component, int ret; int dspsr, dsp_run; struct adau *adau = snd_soc_component_get_drvdata(component); - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); /* Check if sample rate is the same as before. If it is there is no * point in performing the below steps as the call to @@ -922,7 +922,7 @@ static int adau17x1_setup_firmware(struct snd_soc_component *component, int adau17x1_add_widgets(struct snd_soc_component *component) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct adau *adau = snd_soc_component_get_drvdata(component); int ret; @@ -958,7 +958,7 @@ EXPORT_SYMBOL_GPL(adau17x1_add_widgets); int adau17x1_add_routes(struct snd_soc_component *component) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct adau *adau = snd_soc_component_get_drvdata(component); int ret; diff --git a/sound/soc/codecs/adau1977.c b/sound/soc/codecs/adau1977.c index c193a9f22f5901..b42f35b1a60367 100644 --- a/sound/soc/codecs/adau1977.c +++ b/sound/soc/codecs/adau1977.c @@ -473,6 +473,7 @@ static int adau1977_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { struct adau1977 *adau1977 = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); int ret = 0; switch (level) { @@ -481,7 +482,7 @@ static int adau1977_set_bias_level(struct snd_soc_component *component, case SND_SOC_BIAS_PREPARE: break; case SND_SOC_BIAS_STANDBY: - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) ret = adau1977_power_enable(adau1977); break; case SND_SOC_BIAS_OFF: @@ -845,7 +846,7 @@ static int adau1977_set_sysclk(struct snd_soc_component *component, static int adau1977_component_probe(struct snd_soc_component *component) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct adau1977 *adau1977 = snd_soc_component_get_drvdata(component); int ret; diff --git a/sound/soc/codecs/adau7118.c b/sound/soc/codecs/adau7118.c index 14259807c87253..5ddea63a6612c9 100644 --- a/sound/soc/codecs/adau7118.c +++ b/sound/soc/codecs/adau7118.c @@ -335,6 +335,7 @@ static int adau7118_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { struct adau7118_data *st = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); int ret = 0; dev_dbg(st->dev, "Set bias level %d\n", level); @@ -345,8 +346,7 @@ static int adau7118_set_bias_level(struct snd_soc_component *component, break; case SND_SOC_BIAS_STANDBY: - if (snd_soc_component_get_bias_level(component) == - SND_SOC_BIAS_OFF) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) { /* power on */ ret = regulator_enable(st->iovdd); if (ret) @@ -393,8 +393,7 @@ static int adau7118_set_bias_level(struct snd_soc_component *component, static int adau7118_component_probe(struct snd_soc_component *component) { struct adau7118_data *st = snd_soc_component_get_drvdata(component); - struct snd_soc_dapm_context *dapm = - snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); int ret = 0; if (st->hw_mode) { diff --git a/sound/soc/codecs/adav80x.c b/sound/soc/codecs/adav80x.c index c9c41496c17dd5..8a89187f9c7825 100644 --- a/sound/soc/codecs/adav80x.c +++ b/sound/soc/codecs/adav80x.c @@ -539,7 +539,7 @@ static int adav80x_set_sysclk(struct snd_soc_component *component, unsigned int freq, int dir) { struct adav80x *adav80x = snd_soc_component_get_drvdata(component); - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); if (dir == SND_SOC_CLOCK_IN) { switch (clk_id) { @@ -622,7 +622,7 @@ static int adav80x_set_sysclk(struct snd_soc_component *component, static int adav80x_set_pll(struct snd_soc_component *component, int pll_id, int source, unsigned int freq_in, unsigned int freq_out) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct adav80x *adav80x = snd_soc_component_get_drvdata(component); unsigned int pll_ctrl1 = 0; unsigned int pll_ctrl2 = 0; @@ -802,7 +802,7 @@ static struct snd_soc_dai_driver adav80x_dais[] = { static int adav80x_probe(struct snd_soc_component *component) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct adav80x *adav80x = snd_soc_component_get_drvdata(component); /* Force PLLs on for SYSCLK output */ diff --git a/sound/soc/codecs/ak4641.c b/sound/soc/codecs/ak4641.c index 53c5d3f50353fe..9db8cdb26d33a5 100644 --- a/sound/soc/codecs/ak4641.c +++ b/sound/soc/codecs/ak4641.c @@ -415,6 +415,7 @@ static int ak4641_mute(struct snd_soc_dai *dai, int mute, int direction) static int ak4641_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct ak4641_priv *ak4641 = snd_soc_component_get_drvdata(component); struct ak4641_platform_data *pdata = component->dev->platform_data; int ret; @@ -429,7 +430,7 @@ static int ak4641_set_bias_level(struct snd_soc_component *component, snd_soc_component_update_bits(component, AK4641_DAC, 0x20, 0x20); break; case SND_SOC_BIAS_STANDBY: - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) { if (pdata && gpio_is_valid(pdata->gpio_power)) gpio_set_value(pdata->gpio_power, 1); mdelay(1); diff --git a/sound/soc/codecs/alc5623.c b/sound/soc/codecs/alc5623.c index fbf72375807970..a9946dcdc9f69c 100644 --- a/sound/soc/codecs/alc5623.c +++ b/sound/soc/codecs/alc5623.c @@ -888,7 +888,7 @@ static int alc5623_resume(struct snd_soc_component *component) static int alc5623_probe(struct snd_soc_component *component) { struct alc5623_priv *alc5623 = snd_soc_component_get_drvdata(component); - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); alc5623_reset(component); diff --git a/sound/soc/codecs/arizona-jack.c b/sound/soc/codecs/arizona-jack.c index 6b55610ad535d6..303c1d44ebd8cf 100644 --- a/sound/soc/codecs/arizona-jack.c +++ b/sound/soc/codecs/arizona-jack.c @@ -212,17 +212,16 @@ static void arizona_extcon_pulse_micbias(struct arizona_priv *info) struct arizona *arizona = info->arizona; const char *widget = arizona_extcon_get_micbias(info); struct snd_soc_dapm_context *dapm = arizona->dapm; - struct snd_soc_component *component = snd_soc_dapm_to_component(dapm); int ret; - ret = snd_soc_component_force_enable_pin(component, widget); + ret = snd_soc_dapm_force_enable_pin(dapm, widget); if (ret) dev_warn(arizona->dev, "Failed to enable %s: %d\n", widget, ret); snd_soc_dapm_sync(dapm); if (!arizona->pdata.micd_force_micbias) { - ret = snd_soc_component_disable_pin(component, widget); + ret = snd_soc_dapm_disable_pin(dapm, widget); if (ret) dev_warn(arizona->dev, "Failed to disable %s: %d\n", widget, ret); @@ -287,7 +286,6 @@ static void arizona_stop_mic(struct arizona_priv *info) struct arizona *arizona = info->arizona; const char *widget = arizona_extcon_get_micbias(info); struct snd_soc_dapm_context *dapm = arizona->dapm; - struct snd_soc_component *component = snd_soc_dapm_to_component(dapm); bool change = false; int ret; @@ -297,7 +295,7 @@ static void arizona_stop_mic(struct arizona_priv *info) if (ret < 0) dev_err(arizona->dev, "Failed to disable micd: %d\n", ret); - ret = snd_soc_component_disable_pin(component, widget); + ret = snd_soc_dapm_disable_pin(dapm, widget); if (ret) dev_warn(arizona->dev, "Failed to disable %s: %d\n", widget, ret); diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c index 99884dc6ff86e2..8c683b0bb74c4c 100644 --- a/sound/soc/codecs/arizona.c +++ b/sound/soc/codecs/arizona.c @@ -169,7 +169,7 @@ static const struct snd_soc_dapm_widget arizona_spkr = int arizona_init_spk(struct snd_soc_component *component) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct arizona_priv *priv = snd_soc_component_get_drvdata(component); struct arizona *arizona = priv->arizona; int ret; @@ -238,7 +238,7 @@ static const struct snd_soc_dapm_route arizona_mono_routes[] = { int arizona_init_mono(struct snd_soc_component *component) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct arizona_priv *priv = snd_soc_component_get_drvdata(component); struct arizona *arizona = priv->arizona; int i; @@ -255,6 +255,7 @@ EXPORT_SYMBOL_GPL(arizona_init_mono); int arizona_init_gpio(struct snd_soc_component *component) { + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct arizona_priv *priv = snd_soc_component_get_drvdata(component); struct arizona *arizona = priv->arizona; int i; @@ -262,24 +263,21 @@ int arizona_init_gpio(struct snd_soc_component *component) switch (arizona->type) { case WM5110: case WM8280: - snd_soc_component_disable_pin(component, - "DRC2 Signal Activity"); + snd_soc_dapm_disable_pin(dapm, "DRC2 Signal Activity"); break; default: break; } - snd_soc_component_disable_pin(component, "DRC1 Signal Activity"); + snd_soc_dapm_disable_pin(dapm, "DRC1 Signal Activity"); for (i = 0; i < ARRAY_SIZE(arizona->pdata.gpio_defaults); i++) { switch (arizona->pdata.gpio_defaults[i] & ARIZONA_GPN_FN_MASK) { case ARIZONA_GP_FN_DRC1_SIGNAL_DETECT: - snd_soc_component_enable_pin(component, - "DRC1 Signal Activity"); + snd_soc_dapm_enable_pin(dapm, "DRC1 Signal Activity"); break; case ARIZONA_GP_FN_DRC2_SIGNAL_DETECT: - snd_soc_component_enable_pin(component, - "DRC2 Signal Activity"); + snd_soc_dapm_enable_pin(dapm, "DRC2 Signal Activity"); break; default: break; @@ -1911,7 +1909,7 @@ static int arizona_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id, unsigned int freq, int dir) { struct snd_soc_component *component = dai->component; - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct arizona_priv *priv = snd_soc_component_get_drvdata(component); struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1]; struct snd_soc_dapm_route routes[2]; diff --git a/sound/soc/codecs/audio-iio-aux.c b/sound/soc/codecs/audio-iio-aux.c index 588e48044c13c8..066e401912b052 100644 --- a/sound/soc/codecs/audio-iio-aux.c +++ b/sound/soc/codecs/audio-iio-aux.c @@ -131,7 +131,7 @@ static_assert(ARRAY_SIZE(routes) >= 2, "2 routes are needed"); static int audio_iio_aux_add_dapms(struct snd_soc_component *component, struct audio_iio_aux_chan *chan) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); int ret; /* Allocated names are not needed afterwards (duplicated in ASoC internals) */ diff --git a/sound/soc/codecs/aw88166.c b/sound/soc/codecs/aw88166.c index 1629906d5d3314..daee4de9e3b01f 100644 --- a/sound/soc/codecs/aw88166.c +++ b/sound/soc/codecs/aw88166.c @@ -41,109 +41,6 @@ static const struct regmap_config aw88166_remap_config = { .val_format_endian = REGMAP_ENDIAN_BIG, }; -static int aw_dev_dsp_write_16bit(struct aw_device *aw_dev, - unsigned short dsp_addr, unsigned int dsp_data) -{ - int ret; - - ret = regmap_write(aw_dev->regmap, AW88166_DSPMADD_REG, dsp_addr); - if (ret) { - dev_err(aw_dev->dev, "%s write addr error, ret=%d", __func__, ret); - return ret; - } - - ret = regmap_write(aw_dev->regmap, AW88166_DSPMDAT_REG, (u16)dsp_data); - if (ret) { - dev_err(aw_dev->dev, "%s write data error, ret=%d", __func__, ret); - return ret; - } - - return 0; -} - -static int aw_dev_dsp_read_16bit(struct aw_device *aw_dev, - unsigned short dsp_addr, unsigned int *dsp_data) -{ - unsigned int temp_data; - int ret; - - ret = regmap_write(aw_dev->regmap, AW88166_DSPMADD_REG, dsp_addr); - if (ret) { - dev_err(aw_dev->dev, "%s write error, ret=%d", __func__, ret); - return ret; - } - - ret = regmap_read(aw_dev->regmap, AW88166_DSPMDAT_REG, &temp_data); - if (ret) { - dev_err(aw_dev->dev, "%s read error, ret=%d", __func__, ret); - return ret; - } - *dsp_data = temp_data; - - return 0; -} - -static int aw_dev_dsp_read_32bit(struct aw_device *aw_dev, - unsigned short dsp_addr, unsigned int *dsp_data) -{ - unsigned int temp_data; - int ret; - - ret = regmap_write(aw_dev->regmap, AW88166_DSPMADD_REG, dsp_addr); - if (ret) { - dev_err(aw_dev->dev, "%s write error, ret=%d", __func__, ret); - return ret; - } - - ret = regmap_read(aw_dev->regmap, AW88166_DSPMDAT_REG, &temp_data); - if (ret) { - dev_err(aw_dev->dev, "%s read error, ret=%d", __func__, ret); - return ret; - } - *dsp_data = temp_data; - - ret = regmap_read(aw_dev->regmap, AW88166_DSPMDAT_REG, &temp_data); - if (ret) { - dev_err(aw_dev->dev, "%s read error, ret=%d", __func__, ret); - return ret; - } - *dsp_data |= (temp_data << 16); - - return 0; -} - -static int aw_dev_dsp_read(struct aw_device *aw_dev, - unsigned short dsp_addr, unsigned int *dsp_data, unsigned char data_type) -{ - u32 reg_value; - int ret; - - mutex_lock(&aw_dev->dsp_lock); - switch (data_type) { - case AW88166_DSP_16_DATA: - ret = aw_dev_dsp_read_16bit(aw_dev, dsp_addr, dsp_data); - if (ret) - dev_err(aw_dev->dev, "read dsp_addr[0x%x] 16-bit failed", (u32)dsp_addr); - break; - case AW88166_DSP_32_DATA: - ret = aw_dev_dsp_read_32bit(aw_dev, dsp_addr, dsp_data); - if (ret) - dev_err(aw_dev->dev, "read dsp_addr[0x%x] 32-bit failed", (u32)dsp_addr); - break; - default: - dev_err(aw_dev->dev, "data type[%d] unsupported", data_type); - ret = -EINVAL; - break; - } - - /* clear dsp chip select state */ - if (regmap_read(aw_dev->regmap, AW88166_ID_REG, ®_value)) - dev_err(aw_dev->dev, "%s fail to clear chip state. ret=%d\n", __func__, ret); - mutex_unlock(&aw_dev->dsp_lock); - - return ret; -} - static void aw_dev_pwd(struct aw_device *aw_dev, bool pwd) { int ret; @@ -904,25 +801,19 @@ static int aw_dev_dsp_update_container(struct aw_device *aw_dev, u32 tmp_len; int i, ret; - mutex_lock(&aw_dev->dsp_lock); ret = regmap_write(aw_dev->regmap, AW88166_DSPMADD_REG, base); if (ret) - goto error_operation; + return ret; for (i = 0; i < len; i += AW88166_MAX_RAM_WRITE_BYTE_SIZE) { tmp_len = min(len - i, AW88166_MAX_RAM_WRITE_BYTE_SIZE); ret = regmap_raw_write(aw_dev->regmap, AW88166_DSPMDAT_REG, &data[i], tmp_len); if (ret) - goto error_operation; + return ret; } - mutex_unlock(&aw_dev->dsp_lock); return 0; - -error_operation: - mutex_unlock(&aw_dev->dsp_lock); - return ret; } static int aw_dev_get_ra(struct aw_cali_desc *cali_desc) @@ -933,7 +824,7 @@ static int aw_dev_get_ra(struct aw_cali_desc *cali_desc) int ret; ret = aw_dev_dsp_read(aw_dev, AW88166_DSP_REG_CFG_ADPZ_RA, - &dsp_ra, AW88166_DSP_32_DATA); + &dsp_ra, AW_DSP_32_DATA); if (ret) { dev_err(aw_dev->dev, "read ra error\n"); return ret; @@ -990,29 +881,25 @@ static int aw_dev_check_sram(struct aw_device *aw_dev) { unsigned int reg_val; - mutex_lock(&aw_dev->dsp_lock); /* read dsp_rom_check_reg */ - aw_dev_dsp_read_16bit(aw_dev, AW88166_DSP_ROM_CHECK_ADDR, ®_val); + aw_dev_dsp_read(aw_dev, AW88166_DSP_ROM_CHECK_ADDR, ®_val, AW_DSP_16_DATA); if (reg_val != AW88166_DSP_ROM_CHECK_DATA) { dev_err(aw_dev->dev, "check dsp rom failed, read[0x%x] != check[0x%x]\n", reg_val, AW88166_DSP_ROM_CHECK_DATA); - goto error; + return -EPERM; } /* check dsp_cfg_base_addr */ - aw_dev_dsp_write_16bit(aw_dev, AW88166_DSP_CFG_ADDR, AW88166_DSP_ODD_NUM_BIT_TEST); - aw_dev_dsp_read_16bit(aw_dev, AW88166_DSP_CFG_ADDR, ®_val); + aw_dev_dsp_write(aw_dev, AW88166_DSP_CFG_ADDR, + AW88166_DSP_ODD_NUM_BIT_TEST, AW_DSP_16_DATA); + aw_dev_dsp_read(aw_dev, AW88166_DSP_CFG_ADDR, ®_val, AW_DSP_16_DATA); if (reg_val != AW88166_DSP_ODD_NUM_BIT_TEST) { dev_err(aw_dev->dev, "check dsp cfg failed, read[0x%x] != write[0x%x]\n", reg_val, AW88166_DSP_ODD_NUM_BIT_TEST); - goto error; + return -EPERM; } - mutex_unlock(&aw_dev->dsp_lock); return 0; -error: - mutex_unlock(&aw_dev->dsp_lock); - return -EPERM; } static void aw_dev_select_memclk(struct aw_device *aw_dev, unsigned char flag) diff --git a/sound/soc/codecs/aw88166.h b/sound/soc/codecs/aw88166.h index 3a53ba0ac6257e..9f3f47a7003e28 100644 --- a/sound/soc/codecs/aw88166.h +++ b/sound/soc/codecs/aw88166.h @@ -516,11 +516,6 @@ enum AW88166_DEV_DSP_CFG { AW88166_DEV_DSP_BYPASS = 1, }; -enum { - AW88166_DSP_16_DATA = 0, - AW88166_DSP_32_DATA = 1, -}; - enum { AW88166_SYNC_START = 0, AW88166_ASYNC_START, diff --git a/sound/soc/codecs/aw88261.c b/sound/soc/codecs/aw88261.c index 8600b21ea618ce..8f37bfb974ae48 100644 --- a/sound/soc/codecs/aw88261.c +++ b/sound/soc/codecs/aw88261.c @@ -1131,7 +1131,7 @@ static int aw88261_request_firmware_file(struct aw88261 *aw88261) static int aw88261_codec_probe(struct snd_soc_component *component) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct aw88261 *aw88261 = snd_soc_component_get_drvdata(component); int ret; diff --git a/sound/soc/codecs/aw88395/aw88395.c b/sound/soc/codecs/aw88395/aw88395.c index 9173629ec12699..3602b5b9f7d77b 100644 --- a/sound/soc/codecs/aw88395/aw88395.c +++ b/sound/soc/codecs/aw88395/aw88395.c @@ -401,7 +401,7 @@ static const struct snd_soc_dapm_route aw88395_audio_map[] = { static int aw88395_codec_probe(struct snd_soc_component *component) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct aw88395 *aw88395 = snd_soc_component_get_drvdata(component); int ret; diff --git a/sound/soc/codecs/aw88395/aw88395_device.c b/sound/soc/codecs/aw88395/aw88395_device.c index e1430940015d6d..79c3135a411036 100644 --- a/sound/soc/codecs/aw88395/aw88395_device.c +++ b/sound/soc/codecs/aw88395/aw88395_device.c @@ -64,7 +64,7 @@ static int aw_dev_dsp_write_32bit(struct aw_device *aw_dev, return 0; } -static int aw_dev_dsp_write(struct aw_device *aw_dev, +int aw_dev_dsp_write(struct aw_device *aw_dev, unsigned short dsp_addr, unsigned int dsp_data, unsigned char data_type) { u32 reg_value; @@ -72,13 +72,13 @@ static int aw_dev_dsp_write(struct aw_device *aw_dev, mutex_lock(&aw_dev->dsp_lock); switch (data_type) { - case AW88395_DSP_16_DATA: + case AW_DSP_16_DATA: ret = aw_dev_dsp_write_16bit(aw_dev, dsp_addr, dsp_data); if (ret) dev_err(aw_dev->dev, "write dsp_addr[0x%x] 16-bit dsp_data[0x%x] failed", (u32)dsp_addr, dsp_data); break; - case AW88395_DSP_32_DATA: + case AW_DSP_32_DATA: ret = aw_dev_dsp_write_32bit(aw_dev, dsp_addr, dsp_data); if (ret) dev_err(aw_dev->dev, "write dsp_addr[0x%x] 32-bit dsp_data[0x%x] failed", @@ -97,6 +97,7 @@ static int aw_dev_dsp_write(struct aw_device *aw_dev, return ret; } +EXPORT_SYMBOL_GPL(aw_dev_dsp_write); static int aw_dev_dsp_read_16bit(struct aw_device *aw_dev, unsigned short dsp_addr, unsigned int *dsp_data) @@ -149,7 +150,7 @@ static int aw_dev_dsp_read_32bit(struct aw_device *aw_dev, return 0; } -static int aw_dev_dsp_read(struct aw_device *aw_dev, +int aw_dev_dsp_read(struct aw_device *aw_dev, unsigned short dsp_addr, unsigned int *dsp_data, unsigned char data_type) { u32 reg_value; @@ -157,13 +158,13 @@ static int aw_dev_dsp_read(struct aw_device *aw_dev, mutex_lock(&aw_dev->dsp_lock); switch (data_type) { - case AW88395_DSP_16_DATA: + case AW_DSP_16_DATA: ret = aw_dev_dsp_read_16bit(aw_dev, dsp_addr, dsp_data); if (ret) dev_err(aw_dev->dev, "read dsp_addr[0x%x] 16-bit dsp_data[0x%x] failed", (u32)dsp_addr, *dsp_data); break; - case AW88395_DSP_32_DATA: + case AW_DSP_32_DATA: ret = aw_dev_dsp_read_32bit(aw_dev, dsp_addr, dsp_data); if (ret) dev_err(aw_dev->dev, "read dsp_addr[0x%x] 32r-bit dsp_data[0x%x] failed", @@ -182,7 +183,7 @@ static int aw_dev_dsp_read(struct aw_device *aw_dev, return ret; } - +EXPORT_SYMBOL_GPL(aw_dev_dsp_read); static int aw_dev_read_chipid(struct aw_device *aw_dev, u16 *chip_id) { @@ -231,7 +232,7 @@ static int aw_dev_dsp_fw_check(struct aw_device *aw_dev) dsp_fw_desc = &set_prof_desc->sec_desc[AW88395_DATA_TYPE_DSP_FW]; for (i = 0; i < AW88395_FW_CHECK_PART; i++) { - ret = aw_dev_dsp_read(aw_dev, addr, &dsp_val, AW88395_DSP_16_DATA); + ret = aw_dev_dsp_read(aw_dev, addr, &dsp_val, AW_DSP_16_DATA); if (ret) { dev_err(aw_dev->dev, "dsp read failed"); return ret; @@ -351,11 +352,11 @@ static int aw_dev_modify_dsp_cfg(struct aw_device *aw_dev, return -EINVAL; } switch (data_type) { - case AW88395_DSP_16_DATA: + case AW_DSP_16_DATA: data1 = cpu_to_le16((u16)dsp_data); memcpy(crc_dsp_cfg->data + addr_offset, (u8 *)&data1, 2); break; - case AW88395_DSP_32_DATA: + case AW_DSP_32_DATA: data2 = cpu_to_le32(dsp_data); memcpy(crc_dsp_cfg->data + addr_offset, (u8 *)&data2, 4); break; @@ -377,14 +378,14 @@ static int aw_dev_dsp_set_cali_re(struct aw_device *aw_dev) /* set cali re to device */ ret = aw_dev_dsp_write(aw_dev, - AW88395_DSP_REG_CFG_ADPZ_RE, cali_re, AW88395_DSP_32_DATA); + AW88395_DSP_REG_CFG_ADPZ_RE, cali_re, AW_DSP_32_DATA); if (ret) { dev_err(aw_dev->dev, "set cali re error"); return ret; } ret = aw_dev_modify_dsp_cfg(aw_dev, AW88395_DSP_REG_CFG_ADPZ_RE, - cali_re, AW88395_DSP_32_DATA); + cali_re, AW_DSP_32_DATA); if (ret) dev_err(aw_dev->dev, "modify dsp cfg failed"); @@ -428,7 +429,7 @@ static int aw_dev_dsp_set_crc32(struct aw_device *aw_dev) crc_value = crc32c(0xFFFFFFFF, crc_dsp_cfg->data, crc_data_len) ^ 0xFFFFFFFF; return aw_dev_dsp_write(aw_dev, AW88395_DSP_REG_CRC_ADDR, crc_value, - AW88395_DSP_32_DATA); + AW_DSP_32_DATA); } static void aw_dev_dsp_check_crc_enable(struct aw_device *aw_dev, bool flag) @@ -663,7 +664,7 @@ static int aw_dev_set_vcalb(struct aw_device *aw_dev) int vcalb, vcalk; int ret; - ret = aw_dev_dsp_read(aw_dev, AW88395_DSP_REG_VCALB, &vcalb_adj, AW88395_DSP_16_DATA); + ret = aw_dev_dsp_read(aw_dev, AW88395_DSP_REG_VCALB, &vcalb_adj, AW_DSP_16_DATA); if (ret) { dev_err(aw_dev->dev, "read vcalb_adj failed"); return ret; @@ -720,14 +721,14 @@ static int aw_dev_set_vcalb(struct aw_device *aw_dev) dev_dbg(aw_dev->dev, "vcalb=%d, reg_val=0x%x, vcalb_adj =0x%x", vcalb, reg_val, vcalb_adj); - ret = aw_dev_dsp_write(aw_dev, AW88395_DSP_REG_VCALB, reg_val, AW88395_DSP_16_DATA); + ret = aw_dev_dsp_write(aw_dev, AW88395_DSP_REG_VCALB, reg_val, AW_DSP_16_DATA); if (ret) { dev_err(aw_dev->dev, "write vcalb failed"); return ret; } ret = aw_dev_modify_dsp_cfg(aw_dev, AW88395_DSP_REG_VCALB, - (u32)reg_val, AW88395_DSP_16_DATA); + (u32)reg_val, AW_DSP_16_DATA); if (ret) dev_err(aw_dev->dev, "modify dsp cfg failed"); @@ -741,7 +742,7 @@ static int aw_dev_get_cali_f0_delay(struct aw_device *aw_dev) int ret; ret = aw_dev_dsp_read(aw_dev, - AW88395_DSP_CALI_F0_DELAY, &cali_delay, AW88395_DSP_16_DATA); + AW88395_DSP_CALI_F0_DELAY, &cali_delay, AW_DSP_16_DATA); if (ret) dev_err(aw_dev->dev, "read cali delay failed, ret=%d", ret); else @@ -991,7 +992,7 @@ static int aw_dev_get_dsp_status(struct aw_device *aw_dev) static int aw_dev_get_vmax(struct aw_device *aw_dev, unsigned int *vmax) { - return aw_dev_dsp_read(aw_dev, AW88395_DSP_REG_VMAX, vmax, AW88395_DSP_16_DATA); + return aw_dev_dsp_read(aw_dev, AW88395_DSP_REG_VMAX, vmax, AW_DSP_16_DATA); } static int aw_dev_update_reg_container(struct aw_device *aw_dev, @@ -1089,7 +1090,7 @@ static int aw_dev_get_ra(struct aw_cali_desc *cali_desc) int ret; ret = aw_dev_dsp_read(aw_dev, AW88395_DSP_REG_CFG_ADPZ_RA, - &dsp_ra, AW88395_DSP_32_DATA); + &dsp_ra, AW_DSP_32_DATA); if (ret) { dev_err(aw_dev->dev, "read ra error"); return ret; diff --git a/sound/soc/codecs/aw88395/aw88395_device.h b/sound/soc/codecs/aw88395/aw88395_device.h index 6f8b30b475dac7..3626f222899d4d 100644 --- a/sound/soc/codecs/aw88395/aw88395_device.h +++ b/sound/soc/codecs/aw88395/aw88395_device.h @@ -89,8 +89,8 @@ enum AW88395_DEV_DSP_CFG { }; enum { - AW88395_DSP_16_DATA = 0, - AW88395_DSP_32_DATA = 1, + AW_DSP_16_DATA = 0, + AW_DSP_32_DATA = 1, }; enum { @@ -210,5 +210,9 @@ int aw88395_dev_get_profile_count(struct aw_device *aw_dev); int aw88395_dev_load_acf_check(struct aw_device *aw_dev, struct aw_container *aw_cfg); int aw88395_dev_cfg_load(struct aw_device *aw_dev, struct aw_container *aw_cfg); void aw88395_dev_mute(struct aw_device *aw_dev, bool is_mute); +int aw_dev_dsp_write(struct aw_device *aw_dev, + unsigned short dsp_addr, unsigned int dsp_data, unsigned char data_type); +int aw_dev_dsp_read(struct aw_device *aw_dev, + unsigned short dsp_addr, unsigned int *dsp_data, unsigned char data_type); #endif diff --git a/sound/soc/codecs/aw88399.c b/sound/soc/codecs/aw88399.c index d1237c5bf925c1..b588c27909b503 100644 --- a/sound/soc/codecs/aw88399.c +++ b/sound/soc/codecs/aw88399.c @@ -26,172 +26,6 @@ static const struct regmap_config aw88399_remap_config = { .val_format_endian = REGMAP_ENDIAN_BIG, }; -static int aw_dev_dsp_write_16bit(struct aw_device *aw_dev, - unsigned short dsp_addr, unsigned int dsp_data) -{ - int ret; - - ret = regmap_write(aw_dev->regmap, AW88399_DSPMADD_REG, dsp_addr); - if (ret) { - dev_err(aw_dev->dev, "%s write addr error, ret=%d", __func__, ret); - return ret; - } - - ret = regmap_write(aw_dev->regmap, AW88399_DSPMDAT_REG, (u16)dsp_data); - if (ret) { - dev_err(aw_dev->dev, "%s write data error, ret=%d", __func__, ret); - return ret; - } - - return 0; -} - -static int aw_dev_dsp_write_32bit(struct aw_device *aw_dev, - unsigned short dsp_addr, unsigned int dsp_data) -{ - unsigned int temp_data; - int ret; - - ret = regmap_write(aw_dev->regmap, AW88399_DSPMADD_REG, dsp_addr); - if (ret) { - dev_err(aw_dev->dev, "%s write addr error, ret=%d", __func__, ret); - return ret; - } - - temp_data = dsp_data & AW88395_DSP_16_DATA_MASK; - ret = regmap_write(aw_dev->regmap, AW88399_DSPMDAT_REG, temp_data); - if (ret) { - dev_err(aw_dev->dev, "%s write datal error, ret=%d", __func__, ret); - return ret; - } - - temp_data = dsp_data >> 16; - ret = regmap_write(aw_dev->regmap, AW88399_DSPMDAT_REG, temp_data); - if (ret) - dev_err(aw_dev->dev, "%s write datah error, ret=%d", __func__, ret); - - return ret; -} - -static int aw_dev_dsp_write(struct aw_device *aw_dev, - unsigned short dsp_addr, unsigned int dsp_data, unsigned char data_type) -{ - unsigned int reg_value; - int ret; - - mutex_lock(&aw_dev->dsp_lock); - switch (data_type) { - case AW88395_DSP_16_DATA: - ret = aw_dev_dsp_write_16bit(aw_dev, dsp_addr, dsp_data); - if (ret) - dev_err(aw_dev->dev, "write dsp_addr[0x%x] 16-bit dsp_data[0x%x] failed", - dsp_addr, dsp_data); - break; - case AW88395_DSP_32_DATA: - ret = aw_dev_dsp_write_32bit(aw_dev, dsp_addr, dsp_data); - if (ret) - dev_err(aw_dev->dev, "write dsp_addr[0x%x] 32-bit dsp_data[0x%x] failed", - dsp_addr, dsp_data); - break; - default: - dev_err(aw_dev->dev, "data type[%d] unsupported", data_type); - ret = -EINVAL; - break; - } - - /* clear dsp chip select state */ - if (regmap_read(aw_dev->regmap, 0x00, ®_value)) - dev_err(aw_dev->dev, "%s fail to clear chip state. Err=%d\n", __func__, ret); - mutex_unlock(&aw_dev->dsp_lock); - - return ret; -} - -static int aw_dev_dsp_read_16bit(struct aw_device *aw_dev, - unsigned short dsp_addr, unsigned int *dsp_data) -{ - unsigned int temp_data; - int ret; - - ret = regmap_write(aw_dev->regmap, AW88399_DSPMADD_REG, dsp_addr); - if (ret) { - dev_err(aw_dev->dev, "%s write error, ret=%d", __func__, ret); - return ret; - } - - ret = regmap_read(aw_dev->regmap, AW88399_DSPMDAT_REG, &temp_data); - if (ret) { - dev_err(aw_dev->dev, "%s read error, ret=%d", __func__, ret); - return ret; - } - *dsp_data = temp_data; - - return 0; -} - -static int aw_dev_dsp_read_32bit(struct aw_device *aw_dev, - unsigned short dsp_addr, unsigned int *dsp_data) -{ - unsigned int temp_data; - int ret; - - ret = regmap_write(aw_dev->regmap, AW88399_DSPMADD_REG, dsp_addr); - if (ret) { - dev_err(aw_dev->dev, "%s write error, ret=%d", __func__, ret); - return ret; - } - - ret = regmap_read(aw_dev->regmap, AW88399_DSPMDAT_REG, &temp_data); - if (ret) { - dev_err(aw_dev->dev, "%s read error, ret=%d", __func__, ret); - return ret; - } - *dsp_data = temp_data; - - ret = regmap_read(aw_dev->regmap, AW88399_DSPMDAT_REG, &temp_data); - if (ret) { - dev_err(aw_dev->dev, "%s read error, ret=%d", __func__, ret); - return ret; - } - *dsp_data |= (temp_data << 16); - - return 0; -} - -static int aw_dev_dsp_read(struct aw_device *aw_dev, - unsigned short dsp_addr, unsigned int *dsp_data, unsigned char data_type) -{ - u32 reg_value; - int ret; - - mutex_lock(&aw_dev->dsp_lock); - switch (data_type) { - case AW88399_DSP_16_DATA: - ret = aw_dev_dsp_read_16bit(aw_dev, dsp_addr, dsp_data); - if (ret) - dev_err(aw_dev->dev, "read dsp_addr[0x%x] 16-bit dsp_data[0x%x] failed", - (u32)dsp_addr, *dsp_data); - break; - case AW88399_DSP_32_DATA: - ret = aw_dev_dsp_read_32bit(aw_dev, dsp_addr, dsp_data); - if (ret) - dev_err(aw_dev->dev, "read dsp_addr[0x%x] 32r-bit dsp_data[0x%x] failed", - (u32)dsp_addr, *dsp_data); - break; - default: - dev_err(aw_dev->dev, "data type[%d] unsupported", data_type); - ret = -EINVAL; - break; - } - - /* clear dsp chip select state */ - if (regmap_read(aw_dev->regmap, AW88399_ID_REG, ®_value)) - dev_err(aw_dev->dev, "%s fail to clear chip state. ret=%d\n", __func__, ret); - mutex_unlock(&aw_dev->dsp_lock); - - return ret; -} - static void aw_dev_pwd(struct aw_device *aw_dev, bool pwd) { int ret; @@ -929,25 +763,19 @@ static int aw_dev_dsp_update_container(struct aw_device *aw_dev, u32 tmp_len; int i, ret; - mutex_lock(&aw_dev->dsp_lock); ret = regmap_write(aw_dev->regmap, AW88399_DSPMADD_REG, base); if (ret) - goto error_operation; + return ret; for (i = 0; i < len; i += AW88399_MAX_RAM_WRITE_BYTE_SIZE) { tmp_len = min(len - i, AW88399_MAX_RAM_WRITE_BYTE_SIZE); ret = regmap_raw_write(aw_dev->regmap, AW88399_DSPMDAT_REG, &data[i], tmp_len); if (ret) - goto error_operation; + return ret; } - mutex_unlock(&aw_dev->dsp_lock); return 0; - -error_operation: - mutex_unlock(&aw_dev->dsp_lock); - return ret; } static int aw_dev_get_ra(struct aw_cali_desc *cali_desc) @@ -958,7 +786,7 @@ static int aw_dev_get_ra(struct aw_cali_desc *cali_desc) int ret; ret = aw_dev_dsp_read(aw_dev, AW88399_DSP_REG_CFG_ADPZ_RA, - &dsp_ra, AW88399_DSP_32_DATA); + &dsp_ra, AW_DSP_32_DATA); if (ret) { dev_err(aw_dev->dev, "read ra error"); return ret; @@ -1015,29 +843,25 @@ static int aw_dev_check_sram(struct aw_device *aw_dev) { unsigned int reg_val; - mutex_lock(&aw_dev->dsp_lock); /* read dsp_rom_check_reg */ - aw_dev_dsp_read_16bit(aw_dev, AW88399_DSP_ROM_CHECK_ADDR, ®_val); + aw_dev_dsp_read(aw_dev, AW88399_DSP_ROM_CHECK_ADDR, ®_val, AW_DSP_16_DATA); if (reg_val != AW88399_DSP_ROM_CHECK_DATA) { dev_err(aw_dev->dev, "check dsp rom failed, read[0x%x] != check[0x%x]", reg_val, AW88399_DSP_ROM_CHECK_DATA); - goto error; + return -EPERM; } /* check dsp_cfg_base_addr */ - aw_dev_dsp_write_16bit(aw_dev, AW88399_DSP_CFG_ADDR, AW88399_DSP_ODD_NUM_BIT_TEST); - aw_dev_dsp_read_16bit(aw_dev, AW88399_DSP_CFG_ADDR, ®_val); + aw_dev_dsp_write(aw_dev, AW88399_DSP_CFG_ADDR, + AW88399_DSP_ODD_NUM_BIT_TEST, AW_DSP_16_DATA); + aw_dev_dsp_read(aw_dev, AW88399_DSP_CFG_ADDR, ®_val, AW_DSP_16_DATA); if (reg_val != AW88399_DSP_ODD_NUM_BIT_TEST) { dev_err(aw_dev->dev, "check dsp cfg failed, read[0x%x] != write[0x%x]", reg_val, AW88399_DSP_ODD_NUM_BIT_TEST); - goto error; + return -EPERM; } - mutex_unlock(&aw_dev->dsp_lock); return 0; -error: - mutex_unlock(&aw_dev->dsp_lock); - return -EPERM; } static void aw_dev_select_memclk(struct aw_device *aw_dev, unsigned char flag) @@ -1432,22 +1256,22 @@ static int aw_cali_svc_get_cali_cfg(struct aw_device *aw_dev) int ret; ret = aw_dev_dsp_read(aw_dev, AW88399_DSP_REG_CFG_MBMEC_ACTAMPTH, - &cali_cfg->data[0], AW88399_DSP_32_DATA); + &cali_cfg->data[0], AW_DSP_32_DATA); if (ret) return ret; ret = aw_dev_dsp_read(aw_dev, AW88399_DSP_REG_CFG_MBMEC_NOISEAMPTH, - &cali_cfg->data[1], AW88399_DSP_32_DATA); + &cali_cfg->data[1], AW_DSP_32_DATA); if (ret) return ret; ret = aw_dev_dsp_read(aw_dev, AW88399_DSP_REG_CFG_ADPZ_USTEPN, - &cali_cfg->data[2], AW88399_DSP_16_DATA); + &cali_cfg->data[2], AW_DSP_16_DATA); if (ret) return ret; ret = aw_dev_dsp_read(aw_dev, AW88399_DSP_REG_CFG_RE_ALPHA, - &cali_cfg->data[3], AW88399_DSP_16_DATA); + &cali_cfg->data[3], AW_DSP_16_DATA); return ret; } @@ -1458,22 +1282,22 @@ static int aw_cali_svc_set_cali_cfg(struct aw_device *aw_dev, int ret; ret = aw_dev_dsp_write(aw_dev, AW88399_DSP_REG_CFG_MBMEC_ACTAMPTH, - cali_cfg.data[0], AW88399_DSP_32_DATA); + cali_cfg.data[0], AW_DSP_32_DATA); if (ret) return ret; ret = aw_dev_dsp_write(aw_dev, AW88399_DSP_REG_CFG_MBMEC_NOISEAMPTH, - cali_cfg.data[1], AW88399_DSP_32_DATA); + cali_cfg.data[1], AW_DSP_32_DATA); if (ret) return ret; ret = aw_dev_dsp_write(aw_dev, AW88399_DSP_REG_CFG_ADPZ_USTEPN, - cali_cfg.data[2], AW88399_DSP_16_DATA); + cali_cfg.data[2], AW_DSP_16_DATA); if (ret) return ret; ret = aw_dev_dsp_write(aw_dev, AW88399_DSP_REG_CFG_RE_ALPHA, - cali_cfg.data[3], AW88399_DSP_16_DATA); + cali_cfg.data[3], AW_DSP_16_DATA); return ret; } @@ -1488,7 +1312,7 @@ static int aw_cali_svc_cali_en(struct aw_device *aw_dev, bool cali_en) regmap_update_bits(aw_dev->regmap, AW88399_DBGCTRL_REG, ~AW883XX_DSP_NG_EN_MASK, AW883XX_DSP_NG_EN_DISABLE_VALUE); aw_dev_dsp_write(aw_dev, AW88399_DSP_LOW_POWER_SWITCH_CFG_ADDR, - AW88399_DSP_LOW_POWER_SWITCH_DISABLE, AW88399_DSP_16_DATA); + AW88399_DSP_LOW_POWER_SWITCH_DISABLE, AW_DSP_16_DATA); ret = aw_cali_svc_get_cali_cfg(aw_dev); if (ret) { @@ -1548,8 +1372,7 @@ static void aw_cali_svc_backup_info(struct aw_device *aw_dev) regmap_read(aw_dev->regmap, AW88399_DBGCTRL_REG, ®_val); backup_desc->dsp_ng_cfg = reg_val & (~AW883XX_DSP_NG_EN_MASK); - aw_dev_dsp_read(aw_dev, AW88399_DSP_LOW_POWER_SWITCH_CFG_ADDR, - &dsp_val, AW88399_DSP_16_DATA); + aw_dev_dsp_read(aw_dev, AW88399_DSP_LOW_POWER_SWITCH_CFG_ADDR, &dsp_val, AW_DSP_16_DATA); backup_desc->dsp_lp_cfg = dsp_val; } @@ -1562,7 +1385,7 @@ static void aw_cali_svc_recover_info(struct aw_device *aw_dev) ~AW883XX_DSP_NG_EN_MASK, backup_desc->dsp_ng_cfg); aw_dev_dsp_write(aw_dev, AW88399_DSP_LOW_POWER_SWITCH_CFG_ADDR, - backup_desc->dsp_lp_cfg, AW88399_DSP_16_DATA); + backup_desc->dsp_lp_cfg, AW_DSP_16_DATA); } static int aw_cali_svc_cali_re_mode_enable(struct aw_device *aw_dev, bool is_enable) @@ -1609,7 +1432,7 @@ static int aw_cali_svc_get_dev_re(struct aw_device *aw_dev, uint32_t *re) uint32_t dsp_re, show_re; int ret; - ret = aw_dev_dsp_read(aw_dev, AW88399_DSP_REG_CALRE, &dsp_re, AW88399_DSP_16_DATA); + ret = aw_dev_dsp_read(aw_dev, AW88399_DSP_REG_CALRE, &dsp_re, AW_DSP_16_DATA); if (ret) return ret; diff --git a/sound/soc/codecs/aw88399.h b/sound/soc/codecs/aw88399.h index cacc03b1eefa60..b386f48367481e 100644 --- a/sound/soc/codecs/aw88399.h +++ b/sound/soc/codecs/aw88399.h @@ -602,11 +602,6 @@ enum AW88399_DEV_DSP_CFG { AW88399_DEV_DSP_BYPASS = 1, }; -enum { - AW88399_DSP_16_DATA = 0, - AW88399_DSP_32_DATA = 1, -}; - enum { AW88399_NOT_RCV_MODE = 0, AW88399_RCV_MODE = 1, diff --git a/sound/soc/codecs/cpcap.c b/sound/soc/codecs/cpcap.c index 3eb862643b5323..6b80c455b07471 100644 --- a/sound/soc/codecs/cpcap.c +++ b/sound/soc/codecs/cpcap.c @@ -380,7 +380,7 @@ static SOC_ENUM_SINGLE_DECL(cpcap_emu_r_mux_enum, 0, 8, cpcap_out_mux_texts); static int cpcap_output_mux_get_enum(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_component *component = snd_soc_dapm_kcontrol_component(kcontrol); + struct snd_soc_component *component = snd_soc_dapm_kcontrol_to_component(kcontrol); struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component); struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; unsigned int shift = e->shift_l; @@ -423,10 +423,9 @@ static int cpcap_output_mux_get_enum(struct snd_kcontrol *kcontrol, static int cpcap_output_mux_put_enum(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_component *component = snd_soc_dapm_kcontrol_component(kcontrol); + struct snd_soc_component *component = snd_soc_dapm_kcontrol_to_component(kcontrol); struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component); - struct snd_soc_dapm_context *dapm = - snd_soc_dapm_kcontrol_dapm(kcontrol); + struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kcontrol); struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; unsigned int muxval = ucontrol->value.enumerated.item[0]; unsigned int mask = BIT(e->shift_l); @@ -468,7 +467,7 @@ static int cpcap_output_mux_put_enum(struct snd_kcontrol *kcontrol, static int cpcap_input_right_mux_get_enum(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_component *component = snd_soc_dapm_kcontrol_component(kcontrol); + struct snd_soc_component *component = snd_soc_dapm_kcontrol_to_component(kcontrol); struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component); int regval, mask; int err; @@ -507,10 +506,9 @@ static int cpcap_input_right_mux_get_enum(struct snd_kcontrol *kcontrol, static int cpcap_input_right_mux_put_enum(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_component *component = snd_soc_dapm_kcontrol_component(kcontrol); + struct snd_soc_component *component = snd_soc_dapm_kcontrol_to_component(kcontrol); struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component); - struct snd_soc_dapm_context *dapm = - snd_soc_dapm_kcontrol_dapm(kcontrol); + struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kcontrol); struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; unsigned int muxval = ucontrol->value.enumerated.item[0]; int regval = 0, mask; @@ -552,7 +550,7 @@ static int cpcap_input_right_mux_put_enum(struct snd_kcontrol *kcontrol, static int cpcap_input_left_mux_get_enum(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_component *component = snd_soc_dapm_kcontrol_component(kcontrol); + struct snd_soc_component *component = snd_soc_dapm_kcontrol_to_component(kcontrol); struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component); int regval, mask; int err; @@ -583,10 +581,9 @@ static int cpcap_input_left_mux_get_enum(struct snd_kcontrol *kcontrol, static int cpcap_input_left_mux_put_enum(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_component *component = snd_soc_dapm_kcontrol_component(kcontrol); + struct snd_soc_component *component = snd_soc_dapm_kcontrol_to_component(kcontrol); struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component); - struct snd_soc_dapm_context *dapm = - snd_soc_dapm_kcontrol_dapm(kcontrol); + struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kcontrol); struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; unsigned int muxval = ucontrol->value.enumerated.item[0]; int regval = 0, mask; diff --git a/sound/soc/codecs/cs-amp-lib-test.c b/sound/soc/codecs/cs-amp-lib-test.c index 7fa6aabc746a09..923f1857e45bec 100644 --- a/sound/soc/codecs/cs-amp-lib-test.c +++ b/sound/soc/codecs/cs-amp-lib-test.c @@ -145,8 +145,6 @@ static void cs_amp_lib_test_cal_data_too_short_test(struct kunit *test) ret = cs_amp_get_efi_calibration_data(&priv->amp_dev->dev, 0, 0, &result_data); KUNIT_EXPECT_EQ(test, ret, -EOVERFLOW); - - kunit_deactivate_static_stub(test, cs_amp_test_hooks->get_efi_variable); } /* Redirected get_efi_variable to simulate that the count is larger than the file */ @@ -189,8 +187,6 @@ static void cs_amp_lib_test_cal_count_too_big_test(struct kunit *test) ret = cs_amp_get_efi_calibration_data(&priv->amp_dev->dev, 0, 0, &result_data); KUNIT_EXPECT_EQ(test, ret, -EOVERFLOW); - - kunit_deactivate_static_stub(test, cs_amp_test_hooks->get_efi_variable); } /* Redirected get_efi_variable to simulate that the variable not found */ @@ -217,8 +213,6 @@ static void cs_amp_lib_test_no_cal_data_test(struct kunit *test) ret = cs_amp_get_efi_calibration_data(&priv->amp_dev->dev, 0, 0, &result_data); KUNIT_EXPECT_EQ(test, ret, -ENOENT); - - kunit_deactivate_static_stub(test, cs_amp_test_hooks->get_efi_variable); } /* Redirected get_efi_variable to simulate reading a cal data blob */ @@ -383,8 +377,6 @@ static void cs_amp_lib_test_get_efi_cal_by_uid_test(struct kunit *test) ret = cs_amp_get_efi_calibration_data(&priv->amp_dev->dev, target_uid, -1, &result_data); KUNIT_EXPECT_EQ(test, ret, 0); - kunit_deactivate_static_stub(test, cs_amp_test_hooks->get_efi_variable); - KUNIT_EXPECT_EQ(test, result_data.calTarget[0], target_uid & 0xFFFFFFFFULL); KUNIT_EXPECT_EQ(test, result_data.calTarget[1], target_uid >> 32); KUNIT_EXPECT_EQ(test, result_data.calTime[0], @@ -418,8 +410,6 @@ static void cs_amp_lib_test_get_efi_cal_by_index_unchecked_test(struct kunit *te param->amp_index, &result_data); KUNIT_EXPECT_EQ(test, ret, 0); - kunit_deactivate_static_stub(test, cs_amp_test_hooks->get_efi_variable); - KUNIT_EXPECT_EQ(test, result_data.calTime[0], priv->cal_blob->data[param->amp_index].calTime[0]); KUNIT_EXPECT_EQ(test, result_data.calTime[1], @@ -453,8 +443,6 @@ static void cs_amp_lib_test_get_efi_cal_by_index_checked_test(struct kunit *test param->amp_index, &result_data); KUNIT_EXPECT_EQ(test, ret, 0); - kunit_deactivate_static_stub(test, cs_amp_test_hooks->get_efi_variable); - KUNIT_EXPECT_EQ(test, result_data.calTime[0], priv->cal_blob->data[param->amp_index].calTime[0]); KUNIT_EXPECT_EQ(test, result_data.calTime[1], @@ -491,8 +479,6 @@ static void cs_amp_lib_test_get_efi_cal_by_index_uid_mismatch_test(struct kunit ret = cs_amp_get_efi_calibration_data(&priv->amp_dev->dev, target_uid, param->amp_index, &result_data); KUNIT_EXPECT_EQ(test, ret, -ENOENT); - - kunit_deactivate_static_stub(test, cs_amp_test_hooks->get_efi_variable); } /* @@ -524,8 +510,6 @@ static void cs_amp_lib_test_get_efi_cal_by_index_fallback_test(struct kunit *tes param->amp_index, &result_data); KUNIT_EXPECT_EQ(test, ret, 0); - kunit_deactivate_static_stub(test, cs_amp_test_hooks->get_efi_variable); - KUNIT_EXPECT_EQ(test, result_data.calTime[0], priv->cal_blob->data[param->amp_index].calTime[0]); KUNIT_EXPECT_EQ(test, result_data.calTime[1], @@ -565,8 +549,6 @@ static void cs_amp_lib_test_get_efi_cal_uid_not_found_noindex_test(struct kunit ret = cs_amp_get_efi_calibration_data(&priv->amp_dev->dev, bad_target_uid, -1, &result_data); KUNIT_EXPECT_EQ(test, ret, -ENOENT); - - kunit_deactivate_static_stub(test, cs_amp_test_hooks->get_efi_variable); } /* @@ -596,8 +578,6 @@ static void cs_amp_lib_test_get_efi_cal_uid_not_found_index_not_found_test(struc ret = cs_amp_get_efi_calibration_data(&priv->amp_dev->dev, bad_target_uid, 99, &result_data); KUNIT_EXPECT_EQ(test, ret, -ENOENT); - - kunit_deactivate_static_stub(test, cs_amp_test_hooks->get_efi_variable); } /* @@ -619,8 +599,6 @@ static void cs_amp_lib_test_get_efi_cal_no_uid_index_not_found_test(struct kunit ret = cs_amp_get_efi_calibration_data(&priv->amp_dev->dev, 0, 99, &result_data); KUNIT_EXPECT_EQ(test, ret, -ENOENT); - - kunit_deactivate_static_stub(test, cs_amp_test_hooks->get_efi_variable); } /* If neither the target UID or the index is given the result should be -ENOENT. */ @@ -639,8 +617,6 @@ static void cs_amp_lib_test_get_efi_cal_no_uid_no_index_test(struct kunit *test) ret = cs_amp_get_efi_calibration_data(&priv->amp_dev->dev, 0, -1, &result_data); KUNIT_EXPECT_EQ(test, ret, -ENOENT); - - kunit_deactivate_static_stub(test, cs_amp_test_hooks->get_efi_variable); } /* @@ -668,8 +644,6 @@ static void cs_amp_lib_test_get_efi_cal_zero_not_matched_test(struct kunit *test ret = cs_amp_get_efi_calibration_data(&priv->amp_dev->dev, 0, -1, &result_data); KUNIT_EXPECT_EQ(test, ret, -ENOENT); - - kunit_deactivate_static_stub(test, cs_amp_test_hooks->get_efi_variable); } /* @@ -711,8 +685,6 @@ static void cs_amp_lib_test_get_efi_cal_empty_entry_test(struct kunit *test) 0, 2, &result_data), -ENOENT); - - kunit_deactivate_static_stub(test, cs_amp_test_hooks->get_efi_variable); } static const struct cirrus_amp_cal_controls cs_amp_lib_test_calibration_controls = { @@ -768,9 +740,6 @@ static void cs_amp_lib_test_write_cal_data_test(struct kunit *test) ret = cs_amp_write_cal_coeffs(dsp, &cs_amp_lib_test_calibration_controls, &data); KUNIT_EXPECT_EQ(test, ret, 0); - - kunit_deactivate_static_stub(test, cs_amp_test_hooks->write_cal_coeff); - KUNIT_EXPECT_EQ(test, list_count_nodes(&priv->ctl_write_list), 4); /* Checksum control must be written last */ diff --git a/sound/soc/codecs/cs-amp-lib.c b/sound/soc/codecs/cs-amp-lib.c index d8f8b0259cd150..8c9fd9980a7d60 100644 --- a/sound/soc/codecs/cs-amp-lib.c +++ b/sound/soc/codecs/cs-amp-lib.c @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -309,9 +310,8 @@ static struct cirrus_amp_efi_data *cs_amp_get_cal_efi_buffer(struct device *dev, efi_guid_t **guid, u32 *attr) { - struct cirrus_amp_efi_data *efi_data; + struct cirrus_amp_efi_data *efi_data __free(kfree) = NULL; unsigned long data_size = 0; - u8 *data; efi_status_t status; int i, ret; @@ -339,19 +339,18 @@ static struct cirrus_amp_efi_data *cs_amp_get_cal_efi_buffer(struct device *dev, } /* Get variable contents into buffer */ - data = kmalloc(data_size, GFP_KERNEL); - if (!data) + efi_data = kmalloc(data_size, GFP_KERNEL); + if (!efi_data) return ERR_PTR(-ENOMEM); status = cs_amp_get_efi_variable(cs_amp_lib_cal_efivars[i].name, cs_amp_lib_cal_efivars[i].guid, - attr, &data_size, data); + attr, &data_size, efi_data); if (status != EFI_SUCCESS) { ret = -EINVAL; goto err; } - efi_data = (struct cirrus_amp_efi_data *)data; dev_dbg(dev, "Calibration: Size=%d, Amp Count=%d\n", efi_data->size, efi_data->count); if ((efi_data->count > 128) || @@ -365,10 +364,9 @@ static struct cirrus_amp_efi_data *cs_amp_get_cal_efi_buffer(struct device *dev, if (efi_data->size == 0) efi_data->size = data_size; - return efi_data; + return_ptr(efi_data); err: - kfree(data); dev_err(dev, "Failed to read calibration data from EFI: %d\n", ret); return ERR_PTR(ret); @@ -391,9 +389,9 @@ static int cs_amp_set_cal_efi_buffer(struct device *dev, static int _cs_amp_get_efi_calibration_data(struct device *dev, u64 target_uid, int amp_index, struct cirrus_amp_cal_data *out_data) { - struct cirrus_amp_efi_data *efi_data; + struct cirrus_amp_efi_data *efi_data __free(kfree) = NULL; struct cirrus_amp_cal_data *cal = NULL; - int i, ret; + int i; efi_data = cs_amp_get_cal_efi_buffer(dev, NULL, NULL, NULL); if (IS_ERR(efi_data)) @@ -434,17 +432,14 @@ static int _cs_amp_get_efi_calibration_data(struct device *dev, u64 target_uid, dev_warn(dev, "Calibration entry %d does not match silicon ID", amp_index); } - if (cal) { - memcpy(out_data, cal, sizeof(*out_data)); - ret = 0; - } else { + if (!cal) { dev_warn(dev, "No calibration for silicon ID %#llx\n", target_uid); - ret = -ENOENT; + return -ENOENT; } - kfree(efi_data); + memcpy(out_data, cal, sizeof(*out_data)); - return ret; + return 0; } static int _cs_amp_set_efi_calibration_data(struct device *dev, int amp_index, int num_amps, diff --git a/sound/soc/codecs/cs35l33.c b/sound/soc/codecs/cs35l33.c index c927592f90c9f5..98b4d371d93129 100644 --- a/sound/soc/codecs/cs35l33.c +++ b/sound/soc/codecs/cs35l33.c @@ -547,7 +547,7 @@ static int cs35l33_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width) { struct snd_soc_component *component = dai->component; - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct cs35l33_private *priv = snd_soc_component_get_drvdata(component); unsigned int reg, bit_pos, i; int slot, slot_num; @@ -695,7 +695,7 @@ static int cs35l33_set_hg_data(struct snd_soc_component *component, struct cs35l33_pdata *pdata) { struct cs35l33_hg *hg_config = &pdata->hg_config; - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct cs35l33_private *priv = snd_soc_component_get_drvdata(component); if (hg_config->enable_hg_algo) { diff --git a/sound/soc/codecs/cs35l41.c b/sound/soc/codecs/cs35l41.c index 173d7c59b7254d..3a8a8dd065b772 100644 --- a/sound/soc/codecs/cs35l41.c +++ b/sound/soc/codecs/cs35l41.c @@ -928,7 +928,7 @@ static const struct snd_soc_dapm_widget cs35l41_ext_bst_widget[] = { static int cs35l41_component_probe(struct snd_soc_component *component) { struct cs35l41_private *cs35l41 = snd_soc_component_get_drvdata(component); - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); int ret; if (cs35l41->hw_cfg.bst_type == CS35L41_EXT_BOOST) { diff --git a/sound/soc/codecs/cs35l45.c b/sound/soc/codecs/cs35l45.c index 28f47e9607719d..e33f1143598045 100644 --- a/sound/soc/codecs/cs35l45.c +++ b/sound/soc/codecs/cs35l45.c @@ -214,7 +214,7 @@ static int cs35l45_amplifier_mode_put(struct snd_kcontrol *kcontrol, struct cs35l45_private *cs35l45 = snd_soc_component_get_drvdata(component); struct snd_soc_dapm_context *dapm = - snd_soc_component_get_dapm(component); + snd_soc_component_to_dapm(component); unsigned int amp_state; int ret; @@ -233,7 +233,7 @@ static int cs35l45_amplifier_mode_put(struct snd_kcontrol *kcontrol, regmap_clear_bits(cs35l45->regmap, CS35L45_BLOCK_ENABLES, CS35L45_AMP_EN_MASK); - snd_soc_component_disable_pin_unlocked(component, "SPK"); + snd_soc_dapm_disable_pin_unlocked(dapm, "SPK"); snd_soc_dapm_sync_unlocked(dapm); if (ucontrol->value.integer.value[0] == AMP_MODE_SPK) { @@ -287,7 +287,7 @@ static int cs35l45_amplifier_mode_put(struct snd_kcontrol *kcontrol, regmap_set_bits(cs35l45->regmap, CS35L45_BLOCK_ENABLES, CS35L45_AMP_EN_MASK); - snd_soc_component_enable_pin_unlocked(component, "SPK"); + snd_soc_dapm_enable_pin_unlocked(dapm, "SPK"); snd_soc_dapm_sync_unlocked(dapm); snd_soc_dapm_mutex_unlock(dapm); diff --git a/sound/soc/codecs/cs35l56-shared.c b/sound/soc/codecs/cs35l56-shared.c index fe0693c3f7dee2..60100c8f8c952b 100644 --- a/sound/soc/codecs/cs35l56-shared.c +++ b/sound/soc/codecs/cs35l56-shared.c @@ -962,8 +962,8 @@ int cs35l56_get_calibration(struct cs35l56_base *cs35l56_base) } EXPORT_SYMBOL_NS_GPL(cs35l56_get_calibration, "SND_SOC_CS35L56_SHARED"); -static int cs35l56_stash_calibration(struct cs35l56_base *cs35l56_base, - const struct cirrus_amp_cal_data *data) +int cs35l56_stash_calibration(struct cs35l56_base *cs35l56_base, + const struct cirrus_amp_cal_data *data) { /* Ignore if it is empty */ @@ -980,6 +980,7 @@ static int cs35l56_stash_calibration(struct cs35l56_base *cs35l56_base, return 0; } +EXPORT_SYMBOL_NS_GPL(cs35l56_stash_calibration, "SND_SOC_CS35L56_SHARED"); static int cs35l56_perform_calibration(struct cs35l56_base *cs35l56_base) { @@ -1262,6 +1263,54 @@ void cs35l56_remove_cal_debugfs(struct cs35l56_base *cs35l56_base) } EXPORT_SYMBOL_NS_GPL(cs35l56_remove_cal_debugfs, "SND_SOC_CS35L56_SHARED"); +const char * const cs35l56_cal_set_status_text[] = { + "Unknown", "Default", "Set", +}; +EXPORT_SYMBOL_NS_GPL(cs35l56_cal_set_status_text, "SND_SOC_CS35L56_SHARED"); + +int cs35l56_cal_set_status_get(struct cs35l56_base *cs35l56_base, + struct snd_ctl_elem_value *uvalue) +{ + struct cs_dsp *dsp = cs35l56_base->dsp; + __be32 cal_set_status_be; + int alg_id; + int ret; + + switch (cs35l56_base->type) { + case 0x54: + case 0x56: + case 0x57: + alg_id = 0x9f210; + break; + default: + alg_id = 0xbf210; + break; + } + + scoped_guard(mutex, &dsp->pwr_lock) { + ret = cs_dsp_coeff_read_ctrl(cs_dsp_get_ctl(dsp, + "CAL_SET_STATUS", + WMFW_ADSP2_YM, alg_id), + 0, &cal_set_status_be, + sizeof(cal_set_status_be)); + } + if (ret) { + uvalue->value.enumerated.item[0] = CS35L56_CAL_SET_STATUS_UNKNOWN; + return 0; + } + + switch (be32_to_cpu(cal_set_status_be)) { + case CS35L56_CAL_SET_STATUS_DEFAULT: + case CS35L56_CAL_SET_STATUS_SET: + uvalue->value.enumerated.item[0] = be32_to_cpu(cal_set_status_be); + return 0; + default: + uvalue->value.enumerated.item[0] = CS35L56_CAL_SET_STATUS_UNKNOWN; + return 0; + } +} +EXPORT_SYMBOL_NS_GPL(cs35l56_cal_set_status_get, "SND_SOC_CS35L56_SHARED"); + int cs35l56_read_prot_status(struct cs35l56_base *cs35l56_base, bool *fw_missing, unsigned int *fw_version) { @@ -1288,6 +1337,23 @@ int cs35l56_read_prot_status(struct cs35l56_base *cs35l56_base, } EXPORT_SYMBOL_NS_GPL(cs35l56_read_prot_status, "SND_SOC_CS35L56_SHARED"); +void cs35l56_warn_if_firmware_missing(struct cs35l56_base *cs35l56_base) +{ + unsigned int firmware_version; + bool firmware_missing; + int ret; + + ret = cs35l56_read_prot_status(cs35l56_base, &firmware_missing, &firmware_version); + if (ret) + return; + + if (!firmware_missing) + return; + + dev_warn(cs35l56_base->dev, "FIRMWARE_MISSING\n"); +} +EXPORT_SYMBOL_NS_GPL(cs35l56_warn_if_firmware_missing, "SND_SOC_CS35L56_SHARED"); + void cs35l56_log_tuning(struct cs35l56_base *cs35l56_base, struct cs_dsp *cs_dsp) { __be32 pid, sid, tid; diff --git a/sound/soc/codecs/cs35l56.c b/sound/soc/codecs/cs35l56.c index 091a723255078c..55b4d0d55712a7 100644 --- a/sound/soc/codecs/cs35l56.c +++ b/sound/soc/codecs/cs35l56.c @@ -66,6 +66,18 @@ static int cs35l56_dspwait_put_volsw(struct snd_kcontrol *kcontrol, static DECLARE_TLV_DB_SCALE(vol_tlv, -10000, 25, 0); +static SOC_ENUM_SINGLE_DECL(cs35l56_cal_set_status_enum, SND_SOC_NOPM, 0, + cs35l56_cal_set_status_text); + +static int cs35l56_cal_set_status_ctl_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(component); + + return cs35l56_cal_set_status_get(&cs35l56->base, ucontrol); +} + static const struct snd_kcontrol_new cs35l56_controls[] = { SOC_SINGLE_EXT("Speaker Switch", CS35L56_MAIN_RENDER_USER_MUTE, 0, 1, 1, @@ -83,6 +95,9 @@ static const struct snd_kcontrol_new cs35l56_controls[] = { SOC_SINGLE_EXT("Posture Number", CS35L56_MAIN_POSTURE_NUMBER, 0, 255, 0, cs35l56_dspwait_get_volsw, cs35l56_dspwait_put_volsw), + SOC_ENUM_EXT_ACC("CAL_SET_STATUS", cs35l56_cal_set_status_enum, + cs35l56_cal_set_status_ctl_get, NULL, + SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE), }; static const struct snd_kcontrol_new cs35l63_controls[] = { @@ -102,6 +117,9 @@ static const struct snd_kcontrol_new cs35l63_controls[] = { SOC_SINGLE_EXT("Posture Number", CS35L63_MAIN_POSTURE_NUMBER, 0, 255, 0, cs35l56_dspwait_get_volsw, cs35l56_dspwait_put_volsw), + SOC_ENUM_EXT_ACC("CAL_SET_STATUS", cs35l56_cal_set_status_enum, + cs35l56_cal_set_status_ctl_get, NULL, + SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE), }; static SOC_VALUE_ENUM_SINGLE_DECL(cs35l56_asp1tx1_enum, @@ -805,6 +823,9 @@ static void cs35l56_patch(struct cs35l56_private *cs35l56, bool firmware_missing goto err_unlock; } + /* Check if the firmware is still reported missing */ + cs35l56_warn_if_firmware_missing(&cs35l56->base); + regmap_clear_bits(cs35l56->base.regmap, cs35l56->base.fw_reg->prot_sts, CS35L56_FIRMWARE_MISSING); @@ -880,10 +901,10 @@ static void cs35l56_dsp_work(struct work_struct *work) static struct snd_soc_dapm_context *cs35l56_power_up_for_cal(struct cs35l56_private *cs35l56) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(cs35l56->component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(cs35l56->component); int ret; - ret = snd_soc_component_enable_pin(cs35l56->component, "Calibrate"); + ret = snd_soc_dapm_enable_pin(dapm, "Calibrate"); if (ret) return ERR_PTR(ret); @@ -894,9 +915,9 @@ static struct snd_soc_dapm_context *cs35l56_power_up_for_cal(struct cs35l56_priv static void cs35l56_power_down_after_cal(struct cs35l56_private *cs35l56) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(cs35l56->component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(cs35l56->component); - snd_soc_component_disable_pin(cs35l56->component, "Calibrate"); + snd_soc_dapm_disable_pin(dapm, "Calibrate"); snd_soc_dapm_sync(dapm); } @@ -1024,6 +1045,68 @@ static const struct cs35l56_cal_debugfs_fops cs35l56_cal_debugfs_fops = { }, }; +static int cs35l56_cal_data_rb_ctl_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(component); + + if (!cs35l56->base.cal_data_valid) + return -ENODATA; + + memcpy(ucontrol->value.bytes.data, &cs35l56->base.cal_data, + sizeof(cs35l56->base.cal_data)); + + return 0; +} + +static int cs35l56_cal_data_ctl_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(component); + + /* + * This control is write-only but mixer libraries often try to read + * a control before writing it. So we have to implement read. + * Return zeros so a write of valid data will always be a change + * from its "current value". + */ + memset(ucontrol->value.bytes.data, 0, sizeof(cs35l56->base.cal_data)); + + return 0; +} + +static int cs35l56_cal_data_ctl_set(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(component); + const struct cirrus_amp_cal_data *cal_data = (const void *)ucontrol->value.bytes.data; + int ret; + + if (cs35l56->base.cal_data_valid) + return -EACCES; + + ret = cs35l56_stash_calibration(&cs35l56->base, cal_data); + if (ret) + return ret; + + ret = cs35l56_new_cal_data_apply(cs35l56); + if (ret < 0) + return ret; + + return 1; +} + +static const struct snd_kcontrol_new cs35l56_cal_data_restore_controls[] = { + SND_SOC_BYTES_E("CAL_DATA", 0, sizeof(struct cirrus_amp_cal_data) / sizeof(u32), + cs35l56_cal_data_ctl_get, cs35l56_cal_data_ctl_set), + SND_SOC_BYTES_E_ACC("CAL_DATA_RB", 0, sizeof(struct cirrus_amp_cal_data) / sizeof(u32), + cs35l56_cal_data_rb_ctl_get, NULL, + SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE), +}; + static int cs35l56_set_fw_suffix(struct cs35l56_private *cs35l56) { if (cs35l56->dsp.fwf_suffix) @@ -1054,6 +1137,7 @@ static int cs35l56_set_fw_suffix(struct cs35l56_private *cs35l56) static int cs35l56_component_probe(struct snd_soc_component *component) { + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(component); struct dentry *debugfs_root = component->debugfs_root; unsigned short vendor, device; @@ -1118,10 +1202,16 @@ static int cs35l56_component_probe(struct snd_soc_component *component) break; } + if (!ret && IS_ENABLED(CONFIG_SND_SOC_CS35L56_CAL_SET_CTRL)) { + ret = snd_soc_add_component_controls(component, + cs35l56_cal_data_restore_controls, + ARRAY_SIZE(cs35l56_cal_data_restore_controls)); + } + if (ret) return dev_err_probe(cs35l56->base.dev, ret, "unable to add controls\n"); - ret = snd_soc_component_disable_pin(component, "Calibrate"); + ret = snd_soc_dapm_disable_pin(dapm, "Calibrate"); if (ret) return ret; @@ -1159,6 +1249,7 @@ static int cs35l56_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); switch (level) { case SND_SOC_BIAS_STANDBY: @@ -1166,7 +1257,7 @@ static int cs35l56_set_bias_level(struct snd_soc_component *component, * Wait for patching to complete when transitioning from * BIAS_OFF to BIAS_STANDBY */ - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) cs35l56_wait_dsp_ready(cs35l56); break; diff --git a/sound/soc/codecs/cs4234.c b/sound/soc/codecs/cs4234.c index fab4695644bce3..89c424dd838b80 100644 --- a/sound/soc/codecs/cs4234.c +++ b/sound/soc/codecs/cs4234.c @@ -87,7 +87,7 @@ static int cs4234_dac14_grp_delay_put(struct snd_kcontrol *kctrl, { struct snd_soc_component *component = snd_kcontrol_chip(kctrl); struct cs4234 *cs4234 = snd_soc_component_get_drvdata(component); - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); unsigned int val = 0; int ret = 0; @@ -126,10 +126,11 @@ static int cs4234_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { struct cs4234 *cs4234 = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); switch (level) { case SND_SOC_BIAS_PREPARE: - switch (snd_soc_component_get_bias_level(component)) { + switch (snd_soc_dapm_get_bias_level(dapm)) { case SND_SOC_BIAS_STANDBY: wait_for_completion(&cs4234->vq_ramp_complete); break; diff --git a/sound/soc/codecs/cs42l43-jack.c b/sound/soc/codecs/cs42l43-jack.c index ab6851d9afc770..b719d62635a0eb 100644 --- a/sound/soc/codecs/cs42l43-jack.c +++ b/sound/soc/codecs/cs42l43-jack.c @@ -502,7 +502,7 @@ static void cs42l43_start_load_detect(struct cs42l43_codec *priv) dev_dbg(priv->dev, "Start load detect\n"); - snd_soc_dapm_mutex_lock(snd_soc_component_get_dapm(priv->component)); + snd_soc_dapm_mutex_lock(snd_soc_component_to_dapm(priv->component)); priv->load_detect_running = true; @@ -539,7 +539,7 @@ static void cs42l43_start_load_detect(struct cs42l43_codec *priv) CS42L43_HPLOAD_DET_EN_MASK, CS42L43_HPLOAD_DET_EN_MASK); - snd_soc_dapm_mutex_unlock(snd_soc_component_get_dapm(priv->component)); + snd_soc_dapm_mutex_unlock(snd_soc_component_to_dapm(priv->component)); } static void cs42l43_stop_load_detect(struct cs42l43_codec *priv) @@ -548,7 +548,7 @@ static void cs42l43_stop_load_detect(struct cs42l43_codec *priv) dev_dbg(priv->dev, "Stop load detect\n"); - snd_soc_dapm_mutex_lock(snd_soc_component_get_dapm(priv->component)); + snd_soc_dapm_mutex_lock(snd_soc_component_to_dapm(priv->component)); regmap_update_bits(cs42l43->regmap, CS42L43_LOADDETENA, CS42L43_HPLOAD_DET_EN_MASK, 0); @@ -587,7 +587,7 @@ static void cs42l43_stop_load_detect(struct cs42l43_codec *priv) priv->load_detect_running = false; - snd_soc_dapm_mutex_unlock(snd_soc_component_get_dapm(priv->component)); + snd_soc_dapm_mutex_unlock(snd_soc_component_to_dapm(priv->component)); } static int cs42l43_run_load_detect(struct cs42l43_codec *priv, bool mic) diff --git a/sound/soc/codecs/cs42l43.c b/sound/soc/codecs/cs42l43.c index 3a7d76cf24dcd0..fd02d8a57e0f22 100644 --- a/sound/soc/codecs/cs42l43.c +++ b/sound/soc/codecs/cs42l43.c @@ -154,7 +154,7 @@ static void cs42l43_hp_ilimit_clear_work(struct work_struct *work) { struct cs42l43_codec *priv = container_of(work, struct cs42l43_codec, hp_ilimit_clear_work.work); - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(priv->component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(priv->component); snd_soc_dapm_mutex_lock(dapm); @@ -170,7 +170,7 @@ static void cs42l43_hp_ilimit_clear_work(struct work_struct *work) static irqreturn_t cs42l43_hp_ilimit(int irq, void *data) { struct cs42l43_codec *priv = data; - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(priv->component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(priv->component); struct cs42l43 *cs42l43 = priv->core; dev_dbg(priv->dev, "headphone ilimit IRQ\n"); @@ -451,7 +451,7 @@ static int cs42l43_asp_hw_params(struct snd_pcm_substream *substream, static int cs42l43_asp_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) { struct snd_soc_component *component = dai->component; - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct cs42l43_codec *priv = snd_soc_component_get_drvdata(component); struct cs42l43 *cs42l43 = priv->core; int provider = regmap_test_bits(cs42l43->regmap, CS42L43_ASP_CLK_CONFIG2, @@ -950,7 +950,7 @@ static int cs42l43_dapm_get_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); int ret; snd_soc_dapm_mutex_lock(dapm); @@ -964,7 +964,7 @@ static int cs42l43_dapm_put_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); int ret; snd_soc_dapm_mutex_lock(dapm); @@ -978,7 +978,7 @@ static int cs42l43_dapm_get_enum(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); int ret; snd_soc_dapm_mutex_lock(dapm); @@ -992,7 +992,7 @@ static int cs42l43_dapm_put_enum(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); int ret; snd_soc_dapm_mutex_lock(dapm); @@ -1017,7 +1017,7 @@ static int cs42l43_eq_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct cs42l43_codec *priv = snd_soc_component_get_drvdata(component); snd_soc_dapm_mutex_lock(dapm); diff --git a/sound/soc/codecs/cs42l51.c b/sound/soc/codecs/cs42l51.c index 7b60aee9cf15b1..0519affe0ed8da 100644 --- a/sound/soc/codecs/cs42l51.c +++ b/sound/soc/codecs/cs42l51.c @@ -567,7 +567,7 @@ static int cs42l51_component_probe(struct snd_soc_component *component) struct cs42l51_private *cs42l51; cs42l51 = snd_soc_component_get_drvdata(component); - dapm = snd_soc_component_get_dapm(component); + dapm = snd_soc_component_to_dapm(component); if (cs42l51->mclk_handle) snd_soc_dapm_new_controls(dapm, cs42l51_dapm_mclk_widgets, 1); diff --git a/sound/soc/codecs/cs42l52.c b/sound/soc/codecs/cs42l52.c index a9ffba62aaf88c..662dc1a4835bdb 100644 --- a/sound/soc/codecs/cs42l52.c +++ b/sound/soc/codecs/cs42l52.c @@ -851,6 +851,7 @@ static int cs42l52_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { struct cs42l52_private *cs42l52 = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); switch (level) { case SND_SOC_BIAS_ON: @@ -860,7 +861,7 @@ static int cs42l52_set_bias_level(struct snd_soc_component *component, CS42L52_PWRCTL1_PDN_CODEC, 0); break; case SND_SOC_BIAS_STANDBY: - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) { regcache_cache_only(cs42l52->regmap, false); regcache_sync(cs42l52->regmap); } @@ -919,7 +920,7 @@ static void cs42l52_beep_work(struct work_struct *work) struct cs42l52_private *cs42l52 = container_of(work, struct cs42l52_private, beep_work); struct snd_soc_component *component = cs42l52->component; - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); int i; int val = 0; int best = 0; diff --git a/sound/soc/codecs/cs42l56.c b/sound/soc/codecs/cs42l56.c index 98fa812bc07b87..aabb74f1f43c24 100644 --- a/sound/soc/codecs/cs42l56.c +++ b/sound/soc/codecs/cs42l56.c @@ -911,6 +911,7 @@ static int cs42l56_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { struct cs42l56_private *cs42l56 = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); int ret; switch (level) { @@ -923,7 +924,7 @@ static int cs42l56_set_bias_level(struct snd_soc_component *component, CS42L56_PDN_ALL_MASK, 0); break; case SND_SOC_BIAS_STANDBY: - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) { regcache_cache_only(cs42l56->regmap, false); regcache_sync(cs42l56->regmap); ret = regulator_bulk_enable(ARRAY_SIZE(cs42l56->supplies), @@ -996,7 +997,7 @@ static void cs42l56_beep_work(struct work_struct *work) struct cs42l56_private *cs42l56 = container_of(work, struct cs42l56_private, beep_work); struct snd_soc_component *component = cs42l56->component; - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); int i; int val = 0; int best = 0; diff --git a/sound/soc/codecs/cs42l73.c b/sound/soc/codecs/cs42l73.c index 535a867f9f2a6d..bda8442c1d661d 100644 --- a/sound/soc/codecs/cs42l73.c +++ b/sound/soc/codecs/cs42l73.c @@ -1101,6 +1101,7 @@ static int cs42l73_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { struct cs42l73_private *cs42l73 = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); switch (level) { case SND_SOC_BIAS_ON: @@ -1112,7 +1113,7 @@ static int cs42l73_set_bias_level(struct snd_soc_component *component, break; case SND_SOC_BIAS_STANDBY: - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) { regcache_cache_only(cs42l73->regmap, false); regcache_sync(cs42l73->regmap); } diff --git a/sound/soc/codecs/cs42xx8.c b/sound/soc/codecs/cs42xx8.c index 6a925f3f7137dd..d14538c49b9768 100644 --- a/sound/soc/codecs/cs42xx8.c +++ b/sound/soc/codecs/cs42xx8.c @@ -465,7 +465,7 @@ EXPORT_SYMBOL_GPL(cs42xx8_regmap_config); static int cs42xx8_component_probe(struct snd_soc_component *component) { struct cs42xx8_priv *cs42xx8 = snd_soc_component_get_drvdata(component); - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); switch (cs42xx8->drvdata->num_adcs) { case 3: diff --git a/sound/soc/codecs/cs47l15.c b/sound/soc/codecs/cs47l15.c index cc53ce552c2eb5..da64e0a1db28ee 100644 --- a/sound/soc/codecs/cs47l15.c +++ b/sound/soc/codecs/cs47l15.c @@ -1278,6 +1278,7 @@ static const struct snd_soc_dapm_route cs47l15_mono_routes[] = { static int cs47l15_component_probe(struct snd_soc_component *component) { + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct cs47l15 *cs47l15 = snd_soc_component_get_drvdata(component); struct madera *madera = cs47l15->core.madera; int ret; @@ -1285,7 +1286,7 @@ static int cs47l15_component_probe(struct snd_soc_component *component) snd_soc_component_init_regmap(component, madera->regmap); mutex_lock(&madera->dapm_ptr_lock); - madera->dapm = snd_soc_component_get_dapm(component); + madera->dapm = snd_soc_component_to_dapm(component); mutex_unlock(&madera->dapm_ptr_lock); ret = madera_init_inputs(component); @@ -1298,7 +1299,7 @@ static int cs47l15_component_probe(struct snd_soc_component *component) if (ret) return ret; - snd_soc_component_disable_pin(component, "HAPTICS"); + snd_soc_dapm_disable_pin(dapm, "HAPTICS"); ret = snd_soc_add_component_controls(component, madera_adsp_rate_controls, diff --git a/sound/soc/codecs/cs47l24.c b/sound/soc/codecs/cs47l24.c index e2a839fae4fccc..5100b1aac90220 100644 --- a/sound/soc/codecs/cs47l24.c +++ b/sound/soc/codecs/cs47l24.c @@ -1124,7 +1124,7 @@ static irqreturn_t cs47l24_adsp2_irq(int irq, void *data) static int cs47l24_component_probe(struct snd_soc_component *component) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct cs47l24_priv *priv = snd_soc_component_get_drvdata(component); struct arizona *arizona = priv->core.arizona; int ret; @@ -1153,7 +1153,7 @@ static int cs47l24_component_probe(struct snd_soc_component *component) if (ret) goto err_adsp2_codec_probe; - snd_soc_component_disable_pin(component, "HAPTICS"); + snd_soc_dapm_disable_pin(dapm, "HAPTICS"); return 0; diff --git a/sound/soc/codecs/cs47l35.c b/sound/soc/codecs/cs47l35.c index 85555c7a2e4bc9..a8fe5a99a8bb54 100644 --- a/sound/soc/codecs/cs47l35.c +++ b/sound/soc/codecs/cs47l35.c @@ -1559,6 +1559,7 @@ static const struct snd_soc_dapm_route cs47l35_mono_routes[] = { static int cs47l35_component_probe(struct snd_soc_component *component) { + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct cs47l35 *cs47l35 = snd_soc_component_get_drvdata(component); struct madera *madera = cs47l35->core.madera; int i, ret; @@ -1566,7 +1567,7 @@ static int cs47l35_component_probe(struct snd_soc_component *component) snd_soc_component_init_regmap(component, madera->regmap); mutex_lock(&madera->dapm_ptr_lock); - madera->dapm = snd_soc_component_get_dapm(component); + madera->dapm = snd_soc_component_to_dapm(component); mutex_unlock(&madera->dapm_ptr_lock); ret = madera_init_inputs(component); @@ -1579,7 +1580,7 @@ static int cs47l35_component_probe(struct snd_soc_component *component) if (ret) return ret; - snd_soc_component_disable_pin(component, "HAPTICS"); + snd_soc_dapm_disable_pin(dapm, "HAPTICS"); ret = snd_soc_add_component_controls(component, madera_adsp_rate_controls, diff --git a/sound/soc/codecs/cs47l85.c b/sound/soc/codecs/cs47l85.c index d34f4e8c26d37d..42fafb0b392c31 100644 --- a/sound/soc/codecs/cs47l85.c +++ b/sound/soc/codecs/cs47l85.c @@ -2497,6 +2497,7 @@ static irqreturn_t cs47l85_adsp2_irq(int irq, void *data) static int cs47l85_component_probe(struct snd_soc_component *component) { + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct cs47l85 *cs47l85 = snd_soc_component_get_drvdata(component); struct madera *madera = cs47l85->core.madera; int i, ret; @@ -2504,7 +2505,7 @@ static int cs47l85_component_probe(struct snd_soc_component *component) snd_soc_component_init_regmap(component, madera->regmap); mutex_lock(&madera->dapm_ptr_lock); - madera->dapm = snd_soc_component_get_dapm(component); + madera->dapm = snd_soc_component_to_dapm(component); mutex_unlock(&madera->dapm_ptr_lock); ret = madera_init_inputs(component); @@ -2516,7 +2517,7 @@ static int cs47l85_component_probe(struct snd_soc_component *component) if (ret) return ret; - snd_soc_component_disable_pin(component, "HAPTICS"); + snd_soc_dapm_disable_pin(dapm, "HAPTICS"); ret = snd_soc_add_component_controls(component, madera_adsp_rate_controls, diff --git a/sound/soc/codecs/cs47l90.c b/sound/soc/codecs/cs47l90.c index a9e703981f3712..77e8aabb241a1a 100644 --- a/sound/soc/codecs/cs47l90.c +++ b/sound/soc/codecs/cs47l90.c @@ -2416,6 +2416,7 @@ static irqreturn_t cs47l90_adsp2_irq(int irq, void *data) static int cs47l90_component_probe(struct snd_soc_component *component) { + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct cs47l90 *cs47l90 = snd_soc_component_get_drvdata(component); struct madera *madera = cs47l90->core.madera; int ret, i; @@ -2423,7 +2424,7 @@ static int cs47l90_component_probe(struct snd_soc_component *component) snd_soc_component_init_regmap(component, madera->regmap); mutex_lock(&madera->dapm_ptr_lock); - madera->dapm = snd_soc_component_get_dapm(component); + madera->dapm = snd_soc_component_to_dapm(component); mutex_unlock(&madera->dapm_ptr_lock); ret = madera_init_inputs(component); @@ -2435,7 +2436,7 @@ static int cs47l90_component_probe(struct snd_soc_component *component) if (ret) return ret; - snd_soc_component_disable_pin(component, "HAPTICS"); + snd_soc_dapm_disable_pin(dapm, "HAPTICS"); ret = snd_soc_add_component_controls(component, madera_adsp_rate_controls, diff --git a/sound/soc/codecs/cs47l92.c b/sound/soc/codecs/cs47l92.c index 2c355c61acd8be..868237bd6d910e 100644 --- a/sound/soc/codecs/cs47l92.c +++ b/sound/soc/codecs/cs47l92.c @@ -52,10 +52,8 @@ static const char * const cs47l92_outdemux_texts[] = { static int cs47l92_put_demux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_component *component = - snd_soc_dapm_kcontrol_component(kcontrol); - struct snd_soc_dapm_context *dapm = - snd_soc_component_get_dapm(component); + struct snd_soc_component *component = snd_soc_dapm_kcontrol_to_component(kcontrol); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct cs47l92 *cs47l92 = snd_soc_component_get_drvdata(component); struct madera_priv *priv = &cs47l92->core; struct madera *madera = priv->madera; @@ -1887,6 +1885,7 @@ static const struct snd_soc_dapm_route cs47l92_mono_routes[] = { static int cs47l92_component_probe(struct snd_soc_component *component) { + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct cs47l92 *cs47l92 = snd_soc_component_get_drvdata(component); struct madera *madera = cs47l92->core.madera; int ret; @@ -1894,7 +1893,7 @@ static int cs47l92_component_probe(struct snd_soc_component *component) snd_soc_component_init_regmap(component, madera->regmap); mutex_lock(&madera->dapm_ptr_lock); - madera->dapm = snd_soc_component_get_dapm(component); + madera->dapm = snd_soc_component_to_dapm(component); mutex_unlock(&madera->dapm_ptr_lock); ret = madera_init_inputs(component); @@ -1907,7 +1906,7 @@ static int cs47l92_component_probe(struct snd_soc_component *component) if (ret) return ret; - snd_soc_component_disable_pin(component, "HAPTICS"); + snd_soc_dapm_disable_pin(dapm, "HAPTICS"); ret = snd_soc_add_component_controls(component, madera_adsp_rate_controls, diff --git a/sound/soc/codecs/cs48l32.c b/sound/soc/codecs/cs48l32.c index 657f0697e8569c..086ed0f57a85e0 100644 --- a/sound/soc/codecs/cs48l32.c +++ b/sound/soc/codecs/cs48l32.c @@ -320,8 +320,8 @@ static const struct soc_enum cs48l32_sample_rate[] = { static int cs48l32_inmux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_component *component = snd_soc_dapm_kcontrol_component(kcontrol); - struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol); + struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kcontrol); + struct snd_soc_component *component = snd_soc_dapm_to_component(dapm); struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component); struct soc_enum *e = (struct soc_enum *) kcontrol->private_value; unsigned int mux, src_val, in_type; @@ -347,7 +347,7 @@ static int cs48l32_inmux_put(struct snd_kcontrol *kcontrol, if (in_type == CS48L32_IN_TYPE_SE) src_val |= 1 << CS48L32_INx_SRC_SHIFT; - ret = snd_soc_component_update_bits(dapm->component, + ret = snd_soc_component_update_bits(component, e->reg, CS48L32_INx_SRC_MASK, src_val); @@ -385,7 +385,7 @@ static const char * const cs48l32_dmode_texts[] = { static int cs48l32_dmode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol); + struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kcontrol); struct snd_soc_component *component = snd_soc_dapm_to_component(dapm); struct soc_enum *e = (struct soc_enum *) kcontrol->private_value; unsigned int mode; @@ -705,7 +705,7 @@ static int cs48l32_in_rate_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; int ret; @@ -756,7 +756,7 @@ static int cs48l32_low_power_mode_put(struct snd_kcontrol *kcontrol, { struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); int ret; snd_soc_dapm_mutex_lock(dapm); @@ -962,7 +962,7 @@ static int cs48l32_eq_mode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component); struct soc_enum *e = (struct soc_enum *) kcontrol->private_value; unsigned int *item = ucontrol->value.enumerated.item; @@ -1026,7 +1026,7 @@ static int cs48l32_eq_coeff_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component); struct cs48l32_eq_control *params = (void *)kcontrol->private_value; __be16 *coeffs; @@ -1083,7 +1083,7 @@ static int cs48l32_dsp_rate_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component); struct soc_enum *e = (struct soc_enum *) kcontrol->private_value; const unsigned int rate_num = e->mask; diff --git a/sound/soc/codecs/cs530x.c b/sound/soc/codecs/cs530x.c index f8f409d0b03507..18b5ff75feec4b 100644 --- a/sound/soc/codecs/cs530x.c +++ b/sound/soc/codecs/cs530x.c @@ -131,7 +131,7 @@ static int cs530x_put_volsw_vu(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct cs530x_priv *cs530x = snd_soc_component_get_drvdata(component); struct regmap *regmap = cs530x->regmap; int ret; @@ -522,7 +522,7 @@ static const struct snd_soc_dapm_route adc_ch5_8_routes[] = { static void cs530x_add_12_adc_widgets(struct snd_soc_component *component) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); snd_soc_add_component_controls(component, cs530x_in_1_to_2_controls, @@ -537,7 +537,7 @@ static void cs530x_add_12_adc_widgets(struct snd_soc_component *component) static void cs530x_add_34_adc_widgets(struct snd_soc_component *component) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); snd_soc_add_component_controls(component, cs530x_in_3_to_4_controls, @@ -669,7 +669,7 @@ static const struct snd_soc_dapm_route dac_ch5_8_routes[] = { static void cs530x_add_12_dac_widgets(struct snd_soc_component *component) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); snd_soc_add_component_controls(component, cs530x_out_1_to_2_controls, @@ -684,7 +684,7 @@ static void cs530x_add_12_dac_widgets(struct snd_soc_component *component) static void cs530x_add_34_dac_widgets(struct snd_soc_component *component) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); snd_soc_add_component_controls(component, cs530x_out_3_to_4_controls, @@ -1007,7 +1007,7 @@ static int cs530x_set_pll(struct snd_soc_component *component, int pll_id, static int cs530x_component_probe(struct snd_soc_component *component) { struct cs530x_priv *cs530x = snd_soc_component_get_drvdata(component); - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); int num_widgets; snd_soc_dapm_new_controls(dapm, cs530x_gen_dapm_widgets, diff --git a/sound/soc/codecs/cs53l30.c b/sound/soc/codecs/cs53l30.c index 61bf72681674c0..93ea2fb4dae93f 100644 --- a/sound/soc/codecs/cs53l30.c +++ b/sound/soc/codecs/cs53l30.c @@ -649,8 +649,9 @@ static int cs53l30_pcm_hw_params(struct snd_pcm_substream *substream, static int cs53l30_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct cs53l30_private *priv = snd_soc_component_get_drvdata(component); + enum snd_soc_bias_level bias_level = snd_soc_dapm_get_bias_level(dapm); unsigned int reg; int i, inter_max_check, ret; @@ -658,12 +659,12 @@ static int cs53l30_set_bias_level(struct snd_soc_component *component, case SND_SOC_BIAS_ON: break; case SND_SOC_BIAS_PREPARE: - if (dapm->bias_level == SND_SOC_BIAS_STANDBY) + if (bias_level == SND_SOC_BIAS_STANDBY) regmap_update_bits(priv->regmap, CS53L30_PWRCTL, CS53L30_PDN_LP_MASK, 0); break; case SND_SOC_BIAS_STANDBY: - if (dapm->bias_level == SND_SOC_BIAS_OFF) { + if (bias_level == SND_SOC_BIAS_OFF) { ret = clk_prepare_enable(priv->mclk); if (ret) { dev_err(component->dev, @@ -857,7 +858,7 @@ static struct snd_soc_dai_driver cs53l30_dai = { static int cs53l30_component_probe(struct snd_soc_component *component) { struct cs53l30_private *priv = snd_soc_component_get_drvdata(component); - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); if (priv->use_sdout2) snd_soc_dapm_add_routes(dapm, cs53l30_dapm_routes_sdout2, diff --git a/sound/soc/codecs/cx20442.c b/sound/soc/codecs/cx20442.c index 9d54141a0cd1e9..d6121c0a26167c 100644 --- a/sound/soc/codecs/cx20442.c +++ b/sound/soc/codecs/cx20442.c @@ -315,11 +315,12 @@ static int cx20442_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { struct cx20442_priv *cx20442 = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); int err = 0; switch (level) { case SND_SOC_BIAS_PREPARE: - if (snd_soc_component_get_bias_level(component) != SND_SOC_BIAS_STANDBY) + if (snd_soc_dapm_get_bias_level(dapm) != SND_SOC_BIAS_STANDBY) break; if (IS_ERR(cx20442->por)) err = PTR_ERR(cx20442->por); @@ -327,7 +328,7 @@ static int cx20442_set_bias_level(struct snd_soc_component *component, err = regulator_enable(cx20442->por); break; case SND_SOC_BIAS_STANDBY: - if (snd_soc_component_get_bias_level(component) != SND_SOC_BIAS_PREPARE) + if (snd_soc_dapm_get_bias_level(dapm) != SND_SOC_BIAS_PREPARE) break; if (IS_ERR(cx20442->por)) err = PTR_ERR(cx20442->por); diff --git a/sound/soc/codecs/cx2072x.c b/sound/soc/codecs/cx2072x.c index 934526f8f292ca..b0033bf9be3aa8 100644 --- a/sound/soc/codecs/cx2072x.c +++ b/sound/soc/codecs/cx2072x.c @@ -1341,8 +1341,8 @@ static int cx2072x_set_bias_level(struct snd_soc_component *codec, enum snd_soc_bias_level level) { struct cx2072x_priv *cx2072x = snd_soc_component_get_drvdata(codec); - const enum snd_soc_bias_level old_level = - snd_soc_component_get_bias_level(codec); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(codec); + const enum snd_soc_bias_level old_level = snd_soc_dapm_get_bias_level(dapm); if (level == SND_SOC_BIAS_STANDBY && old_level == SND_SOC_BIAS_OFF) regmap_write(cx2072x->regmap, CX2072X_AFG_POWER_STATE, 0); @@ -1363,7 +1363,7 @@ static int cx2072x_set_bias_level(struct snd_soc_component *codec, static void cx2072x_enable_jack_detect(struct snd_soc_component *codec) { struct cx2072x_priv *cx2072x = snd_soc_component_get_drvdata(codec); - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(codec); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(codec); /* No-sticky input type */ regmap_write(cx2072x->regmap, CX2072X_GPIO_STICKY_MASK, 0x1f); diff --git a/sound/soc/codecs/da7213.c b/sound/soc/codecs/da7213.c index 81bd5b03e2b659..0a2b50cdea95cb 100644 --- a/sound/soc/codecs/da7213.c +++ b/sound/soc/codecs/da7213.c @@ -1816,6 +1816,7 @@ static int da7213_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { struct da7213_priv *da7213 = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); int ret; switch (level) { @@ -1823,7 +1824,7 @@ static int da7213_set_bias_level(struct snd_soc_component *component, break; case SND_SOC_BIAS_PREPARE: /* Enable MCLK for transition to ON state */ - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_STANDBY) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_STANDBY) { if (da7213->mclk) { ret = clk_prepare_enable(da7213->mclk); if (ret) { @@ -1837,7 +1838,7 @@ static int da7213_set_bias_level(struct snd_soc_component *component, } break; case SND_SOC_BIAS_STANDBY: - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) { /* Enable VMID reference & master bias */ snd_soc_component_update_bits(component, DA7213_REFERENCES, DA7213_VMID_EN | DA7213_BIAS_EN, diff --git a/sound/soc/codecs/da7218.c b/sound/soc/codecs/da7218.c index e6f4299073e9ac..5c80839704c70e 100644 --- a/sound/soc/codecs/da7218.c +++ b/sound/soc/codecs/da7218.c @@ -2562,6 +2562,7 @@ static int da7218_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); int ret; switch (level) { @@ -2569,7 +2570,7 @@ static int da7218_set_bias_level(struct snd_soc_component *component, break; case SND_SOC_BIAS_PREPARE: /* Enable MCLK for transition to ON state */ - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_STANDBY) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_STANDBY) { if (da7218->mclk) { ret = clk_prepare_enable(da7218->mclk); if (ret) { @@ -2581,7 +2582,7 @@ static int da7218_set_bias_level(struct snd_soc_component *component, break; case SND_SOC_BIAS_STANDBY: - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) { /* Master bias */ snd_soc_component_update_bits(component, DA7218_REFERENCES, DA7218_BIAS_EN_MASK, diff --git a/sound/soc/codecs/da7219-aad.c b/sound/soc/codecs/da7219-aad.c index 15e5e3eb592b30..d9d932a78b710c 100644 --- a/sound/soc/codecs/da7219-aad.c +++ b/sound/soc/codecs/da7219-aad.c @@ -53,7 +53,7 @@ static void da7219_aad_btn_det_work(struct work_struct *work) struct da7219_aad_priv *da7219_aad = container_of(work, struct da7219_aad_priv, btn_det_work); struct snd_soc_component *component = da7219_aad->component; - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component); u8 statusa, micbias_ctrl; bool micbias_up = false; @@ -109,7 +109,7 @@ static void da7219_aad_hptest_work(struct work_struct *work) struct da7219_aad_priv *da7219_aad = container_of(work, struct da7219_aad_priv, hptest_work); struct snd_soc_component *component = da7219_aad->component; - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component); __le16 tonegen_freq_hptest; @@ -351,7 +351,7 @@ static irqreturn_t da7219_aad_irq_thread(int irq, void *data) { struct da7219_aad_priv *da7219_aad = data; struct snd_soc_component *component = da7219_aad->component; - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component); u8 events[DA7219_AAD_IRQ_REG_MAX]; u8 statusa; @@ -928,7 +928,7 @@ void da7219_aad_suspend(struct snd_soc_component *component) { struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component); struct da7219_aad_priv *da7219_aad = da7219->aad; - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); u8 micbias_ctrl; disable_irq(da7219_aad->irq); @@ -962,7 +962,7 @@ void da7219_aad_resume(struct snd_soc_component *component) { struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component); struct da7219_aad_priv *da7219_aad = da7219->aad; - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); if (da7219_aad->jack) { /* Re-enable micbias if previously enabled for 4-pole jack */ diff --git a/sound/soc/codecs/da7219.c b/sound/soc/codecs/da7219.c index 2bc6b03488105f..298a626df3adec 100644 --- a/sound/soc/codecs/da7219.c +++ b/sound/soc/codecs/da7219.c @@ -1807,6 +1807,7 @@ static int da7219_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); int ret; switch (level) { @@ -1814,7 +1815,7 @@ static int da7219_set_bias_level(struct snd_soc_component *component, break; case SND_SOC_BIAS_PREPARE: /* Enable MCLK for transition to ON state */ - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_STANDBY) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_STANDBY) { if (da7219->mclk) { ret = clk_prepare_enable(da7219->mclk); if (ret) { @@ -1827,13 +1828,13 @@ static int da7219_set_bias_level(struct snd_soc_component *component, break; case SND_SOC_BIAS_STANDBY: - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) /* Master bias */ snd_soc_component_update_bits(component, DA7219_REFERENCES, DA7219_BIAS_EN_MASK, DA7219_BIAS_EN_MASK); - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_PREPARE) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_PREPARE) { /* Remove MCLK */ if (da7219->mclk) clk_disable_unprepare(da7219->mclk); @@ -2613,12 +2614,13 @@ static void da7219_remove(struct snd_soc_component *component) static int da7219_suspend(struct snd_soc_component *component) { struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); /* Suspend AAD if we're not a wake-up source */ if (!da7219->wakeup_source) da7219_aad_suspend(component); - snd_soc_component_force_bias_level(component, SND_SOC_BIAS_OFF); + snd_soc_dapm_force_bias_level(dapm, SND_SOC_BIAS_OFF); return 0; } @@ -2626,8 +2628,9 @@ static int da7219_suspend(struct snd_soc_component *component) static int da7219_resume(struct snd_soc_component *component) { struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); - snd_soc_component_force_bias_level(component, SND_SOC_BIAS_STANDBY); + snd_soc_dapm_force_bias_level(dapm, SND_SOC_BIAS_STANDBY); /* Resume AAD if previously suspended */ if (!da7219->wakeup_source) diff --git a/sound/soc/codecs/da732x.c b/sound/soc/codecs/da732x.c index 8ff308ba73846b..140e449d3ef4d2 100644 --- a/sound/soc/codecs/da732x.c +++ b/sound/soc/codecs/da732x.c @@ -1408,6 +1408,7 @@ static int da732x_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { struct da732x_priv *da732x = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); switch (level) { case SND_SOC_BIAS_ON: @@ -1418,7 +1419,7 @@ static int da732x_set_bias_level(struct snd_soc_component *component, case SND_SOC_BIAS_PREPARE: break; case SND_SOC_BIAS_STANDBY: - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) { /* Init Codec */ snd_soc_component_write(component, DA732X_REG_REF1, DA732X_VMID_FASTCHG); diff --git a/sound/soc/codecs/da9055.c b/sound/soc/codecs/da9055.c index e64b5101961439..a52276e32f2fdc 100644 --- a/sound/soc/codecs/da9055.c +++ b/sound/soc/codecs/da9055.c @@ -1352,12 +1352,14 @@ static struct snd_soc_dai_driver da9055_dai = { static int da9055_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); + switch (level) { case SND_SOC_BIAS_ON: case SND_SOC_BIAS_PREPARE: break; case SND_SOC_BIAS_STANDBY: - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) { /* Enable VMID reference & master bias */ snd_soc_component_update_bits(component, DA9055_REFERENCES, DA9055_VMID_EN | DA9055_BIAS_EN, diff --git a/sound/soc/codecs/es7134.c b/sound/soc/codecs/es7134.c index f5150d2f95da68..441df1523f1c96 100644 --- a/sound/soc/codecs/es7134.c +++ b/sound/soc/codecs/es7134.c @@ -104,7 +104,7 @@ static int es7134_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) static int es7134_component_probe(struct snd_soc_component *c) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(c); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(c); struct es7134_data *priv = snd_soc_component_get_drvdata(c); const struct es7134_chip *chip = priv->chip; int ret; diff --git a/sound/soc/codecs/es8311.c b/sound/soc/codecs/es8311.c index f557e33c26ad9e..0b07a53cc792e6 100644 --- a/sound/soc/codecs/es8311.c +++ b/sound/soc/codecs/es8311.c @@ -760,6 +760,7 @@ static int es8311_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { struct es8311_priv *es8311 = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); switch (level) { case SND_SOC_BIAS_ON: @@ -767,7 +768,7 @@ static int es8311_set_bias_level(struct snd_soc_component *component, case SND_SOC_BIAS_PREPARE: break; case SND_SOC_BIAS_STANDBY: - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) { int ret = clk_prepare_enable(es8311->mclk); if (ret) { dev_err(component->dev, diff --git a/sound/soc/codecs/es8316.c b/sound/soc/codecs/es8316.c index e7bd561a8f40d4..9245c33700dee2 100644 --- a/sound/soc/codecs/es8316.c +++ b/sound/soc/codecs/es8316.c @@ -590,7 +590,7 @@ static struct snd_soc_dai_driver es8316_dai = { static void es8316_enable_micbias_for_mic_gnd_short_detect( struct snd_soc_component *component) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); snd_soc_dapm_mutex_lock(dapm); snd_soc_dapm_force_enable_pin_unlocked(dapm, "Bias"); @@ -605,7 +605,7 @@ static void es8316_enable_micbias_for_mic_gnd_short_detect( static void es8316_disable_micbias_for_mic_gnd_short_detect( struct snd_soc_component *component) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); snd_soc_dapm_mutex_lock(dapm); snd_soc_dapm_disable_pin_unlocked(dapm, "Mic Bias"); diff --git a/sound/soc/codecs/es8326.c b/sound/soc/codecs/es8326.c index f3b25220141b54..05b13661c38cdf 100644 --- a/sound/soc/codecs/es8326.c +++ b/sound/soc/codecs/es8326.c @@ -737,7 +737,7 @@ static struct snd_soc_dai_driver es8326_dai = { static void es8326_enable_micbias(struct snd_soc_component *component) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); snd_soc_dapm_mutex_lock(dapm); snd_soc_dapm_force_enable_pin_unlocked(dapm, "MICBIAS1"); @@ -748,7 +748,7 @@ static void es8326_enable_micbias(struct snd_soc_component *component) static void es8326_disable_micbias(struct snd_soc_component *component) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); snd_soc_dapm_mutex_lock(dapm); snd_soc_dapm_disable_pin_unlocked(dapm, "MICBIAS1"); diff --git a/sound/soc/codecs/es8328.c b/sound/soc/codecs/es8328.c index e5762c6e56e663..1e11175cfbbbf2 100644 --- a/sound/soc/codecs/es8328.c +++ b/sound/soc/codecs/es8328.c @@ -643,6 +643,8 @@ static int es8328_set_dai_fmt(struct snd_soc_dai *codec_dai, static int es8328_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); + switch (level) { case SND_SOC_BIAS_ON: break; @@ -658,7 +660,7 @@ static int es8328_set_bias_level(struct snd_soc_component *component, break; case SND_SOC_BIAS_STANDBY: - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) { snd_soc_component_update_bits(component, ES8328_CONTROL1, ES8328_CONTROL1_VMIDSEL_MASK | ES8328_CONTROL1_ENREF, diff --git a/sound/soc/codecs/es8389.c b/sound/soc/codecs/es8389.c index 6e4c75d288ef99..a84d79f9d3d18c 100644 --- a/sound/soc/codecs/es8389.c +++ b/sound/soc/codecs/es8389.c @@ -57,8 +57,8 @@ static const DECLARE_TLV_DB_SCALE(alc_max_level, -3200, 200, 0); static int es8389_dmic_set(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_component *component = snd_soc_dapm_kcontrol_component(kcontrol); - struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol); + struct snd_soc_component *component = snd_soc_dapm_kcontrol_to_component(kcontrol); + struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kcontrol); struct es8389_private *es8389 = snd_soc_component_get_drvdata(component); struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; unsigned int val; diff --git a/sound/soc/codecs/hda.c b/sound/soc/codecs/hda.c index ede980cc60501e..237b0b060457e8 100644 --- a/sound/soc/codecs/hda.c +++ b/sound/soc/codecs/hda.c @@ -96,7 +96,7 @@ static int hda_codec_register_dais(struct hda_codec *codec, struct snd_soc_compo if (ret < 0) return ret; - dapm = snd_soc_component_get_dapm(component); + dapm = snd_soc_component_to_dapm(component); list_for_each_entry(pcm, &codec->pcm_list_head, list) { struct snd_soc_dai *dai; diff --git a/sound/soc/codecs/hdac_hda.c b/sound/soc/codecs/hdac_hda.c index afd8edf10fdc87..680e341aa7f1b3 100644 --- a/sound/soc/codecs/hdac_hda.c +++ b/sound/soc/codecs/hdac_hda.c @@ -405,8 +405,6 @@ static int hdac_hda_codec_probe(struct snd_soc_component *component) { struct hdac_hda_priv *hda_pvt = snd_soc_component_get_drvdata(component); - struct snd_soc_dapm_context *dapm = - snd_soc_component_get_dapm(component); struct hdac_device *hdev = &hda_pvt->codec->core; struct hda_codec *hcodec = hda_pvt->codec; struct hda_codec_driver *driver = hda_codec_to_driver(hcodec); @@ -470,7 +468,7 @@ static int hdac_hda_codec_probe(struct snd_soc_component *component) */ pm_runtime_get_noresume(&hdev->dev); - hcodec->bus->card = dapm->card->snd_card; + hcodec->bus->card = component->card->snd_card; ret = snd_hda_codec_set_name(hcodec, hcodec->preset->name); if (ret < 0) { diff --git a/sound/soc/codecs/hdac_hdmi.c b/sound/soc/codecs/hdac_hdmi.c index e50afd0bfcecc7..2652fcf2a3a345 100644 --- a/sound/soc/codecs/hdac_hdmi.c +++ b/sound/soc/codecs/hdac_hdmi.c @@ -769,7 +769,8 @@ static int hdac_hdmi_pin_output_widget_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kc, int event) { struct hdac_hdmi_port *port = w->priv; - struct hdac_device *hdev = dev_to_hdac_dev(w->dapm->dev); + struct device *dev = snd_soc_dapm_to_dev(w->dapm); + struct hdac_device *hdev = dev_to_hdac_dev(dev); struct hdac_hdmi_pcm *pcm; dev_dbg(&hdev->dev, "%s: widget: %s event: %x\n", @@ -814,7 +815,8 @@ static int hdac_hdmi_cvt_output_widget_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kc, int event) { struct hdac_hdmi_cvt *cvt = w->priv; - struct hdac_device *hdev = dev_to_hdac_dev(w->dapm->dev); + struct device *dev = snd_soc_dapm_to_dev(w->dapm); + struct hdac_device *hdev = dev_to_hdac_dev(dev); struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(hdev); struct hdac_hdmi_pcm *pcm; @@ -869,7 +871,8 @@ static int hdac_hdmi_pin_mux_widget_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kc, int event) { struct hdac_hdmi_port *port = w->priv; - struct hdac_device *hdev = dev_to_hdac_dev(w->dapm->dev); + struct device *dev = snd_soc_dapm_to_dev(w->dapm); + struct hdac_device *hdev = dev_to_hdac_dev(dev); int mux_idx; dev_dbg(&hdev->dev, "%s: widget: %s event: %x\n", @@ -878,7 +881,7 @@ static int hdac_hdmi_pin_mux_widget_event(struct snd_soc_dapm_widget *w, if (!kc) kc = w->kcontrols[0]; - mux_idx = dapm_kcontrol_get_value(kc); + mux_idx = snd_soc_dapm_kcontrol_get_value(kc); /* set the device if pin is mst_capable */ if (hdac_hdmi_port_select_set(hdev, port) < 0) @@ -901,10 +904,11 @@ static int hdac_hdmi_set_pin_port_mux(struct snd_kcontrol *kcontrol, int ret; struct hdac_hdmi_port *p, *p_next; struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; - struct snd_soc_dapm_widget *w = snd_soc_dapm_kcontrol_widget(kcontrol); + struct snd_soc_dapm_widget *w = snd_soc_dapm_kcontrol_to_widget(kcontrol); struct snd_soc_dapm_context *dapm = w->dapm; + struct device *dev = snd_soc_dapm_to_dev(dapm); struct hdac_hdmi_port *port = w->priv; - struct hdac_device *hdev = dev_to_hdac_dev(dapm->dev); + struct hdac_device *hdev = dev_to_hdac_dev(dev); struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(hdev); struct hdac_hdmi_pcm *pcm; const char *cvt_name = e->texts[ucontrol->value.enumerated.item[0]]; @@ -1070,9 +1074,11 @@ static void hdac_hdmi_add_pinmux_cvt_route(struct hdac_device *hdev, */ static int create_fill_widget_route_map(struct snd_soc_dapm_context *dapm) { + struct device *dev = snd_soc_dapm_to_dev(dapm); + struct snd_soc_card *card = snd_soc_dapm_to_card(dapm); struct snd_soc_dapm_widget *widgets; struct snd_soc_dapm_route *route; - struct hdac_device *hdev = dev_to_hdac_dev(dapm->dev); + struct hdac_device *hdev = dev_to_hdac_dev(dev); struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(hdev); struct snd_soc_dai_driver *dai_drv = hdmi->dai_drv; char widget_name[NAME_SIZE]; @@ -1083,7 +1089,7 @@ static int create_fill_widget_route_map(struct snd_soc_dapm_context *dapm) if (list_empty(&hdmi->cvt_list) || list_empty(&hdmi->pin_list)) return -EINVAL; - widgets = devm_kzalloc(dapm->dev, (sizeof(*widgets) * + widgets = devm_kzalloc(dev, (sizeof(*widgets) * ((2 * hdmi->num_ports) + hdmi->num_cvt)), GFP_KERNEL); @@ -1093,7 +1099,7 @@ static int create_fill_widget_route_map(struct snd_soc_dapm_context *dapm) /* DAPM widgets to represent each converter widget */ list_for_each_entry(cvt, &hdmi->cvt_list, head) { sprintf(widget_name, "Converter %d", cvt->nid); - ret = hdac_hdmi_fill_widget_info(dapm->dev, &widgets[i], + ret = hdac_hdmi_fill_widget_info(dev, &widgets[i], snd_soc_dapm_aif_in, cvt, widget_name, dai_drv[i].playback.stream_name, NULL, 0, hdac_hdmi_cvt_output_widget_event, @@ -1107,7 +1113,7 @@ static int create_fill_widget_route_map(struct snd_soc_dapm_context *dapm) for (j = 0; j < pin->num_ports; j++) { sprintf(widget_name, "hif%d-%d Output", pin->nid, pin->ports[j].id); - ret = hdac_hdmi_fill_widget_info(dapm->dev, &widgets[i], + ret = hdac_hdmi_fill_widget_info(dev, &widgets[i], snd_soc_dapm_output, &pin->ports[j], widget_name, NULL, NULL, 0, hdac_hdmi_pin_output_widget_event, @@ -1140,7 +1146,7 @@ static int create_fill_widget_route_map(struct snd_soc_dapm_context *dapm) } } - route = devm_kzalloc(dapm->dev, (sizeof(*route) * num_routes), + route = devm_kzalloc(dev, (sizeof(*route) * num_routes), GFP_KERNEL); if (!route) return -ENOMEM; @@ -1166,7 +1172,7 @@ static int create_fill_widget_route_map(struct snd_soc_dapm_context *dapm) ((2 * hdmi->num_ports) + hdmi->num_cvt)); snd_soc_dapm_add_routes(dapm, route, num_routes); - snd_soc_dapm_new_widgets(dapm->card); + snd_soc_dapm_new_widgets(card); return 0; @@ -1666,8 +1672,7 @@ static int hdmi_codec_probe(struct snd_soc_component *component) { struct hdac_hdmi_priv *hdmi = snd_soc_component_get_drvdata(component); struct hdac_device *hdev = hdmi->hdev; - struct snd_soc_dapm_context *dapm = - snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct hdac_ext_link *hlink; int ret; @@ -1698,7 +1703,7 @@ static int hdmi_codec_probe(struct snd_soc_component *component) hdac_hdmi_present_sense_all_pins(hdev, hdmi, true); /* Imp: Store the card pointer in hda_codec */ - hdmi->card = dapm->card->snd_card; + hdmi->card = component->card->snd_card; /* * Setup a device_link between card device and HDMI codec device. diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c index e1933f733af103..13ae9e83bc21ff 100644 --- a/sound/soc/codecs/hdmi-codec.c +++ b/sound/soc/codecs/hdmi-codec.c @@ -908,7 +908,7 @@ static int hdmi_dai_probe(struct snd_soc_dai *dai) }; int ret, i; - dapm = snd_soc_component_get_dapm(dai->component); + dapm = snd_soc_component_to_dapm(dai->component); /* One of the directions might be omitted for unidirectional DAIs */ for (i = 0; i < ARRAY_SIZE(route); i++) { diff --git a/sound/soc/codecs/jz4740.c b/sound/soc/codecs/jz4740.c index d1cea93bdb5984..d3d801d850a16e 100644 --- a/sound/soc/codecs/jz4740.c +++ b/sound/soc/codecs/jz4740.c @@ -231,6 +231,7 @@ static void jz4740_codec_wakeup(struct regmap *regmap) static int jz4740_codec_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct jz4740_codec *jz4740_codec = snd_soc_component_get_drvdata(component); struct regmap *regmap = jz4740_codec->regmap; unsigned int mask; @@ -247,7 +248,7 @@ static int jz4740_codec_set_bias_level(struct snd_soc_component *component, break; case SND_SOC_BIAS_STANDBY: /* The only way to clear the suspend flag is to reset the codec */ - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) jz4740_codec_wakeup(regmap); mask = JZ4740_CODEC_1_VREF_DISABLE | diff --git a/sound/soc/codecs/jz4760.c b/sound/soc/codecs/jz4760.c index e04af1b9ace861..344c251be39775 100644 --- a/sound/soc/codecs/jz4760.c +++ b/sound/soc/codecs/jz4760.c @@ -197,7 +197,7 @@ static int jz4760_codec_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct snd_soc_component *codec = dai->component; - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(codec); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(codec); int ret = 0; /* @@ -214,7 +214,7 @@ static void jz4760_codec_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct snd_soc_component *codec = dai->component; - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(codec); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(codec); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) snd_soc_dapm_disable_pin(dapm, "SYSCLK"); @@ -225,6 +225,7 @@ static int jz4760_codec_pcm_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai) { struct snd_soc_component *codec = dai->component; + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(codec); int ret = 0; switch (cmd) { @@ -232,7 +233,7 @@ static int jz4760_codec_pcm_trigger(struct snd_pcm_substream *substream, case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK) - snd_soc_component_force_bias_level(codec, SND_SOC_BIAS_ON); + snd_soc_dapm_force_bias_level(dapm, SND_SOC_BIAS_ON); break; case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_SUSPEND: diff --git a/sound/soc/codecs/jz4770.c b/sound/soc/codecs/jz4770.c index 312202ab5ceae3..6b86d47028d778 100644 --- a/sound/soc/codecs/jz4770.c +++ b/sound/soc/codecs/jz4770.c @@ -217,7 +217,7 @@ static int jz4770_codec_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct snd_soc_component *codec = dai->component; - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(codec); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(codec); /* * SYSCLK output from the codec to the AIC is required to keep the @@ -234,7 +234,7 @@ static void jz4770_codec_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct snd_soc_component *codec = dai->component; - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(codec); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(codec); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) snd_soc_dapm_disable_pin(dapm, "SYSCLK"); @@ -245,6 +245,7 @@ static int jz4770_codec_pcm_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai) { struct snd_soc_component *codec = dai->component; + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(codec); int ret = 0; switch (cmd) { @@ -252,8 +253,7 @@ static int jz4770_codec_pcm_trigger(struct snd_pcm_substream *substream, case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK) - snd_soc_component_force_bias_level(codec, - SND_SOC_BIAS_ON); + snd_soc_dapm_force_bias_level(dapm, SND_SOC_BIAS_ON); break; case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_SUSPEND: diff --git a/sound/soc/codecs/lm49453.c b/sound/soc/codecs/lm49453.c index ab89af7965bfc6..0430305097959e 100644 --- a/sound/soc/codecs/lm49453.c +++ b/sound/soc/codecs/lm49453.c @@ -1255,6 +1255,7 @@ static int lm49453_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { struct lm49453_priv *lm49453 = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); switch (level) { case SND_SOC_BIAS_ON: @@ -1262,7 +1263,7 @@ static int lm49453_set_bias_level(struct snd_soc_component *component, break; case SND_SOC_BIAS_STANDBY: - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) regcache_sync(lm49453->regmap); snd_soc_component_update_bits(component, LM49453_P0_PMC_SETUP_REG, diff --git a/sound/soc/codecs/lpass-rx-macro.c b/sound/soc/codecs/lpass-rx-macro.c index 9053c93bd44c54..0a8de5620e7235 100644 --- a/sound/soc/codecs/lpass-rx-macro.c +++ b/sound/soc/codecs/lpass-rx-macro.c @@ -1682,7 +1682,7 @@ static const struct regmap_config rx_regmap_config = { static int rx_macro_int_dem_inp_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_widget(kcontrol); + struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_to_widget(kcontrol); struct snd_soc_component *component = snd_soc_dapm_to_component(widget->dapm); struct rx_macro *rx = snd_soc_component_get_drvdata(component); struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; @@ -1905,52 +1905,48 @@ static int rx_macro_digital_mute(struct snd_soc_dai *dai, int mute, int stream) { struct snd_soc_component *component = dai->component; struct rx_macro *rx = snd_soc_component_get_drvdata(component); - uint16_t j, reg, mix_reg, dsm_reg; - u16 int_mux_cfg0, int_mux_cfg1; + u32 port, j, reg, mix_reg, int_mux_cfg0, int_mux_cfg1; + u32 mask, val; u8 int_mux_cfg0_val, int_mux_cfg1_val; - switch (dai->id) { - case RX_MACRO_AIF1_PB: - case RX_MACRO_AIF2_PB: - case RX_MACRO_AIF3_PB: - case RX_MACRO_AIF4_PB: - for (j = 0; j < INTERP_MAX; j++) { - reg = CDC_RX_RXn_RX_PATH_CTL(rx, j); - mix_reg = CDC_RX_RXn_RX_PATH_MIX_CTL(rx, j); - dsm_reg = CDC_RX_RXn_RX_PATH_DSM_CTL(rx, j); - - if (mute) { - snd_soc_component_update_bits(component, reg, - CDC_RX_PATH_PGA_MUTE_MASK, - CDC_RX_PATH_PGA_MUTE_ENABLE); - snd_soc_component_update_bits(component, mix_reg, - CDC_RX_PATH_PGA_MUTE_MASK, - CDC_RX_PATH_PGA_MUTE_ENABLE); - } else { - snd_soc_component_update_bits(component, reg, - CDC_RX_PATH_PGA_MUTE_MASK, 0x0); - snd_soc_component_update_bits(component, mix_reg, - CDC_RX_PATH_PGA_MUTE_MASK, 0x0); + if (stream != SNDRV_PCM_STREAM_PLAYBACK) + return 0; + + for (j = 0; j < INTERP_MAX; j++) { + reg = CDC_RX_RXn_RX_PATH_CTL(rx, j); + mix_reg = CDC_RX_RXn_RX_PATH_MIX_CTL(rx, j); + + mask = CDC_RX_PATH_PGA_MUTE_MASK; + val = 0; + if (mute) + val |= CDC_RX_PATH_PGA_MUTE_ENABLE; + if (rx->main_clk_users[j] > 0) { + mask |= CDC_RX_PATH_CLK_EN_MASK; + val |= CDC_RX_PATH_CLK_ENABLE; + } + + int_mux_cfg0 = CDC_RX_INP_MUX_RX_INT0_CFG0 + j * 8; + int_mux_cfg1 = int_mux_cfg0 + 4; + int_mux_cfg0_val = snd_soc_component_read(component, int_mux_cfg0); + int_mux_cfg1_val = snd_soc_component_read(component, int_mux_cfg1); + + for_each_set_bit(port, &rx->active_ch_mask[dai->id], RX_MACRO_PORTS_MAX) { + if (((int_mux_cfg0_val & 0x0f) == port + INTn_1_INP_SEL_RX0) || + ((int_mux_cfg0_val >> 4) == port + INTn_1_INP_SEL_RX0) || + ((int_mux_cfg1_val >> 4) == port + INTn_1_INP_SEL_RX0)) { + snd_soc_component_update_bits(component, reg, mask, val); } - int_mux_cfg0 = CDC_RX_INP_MUX_RX_INT0_CFG0 + j * 8; - int_mux_cfg1 = int_mux_cfg0 + 4; - int_mux_cfg0_val = snd_soc_component_read(component, int_mux_cfg0); - int_mux_cfg1_val = snd_soc_component_read(component, int_mux_cfg1); - - if (snd_soc_component_read(component, dsm_reg) & 0x01) { - if (int_mux_cfg0_val || (int_mux_cfg1_val & 0xF0)) - snd_soc_component_update_bits(component, reg, 0x20, 0x20); - if (int_mux_cfg1_val & 0x0F) { - snd_soc_component_update_bits(component, reg, 0x20, 0x20); - snd_soc_component_update_bits(component, mix_reg, 0x20, - 0x20); + if ((int_mux_cfg1_val & 0x0f) == port + INTn_2_INP_SEL_RX0) { + snd_soc_component_update_bits(component, mix_reg, mask, val); + /* main clock needs to be enabled for mix to be useful: */ + if (rx->main_clk_users[j] > 0) { + snd_soc_component_update_bits(component, reg, + CDC_RX_PATH_CLK_EN_MASK, + CDC_RX_PATH_CLK_ENABLE); } } } - break; - default: - break; } return 0; } @@ -2458,7 +2454,7 @@ static int rx_macro_set_compander(struct snd_kcontrol *kcontrol, static int rx_macro_mux_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_widget(kcontrol); + struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_to_widget(kcontrol); struct snd_soc_component *component = snd_soc_dapm_to_component(widget->dapm); struct rx_macro *rx = snd_soc_component_get_drvdata(component); @@ -2470,7 +2466,7 @@ static int rx_macro_mux_get(struct snd_kcontrol *kcontrol, static int rx_macro_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_widget(kcontrol); + struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_to_widget(kcontrol); struct snd_soc_component *component = snd_soc_dapm_to_component(widget->dapm); struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; struct snd_soc_dapm_update *update = NULL; @@ -3609,7 +3605,7 @@ static const struct snd_soc_dapm_route rx_audio_map[] = { static int rx_macro_component_probe(struct snd_soc_component *component) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct rx_macro *rx = snd_soc_component_get_drvdata(component); const struct snd_soc_dapm_widget *widgets; const struct snd_kcontrol_new *controls; @@ -3951,6 +3947,9 @@ static const struct of_device_id rx_macro_dt_match[] = { .compatible = "qcom,sc7280-lpass-rx-macro", .data = (void *)LPASS_MACRO_FLAG_HAS_NPL_CLOCK, + }, { + .compatible = "qcom,sm6115-lpass-rx-macro", + .data = (void *)LPASS_MACRO_FLAG_HAS_NPL_CLOCK, }, { .compatible = "qcom,sm8250-lpass-rx-macro", .data = (void *)LPASS_MACRO_FLAG_HAS_NPL_CLOCK, diff --git a/sound/soc/codecs/lpass-tx-macro.c b/sound/soc/codecs/lpass-tx-macro.c index 1aefd3bde81833..f7d168f557dd85 100644 --- a/sound/soc/codecs/lpass-tx-macro.c +++ b/sound/soc/codecs/lpass-tx-macro.c @@ -800,7 +800,7 @@ static void tx_macro_update_smic_sel_v9_2(struct snd_soc_component *component, static int tx_macro_put_dec_enum(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_widget(kcontrol); + struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_to_widget(kcontrol); struct snd_soc_component *component = snd_soc_dapm_to_component(widget->dapm); struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; struct tx_macro *tx = snd_soc_component_get_drvdata(component); @@ -859,7 +859,7 @@ static int tx_macro_put_dec_enum(struct snd_kcontrol *kcontrol, static int tx_macro_tx_mixer_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_widget(kcontrol); + struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_to_widget(kcontrol); struct snd_soc_component *component = snd_soc_dapm_to_component(widget->dapm); struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; u32 dai_id = widget->shift; @@ -877,7 +877,7 @@ static int tx_macro_tx_mixer_get(struct snd_kcontrol *kcontrol, static int tx_macro_tx_mixer_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_widget(kcontrol); + struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_to_widget(kcontrol); struct snd_soc_component *component = snd_soc_dapm_to_component(widget->dapm); struct snd_soc_dapm_update *update = NULL; struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; @@ -2081,7 +2081,7 @@ static const struct snd_kcontrol_new tx_macro_snd_controls[] = { static int tx_macro_component_extend(struct snd_soc_component *comp) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(comp); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(comp); struct tx_macro *tx = snd_soc_component_get_drvdata(comp); int ret; @@ -2473,7 +2473,8 @@ static const struct tx_macro_data lpass_ver_9_2 = { }; static const struct tx_macro_data lpass_ver_10_sm6115 = { - .flags = LPASS_MACRO_FLAG_HAS_NPL_CLOCK, + .flags = LPASS_MACRO_FLAG_HAS_NPL_CLOCK | + LPASS_MACRO_FLAG_RESET_SWR, .ver = LPASS_VER_10_0_0, .extra_widgets = tx_macro_dapm_widgets_v9_2, .extra_widgets_num = ARRAY_SIZE(tx_macro_dapm_widgets_v9_2), diff --git a/sound/soc/codecs/lpass-va-macro.c b/sound/soc/codecs/lpass-va-macro.c index 29a268fc1c9f19..528d5b167ecffe 100644 --- a/sound/soc/codecs/lpass-va-macro.c +++ b/sound/soc/codecs/lpass-va-macro.c @@ -524,8 +524,7 @@ static int va_macro_mclk_event(struct snd_soc_dapm_widget *w, static int va_macro_put_dec_enum(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_widget *widget = - snd_soc_dapm_kcontrol_widget(kcontrol); + struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_to_widget(kcontrol); struct snd_soc_component *component = snd_soc_dapm_to_component(widget->dapm); struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; @@ -564,8 +563,7 @@ static int va_macro_put_dec_enum(struct snd_kcontrol *kcontrol, static int va_macro_tx_mixer_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_widget *widget = - snd_soc_dapm_kcontrol_widget(kcontrol); + struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_to_widget(kcontrol); struct snd_soc_component *component = snd_soc_dapm_to_component(widget->dapm); struct soc_mixer_control *mc = @@ -585,8 +583,7 @@ static int va_macro_tx_mixer_get(struct snd_kcontrol *kcontrol, static int va_macro_tx_mixer_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_widget *widget = - snd_soc_dapm_kcontrol_widget(kcontrol); + struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_to_widget(kcontrol); struct snd_soc_component *component = snd_soc_dapm_to_component(widget->dapm); struct snd_soc_dapm_update *update = NULL; @@ -1759,6 +1756,7 @@ static const struct dev_pm_ops va_macro_pm_ops = { static const struct of_device_id va_macro_dt_match[] = { { .compatible = "qcom,sc7280-lpass-va-macro", .data = &sm8250_va_data }, + { .compatible = "qcom,sm6115-lpass-va-macro", .data = &sm8450_va_data }, { .compatible = "qcom,sm8250-lpass-va-macro", .data = &sm8250_va_data }, { .compatible = "qcom,sm8450-lpass-va-macro", .data = &sm8450_va_data }, { .compatible = "qcom,sm8550-lpass-va-macro", .data = &sm8550_va_data }, diff --git a/sound/soc/codecs/lpass-wsa-macro.c b/sound/soc/codecs/lpass-wsa-macro.c index cc0488965654d9..b695c77c18ac6f 100644 --- a/sound/soc/codecs/lpass-wsa-macro.c +++ b/sound/soc/codecs/lpass-wsa-macro.c @@ -297,8 +297,7 @@ enum { enum { WSA_MACRO_RX0 = 0, WSA_MACRO_RX1, - WSA_MACRO_RX_MIX, - WSA_MACRO_RX_MIX0 = WSA_MACRO_RX_MIX, + WSA_MACRO_RX_MIX0, WSA_MACRO_RX_MIX1, WSA_MACRO_RX_MAX, }; @@ -1168,12 +1167,6 @@ static int wsa_macro_set_prim_interpolator_rate(struct snd_soc_dai *dai, for_each_set_bit(port, &wsa->active_ch_mask[dai->id], WSA_MACRO_RX_MAX) { int_1_mix1_inp = port; - if ((int_1_mix1_inp < WSA_MACRO_RX0) || (int_1_mix1_inp > WSA_MACRO_RX_MIX1)) { - dev_err(component->dev, "%s: Invalid RX port, Dai ID is %d\n", - __func__, dai->id); - return -EINVAL; - } - int_mux_cfg0 = CDC_WSA_RX_INP_MUX_RX_INT0_CFG0; /* @@ -1220,11 +1213,6 @@ static int wsa_macro_set_mix_interpolator_rate(struct snd_soc_dai *dai, for_each_set_bit(port, &wsa->active_ch_mask[dai->id], WSA_MACRO_RX_MAX) { int_2_inp = port; - if ((int_2_inp < WSA_MACRO_RX0) || (int_2_inp > WSA_MACRO_RX_MIX1)) { - dev_err(component->dev, "%s: Invalid RX port, Dai ID is %d\n", - __func__, dai->id); - return -EINVAL; - } int_mux_cfg1 = CDC_WSA_RX_INP_MUX_RX_INT0_CFG1; for (j = 0; j < NUM_INTERPOLATORS; j++) { @@ -1574,41 +1562,6 @@ static int wsa_macro_enable_vi_feedback(struct snd_soc_dapm_widget *w, return 0; } -static int wsa_macro_enable_mix_path(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); - u16 path_reg, gain_reg; - int val; - - switch (w->shift) { - case WSA_MACRO_RX_MIX0: - path_reg = CDC_WSA_RX0_RX_PATH_MIX_CTL; - gain_reg = CDC_WSA_RX0_RX_VOL_MIX_CTL; - break; - case WSA_MACRO_RX_MIX1: - path_reg = CDC_WSA_RX1_RX_PATH_MIX_CTL; - gain_reg = CDC_WSA_RX1_RX_VOL_MIX_CTL; - break; - default: - return 0; - } - - switch (event) { - case SND_SOC_DAPM_POST_PMU: - val = snd_soc_component_read(component, gain_reg); - snd_soc_component_write(component, gain_reg, val); - break; - case SND_SOC_DAPM_POST_PMD: - snd_soc_component_update_bits(component, path_reg, - CDC_WSA_RX_PATH_MIX_CLK_EN_MASK, - CDC_WSA_RX_PATH_MIX_CLK_DISABLE); - break; - } - - return 0; -} - static void wsa_macro_hd2_control(struct snd_soc_component *component, u16 reg, int event) { @@ -1772,59 +1725,6 @@ static int wsa_macro_config_softclip(struct snd_soc_component *component, return 0; } -static bool wsa_macro_adie_lb(struct snd_soc_component *component, - int interp_idx) -{ - struct wsa_macro *wsa = snd_soc_component_get_drvdata(component); - u16 int_mux_cfg0, int_mux_cfg1; - u8 int_n_inp0, int_n_inp1, int_n_inp2; - - int_mux_cfg0 = CDC_WSA_RX_INP_MUX_RX_INT0_CFG0 + interp_idx * 8; - int_mux_cfg1 = int_mux_cfg0 + 4; - - int_n_inp0 = snd_soc_component_read_field(component, int_mux_cfg0, - wsa->reg_layout->rx_intx_1_mix_inp0_sel_mask); - if (int_n_inp0 == INTn_1_INP_SEL_DEC0 || - int_n_inp0 == INTn_1_INP_SEL_DEC1) - return true; - - int_n_inp1 = snd_soc_component_read_field(component, int_mux_cfg0, - wsa->reg_layout->rx_intx_1_mix_inp1_sel_mask); - if (int_n_inp1 == INTn_1_INP_SEL_DEC0 || - int_n_inp1 == INTn_1_INP_SEL_DEC1) - return true; - - int_n_inp2 = snd_soc_component_read_field(component, int_mux_cfg1, - wsa->reg_layout->rx_intx_1_mix_inp2_sel_mask); - if (int_n_inp2 == INTn_1_INP_SEL_DEC0 || - int_n_inp2 == INTn_1_INP_SEL_DEC1) - return true; - - return false; -} - -static int wsa_macro_enable_main_path(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, - int event) -{ - struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); - u16 reg; - - reg = CDC_WSA_RX0_RX_PATH_CTL + WSA_MACRO_RX_PATH_OFFSET * w->shift; - switch (event) { - case SND_SOC_DAPM_PRE_PMU: - if (wsa_macro_adie_lb(component, w->shift)) { - snd_soc_component_update_bits(component, reg, - CDC_WSA_RX_PATH_CLK_EN_MASK, - CDC_WSA_RX_PATH_CLK_ENABLE); - } - break; - default: - break; - } - return 0; -} - static int wsa_macro_interp_get_primary_reg(u16 reg, u16 *ind) { u16 prim_int_reg = 0; @@ -1942,7 +1842,6 @@ static int wsa_macro_enable_interpolator(struct snd_soc_dapm_widget *w, struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); u16 gain_reg; u16 reg; - int val; struct wsa_macro *wsa = snd_soc_component_get_drvdata(component); if (w->shift == WSA_MACRO_COMP1) { @@ -1982,8 +1881,6 @@ static int wsa_macro_enable_interpolator(struct snd_soc_dapm_widget *w, CDC_WSA_RX_PGA_HALF_DB_MASK, CDC_WSA_RX_PGA_HALF_DB_ENABLE); } - val = snd_soc_component_read(component, gain_reg); - snd_soc_component_write(component, gain_reg, val); wsa_macro_config_ear_spkr_gain(component, wsa, event, gain_reg); break; @@ -2186,8 +2083,7 @@ static int wsa_macro_ear_spkr_pa_gain_put(struct snd_kcontrol *kcontrol, static int wsa_macro_rx_mux_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_widget *widget = - snd_soc_dapm_kcontrol_widget(kcontrol); + struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_to_widget(kcontrol); struct snd_soc_component *component = snd_soc_dapm_to_component(widget->dapm); struct wsa_macro *wsa = snd_soc_component_get_drvdata(component); @@ -2200,8 +2096,7 @@ static int wsa_macro_rx_mux_get(struct snd_kcontrol *kcontrol, static int wsa_macro_rx_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_widget *widget = - snd_soc_dapm_kcontrol_widget(kcontrol); + struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_to_widget(kcontrol); struct snd_soc_component *component = snd_soc_dapm_to_component(widget->dapm); struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; @@ -2297,6 +2192,10 @@ static const struct snd_kcontrol_new wsa_macro_snd_controls[] = { -84, 40, digital_gain), SOC_SINGLE_S8_TLV("WSA_RX1 Digital Volume", CDC_WSA_RX1_RX_VOL_CTL, -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("WSA_RX0_MIX Digital Volume", CDC_WSA_RX0_RX_VOL_MIX_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("WSA_RX1_MIX Digital Volume", CDC_WSA_RX1_RX_VOL_MIX_CTL, + -84, 40, digital_gain), SOC_SINGLE("WSA_RX0 Digital Mute", CDC_WSA_RX0_RX_PATH_CTL, 4, 1, 0), SOC_SINGLE("WSA_RX1 Digital Mute", CDC_WSA_RX1_RX_PATH_CTL, 4, 1, 0), @@ -2331,7 +2230,7 @@ static const struct snd_kcontrol_new rx_mux[WSA_MACRO_RX_MAX] = { static int wsa_macro_vi_feed_mixer_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_widget(kcontrol); + struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_to_widget(kcontrol); struct snd_soc_component *component = snd_soc_dapm_to_component(widget->dapm); struct soc_mixer_control *mixer = (struct soc_mixer_control *)kcontrol->private_value; struct wsa_macro *wsa = snd_soc_component_get_drvdata(component); @@ -2349,7 +2248,7 @@ static int wsa_macro_vi_feed_mixer_get(struct snd_kcontrol *kcontrol, static int wsa_macro_vi_feed_mixer_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_widget(kcontrol); + struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_to_widget(kcontrol); struct snd_soc_component *component = snd_soc_dapm_to_component(widget->dapm); struct soc_mixer_control *mixer = (struct soc_mixer_control *)kcontrol->private_value; struct wsa_macro *wsa = snd_soc_component_get_drvdata(component); @@ -2440,10 +2339,8 @@ static const struct snd_soc_dapm_widget wsa_macro_dapm_widgets[] = { SND_SOC_DAPM_MIXER("WSA RX_MIX0", SND_SOC_NOPM, 0, 0, NULL, 0), SND_SOC_DAPM_MIXER("WSA RX_MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), - SND_SOC_DAPM_MIXER_E("WSA_RX INT0 MIX", SND_SOC_NOPM, 0, 0, NULL, 0, - wsa_macro_enable_main_path, SND_SOC_DAPM_PRE_PMU), - SND_SOC_DAPM_MIXER_E("WSA_RX INT1 MIX", SND_SOC_NOPM, 1, 0, NULL, 0, - wsa_macro_enable_main_path, SND_SOC_DAPM_PRE_PMU), + SND_SOC_DAPM_MIXER("WSA_RX INT0 MIX", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("WSA_RX INT1 MIX", SND_SOC_NOPM, 0, 0, NULL, 0), SND_SOC_DAPM_MIXER("WSA_RX INT0 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0), SND_SOC_DAPM_MIXER("WSA_RX INT1 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0), @@ -2494,30 +2391,22 @@ static const struct snd_soc_dapm_widget wsa_macro_dapm_widgets_v2_1[] = { SND_SOC_DAPM_MUX("WSA_RX0 INP0", SND_SOC_NOPM, 0, 0, &rx0_prim_inp0_mux_v2_1), SND_SOC_DAPM_MUX("WSA_RX0 INP1", SND_SOC_NOPM, 0, 0, &rx0_prim_inp1_mux_v2_1), SND_SOC_DAPM_MUX("WSA_RX0 INP2", SND_SOC_NOPM, 0, 0, &rx0_prim_inp2_mux_v2_1), - SND_SOC_DAPM_MUX_E("WSA_RX0 MIX INP", SND_SOC_NOPM, WSA_MACRO_RX_MIX0, - 0, &rx0_mix_mux_v2_1, wsa_macro_enable_mix_path, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX("WSA_RX0 MIX INP", SND_SOC_NOPM, 0, 0, &rx0_mix_mux_v2_1), SND_SOC_DAPM_MUX("WSA_RX1 INP0", SND_SOC_NOPM, 0, 0, &rx1_prim_inp0_mux_v2_1), SND_SOC_DAPM_MUX("WSA_RX1 INP1", SND_SOC_NOPM, 0, 0, &rx1_prim_inp1_mux_v2_1), SND_SOC_DAPM_MUX("WSA_RX1 INP2", SND_SOC_NOPM, 0, 0, &rx1_prim_inp2_mux_v2_1), - SND_SOC_DAPM_MUX_E("WSA_RX1 MIX INP", SND_SOC_NOPM, WSA_MACRO_RX_MIX1, - 0, &rx1_mix_mux_v2_1, wsa_macro_enable_mix_path, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX("WSA_RX1 MIX INP", SND_SOC_NOPM, 0, 0, &rx1_mix_mux_v2_1), }; static const struct snd_soc_dapm_widget wsa_macro_dapm_widgets_v2_5[] = { SND_SOC_DAPM_MUX("WSA_RX0 INP0", SND_SOC_NOPM, 0, 0, &rx0_prim_inp0_mux_v2_5), SND_SOC_DAPM_MUX("WSA_RX0 INP1", SND_SOC_NOPM, 0, 0, &rx0_prim_inp1_mux_v2_5), SND_SOC_DAPM_MUX("WSA_RX0 INP2", SND_SOC_NOPM, 0, 0, &rx0_prim_inp2_mux_v2_5), - SND_SOC_DAPM_MUX_E("WSA_RX0 MIX INP", SND_SOC_NOPM, WSA_MACRO_RX_MIX0, - 0, &rx0_mix_mux_v2_5, wsa_macro_enable_mix_path, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX("WSA_RX0 MIX INP", SND_SOC_NOPM, 0, 0, &rx0_mix_mux_v2_5), SND_SOC_DAPM_MUX("WSA_RX1 INP0", SND_SOC_NOPM, 0, 0, &rx1_prim_inp0_mux_v2_5), SND_SOC_DAPM_MUX("WSA_RX1 INP1", SND_SOC_NOPM, 0, 0, &rx1_prim_inp1_mux_v2_5), SND_SOC_DAPM_MUX("WSA_RX1 INP2", SND_SOC_NOPM, 0, 0, &rx1_prim_inp2_mux_v2_5), - SND_SOC_DAPM_MUX_E("WSA_RX1 MIX INP", SND_SOC_NOPM, WSA_MACRO_RX_MIX1, - 0, &rx1_mix_mux_v2_5, wsa_macro_enable_mix_path, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX("WSA_RX1 MIX INP", SND_SOC_NOPM, 0, 0, &rx1_mix_mux_v2_5), }; static const struct snd_soc_dapm_route wsa_audio_map[] = { @@ -2553,10 +2442,8 @@ static const struct snd_soc_dapm_route wsa_audio_map[] = { {"WSA RX_MIX0", NULL, "WSA RX_MIX0 MUX"}, {"WSA RX_MIX1", NULL, "WSA RX_MIX1 MUX"}, - {"WSA RX0", NULL, "WSA_RX0_CLK"}, - {"WSA RX1", NULL, "WSA_RX1_CLK"}, - {"WSA RX_MIX0", NULL, "WSA_RX_MIX0_CLK"}, - {"WSA RX_MIX1", NULL, "WSA_RX_MIX1_CLK"}, + {"WSA_RX INT0 MIX", NULL, "WSA_RX0_CLK"}, + {"WSA_RX INT1 MIX", NULL, "WSA_RX1_CLK"}, {"WSA_RX0 INP0", "RX0", "WSA RX0"}, {"WSA_RX0 INP0", "RX1", "WSA RX1"}, @@ -2586,6 +2473,8 @@ static const struct snd_soc_dapm_route wsa_audio_map[] = { {"WSA_RX0 MIX INP", "RX1", "WSA RX1"}, {"WSA_RX0 MIX INP", "RX_MIX0", "WSA RX_MIX0"}, {"WSA_RX0 MIX INP", "RX_MIX1", "WSA RX_MIX1"}, + {"WSA_RX0 MIX INP", NULL, "WSA_RX0_CLK"}, + {"WSA_RX0 MIX INP", NULL, "WSA_RX_MIX0_CLK"}, {"WSA_RX INT0 SEC MIX", NULL, "WSA_RX0 MIX INP"}, {"WSA_RX INT0 SEC MIX", NULL, "WSA_RX INT0 MIX"}, @@ -2625,6 +2514,8 @@ static const struct snd_soc_dapm_route wsa_audio_map[] = { {"WSA_RX1 MIX INP", "RX1", "WSA RX1"}, {"WSA_RX1 MIX INP", "RX_MIX0", "WSA RX_MIX0"}, {"WSA_RX1 MIX INP", "RX_MIX1", "WSA RX_MIX1"}, + {"WSA_RX1 MIX INP", NULL, "WSA_RX1_CLK"}, + {"WSA_RX1 MIX INP", NULL, "WSA_RX_MIX1_CLK"}, {"WSA_RX INT1 SEC MIX", NULL, "WSA_RX1 MIX INP"}, {"WSA_RX INT1 SEC MIX", NULL, "WSA_RX INT1 MIX"}, @@ -2665,7 +2556,7 @@ static int wsa_swrm_clock(struct wsa_macro *wsa, bool enable) static int wsa_macro_component_probe(struct snd_soc_component *comp) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(comp); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(comp); struct wsa_macro *wsa = snd_soc_component_get_drvdata(comp); const struct snd_soc_dapm_widget *widgets; unsigned int num_widgets; diff --git a/sound/soc/codecs/madera.c b/sound/soc/codecs/madera.c index 057f75bf0053b4..98d72db599d8a1 100644 --- a/sound/soc/codecs/madera.c +++ b/sound/soc/codecs/madera.c @@ -541,10 +541,8 @@ EXPORT_SYMBOL_GPL(madera_domain_clk_ev); int madera_out1_demux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_component *component = - snd_soc_dapm_kcontrol_component(kcontrol); - struct snd_soc_dapm_context *dapm = - snd_soc_dapm_kcontrol_dapm(kcontrol); + struct snd_soc_component *component = snd_soc_dapm_kcontrol_to_component(kcontrol); + struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kcontrol); struct madera_priv *priv = snd_soc_component_get_drvdata(component); struct madera *madera = priv->madera; struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; @@ -632,8 +630,7 @@ EXPORT_SYMBOL_GPL(madera_out1_demux_put); int madera_out1_demux_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_component *component = - snd_soc_dapm_kcontrol_component(kcontrol); + struct snd_soc_component *component = snd_soc_dapm_kcontrol_to_component(kcontrol); unsigned int val; val = snd_soc_component_read(component, MADERA_OUTPUT_ENABLES_1); @@ -648,10 +645,8 @@ EXPORT_SYMBOL_GPL(madera_out1_demux_get); static int madera_inmux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_component *component = - snd_soc_dapm_kcontrol_component(kcontrol); - struct snd_soc_dapm_context *dapm = - snd_soc_dapm_kcontrol_dapm(kcontrol); + struct snd_soc_component *component = snd_soc_dapm_kcontrol_to_component(kcontrol); + struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kcontrol); struct madera_priv *priv = snd_soc_component_get_drvdata(component); struct madera *madera = priv->madera; struct regmap *regmap = madera->regmap; @@ -1211,8 +1206,7 @@ int madera_init_outputs(struct snd_soc_component *component, const struct snd_soc_dapm_route *routes, int n_mono_routes, int n_real) { - struct snd_soc_dapm_context *dapm = - snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct madera_priv *priv = snd_soc_component_get_drvdata(component); struct madera *madera = priv->madera; const struct madera_codec_pdata *pdata = &madera->pdata.codec; @@ -2161,8 +2155,7 @@ int madera_dfc_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); - struct snd_soc_dapm_context *dapm = - snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; unsigned int reg = e->reg; unsigned int val; @@ -2193,8 +2186,7 @@ int madera_lp_mode_put(struct snd_kcontrol *kcontrol, struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); - struct snd_soc_dapm_context *dapm = - snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); unsigned int val, mask; int ret; @@ -3236,8 +3228,7 @@ static int madera_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id, unsigned int freq, int dir) { struct snd_soc_component *component = dai->component; - struct snd_soc_dapm_context *dapm = - snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct madera_priv *priv = snd_soc_component_get_drvdata(component); struct madera_dai_priv *dai_priv = &priv->dai[dai->id - 1]; struct snd_soc_dapm_route routes[2]; diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c index f1cff60abce0f9..9f40ca4b60d5b4 100644 --- a/sound/soc/codecs/max98088.c +++ b/sound/soc/codecs/max98088.c @@ -1296,6 +1296,7 @@ static int max98088_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { struct max98088_priv *max98088 = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); int ret; switch (level) { @@ -1311,8 +1312,7 @@ static int max98088_set_bias_level(struct snd_soc_component *component, * enable it. */ if (!IS_ERR(max98088->mclk)) { - if (snd_soc_component_get_bias_level(component) == - SND_SOC_BIAS_ON) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_ON) { clk_disable_unprepare(max98088->mclk); } else { ret = clk_prepare_enable(max98088->mclk); @@ -1323,7 +1323,7 @@ static int max98088_set_bias_level(struct snd_soc_component *component, break; case SND_SOC_BIAS_STANDBY: - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) regcache_sync(max98088->regmap); snd_soc_component_update_bits(component, M98088_REG_4C_PWR_EN_IN, diff --git a/sound/soc/codecs/max98090.c b/sound/soc/codecs/max98090.c index b63186feca05e4..13a15459040fc3 100644 --- a/sound/soc/codecs/max98090.c +++ b/sound/soc/codecs/max98090.c @@ -1469,7 +1469,7 @@ static const struct snd_soc_dapm_route max98091_dapm_routes[] = { static int max98090_add_widgets(struct snd_soc_component *component) { struct max98090_priv *max98090 = snd_soc_component_get_drvdata(component); - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); snd_soc_add_component_controls(component, max98090_snd_controls, ARRAY_SIZE(max98090_snd_controls)); @@ -1751,6 +1751,7 @@ static int max98090_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { struct max98090_priv *max98090 = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); int ret; switch (level) { @@ -1768,7 +1769,7 @@ static int max98090_set_bias_level(struct snd_soc_component *component, if (IS_ERR(max98090->mclk)) break; - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_ON) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_ON) { clk_disable_unprepare(max98090->mclk); } else { ret = clk_prepare_enable(max98090->mclk); @@ -1778,7 +1779,7 @@ static int max98090_set_bias_level(struct snd_soc_component *component, break; case SND_SOC_BIAS_STANDBY: - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) { ret = regcache_sync(max98090->regmap); if (ret != 0) { dev_err(component->dev, diff --git a/sound/soc/codecs/max98095.c b/sound/soc/codecs/max98095.c index ab5a08a9b9c770..aae6423156e166 100644 --- a/sound/soc/codecs/max98095.c +++ b/sound/soc/codecs/max98095.c @@ -1359,6 +1359,7 @@ static int max98095_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { struct max98095_priv *max98095 = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); int ret; switch (level) { @@ -1376,7 +1377,7 @@ static int max98095_set_bias_level(struct snd_soc_component *component, if (IS_ERR(max98095->mclk)) break; - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_ON) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_ON) { clk_disable_unprepare(max98095->mclk); } else { ret = clk_prepare_enable(max98095->mclk); @@ -1386,7 +1387,7 @@ static int max98095_set_bias_level(struct snd_soc_component *component, break; case SND_SOC_BIAS_STANDBY: - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) { ret = regcache_sync(max98095->regmap); if (ret != 0) { @@ -1917,11 +1918,12 @@ EXPORT_SYMBOL_GPL(max98095_jack_detect); static int max98095_suspend(struct snd_soc_component *component) { struct max98095_priv *max98095 = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); if (max98095->headphone_jack || max98095->mic_jack) max98095_jack_detect_disable(component); - snd_soc_component_force_bias_level(component, SND_SOC_BIAS_OFF); + snd_soc_dapm_force_bias_level(dapm, SND_SOC_BIAS_OFF); return 0; } @@ -1930,8 +1932,9 @@ static int max98095_resume(struct snd_soc_component *component) { struct max98095_priv *max98095 = snd_soc_component_get_drvdata(component); struct i2c_client *client = to_i2c_client(component->dev); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); - snd_soc_component_force_bias_level(component, SND_SOC_BIAS_STANDBY); + snd_soc_dapm_force_bias_level(dapm, SND_SOC_BIAS_STANDBY); if (max98095->headphone_jack || max98095->mic_jack) { max98095_jack_detect_enable(component); diff --git a/sound/soc/codecs/max98373.c b/sound/soc/codecs/max98373.c index 33eb4576da2345..cfb95fd4f85ecd 100644 --- a/sound/soc/codecs/max98373.c +++ b/sound/soc/codecs/max98373.c @@ -174,12 +174,13 @@ static int max98373_feedback_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; struct max98373_priv *max98373 = snd_soc_component_get_drvdata(component); int i; - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) { /* * Register values will be cached before suspend. The cached value * will be a valid value and userspace will happy with that. diff --git a/sound/soc/codecs/max98390.c b/sound/soc/codecs/max98390.c index fabc8e212370bb..3dd4dd94bc371f 100644 --- a/sound/soc/codecs/max98390.c +++ b/sound/soc/codecs/max98390.c @@ -628,7 +628,7 @@ static int max98390_dsm_calib_put(struct snd_kcontrol *kcontrol, { struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); struct max98390_priv *max98390 = snd_soc_component_get_drvdata(component); - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); unsigned int rdc, rdc_cal_result, rdc_integer, rdc_factor, temp, val; snd_soc_dapm_mutex_lock(dapm); diff --git a/sound/soc/codecs/max98396.c b/sound/soc/codecs/max98396.c index 4b4e1fc98a6da5..18fd902271871d 100644 --- a/sound/soc/codecs/max98396.c +++ b/sound/soc/codecs/max98396.c @@ -953,8 +953,7 @@ static const DECLARE_TLV_DB_RANGE(max98397_spk_tlv, static int max98396_mux_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_component *component = - snd_soc_dapm_kcontrol_component(kcontrol); + struct snd_soc_component *component = snd_soc_dapm_kcontrol_to_component(kcontrol); struct max98396_priv *max98396 = snd_soc_component_get_drvdata(component); int reg, val; @@ -973,9 +972,8 @@ static int max98396_mux_get(struct snd_kcontrol *kcontrol, static int max98396_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_component *component = - snd_soc_dapm_kcontrol_component(kcontrol); - struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol); + struct snd_soc_component *component = snd_soc_dapm_kcontrol_to_component(kcontrol); + struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kcontrol); struct max98396_priv *max98396 = snd_soc_component_get_drvdata(component); struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; unsigned int *item = ucontrol->value.enumerated.item; @@ -1107,6 +1105,7 @@ static int max98396_adc_value_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; struct max98396_priv *max98396 = snd_soc_component_get_drvdata(component); @@ -1115,7 +1114,7 @@ static int max98396_adc_value_get(struct snd_kcontrol *kcontrol, int reg = mc->reg; /* ADC value is not available if the device is powered down */ - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) goto exit; if (max98396->device_id == CODEC_TYPE_MAX98397) { diff --git a/sound/soc/codecs/max9850.c b/sound/soc/codecs/max9850.c index c395132689b4ef..1fcbc64a277110 100644 --- a/sound/soc/codecs/max9850.c +++ b/sound/soc/codecs/max9850.c @@ -225,6 +225,7 @@ static int max9850_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { struct max9850_priv *max9850 = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); int ret; switch (level) { @@ -233,7 +234,7 @@ static int max9850_set_bias_level(struct snd_soc_component *component, case SND_SOC_BIAS_PREPARE: break; case SND_SOC_BIAS_STANDBY: - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) { ret = regcache_sync(max9850->regmap); if (ret) { dev_err(component->dev, diff --git a/sound/soc/codecs/max9867.c b/sound/soc/codecs/max9867.c index 35ec9c1b18f918..9cad9b698cf2fb 100644 --- a/sound/soc/codecs/max9867.c +++ b/sound/soc/codecs/max9867.c @@ -556,14 +556,18 @@ static struct snd_soc_dai_driver max9867_dai[] = { #ifdef CONFIG_PM static int max9867_suspend(struct snd_soc_component *component) { - snd_soc_component_force_bias_level(component, SND_SOC_BIAS_OFF); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); + + snd_soc_dapm_force_bias_level(dapm, SND_SOC_BIAS_OFF); return 0; } static int max9867_resume(struct snd_soc_component *component) { - snd_soc_component_force_bias_level(component, SND_SOC_BIAS_STANDBY); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); + + snd_soc_dapm_force_bias_level(dapm, SND_SOC_BIAS_STANDBY); return 0; } @@ -577,6 +581,7 @@ static int max9867_set_bias_level(struct snd_soc_component *component, { int err; struct max9867_priv *max9867 = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); switch (level) { case SND_SOC_BIAS_ON: @@ -585,7 +590,7 @@ static int max9867_set_bias_level(struct snd_soc_component *component, return err; break; case SND_SOC_BIAS_STANDBY: - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) { err = regcache_sync(max9867->regmap); if (err) return err; diff --git a/sound/soc/codecs/ml26124.c b/sound/soc/codecs/ml26124.c index c6585e8143a5e5..fad0cc90234614 100644 --- a/sound/soc/codecs/ml26124.c +++ b/sound/soc/codecs/ml26124.c @@ -459,6 +459,7 @@ static int ml26124_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { struct ml26124_priv *priv = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); switch (level) { case SND_SOC_BIAS_ON: @@ -473,7 +474,7 @@ static int ml26124_set_bias_level(struct snd_soc_component *component, break; case SND_SOC_BIAS_STANDBY: /* VMID ON */ - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) { snd_soc_component_update_bits(component, ML26124_PW_REF_PW_MNG, ML26124_VMID, ML26124_VMID); msleep(500); diff --git a/sound/soc/codecs/mt6357.c b/sound/soc/codecs/mt6357.c index 988728df15e4a9..674cf7df9df4dc 100644 --- a/sound/soc/codecs/mt6357.c +++ b/sound/soc/codecs/mt6357.c @@ -597,7 +597,7 @@ static int mt_mic_type_event(struct snd_soc_dapm_widget *w, { struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); struct mt6357_priv *priv = snd_soc_component_get_drvdata(cmpnt); - unsigned int mic_type = dapm_kcontrol_get_value(w->kcontrols[0]); + unsigned int mic_type = snd_soc_dapm_kcontrol_get_value(w->kcontrols[0]); switch (event) { case SND_SOC_DAPM_PRE_PMU: diff --git a/sound/soc/codecs/mt6358.c b/sound/soc/codecs/mt6358.c index de611c483e0bea..a787accb88e851 100644 --- a/sound/soc/codecs/mt6358.c +++ b/sound/soc/codecs/mt6358.c @@ -1287,7 +1287,7 @@ static int mt_hp_event(struct snd_soc_dapm_widget *w, { struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); struct mt6358_priv *priv = snd_soc_component_get_drvdata(cmpnt); - unsigned int mux = dapm_kcontrol_get_value(w->kcontrols[0]); + unsigned int mux = snd_soc_dapm_kcontrol_get_value(w->kcontrols[0]); int device = DEVICE_HP; dev_info(priv->dev, "%s(), event 0x%x, dev_counter[DEV_HP] %d, mux %u\n", @@ -1349,7 +1349,7 @@ static int mt_rcv_event(struct snd_soc_dapm_widget *w, dev_info(priv->dev, "%s(), event 0x%x, mux %u\n", __func__, event, - dapm_kcontrol_get_value(w->kcontrols[0])); + snd_soc_dapm_kcontrol_get_value(w->kcontrols[0])); switch (event) { case SND_SOC_DAPM_PRE_PMU: @@ -1828,7 +1828,7 @@ static int mt_mic_type_event(struct snd_soc_dapm_widget *w, { struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); struct mt6358_priv *priv = snd_soc_component_get_drvdata(cmpnt); - unsigned int mux = dapm_kcontrol_get_value(w->kcontrols[0]); + unsigned int mux = snd_soc_dapm_kcontrol_get_value(w->kcontrols[0]); dev_dbg(priv->dev, "%s(), event 0x%x, mux %u\n", __func__, event, mux); @@ -1874,7 +1874,7 @@ static int mt_adc_l_event(struct snd_soc_dapm_widget *w, { struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); struct mt6358_priv *priv = snd_soc_component_get_drvdata(cmpnt); - unsigned int mux = dapm_kcontrol_get_value(w->kcontrols[0]); + unsigned int mux = snd_soc_dapm_kcontrol_get_value(w->kcontrols[0]); dev_dbg(priv->dev, "%s(), event = 0x%x, mux %u\n", __func__, event, mux); @@ -1890,7 +1890,7 @@ static int mt_adc_r_event(struct snd_soc_dapm_widget *w, { struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); struct mt6358_priv *priv = snd_soc_component_get_drvdata(cmpnt); - unsigned int mux = dapm_kcontrol_get_value(w->kcontrols[0]); + unsigned int mux = snd_soc_dapm_kcontrol_get_value(w->kcontrols[0]); dev_dbg(priv->dev, "%s(), event = 0x%x, mux %u\n", __func__, event, mux); @@ -1906,7 +1906,7 @@ static int mt_pga_left_event(struct snd_soc_dapm_widget *w, { struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); struct mt6358_priv *priv = snd_soc_component_get_drvdata(cmpnt); - unsigned int mux = dapm_kcontrol_get_value(w->kcontrols[0]); + unsigned int mux = snd_soc_dapm_kcontrol_get_value(w->kcontrols[0]); dev_dbg(priv->dev, "%s(), event = 0x%x, mux %u\n", __func__, event, mux); @@ -1922,7 +1922,7 @@ static int mt_pga_right_event(struct snd_soc_dapm_widget *w, { struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); struct mt6358_priv *priv = snd_soc_component_get_drvdata(cmpnt); - unsigned int mux = dapm_kcontrol_get_value(w->kcontrols[0]); + unsigned int mux = snd_soc_dapm_kcontrol_get_value(w->kcontrols[0]); dev_dbg(priv->dev, "%s(), event = 0x%x, mux %u\n", __func__, event, mux); diff --git a/sound/soc/codecs/mt6359.c b/sound/soc/codecs/mt6359.c index be5c9739039866..b15bdb15dbb079 100644 --- a/sound/soc/codecs/mt6359.c +++ b/sound/soc/codecs/mt6359.c @@ -1043,7 +1043,7 @@ static int mt_hp_event(struct snd_soc_dapm_widget *w, { struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); struct mt6359_priv *priv = snd_soc_component_get_drvdata(cmpnt); - unsigned int mux = dapm_kcontrol_get_value(w->kcontrols[0]); + unsigned int mux = snd_soc_dapm_kcontrol_get_value(w->kcontrols[0]); int device = DEVICE_HP; dev_dbg(priv->dev, "%s(), event 0x%x, dev_counter[DEV_HP] %d, mux %u\n", @@ -1075,7 +1075,7 @@ static int mt_rcv_event(struct snd_soc_dapm_widget *w, struct mt6359_priv *priv = snd_soc_component_get_drvdata(cmpnt); dev_dbg(priv->dev, "%s(), event 0x%x, mux %u\n", - __func__, event, dapm_kcontrol_get_value(w->kcontrols[0])); + __func__, event, snd_soc_dapm_kcontrol_get_value(w->kcontrols[0])); switch (event) { case SND_SOC_DAPM_PRE_PMU: @@ -1157,7 +1157,7 @@ static int mt_lo_event(struct snd_soc_dapm_widget *w, { struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); struct mt6359_priv *priv = snd_soc_component_get_drvdata(cmpnt); - unsigned int mux = dapm_kcontrol_get_value(w->kcontrols[0]); + unsigned int mux = snd_soc_dapm_kcontrol_get_value(w->kcontrols[0]); dev_dbg(priv->dev, "%s(), event 0x%x, mux %u\n", __func__, event, mux); @@ -1637,7 +1637,7 @@ static int mt_pga_l_mux_event(struct snd_soc_dapm_widget *w, { struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); struct mt6359_priv *priv = snd_soc_component_get_drvdata(cmpnt); - unsigned int mux = dapm_kcontrol_get_value(w->kcontrols[0]); + unsigned int mux = snd_soc_dapm_kcontrol_get_value(w->kcontrols[0]); dev_dbg(priv->dev, "%s(), mux %d\n", __func__, mux); priv->mux_select[MUX_PGA_L] = mux >> RG_AUDPREAMPLINPUTSEL_SFT; @@ -1650,7 +1650,7 @@ static int mt_pga_r_mux_event(struct snd_soc_dapm_widget *w, { struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); struct mt6359_priv *priv = snd_soc_component_get_drvdata(cmpnt); - unsigned int mux = dapm_kcontrol_get_value(w->kcontrols[0]); + unsigned int mux = snd_soc_dapm_kcontrol_get_value(w->kcontrols[0]); dev_dbg(priv->dev, "%s(), mux %d\n", __func__, mux); priv->mux_select[MUX_PGA_R] = mux >> RG_AUDPREAMPRINPUTSEL_SFT; @@ -1663,7 +1663,7 @@ static int mt_pga_3_mux_event(struct snd_soc_dapm_widget *w, { struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); struct mt6359_priv *priv = snd_soc_component_get_drvdata(cmpnt); - unsigned int mux = dapm_kcontrol_get_value(w->kcontrols[0]); + unsigned int mux = snd_soc_dapm_kcontrol_get_value(w->kcontrols[0]); dev_dbg(priv->dev, "%s(), mux %d\n", __func__, mux); priv->mux_select[MUX_PGA_3] = mux >> RG_AUDPREAMP3INPUTSEL_SFT; diff --git a/sound/soc/codecs/nau8325.c b/sound/soc/codecs/nau8325.c index 2266f320a8f228..3bfdb448f8bd72 100644 --- a/sound/soc/codecs/nau8325.c +++ b/sound/soc/codecs/nau8325.c @@ -422,7 +422,7 @@ static int nau8325_clksrc_choose(struct nau8325 *nau8325, *n1_sel = i; *mult_sel = j; ratio_sel = ratio; - goto proc_done; + goto proc_done; } } } @@ -829,8 +829,7 @@ static int nau8325_read_device_properties(struct device *dev, return 0; } -static int nau8325_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int nau8325_i2c_probe(struct i2c_client *i2c) { struct device *dev = &i2c->dev; struct nau8325 *nau8325 = dev_get_platdata(dev); diff --git a/sound/soc/codecs/nau8810.c b/sound/soc/codecs/nau8810.c index 54ff8dd82f66d6..9870e62d372e2b 100644 --- a/sound/soc/codecs/nau8810.c +++ b/sound/soc/codecs/nau8810.c @@ -775,6 +775,7 @@ static int nau8810_pcm_hw_params(struct snd_pcm_substream *substream, static int nau8810_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct nau8810 *nau8810 = snd_soc_component_get_drvdata(component); struct regmap *map = nau8810->regmap; @@ -790,7 +791,7 @@ static int nau8810_set_bias_level(struct snd_soc_component *component, NAU8810_IOBUF_EN | NAU8810_ABIAS_EN, NAU8810_IOBUF_EN | NAU8810_ABIAS_EN); - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) { regcache_sync(map); regmap_update_bits(map, NAU8810_REG_POWER1, NAU8810_REFIMP_MASK, NAU8810_REFIMP_3K); diff --git a/sound/soc/codecs/nau8821.c b/sound/soc/codecs/nau8821.c index 4fa9a785513e52..3beb3c44dc2c03 100644 --- a/sound/soc/codecs/nau8821.c +++ b/sound/soc/codecs/nau8821.c @@ -1047,7 +1047,6 @@ static void nau8821_eject_jack(struct nau8821 *nau8821) { struct snd_soc_dapm_context *dapm = nau8821->dapm; struct regmap *regmap = nau8821->regmap; - struct snd_soc_component *component = snd_soc_dapm_to_component(dapm); /* Detach 2kOhm Resistors from MICBIAS to MICGND */ regmap_update_bits(regmap, NAU8821_R74_MIC_BIAS, @@ -1055,7 +1054,7 @@ static void nau8821_eject_jack(struct nau8821 *nau8821) /* HPL/HPR short to ground */ regmap_update_bits(regmap, NAU8821_R0D_JACK_DET_CTRL, NAU8821_SPKR_DWN1R | NAU8821_SPKR_DWN1L, 0); - snd_soc_component_disable_pin(component, "MICBIAS"); + snd_soc_dapm_disable_pin(dapm, "MICBIAS"); snd_soc_dapm_sync(dapm); /* Disable & mask both insertion & ejection IRQs */ @@ -1080,7 +1079,7 @@ static void nau8821_eject_jack(struct nau8821 *nau8821) NAU8821_JACK_DET_DB_BYPASS, NAU8821_JACK_DET_DB_BYPASS); /* Close clock for jack type detection at manual mode */ - if (dapm->bias_level < SND_SOC_BIAS_PREPARE) + if (snd_soc_dapm_get_bias_level(dapm) < SND_SOC_BIAS_PREPARE) nau8821_configure_sysclk(nau8821, NAU8821_CLK_DIS, 0); /* Recover to normal channel input */ @@ -1106,7 +1105,6 @@ static void nau8821_jdet_work(struct work_struct *work) struct nau8821 *nau8821 = container_of(work, struct nau8821, jdet_work.work); struct snd_soc_dapm_context *dapm = nau8821->dapm; - struct snd_soc_component *component = snd_soc_dapm_to_component(dapm); struct regmap *regmap = nau8821->regmap; int jack_status_reg, mic_detected, event = 0, event_mask = 0; @@ -1133,13 +1131,13 @@ static void nau8821_jdet_work(struct work_struct *work) NAU8821_IRQ_KEY_RELEASE_DIS | NAU8821_IRQ_KEY_PRESS_DIS, 0); } else { - snd_soc_component_disable_pin(component, "MICBIAS"); - snd_soc_dapm_sync(nau8821->dapm); + snd_soc_dapm_disable_pin(dapm, "MICBIAS"); + snd_soc_dapm_sync(dapm); } } else { dev_dbg(nau8821->dev, "Headphone connected\n"); event |= SND_JACK_HEADPHONE; - snd_soc_component_disable_pin(component, "MICBIAS"); + snd_soc_dapm_disable_pin(dapm, "MICBIAS"); snd_soc_dapm_sync(dapm); } @@ -1162,7 +1160,7 @@ static void nau8821_setup_inserted_irq(struct nau8821 *nau8821) nau8821_irq_status_clear(regmap, NAU8821_JACK_INSERT_DETECTED); /* Enable internal VCO needed for interruptions */ - if (nau8821->dapm->bias_level < SND_SOC_BIAS_PREPARE) + if (snd_soc_dapm_get_bias_level(nau8821->dapm) < SND_SOC_BIAS_PREPARE) nau8821_configure_sysclk(nau8821, NAU8821_CLK_INTERNAL, 0); /* Chip needs one FSCLK cycle in order to generate interruptions, @@ -1191,7 +1189,6 @@ static irqreturn_t nau8821_interrupt(int irq, void *data) { struct nau8821 *nau8821 = (struct nau8821 *)data; struct regmap *regmap = nau8821->regmap; - struct snd_soc_component *component; int active_irq, event = 0, event_mask = 0; if (regmap_read(regmap, NAU8821_R10_IRQ_STATUS, &active_irq)) { @@ -1222,8 +1219,7 @@ static irqreturn_t nau8821_interrupt(int irq, void *data) NAU8821_MICDET_MASK, NAU8821_MICDET_EN); if (nau8821_is_jack_inserted(regmap)) { /* Detect microphone and jack type */ - component = snd_soc_dapm_to_component(nau8821->dapm); - snd_soc_component_force_enable_pin(component, "MICBIAS"); + snd_soc_dapm_force_enable_pin(nau8821->dapm, "MICBIAS"); snd_soc_dapm_sync(nau8821->dapm); schedule_delayed_work(&nau8821->jdet_work, msecs_to_jiffies(20)); /* Turn off insertion interruption at manual mode */ @@ -1261,8 +1257,7 @@ static const struct regmap_config nau8821_regmap_config = { static int nau8821_component_probe(struct snd_soc_component *component) { struct nau8821 *nau8821 = snd_soc_component_get_drvdata(component); - struct snd_soc_dapm_context *dapm = - snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); nau8821->dapm = dapm; @@ -1564,8 +1559,7 @@ static int nau8821_set_bias_level(struct snd_soc_component *component, case SND_SOC_BIAS_STANDBY: /* Setup codec configuration after resume */ - if (snd_soc_component_get_bias_level(component) == - SND_SOC_BIAS_OFF) + if (snd_soc_dapm_get_bias_level(nau8821->dapm) == SND_SOC_BIAS_OFF) nau8821_resume_setup(nau8821); break; @@ -1603,9 +1597,9 @@ static int __maybe_unused nau8821_suspend(struct snd_soc_component *component) if (nau8821->irq) disable_irq(nau8821->irq); - snd_soc_component_force_bias_level(component, SND_SOC_BIAS_OFF); + snd_soc_dapm_force_bias_level(nau8821->dapm, SND_SOC_BIAS_OFF); /* Power down codec power; don't support button wakeup */ - snd_soc_component_disable_pin(component, "MICBIAS"); + snd_soc_dapm_disable_pin(nau8821->dapm, "MICBIAS"); snd_soc_dapm_sync(nau8821->dapm); regcache_cache_only(nau8821->regmap, true); regcache_mark_dirty(nau8821->regmap); diff --git a/sound/soc/codecs/nau8822.c b/sound/soc/codecs/nau8822.c index 0373167c25f448..a11759f85eaca1 100644 --- a/sound/soc/codecs/nau8822.c +++ b/sound/soc/codecs/nau8822.c @@ -957,6 +957,7 @@ static int nau8822_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { struct nau8822 *nau8822 = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); switch (level) { case SND_SOC_BIAS_ON: @@ -964,7 +965,7 @@ static int nau8822_set_bias_level(struct snd_soc_component *component, case SND_SOC_BIAS_PREPARE: if (nau8822->mclk && - snd_soc_component_get_bias_level(component) != SND_SOC_BIAS_ON) { + snd_soc_dapm_get_bias_level(dapm) != SND_SOC_BIAS_ON) { int ret = clk_prepare_enable(nau8822->mclk); if (ret) { @@ -981,7 +982,7 @@ static int nau8822_set_bias_level(struct snd_soc_component *component, case SND_SOC_BIAS_STANDBY: if (nau8822->mclk && - snd_soc_component_get_bias_level(component) != SND_SOC_BIAS_OFF) + snd_soc_dapm_get_bias_level(dapm) != SND_SOC_BIAS_OFF) clk_disable_unprepare(nau8822->mclk); snd_soc_component_update_bits(component, @@ -989,8 +990,7 @@ static int nau8822_set_bias_level(struct snd_soc_component *component, NAU8822_IOBUF_EN | NAU8822_ABIAS_EN, NAU8822_IOBUF_EN | NAU8822_ABIAS_EN); - if (snd_soc_component_get_bias_level(component) == - SND_SOC_BIAS_OFF) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) { snd_soc_component_update_bits(component, NAU8822_REG_POWER_MANAGEMENT_1, NAU8822_REFIMP_MASK, NAU8822_REFIMP_3K); @@ -1053,8 +1053,9 @@ static struct snd_soc_dai_driver nau8822_dai = { static int nau8822_suspend(struct snd_soc_component *component) { struct nau8822 *nau8822 = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); - snd_soc_component_force_bias_level(component, SND_SOC_BIAS_OFF); + snd_soc_dapm_force_bias_level(dapm, SND_SOC_BIAS_OFF); regcache_mark_dirty(nau8822->regmap); @@ -1064,10 +1065,11 @@ static int nau8822_suspend(struct snd_soc_component *component) static int nau8822_resume(struct snd_soc_component *component) { struct nau8822 *nau8822 = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); regcache_sync(nau8822->regmap); - snd_soc_component_force_bias_level(component, SND_SOC_BIAS_STANDBY); + snd_soc_dapm_force_bias_level(dapm, SND_SOC_BIAS_STANDBY); return 0; } diff --git a/sound/soc/codecs/nau8824.c b/sound/soc/codecs/nau8824.c index 542bd22e618018..6ce76376244300 100644 --- a/sound/soc/codecs/nau8824.c +++ b/sound/soc/codecs/nau8824.c @@ -876,7 +876,7 @@ static void nau8824_eject_jack(struct nau8824 *nau8824) NAU8824_JD_SLEEP_MODE, NAU8824_JD_SLEEP_MODE); /* Close clock for jack type detection at manual mode */ - if (dapm->bias_level < SND_SOC_BIAS_PREPARE) + if (snd_soc_dapm_get_bias_level(dapm) < SND_SOC_BIAS_PREPARE) nau8824_config_sysclk(nau8824, NAU8824_CLK_DIS, 0); } @@ -931,7 +931,7 @@ static void nau8824_setup_auto_irq(struct nau8824 *nau8824) regmap_update_bits(regmap, NAU8824_REG_INTERRUPT_SETTING, NAU8824_IRQ_EJECT_DIS, 0); /* Enable internal VCO needed for interruptions */ - if (nau8824->dapm->bias_level < SND_SOC_BIAS_PREPARE) + if (snd_soc_dapm_get_bias_level(nau8824->dapm) < SND_SOC_BIAS_PREPARE) nau8824_config_sysclk(nau8824, NAU8824_CLK_INTERNAL, 0); regmap_update_bits(regmap, NAU8824_REG_ENA_CTRL, NAU8824_JD_SLEEP_MODE, 0); @@ -1498,7 +1498,7 @@ static int nau8824_set_bias_level(struct snd_soc_component *component, break; case SND_SOC_BIAS_STANDBY: - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) { + if (snd_soc_dapm_get_bias_level(nau8824->dapm) == SND_SOC_BIAS_OFF) { /* Setup codec configuration after resume */ nau8824_resume_setup(nau8824); } @@ -1519,7 +1519,7 @@ static int nau8824_set_bias_level(struct snd_soc_component *component, static int nau8824_component_probe(struct snd_soc_component *component) { struct nau8824 *nau8824 = snd_soc_component_get_drvdata(component); - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); nau8824->dapm = dapm; @@ -1532,7 +1532,7 @@ static int __maybe_unused nau8824_suspend(struct snd_soc_component *component) if (nau8824->irq) { disable_irq(nau8824->irq); - snd_soc_component_force_bias_level(component, SND_SOC_BIAS_OFF); + snd_soc_dapm_force_bias_level(nau8824->dapm, SND_SOC_BIAS_OFF); } regcache_cache_only(nau8824->regmap, true); regcache_mark_dirty(nau8824->regmap); diff --git a/sound/soc/codecs/nau8825.c b/sound/soc/codecs/nau8825.c index 25b8b19e27ecd1..dd3528537ae42a 100644 --- a/sound/soc/codecs/nau8825.c +++ b/sound/soc/codecs/nau8825.c @@ -2226,7 +2226,7 @@ static const struct regmap_config nau8825_regmap_config = { static int nau8825_component_probe(struct snd_soc_component *component) { struct nau8825 *nau8825 = snd_soc_component_get_drvdata(component); - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); nau8825->dapm = dapm; @@ -2630,7 +2630,7 @@ static int nau8825_set_bias_level(struct snd_soc_component *component, break; case SND_SOC_BIAS_STANDBY: - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) { + if (snd_soc_dapm_get_bias_level(nau8825->dapm) == SND_SOC_BIAS_OFF) { if (nau8825->mclk_freq) { ret = clk_prepare_enable(nau8825->mclk); if (ret) { @@ -2673,7 +2673,7 @@ static int __maybe_unused nau8825_suspend(struct snd_soc_component *component) struct nau8825 *nau8825 = snd_soc_component_get_drvdata(component); disable_irq(nau8825->irq); - snd_soc_component_force_bias_level(component, SND_SOC_BIAS_OFF); + snd_soc_dapm_force_bias_level(nau8825->dapm, SND_SOC_BIAS_OFF); /* Power down codec power; don't suppoet button wakeup */ snd_soc_dapm_disable_pin(nau8825->dapm, "SAR"); snd_soc_dapm_disable_pin(nau8825->dapm, "MICBIAS"); diff --git a/sound/soc/codecs/pcm186x.c b/sound/soc/codecs/pcm186x.c index 13443f569ddb4d..0d1103fe4e04de 100644 --- a/sound/soc/codecs/pcm186x.c +++ b/sound/soc/codecs/pcm186x.c @@ -546,8 +546,10 @@ static int pcm186x_power_off(struct snd_soc_component *component) static int pcm186x_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); + dev_dbg(component->dev, "## %s: %d -> %d\n", __func__, - snd_soc_component_get_bias_level(component), level); + snd_soc_dapm_get_bias_level(dapm), level); switch (level) { case SND_SOC_BIAS_ON: @@ -555,7 +557,7 @@ static int pcm186x_set_bias_level(struct snd_soc_component *component, case SND_SOC_BIAS_PREPARE: break; case SND_SOC_BIAS_STANDBY: - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) pcm186x_power_on(component); break; case SND_SOC_BIAS_OFF: diff --git a/sound/soc/codecs/pcm512x.c b/sound/soc/codecs/pcm512x.c index 0c06f1f0da3fdd..a70e8ea166dc51 100644 --- a/sound/soc/codecs/pcm512x.c +++ b/sound/soc/codecs/pcm512x.c @@ -235,9 +235,10 @@ static int pcm512x_overclock_pll_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kcontrol); struct pcm512x_priv *pcm512x = snd_soc_component_get_drvdata(component); - switch (snd_soc_component_get_bias_level(component)) { + switch (snd_soc_dapm_get_bias_level(dapm)) { case SND_SOC_BIAS_OFF: case SND_SOC_BIAS_STANDBY: break; @@ -263,9 +264,10 @@ static int pcm512x_overclock_dsp_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kcontrol); struct pcm512x_priv *pcm512x = snd_soc_component_get_drvdata(component); - switch (snd_soc_component_get_bias_level(component)) { + switch (snd_soc_dapm_get_bias_level(dapm)) { case SND_SOC_BIAS_OFF: case SND_SOC_BIAS_STANDBY: break; @@ -291,9 +293,10 @@ static int pcm512x_overclock_dac_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kcontrol); struct pcm512x_priv *pcm512x = snd_soc_component_get_drvdata(component); - switch (snd_soc_component_get_bias_level(component)) { + switch (snd_soc_dapm_get_bias_level(dapm)) { case SND_SOC_BIAS_OFF: case SND_SOC_BIAS_STANDBY: break; diff --git a/sound/soc/codecs/pm4125.c b/sound/soc/codecs/pm4125.c index 5c3907d23542a6..8bc3b999401975 100644 --- a/sound/soc/codecs/pm4125.c +++ b/sound/soc/codecs/pm4125.c @@ -71,7 +71,7 @@ struct pm4125_priv { struct wcd_mbhc_intr intr_ids; struct wcd_common common; struct irq_domain *virq; - const struct regmap_irq_chip *pm4125_regmap_irq_chip; + const struct regmap_irq_chip *chip_desc; struct regmap_irq_chip_data *irq_chip; struct snd_soc_jack *jack; unsigned long status_mask; @@ -177,7 +177,7 @@ static const u32 pm4125_config_regs[] = { PM4125_DIG_SWR_INTR_LEVEL_0, }; -static struct regmap_irq_chip pm4125_regmap_irq_chip = { +static const struct regmap_irq_chip pm4125_regmap_irq_chip = { .name = "pm4125", .irqs = pm4125_irqs, .num_irqs = ARRAY_SIZE(pm4125_irqs), @@ -1301,10 +1301,8 @@ static int pm4125_irq_init(struct pm4125_priv *pm4125, struct device *dev) return -EINVAL; } - pm4125_regmap_irq_chip.irq_drv_data = pm4125; - return devm_regmap_add_irq_chip(dev, pm4125->regmap, irq_create_mapping(pm4125->virq, 0), - IRQF_ONESHOT, 0, &pm4125_regmap_irq_chip, + IRQF_ONESHOT, 0, pm4125->chip_desc, &pm4125->irq_chip); } @@ -1507,6 +1505,10 @@ static int pm4125_bind(struct device *dev) struct device_link *devlink; int ret; + /* Initialize device pointers to NULL for safe cleanup */ + pm4125->rxdev = NULL; + pm4125->txdev = NULL; + /* Give the soundwire subdevices some more time to settle */ usleep_range(15000, 15010); @@ -1530,7 +1532,7 @@ static int pm4125_bind(struct device *dev) if (!pm4125->txdev) { dev_err(dev, "could not find txslave with matching of node\n"); ret = -EINVAL; - goto error_unbind_all; + goto error_put_rx; } pm4125->sdw_priv[AIF1_CAP] = dev_get_drvdata(pm4125->txdev); @@ -1540,7 +1542,7 @@ static int pm4125_bind(struct device *dev) if (!pm4125->tx_sdw_dev) { dev_err(dev, "could not get txslave with matching of dev\n"); ret = -EINVAL; - goto error_unbind_all; + goto error_put_tx; } /* @@ -1552,7 +1554,7 @@ static int pm4125_bind(struct device *dev) if (!devlink) { dev_err(dev, "Could not devlink TX and RX\n"); ret = -EINVAL; - goto error_unbind_all; + goto error_put_tx; } devlink = device_link_add(dev, pm4125->txdev, @@ -1602,6 +1604,10 @@ static int pm4125_bind(struct device *dev) device_link_remove(dev, pm4125->txdev); link_remove_rx_tx: device_link_remove(pm4125->rxdev, pm4125->txdev); +error_put_tx: + put_device(pm4125->txdev); +error_put_rx: + put_device(pm4125->rxdev); error_unbind_all: component_unbind_all(dev, pm4125); return ret; @@ -1612,9 +1618,18 @@ static void pm4125_unbind(struct device *dev) struct pm4125_priv *pm4125 = dev_get_drvdata(dev); snd_soc_unregister_component(dev); + devm_regmap_del_irq_chip(dev, irq_find_mapping(pm4125->virq, 0), + pm4125->irq_chip); device_link_remove(dev, pm4125->txdev); device_link_remove(dev, pm4125->rxdev); device_link_remove(pm4125->rxdev, pm4125->txdev); + + /* Release device references acquired in bind */ + if (pm4125->txdev) + put_device(pm4125->txdev); + if (pm4125->rxdev) + put_device(pm4125->rxdev); + component_unbind_all(dev, pm4125); } @@ -1647,6 +1662,7 @@ static int pm4125_probe(struct platform_device *pdev) { struct component_match *match = NULL; struct device *dev = &pdev->dev; + struct regmap_irq_chip *chip_desc; struct pm4125_priv *pm4125; struct wcd_mbhc_config *cfg; int ret; @@ -1657,6 +1673,14 @@ static int pm4125_probe(struct platform_device *pdev) dev_set_drvdata(dev, pm4125); + chip_desc = devm_kmemdup(dev, &pm4125_regmap_irq_chip, + sizeof(pm4125_regmap_irq_chip), + GFP_KERNEL); + if (!chip_desc) + return -ENOMEM; + chip_desc->irq_drv_data = pm4125; + pm4125->chip_desc = chip_desc; + ret = devm_regulator_bulk_get_enable(dev, ARRAY_SIZE(pm4125_power_supplies), pm4125_power_supplies); if (ret) diff --git a/sound/soc/codecs/rk3308_codec.c b/sound/soc/codecs/rk3308_codec.c index 8b51e87a171150..60befe9d37f05f 100644 --- a/sound/soc/codecs/rk3308_codec.c +++ b/sound/soc/codecs/rk3308_codec.c @@ -786,6 +786,7 @@ static int rk3308_codec_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { struct rk3308_codec_priv *rk3308 = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); switch (level) { case SND_SOC_BIAS_ON: @@ -793,7 +794,7 @@ static int rk3308_codec_set_bias_level(struct snd_soc_component *component, case SND_SOC_BIAS_PREPARE: break; case SND_SOC_BIAS_STANDBY: - if (snd_soc_component_get_bias_level(component) != SND_SOC_BIAS_OFF) + if (snd_soc_dapm_get_bias_level(dapm) != SND_SOC_BIAS_OFF) break; /* Sequence from TRM Section 8.6.3 "Power Up" */ diff --git a/sound/soc/codecs/rt1011.c b/sound/soc/codecs/rt1011.c index 170e257e6ddebb..9f34a6a3548763 100644 --- a/sound/soc/codecs/rt1011.c +++ b/sound/soc/codecs/rt1011.c @@ -1047,13 +1047,14 @@ static int rt1011_recv_spk_mode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kcontrol); struct rt1011_priv *rt1011 = snd_soc_component_get_drvdata(component); if (ucontrol->value.integer.value[0] == rt1011->recv_spk_mode) return 0; - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) { rt1011->recv_spk_mode = ucontrol->value.integer.value[0]; if (rt1011->recv_spk_mode) { @@ -1220,10 +1221,11 @@ static int rt1011_r0_cali_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct rt1011_priv *rt1011 = snd_soc_component_get_drvdata(component); rt1011->cali_done = 0; - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF && + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF && ucontrol->value.integer.value[0]) rt1011_calibrate(rt1011, 1); @@ -1260,6 +1262,7 @@ static int rt1011_r0_load_mode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct rt1011_priv *rt1011 = snd_soc_component_get_drvdata(component); struct device *dev; unsigned int r0_integer, r0_factor, format; @@ -1271,7 +1274,7 @@ static int rt1011_r0_load_mode_put(struct snd_kcontrol *kcontrol, return -EINVAL; dev = regmap_get_device(rt1011->regmap); - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) { rt1011->r0_reg = ucontrol->value.integer.value[0]; format = 2147483648U; /* 2^24 * 128 */ @@ -1658,8 +1661,7 @@ static int rt1011_hw_params(struct snd_pcm_substream *substream, static int rt1011_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) { struct snd_soc_component *component = dai->component; - struct snd_soc_dapm_context *dapm = - snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); unsigned int reg_val = 0, reg_bclk_inv = 0; int ret = 0; @@ -1839,8 +1841,7 @@ static int rt1011_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width) { struct snd_soc_component *component = dai->component; - struct snd_soc_dapm_context *dapm = - snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); unsigned int val = 0, tdm_en = 0, rx_slotnum, tx_slotnum; int ret = 0, first_bit, last_bit; @@ -2212,8 +2213,7 @@ static int rt1011_calibrate(struct rt1011_priv *rt1011, unsigned char cali_flag) unsigned int dc_offset; unsigned int r0_integer, r0_factor, format; struct device *dev = regmap_get_device(rt1011->regmap); - struct snd_soc_dapm_context *dapm = - snd_soc_component_get_dapm(rt1011->component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(rt1011->component); int ret = 0; snd_soc_dapm_mutex_lock(dapm); diff --git a/sound/soc/codecs/rt1015.c b/sound/soc/codecs/rt1015.c index 033a196cb5c73f..ca1ed9d5a24ed4 100644 --- a/sound/soc/codecs/rt1015.c +++ b/sound/soc/codecs/rt1015.c @@ -491,9 +491,10 @@ static int rt1015_bypass_boost_get(struct snd_kcontrol *kcontrol, static void rt1015_calibrate(struct rt1015_priv *rt1015) { struct snd_soc_component *component = rt1015->component; + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct regmap *regmap = rt1015->regmap; - snd_soc_dapm_mutex_lock(&component->dapm); + snd_soc_dapm_mutex_lock(dapm); regcache_cache_bypass(regmap, true); regmap_write(regmap, RT1015_CLK_DET, 0x0000); @@ -515,7 +516,7 @@ static void rt1015_calibrate(struct rt1015_priv *rt1015) regcache_cache_bypass(regmap, false); regcache_mark_dirty(regmap); regcache_sync(regmap); - snd_soc_dapm_mutex_unlock(&component->dapm); + snd_soc_dapm_mutex_unlock(dapm); } static int rt1015_bypass_boost_put(struct snd_kcontrol *kcontrol, diff --git a/sound/soc/codecs/rt274.c b/sound/soc/codecs/rt274.c index 2c055c45111f59..5c33aeaced2fde 100644 --- a/sound/soc/codecs/rt274.c +++ b/sound/soc/codecs/rt274.c @@ -925,10 +925,11 @@ static int rt274_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, static int rt274_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); + switch (level) { case SND_SOC_BIAS_PREPARE: - if (SND_SOC_BIAS_STANDBY == - snd_soc_component_get_bias_level(component)) { + if (SND_SOC_BIAS_STANDBY == snd_soc_dapm_get_bias_level(dapm)) { snd_soc_component_write(component, RT274_SET_AUDIO_POWER, AC_PWRST_D0); } diff --git a/sound/soc/codecs/rt286.c b/sound/soc/codecs/rt286.c index fd8de8b497936c..2fbb5860c42138 100644 --- a/sound/soc/codecs/rt286.c +++ b/sound/soc/codecs/rt286.c @@ -223,7 +223,7 @@ static int rt286_jack_detect(struct rt286_priv *rt286, bool *hp, bool *mic) if (!rt286->component) return -EINVAL; - dapm = snd_soc_component_get_dapm(rt286->component); + dapm = snd_soc_component_to_dapm(rt286->component); if (rt286->pdata.cbj_en) { regmap_read(rt286->regmap, RT286_GET_HP_SENSE, &buf); @@ -314,7 +314,7 @@ static void rt286_jack_detect_work(struct work_struct *work) static int rt286_mic_detect(struct snd_soc_component *component, struct snd_soc_jack *jack, void *data) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct rt286_priv *rt286 = snd_soc_component_get_drvdata(component); rt286->jack = jack; @@ -887,9 +887,11 @@ static int rt286_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio) static int rt286_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); + switch (level) { case SND_SOC_BIAS_PREPARE: - if (SND_SOC_BIAS_STANDBY == snd_soc_component_get_bias_level(component)) { + if (SND_SOC_BIAS_STANDBY == snd_soc_dapm_get_bias_level(dapm)) { snd_soc_component_write(component, RT286_SET_AUDIO_POWER, AC_PWRST_D0); snd_soc_component_update_bits(component, diff --git a/sound/soc/codecs/rt298.c b/sound/soc/codecs/rt298.c index ee3d9291eea65f..02247593513ab2 100644 --- a/sound/soc/codecs/rt298.c +++ b/sound/soc/codecs/rt298.c @@ -227,7 +227,7 @@ static int rt298_jack_detect(struct rt298_priv *rt298, bool *hp, bool *mic) if (!rt298->component) return -EINVAL; - dapm = snd_soc_component_get_dapm(rt298->component); + dapm = snd_soc_component_to_dapm(rt298->component); if (rt298->pdata.cbj_en) { regmap_read(rt298->regmap, RT298_GET_HP_SENSE, &buf); @@ -329,7 +329,7 @@ static void rt298_jack_detect_work(struct work_struct *work) static int rt298_mic_detect(struct snd_soc_component *component, struct snd_soc_jack *jack, void *data) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct rt298_priv *rt298 = snd_soc_component_get_drvdata(component); rt298->jack = jack; @@ -949,10 +949,11 @@ static int rt298_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio) static int rt298_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); + switch (level) { case SND_SOC_BIAS_PREPARE: - if (SND_SOC_BIAS_STANDBY == - snd_soc_component_get_bias_level(component)) { + if (SND_SOC_BIAS_STANDBY == snd_soc_dapm_get_bias_level(dapm)) { snd_soc_component_write(component, RT298_SET_AUDIO_POWER, AC_PWRST_D0); snd_soc_component_update_bits(component, 0x0d, 0x200, 0x200); diff --git a/sound/soc/codecs/rt5514.c b/sound/soc/codecs/rt5514.c index ab9d81c32be8ef..649b44b790b030 100644 --- a/sound/soc/codecs/rt5514.c +++ b/sound/soc/codecs/rt5514.c @@ -325,6 +325,7 @@ static int rt5514_dsp_voice_wake_up_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct rt5514_priv *rt5514 = snd_soc_component_get_drvdata(component); const struct firmware *fw = NULL; u8 buf[8]; @@ -332,7 +333,7 @@ static int rt5514_dsp_voice_wake_up_put(struct snd_kcontrol *kcontrol, if (ucontrol->value.integer.value[0] == rt5514->dsp_enabled) return 0; - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) { rt5514->dsp_enabled = ucontrol->value.integer.value[0]; if (rt5514->dsp_enabled) { @@ -1050,11 +1051,12 @@ static int rt5514_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { struct rt5514_priv *rt5514 = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); int ret; switch (level) { case SND_SOC_BIAS_PREPARE: - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_ON) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_ON) { clk_disable_unprepare(rt5514->mclk); } else { ret = clk_prepare_enable(rt5514->mclk); @@ -1064,7 +1066,7 @@ static int rt5514_set_bias_level(struct snd_soc_component *component, break; case SND_SOC_BIAS_STANDBY: - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) { /* * If the DSP is enabled in start of recording, the DSP * should be disabled, and sync back to normal recording diff --git a/sound/soc/codecs/rt5616.c b/sound/soc/codecs/rt5616.c index 1ec486707ff944..fb9cf127e3ff21 100644 --- a/sound/soc/codecs/rt5616.c +++ b/sound/soc/codecs/rt5616.c @@ -1159,6 +1159,7 @@ static int rt5616_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { struct rt5616_priv *rt5616 = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); int ret; switch (level) { @@ -1174,7 +1175,7 @@ static int rt5616_set_bias_level(struct snd_soc_component *component, * away from ON. Disable the clock in that case, otherwise * enable it. */ - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_ON) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_ON) { clk_disable_unprepare(rt5616->mclk); } else { ret = clk_prepare_enable(rt5616->mclk); @@ -1184,7 +1185,7 @@ static int rt5616_set_bias_level(struct snd_soc_component *component, break; case SND_SOC_BIAS_STANDBY: - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) { snd_soc_component_update_bits(component, RT5616_PWR_ANLG1, RT5616_PWR_VREF1 | RT5616_PWR_MB | RT5616_PWR_BG | RT5616_PWR_VREF2, diff --git a/sound/soc/codecs/rt5631.c b/sound/soc/codecs/rt5631.c index 616db75b634cc3..19c6d8f760d9eb 100644 --- a/sound/soc/codecs/rt5631.c +++ b/sound/soc/codecs/rt5631.c @@ -1535,6 +1535,7 @@ static int rt5631_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { struct rt5631_priv *rt5631 = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); switch (level) { case SND_SOC_BIAS_ON: @@ -1545,7 +1546,7 @@ static int rt5631_set_bias_level(struct snd_soc_component *component, break; case SND_SOC_BIAS_STANDBY: - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) { snd_soc_component_update_bits(component, RT5631_PWR_MANAG_ADD3, RT5631_PWR_VREF | RT5631_PWR_MAIN_BIAS, RT5631_PWR_VREF | RT5631_PWR_MAIN_BIAS); @@ -1575,6 +1576,7 @@ static int rt5631_set_bias_level(struct snd_soc_component *component, static int rt5631_probe(struct snd_soc_component *component) { struct rt5631_priv *rt5631 = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); unsigned int val; val = rt5631_read_index(component, RT5631_ADDA_MIXER_INTL_REG3); @@ -1613,7 +1615,7 @@ static int rt5631_probe(struct snd_soc_component *component) RT5631_DMIC_R_CH_LATCH_RISING); } - snd_soc_component_init_bias_level(component, SND_SOC_BIAS_STANDBY); + snd_soc_dapm_init_bias_level(dapm, SND_SOC_BIAS_STANDBY); return 0; } diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c index f50e771db24b0f..4c08c274f50e2e 100644 --- a/sound/soc/codecs/rt5640.c +++ b/sound/soc/codecs/rt5640.c @@ -1935,6 +1935,7 @@ static int rt5640_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); int ret; switch (level) { @@ -1949,7 +1950,7 @@ static int rt5640_set_bias_level(struct snd_soc_component *component, * away from ON. Disable the clock in that case, otherwise * enable it. */ - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_ON) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_ON) { clk_disable_unprepare(rt5640->mclk); } else { ret = clk_prepare_enable(rt5640->mclk); @@ -1959,7 +1960,7 @@ static int rt5640_set_bias_level(struct snd_soc_component *component, break; case SND_SOC_BIAS_STANDBY: - if (SND_SOC_BIAS_OFF == snd_soc_component_get_bias_level(component)) { + if (SND_SOC_BIAS_OFF == snd_soc_dapm_get_bias_level(dapm)) { snd_soc_component_update_bits(component, RT5640_PWR_ANLG1, RT5640_PWR_VREF1 | RT5640_PWR_MB | RT5640_PWR_BG | RT5640_PWR_VREF2, @@ -2098,7 +2099,7 @@ EXPORT_SYMBOL_GPL(rt5640_sel_asrc_clk_src); void rt5640_enable_micbias1_for_ovcd(struct snd_soc_component *component) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component); snd_soc_dapm_mutex_lock(dapm); @@ -2114,7 +2115,7 @@ EXPORT_SYMBOL_GPL(rt5640_enable_micbias1_for_ovcd); void rt5640_disable_micbias1_for_ovcd(struct snd_soc_component *component) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component); snd_soc_dapm_mutex_lock(dapm); @@ -2586,8 +2587,7 @@ static void rt5640_enable_hda_jack_detect( struct snd_soc_component *component, struct snd_soc_jack *jack) { struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component); - struct snd_soc_dapm_context *dapm = - snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); int ret; /* Select JD1 for Mic */ @@ -2652,7 +2652,7 @@ static int rt5640_set_jack(struct snd_soc_component *component, static int rt5640_probe(struct snd_soc_component *component) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component); u32 dmic1_data_pin = 0; u32 dmic2_data_pin = 0; @@ -2666,7 +2666,7 @@ static int rt5640_probe(struct snd_soc_component *component) rt5640->component = component; - snd_soc_component_force_bias_level(component, SND_SOC_BIAS_OFF); + snd_soc_dapm_force_bias_level(dapm, SND_SOC_BIAS_OFF); snd_soc_component_update_bits(component, RT5640_GCTL1, 0x0301, 0x0301); snd_soc_component_update_bits(component, RT5640_MICBIAS, 0x0030, 0x0030); @@ -2796,6 +2796,7 @@ static void rt5640_remove(struct snd_soc_component *component) static int rt5640_suspend(struct snd_soc_component *component) { struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); if (rt5640->jack) { /* disable jack interrupts during system suspend */ @@ -2804,7 +2805,7 @@ static int rt5640_suspend(struct snd_soc_component *component) cancel_delayed_work_sync(&rt5640->bp_work); } - snd_soc_component_force_bias_level(component, SND_SOC_BIAS_OFF); + snd_soc_dapm_force_bias_level(dapm, SND_SOC_BIAS_OFF); rt5640_reset(component); regcache_cache_only(rt5640->regmap, true); regcache_mark_dirty(rt5640->regmap); diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c index 29a403526cd9e9..f7701b8d0d3c7e 100644 --- a/sound/soc/codecs/rt5645.c +++ b/sound/soc/codecs/rt5645.c @@ -3071,10 +3071,11 @@ static int rt5645_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { struct rt5645_priv *rt5645 = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); switch (level) { case SND_SOC_BIAS_PREPARE: - if (SND_SOC_BIAS_STANDBY == snd_soc_component_get_bias_level(component)) { + if (SND_SOC_BIAS_STANDBY == snd_soc_dapm_get_bias_level(dapm)) { snd_soc_component_update_bits(component, RT5645_PWR_ANLG1, RT5645_PWR_VREF1 | RT5645_PWR_MB | RT5645_PWR_BG | RT5645_PWR_VREF2, @@ -3099,7 +3100,7 @@ static int rt5645_set_bias_level(struct snd_soc_component *component, snd_soc_component_update_bits(component, RT5645_PWR_ANLG1, RT5645_PWR_FV1 | RT5645_PWR_FV2, RT5645_PWR_FV1 | RT5645_PWR_FV2); - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) { snd_soc_component_write(component, RT5645_DEPOP_M2, 0x1140); msleep(40); if (rt5645->en_button_func) @@ -3130,7 +3131,7 @@ static int rt5645_set_bias_level(struct snd_soc_component *component, static void rt5645_enable_push_button_irq(struct snd_soc_component *component, bool enable) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); int ret; if (enable) { @@ -3169,7 +3170,7 @@ static void rt5645_enable_push_button_irq(struct snd_soc_component *component, static int rt5645_jack_detect(struct snd_soc_component *component, int jack_insert) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct rt5645_priv *rt5645 = snd_soc_component_get_drvdata(component); unsigned int val; @@ -3180,7 +3181,7 @@ static int rt5645_jack_detect(struct snd_soc_component *component, int jack_inse snd_soc_dapm_force_enable_pin(dapm, "LDO2"); snd_soc_dapm_force_enable_pin(dapm, "Mic Det Power"); snd_soc_dapm_sync(dapm); - if (!snd_soc_card_is_instantiated(dapm->card)) { + if (!snd_soc_card_is_instantiated(component->card)) { /* Power up necessary bits for JD if dapm is not ready yet */ regmap_update_bits(rt5645->regmap, RT5645_PWR_ANLG1, @@ -3449,7 +3450,7 @@ static void rt5645_btn_check_callback(struct timer_list *t) static int rt5645_probe(struct snd_soc_component *component) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct rt5645_priv *rt5645 = snd_soc_component_get_drvdata(component); rt5645->component = component; @@ -3478,7 +3479,7 @@ static int rt5645_probe(struct snd_soc_component *component) break; } - snd_soc_component_force_bias_level(component, SND_SOC_BIAS_OFF); + snd_soc_dapm_force_bias_level(dapm, SND_SOC_BIAS_OFF); /* for JD function */ if (rt5645->pdata.jd_mode) { diff --git a/sound/soc/codecs/rt5651.c b/sound/soc/codecs/rt5651.c index 9eeeba8cd6ffcb..9af65a38f0ee61 100644 --- a/sound/soc/codecs/rt5651.c +++ b/sound/soc/codecs/rt5651.c @@ -1511,16 +1511,18 @@ static int rt5651_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source, static int rt5651_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); + switch (level) { case SND_SOC_BIAS_PREPARE: - if (SND_SOC_BIAS_STANDBY == snd_soc_component_get_bias_level(component)) { + if (SND_SOC_BIAS_STANDBY == snd_soc_dapm_get_bias_level(dapm)) { if (snd_soc_component_read(component, RT5651_PLL_MODE_1) & 0x9200) snd_soc_component_update_bits(component, RT5651_D_MISC, 0xc00, 0xc00); } break; case SND_SOC_BIAS_STANDBY: - if (SND_SOC_BIAS_OFF == snd_soc_component_get_bias_level(component)) { + if (SND_SOC_BIAS_OFF == snd_soc_dapm_get_bias_level(dapm)) { snd_soc_component_update_bits(component, RT5651_PWR_ANLG1, RT5651_PWR_VREF1 | RT5651_PWR_MB | RT5651_PWR_BG | RT5651_PWR_VREF2, @@ -1557,7 +1559,7 @@ static int rt5651_set_bias_level(struct snd_soc_component *component, static void rt5651_enable_micbias1_for_ovcd(struct snd_soc_component *component) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); snd_soc_dapm_mutex_lock(dapm); snd_soc_dapm_force_enable_pin_unlocked(dapm, "LDO"); @@ -1570,7 +1572,7 @@ static void rt5651_enable_micbias1_for_ovcd(struct snd_soc_component *component) static void rt5651_disable_micbias1_for_ovcd(struct snd_soc_component *component) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); snd_soc_dapm_mutex_lock(dapm); snd_soc_dapm_disable_pin_unlocked(dapm, "Platform Clock"); @@ -2058,13 +2060,14 @@ static void rt5651_apply_properties(struct snd_soc_component *component) static int rt5651_probe(struct snd_soc_component *component) { struct rt5651_priv *rt5651 = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); rt5651->component = component; snd_soc_component_update_bits(component, RT5651_PWR_ANLG1, RT5651_PWR_LDO_DVO_MASK, RT5651_PWR_LDO_DVO_1_2V); - snd_soc_component_force_bias_level(component, SND_SOC_BIAS_OFF); + snd_soc_dapm_force_bias_level(dapm, SND_SOC_BIAS_OFF); rt5651_apply_properties(component); diff --git a/sound/soc/codecs/rt5659.c b/sound/soc/codecs/rt5659.c index da89bdd2310d28..f5957470652c8e 100644 --- a/sound/soc/codecs/rt5659.c +++ b/sound/soc/codecs/rt5659.c @@ -1213,7 +1213,7 @@ static int rt5659_hp_vol_put(struct snd_kcontrol *kcontrol, static void rt5659_enable_push_button_irq(struct snd_soc_component *component, bool enable) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); if (enable) { snd_soc_component_write(component, RT5659_4BTN_IL_CMD_1, 0x000b); @@ -1257,7 +1257,7 @@ static void rt5659_enable_push_button_irq(struct snd_soc_component *component, static int rt5659_headset_detect(struct snd_soc_component *component, int jack_insert) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); int val, i = 0, sleep_time[5] = {300, 150, 100, 50, 30}; int reg_63; @@ -3611,7 +3611,7 @@ static int rt5659_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio) static int rt5659_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct rt5659_priv *rt5659 = snd_soc_component_get_drvdata(component); int ret; @@ -3631,7 +3631,7 @@ static int rt5659_set_bias_level(struct snd_soc_component *component, break; case SND_SOC_BIAS_STANDBY: - if (dapm->bias_level == SND_SOC_BIAS_OFF) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) { ret = clk_prepare_enable(rt5659->mclk); if (ret) { dev_err(component->dev, @@ -3662,8 +3662,7 @@ static int rt5659_set_bias_level(struct snd_soc_component *component, static int rt5659_probe(struct snd_soc_component *component) { - struct snd_soc_dapm_context *dapm = - snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct rt5659_priv *rt5659 = snd_soc_component_get_drvdata(component); rt5659->component = component; diff --git a/sound/soc/codecs/rt5660.c b/sound/soc/codecs/rt5660.c index 44c3a3b92f98fc..84cdfb810c66cd 100644 --- a/sound/soc/codecs/rt5660.c +++ b/sound/soc/codecs/rt5660.c @@ -1069,6 +1069,7 @@ static int rt5660_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { struct rt5660_priv *rt5660 = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); int ret; switch (level) { @@ -1079,7 +1080,7 @@ static int rt5660_set_bias_level(struct snd_soc_component *component, snd_soc_component_update_bits(component, RT5660_GEN_CTRL1, RT5660_DIG_GATE_CTRL, RT5660_DIG_GATE_CTRL); - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_ON) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_ON) { clk_disable_unprepare(rt5660->mclk); } else { ret = clk_prepare_enable(rt5660->mclk); @@ -1089,7 +1090,7 @@ static int rt5660_set_bias_level(struct snd_soc_component *component, break; case SND_SOC_BIAS_STANDBY: - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) { snd_soc_component_update_bits(component, RT5660_PWR_ANLG1, RT5660_PWR_VREF1 | RT5660_PWR_MB | RT5660_PWR_BG | RT5660_PWR_VREF2, diff --git a/sound/soc/codecs/rt5663.c b/sound/soc/codecs/rt5663.c index 50fdeb8f06061d..e4d8785e64c108 100644 --- a/sound/soc/codecs/rt5663.c +++ b/sound/soc/codecs/rt5663.c @@ -1463,7 +1463,7 @@ static void rt5663_enable_push_button_irq(struct snd_soc_component *component, static int rt5663_v2_jack_detect(struct snd_soc_component *component, int jack_insert) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct rt5663_priv *rt5663 = snd_soc_component_get_drvdata(component); int val, i = 0, sleep_time[5] = {300, 150, 100, 50, 30}; @@ -3140,7 +3140,7 @@ static int rt5663_set_bias_level(struct snd_soc_component *component, static int rt5663_probe(struct snd_soc_component *component) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct rt5663_priv *rt5663 = snd_soc_component_get_drvdata(component); rt5663->component = component; diff --git a/sound/soc/codecs/rt5665.c b/sound/soc/codecs/rt5665.c index ca0f0fb4bebaf5..c7beccd54b162e 100644 --- a/sound/soc/codecs/rt5665.c +++ b/sound/soc/codecs/rt5665.c @@ -1067,7 +1067,7 @@ static void rt5665_enable_push_button_irq(struct snd_soc_component *component, static int rt5665_headset_detect(struct snd_soc_component *component, int jack_insert) { struct rt5665_priv *rt5665 = snd_soc_component_get_drvdata(component); - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); unsigned int sar_hs_type, val; if (jack_insert) { diff --git a/sound/soc/codecs/rt5668.c b/sound/soc/codecs/rt5668.c index 8442dd09cfafe5..5fcdb50d5184a2 100644 --- a/sound/soc/codecs/rt5668.c +++ b/sound/soc/codecs/rt5668.c @@ -853,8 +853,7 @@ static int rt5668_headset_detect(struct snd_soc_component *component, int jack_insert) { struct rt5668_priv *rt5668 = snd_soc_component_get_drvdata(component); - struct snd_soc_dapm_context *dapm = - snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); unsigned int val, count; if (jack_insert) { diff --git a/sound/soc/codecs/rt5670.c b/sound/soc/codecs/rt5670.c index 8a681ee96f5be5..cb5d03bf4c7f47 100644 --- a/sound/soc/codecs/rt5670.c +++ b/sound/soc/codecs/rt5670.c @@ -431,7 +431,7 @@ static bool rt5670_readable_register(struct device *dev, unsigned int reg) static int rt5670_headset_detect(struct snd_soc_component *component, int jack_insert) { int val; - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct rt5670_priv *rt5670 = snd_soc_component_get_drvdata(component); if (jack_insert) { @@ -966,7 +966,7 @@ static int rt5670_put_dac1_mix_dac1_switch(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; - struct snd_soc_component *component = snd_soc_dapm_kcontrol_component(kcontrol); + struct snd_soc_component *component = snd_soc_dapm_kcontrol_to_component(kcontrol); struct rt5670_priv *rt5670 = snd_soc_component_get_drvdata(component); int ret; @@ -2670,10 +2670,11 @@ static int rt5670_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { struct rt5670_priv *rt5670 = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); switch (level) { case SND_SOC_BIAS_PREPARE: - if (SND_SOC_BIAS_STANDBY == snd_soc_component_get_bias_level(component)) { + if (SND_SOC_BIAS_STANDBY == snd_soc_dapm_get_bias_level(dapm)) { snd_soc_component_update_bits(component, RT5670_PWR_ANLG1, RT5670_PWR_VREF1 | RT5670_PWR_MB | RT5670_PWR_BG | RT5670_PWR_VREF2, @@ -2723,7 +2724,7 @@ static int rt5670_set_bias_level(struct snd_soc_component *component, static int rt5670_probe(struct snd_soc_component *component) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct rt5670_priv *rt5670 = snd_soc_component_get_drvdata(component); switch (snd_soc_component_read(component, RT5670_RESET) & RT5670_ID_MASK) { diff --git a/sound/soc/codecs/rt5677.c b/sound/soc/codecs/rt5677.c index 6b6c690a9e4552..d46385249867b3 100644 --- a/sound/soc/codecs/rt5677.c +++ b/sound/soc/codecs/rt5677.c @@ -706,8 +706,7 @@ static void rt5677_set_dsp_mode(struct rt5677_priv *rt5677, bool on) static unsigned int rt5677_set_vad_source(struct rt5677_priv *rt5677) { - struct snd_soc_dapm_context *dapm = - snd_soc_component_get_dapm(rt5677->component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(rt5677->component); /* Force dapm to sync before we enable the * DSP to prevent write corruption */ @@ -2733,11 +2732,12 @@ static int rt5677_vref_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct rt5677_priv *rt5677 = snd_soc_component_get_drvdata(component); switch (event) { case SND_SOC_DAPM_POST_PMU: - if (snd_soc_component_get_bias_level(component) != SND_SOC_BIAS_ON && + if (snd_soc_dapm_get_bias_level(dapm) != SND_SOC_BIAS_ON && !rt5677->is_vref_slow) { mdelay(20); regmap_update_bits(rt5677->regmap, RT5677_PWR_ANLG1, @@ -4643,8 +4643,8 @@ static int rt5677_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { struct rt5677_priv *rt5677 = snd_soc_component_get_drvdata(component); - enum snd_soc_bias_level prev_bias = - snd_soc_component_get_bias_level(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); + enum snd_soc_bias_level prev_bias = snd_soc_dapm_get_bias_level(dapm); switch (level) { case SND_SOC_BIAS_ON: @@ -4880,7 +4880,7 @@ static void rt5677_free_gpio(struct i2c_client *i2c) static int rt5677_probe(struct snd_soc_component *component) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct rt5677_priv *rt5677 = snd_soc_component_get_drvdata(component); int i; @@ -4896,7 +4896,7 @@ static int rt5677_probe(struct snd_soc_component *component) ARRAY_SIZE(rt5677_dmic2_clk_1)); } - snd_soc_component_force_bias_level(component, SND_SOC_BIAS_OFF); + snd_soc_dapm_force_bias_level(dapm, SND_SOC_BIAS_OFF); regmap_update_bits(rt5677->regmap, RT5677_DIG_MISC, ~RT5677_IRQ_DEBOUNCE_SEL_MASK, 0x0020); diff --git a/sound/soc/codecs/rt5682.c b/sound/soc/codecs/rt5682.c index a0abd2ce0c1e1f..d39f8e4f3474c1 100644 --- a/sound/soc/codecs/rt5682.c +++ b/sound/soc/codecs/rt5682.c @@ -928,7 +928,7 @@ static void rt5682_enable_push_button_irq(struct snd_soc_component *component, static int rt5682_headset_detect(struct snd_soc_component *component, int jack_insert) { struct rt5682_priv *rt5682 = snd_soc_component_get_drvdata(component); - struct snd_soc_dapm_context *dapm = &component->dapm; + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); unsigned int val, count; if (jack_insert) { @@ -1115,7 +1115,7 @@ void rt5682_jack_detect_handler(struct work_struct *work) } } - dapm = snd_soc_component_get_dapm(rt5682->component); + dapm = snd_soc_component_to_dapm(rt5682->component); snd_soc_dapm_mutex_lock(dapm); mutex_lock(&rt5682->calibrate_mutex); @@ -2595,7 +2595,7 @@ static int rt5682_wclk_prepare(struct clk_hw *hw) return -EINVAL; component = rt5682->component; - dapm = snd_soc_component_get_dapm(component); + dapm = snd_soc_component_to_dapm(component); snd_soc_dapm_mutex_lock(dapm); @@ -2633,7 +2633,7 @@ static void rt5682_wclk_unprepare(struct clk_hw *hw) return; component = rt5682->component; - dapm = snd_soc_component_get_dapm(component); + dapm = snd_soc_component_to_dapm(component); snd_soc_dapm_mutex_lock(dapm); @@ -2928,9 +2928,9 @@ EXPORT_SYMBOL_GPL(rt5682_register_dai_clks); static int rt5682_probe(struct snd_soc_component *component) { struct rt5682_priv *rt5682 = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct sdw_slave *slave; unsigned long time; - struct snd_soc_dapm_context *dapm = &component->dapm; rt5682->component = component; diff --git a/sound/soc/codecs/rt5682s.c b/sound/soc/codecs/rt5682s.c index 1d80a4b862e276..98de94a792603d 100644 --- a/sound/soc/codecs/rt5682s.c +++ b/sound/soc/codecs/rt5682s.c @@ -841,7 +841,7 @@ static void rt5682s_jack_detect_handler(struct work_struct *work) return; } - dapm = snd_soc_component_get_dapm(rt5682s->component); + dapm = snd_soc_component_to_dapm(rt5682s->component); snd_soc_dapm_mutex_lock(dapm); mutex_lock(&rt5682s->calibrate_mutex); @@ -2485,6 +2485,7 @@ static int rt5682s_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { struct rt5682s_priv *rt5682s = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); switch (level) { case SND_SOC_BIAS_PREPARE: @@ -2492,7 +2493,7 @@ static int rt5682s_set_bias_level(struct snd_soc_component *component, RT5682S_PWR_LDO, RT5682S_PWR_LDO); break; case SND_SOC_BIAS_STANDBY: - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) regmap_update_bits(rt5682s->regmap, RT5682S_PWR_DIG_1, RT5682S_DIG_GATE_CTRL, RT5682S_DIG_GATE_CTRL); break; diff --git a/sound/soc/codecs/rt700.c b/sound/soc/codecs/rt700.c index 816117c13aeaea..21523d0a5f08fc 100644 --- a/sound/soc/codecs/rt700.c +++ b/sound/soc/codecs/rt700.c @@ -272,11 +272,10 @@ static void rt700_btn_check_handler(struct work_struct *work) static void rt700_jack_init(struct rt700_priv *rt700) { - struct snd_soc_dapm_context *dapm = - snd_soc_component_get_dapm(rt700->component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(rt700->component); /* power on */ - if (dapm->bias_level <= SND_SOC_BIAS_STANDBY) + if (snd_soc_dapm_get_bias_level(dapm) <= SND_SOC_BIAS_STANDBY) regmap_write(rt700->regmap, RT700_SET_AUDIO_POWER_STATE, AC_PWRST_D0); @@ -307,7 +306,7 @@ static void rt700_jack_init(struct rt700_priv *rt700) } /* power off */ - if (dapm->bias_level <= SND_SOC_BIAS_STANDBY) + if (snd_soc_dapm_get_bias_level(dapm) <= SND_SOC_BIAS_STANDBY) regmap_write(rt700->regmap, RT700_SET_AUDIO_POWER_STATE, AC_PWRST_D3); } @@ -362,8 +361,7 @@ static int rt700_set_amp_gain_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); - struct snd_soc_dapm_context *dapm = - snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; struct rt700_priv *rt700 = snd_soc_component_get_drvdata(component); @@ -398,7 +396,7 @@ static int rt700_set_amp_gain_put(struct snd_kcontrol *kcontrol, val_ll |= read_ll; } - if (dapm->bias_level <= SND_SOC_BIAS_STANDBY) + if (snd_soc_dapm_get_bias_level(dapm) <= SND_SOC_BIAS_STANDBY) regmap_write(rt700->regmap, RT700_SET_AUDIO_POWER_STATE, AC_PWRST_D0); @@ -450,7 +448,7 @@ static int rt700_set_amp_gain_put(struct snd_kcontrol *kcontrol, break; } - if (dapm->bias_level <= SND_SOC_BIAS_STANDBY) + if (snd_soc_dapm_get_bias_level(dapm) <= SND_SOC_BIAS_STANDBY) regmap_write(rt700->regmap, RT700_SET_AUDIO_POWER_STATE, AC_PWRST_D3); return 0; @@ -524,8 +522,7 @@ static const struct snd_kcontrol_new rt700_snd_controls[] = { static int rt700_mux_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_component *component = - snd_soc_dapm_kcontrol_component(kcontrol); + struct snd_soc_component *component = snd_soc_dapm_kcontrol_to_component(kcontrol); struct rt700_priv *rt700 = snd_soc_component_get_drvdata(component); unsigned int reg, val = 0, nid; int ret; @@ -553,10 +550,8 @@ static int rt700_mux_get(struct snd_kcontrol *kcontrol, static int rt700_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_component *component = - snd_soc_dapm_kcontrol_component(kcontrol); - struct snd_soc_dapm_context *dapm = - snd_soc_dapm_kcontrol_dapm(kcontrol); + struct snd_soc_component *component = snd_soc_dapm_kcontrol_to_component(kcontrol); + struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kcontrol); struct rt700_priv *rt700 = snd_soc_component_get_drvdata(component); struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; unsigned int *item = ucontrol->value.enumerated.item; @@ -839,13 +834,12 @@ static int rt700_probe(struct snd_soc_component *component) static int rt700_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { - struct snd_soc_dapm_context *dapm = - snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct rt700_priv *rt700 = snd_soc_component_get_drvdata(component); switch (level) { case SND_SOC_BIAS_PREPARE: - if (dapm->bias_level == SND_SOC_BIAS_STANDBY) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_STANDBY) { regmap_write(rt700->regmap, RT700_SET_AUDIO_POWER_STATE, AC_PWRST_D0); diff --git a/sound/soc/codecs/rt711-sdca.c b/sound/soc/codecs/rt711-sdca.c index 8212887a558ff0..3a26c782d800a2 100644 --- a/sound/soc/codecs/rt711-sdca.c +++ b/sound/soc/codecs/rt711-sdca.c @@ -900,8 +900,7 @@ static const struct snd_kcontrol_new rt711_sdca_snd_controls[] = { static int rt711_sdca_mux_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_component *component = - snd_soc_dapm_kcontrol_component(kcontrol); + struct snd_soc_component *component = snd_soc_dapm_kcontrol_to_component(kcontrol); struct rt711_sdca_priv *rt711 = snd_soc_component_get_drvdata(component); unsigned int val = 0, mask_sft; @@ -923,10 +922,8 @@ static int rt711_sdca_mux_get(struct snd_kcontrol *kcontrol, static int rt711_sdca_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_component *component = - snd_soc_dapm_kcontrol_component(kcontrol); - struct snd_soc_dapm_context *dapm = - snd_soc_dapm_kcontrol_dapm(kcontrol); + struct snd_soc_component *component = snd_soc_dapm_kcontrol_to_component(kcontrol); + struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kcontrol); struct rt711_sdca_priv *rt711 = snd_soc_component_get_drvdata(component); struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; unsigned int *item = ucontrol->value.enumerated.item; diff --git a/sound/soc/codecs/rt711.c b/sound/soc/codecs/rt711.c index af3a49aee618a9..5dbe9b67703e2f 100644 --- a/sound/soc/codecs/rt711.c +++ b/sound/soc/codecs/rt711.c @@ -360,12 +360,11 @@ static void rt711_btn_check_handler(struct work_struct *work) static void rt711_jack_init(struct rt711_priv *rt711) { - struct snd_soc_dapm_context *dapm = - snd_soc_component_get_dapm(rt711->component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(rt711->component); mutex_lock(&rt711->calibrate_mutex); /* power on */ - if (dapm->bias_level <= SND_SOC_BIAS_STANDBY) + if (snd_soc_dapm_get_bias_level(dapm) <= SND_SOC_BIAS_STANDBY) regmap_write(rt711->regmap, RT711_SET_AUDIO_POWER_STATE, AC_PWRST_D0); @@ -448,7 +447,7 @@ static void rt711_jack_init(struct rt711_priv *rt711) } /* power off */ - if (dapm->bias_level <= SND_SOC_BIAS_STANDBY) + if (snd_soc_dapm_get_bias_level(dapm) <= SND_SOC_BIAS_STANDBY) regmap_write(rt711->regmap, RT711_SET_AUDIO_POWER_STATE, AC_PWRST_D3); mutex_unlock(&rt711->calibrate_mutex); @@ -504,8 +503,7 @@ static int rt711_set_amp_gain_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); - struct snd_soc_dapm_context *dapm = - snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; struct rt711_priv *rt711 = snd_soc_component_get_drvdata(component); @@ -543,7 +541,7 @@ static int rt711_set_amp_gain_put(struct snd_kcontrol *kcontrol, val_ll |= read_ll; } - if (dapm->bias_level <= SND_SOC_BIAS_STANDBY) + if (snd_soc_dapm_get_bias_level(dapm) <= SND_SOC_BIAS_STANDBY) regmap_write(rt711->regmap, RT711_SET_AUDIO_POWER_STATE, AC_PWRST_D0); @@ -597,7 +595,7 @@ static int rt711_set_amp_gain_put(struct snd_kcontrol *kcontrol, break; } - if (dapm->bias_level <= SND_SOC_BIAS_STANDBY) + if (snd_soc_dapm_get_bias_level(dapm) <= SND_SOC_BIAS_STANDBY) regmap_write(rt711->regmap, RT711_SET_AUDIO_POWER_STATE, AC_PWRST_D3); @@ -682,8 +680,7 @@ static const struct snd_kcontrol_new rt711_snd_controls[] = { static int rt711_mux_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_component *component = - snd_soc_dapm_kcontrol_component(kcontrol); + struct snd_soc_component *component = snd_soc_dapm_kcontrol_to_component(kcontrol); struct rt711_priv *rt711 = snd_soc_component_get_drvdata(component); unsigned int reg, val = 0, nid; int ret; @@ -712,10 +709,8 @@ static int rt711_mux_get(struct snd_kcontrol *kcontrol, static int rt711_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_component *component = - snd_soc_dapm_kcontrol_component(kcontrol); - struct snd_soc_dapm_context *dapm = - snd_soc_dapm_kcontrol_dapm(kcontrol); + struct snd_soc_component *component = snd_soc_dapm_kcontrol_to_component(kcontrol); + struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kcontrol); struct rt711_priv *rt711 = snd_soc_component_get_drvdata(component); struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; unsigned int *item = ucontrol->value.enumerated.item; @@ -900,13 +895,12 @@ static const struct snd_soc_dapm_route rt711_audio_map[] = { static int rt711_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { - struct snd_soc_dapm_context *dapm = - snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct rt711_priv *rt711 = snd_soc_component_get_drvdata(component); switch (level) { case SND_SOC_BIAS_PREPARE: - if (dapm->bias_level == SND_SOC_BIAS_STANDBY) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_STANDBY) { regmap_write(rt711->regmap, RT711_SET_AUDIO_POWER_STATE, AC_PWRST_D0); diff --git a/sound/soc/codecs/rt712-sdca-dmic.c b/sound/soc/codecs/rt712-sdca-dmic.c index 42f8f7b8bed087..2928649e80e4ed 100644 --- a/sound/soc/codecs/rt712-sdca-dmic.c +++ b/sound/soc/codecs/rt712-sdca-dmic.c @@ -429,8 +429,7 @@ static const struct snd_kcontrol_new rt712_sdca_dmic_snd_controls[] = { static int rt712_sdca_dmic_mux_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_component *component = - snd_soc_dapm_kcontrol_component(kcontrol); + struct snd_soc_component *component = snd_soc_dapm_kcontrol_to_component(kcontrol); struct rt712_sdca_dmic_priv *rt712 = snd_soc_component_get_drvdata(component); unsigned int val = 0, mask_sft; @@ -452,10 +451,8 @@ static int rt712_sdca_dmic_mux_get(struct snd_kcontrol *kcontrol, static int rt712_sdca_dmic_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_component *component = - snd_soc_dapm_kcontrol_component(kcontrol); - struct snd_soc_dapm_context *dapm = - snd_soc_dapm_kcontrol_dapm(kcontrol); + struct snd_soc_component *component = snd_soc_dapm_kcontrol_to_component(kcontrol); + struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kcontrol); struct rt712_sdca_dmic_priv *rt712 = snd_soc_component_get_drvdata(component); struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; unsigned int *item = ucontrol->value.enumerated.item; diff --git a/sound/soc/codecs/rt712-sdca.c b/sound/soc/codecs/rt712-sdca.c index 0ebaae426e73b5..4796fce084ff46 100644 --- a/sound/soc/codecs/rt712-sdca.c +++ b/sound/soc/codecs/rt712-sdca.c @@ -743,8 +743,7 @@ static const struct snd_kcontrol_new rt712_sdca_spk_controls[] = { static int rt712_sdca_mux_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_component *component = - snd_soc_dapm_kcontrol_component(kcontrol); + struct snd_soc_component *component = snd_soc_dapm_kcontrol_to_component(kcontrol); struct rt712_sdca_priv *rt712 = snd_soc_component_get_drvdata(component); unsigned int val = 0, mask = 0x3300; @@ -768,10 +767,8 @@ static int rt712_sdca_mux_get(struct snd_kcontrol *kcontrol, static int rt712_sdca_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_component *component = - snd_soc_dapm_kcontrol_component(kcontrol); - struct snd_soc_dapm_context *dapm = - snd_soc_dapm_kcontrol_dapm(kcontrol); + struct snd_soc_component *component = snd_soc_dapm_kcontrol_to_component(kcontrol); + struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kcontrol); struct rt712_sdca_priv *rt712 = snd_soc_component_get_drvdata(component); struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; unsigned int *item = ucontrol->value.enumerated.item; @@ -1017,7 +1014,7 @@ static int rt712_sdca_parse_dt(struct rt712_sdca_priv *rt712, struct device *dev static int rt712_sdca_probe(struct snd_soc_component *component) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct rt712_sdca_priv *rt712 = snd_soc_component_get_drvdata(component); int ret; @@ -1230,8 +1227,7 @@ static const struct snd_kcontrol_new rt712_sdca_dmic_snd_controls[] = { static int rt712_sdca_dmic_mux_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_component *component = - snd_soc_dapm_kcontrol_component(kcontrol); + struct snd_soc_component *component = snd_soc_dapm_kcontrol_to_component(kcontrol); struct rt712_sdca_priv *rt712 = snd_soc_component_get_drvdata(component); unsigned int val = 0, mask_sft; @@ -1253,10 +1249,8 @@ static int rt712_sdca_dmic_mux_get(struct snd_kcontrol *kcontrol, static int rt712_sdca_dmic_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_component *component = - snd_soc_dapm_kcontrol_component(kcontrol); - struct snd_soc_dapm_context *dapm = - snd_soc_dapm_kcontrol_dapm(kcontrol); + struct snd_soc_component *component = snd_soc_dapm_kcontrol_to_component(kcontrol); + struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kcontrol); struct rt712_sdca_priv *rt712 = snd_soc_component_get_drvdata(component); struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; unsigned int *item = ucontrol->value.enumerated.item; diff --git a/sound/soc/codecs/rt715-sdca.c b/sound/soc/codecs/rt715-sdca.c index db7d43349d7da3..b6a7a807a42866 100644 --- a/sound/soc/codecs/rt715-sdca.c +++ b/sound/soc/codecs/rt715-sdca.c @@ -502,8 +502,7 @@ static const struct snd_kcontrol_new rt715_sdca_snd_controls[] = { static int rt715_sdca_mux_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_component *component = - snd_soc_dapm_kcontrol_component(kcontrol); + struct snd_soc_component *component = snd_soc_dapm_kcontrol_to_component(kcontrol); struct rt715_sdca_priv *rt715 = snd_soc_component_get_drvdata(component); unsigned int val, mask_sft; @@ -538,10 +537,8 @@ static int rt715_sdca_mux_get(struct snd_kcontrol *kcontrol, static int rt715_sdca_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_component *component = - snd_soc_dapm_kcontrol_component(kcontrol); - struct snd_soc_dapm_context *dapm = - snd_soc_dapm_kcontrol_dapm(kcontrol); + struct snd_soc_component *component = snd_soc_dapm_kcontrol_to_component(kcontrol); + struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kcontrol); struct rt715_sdca_priv *rt715 = snd_soc_component_get_drvdata(component); struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; unsigned int *item = ucontrol->value.enumerated.item; diff --git a/sound/soc/codecs/rt715.c b/sound/soc/codecs/rt715.c index 7e1628a5c9d1b9..0881826de2f16b 100644 --- a/sound/soc/codecs/rt715.c +++ b/sound/soc/codecs/rt715.c @@ -125,8 +125,7 @@ static int rt715_set_amp_gain_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); - struct snd_soc_dapm_context *dapm = - snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; struct rt715_priv *rt715 = snd_soc_component_get_drvdata(component); @@ -152,7 +151,7 @@ static int rt715_set_amp_gain_put(struct snd_kcontrol *kcontrol, rt715_get_gain(rt715, addr_h, addr_l, val_h, &read_rl, &read_ll); - if (dapm->bias_level <= SND_SOC_BIAS_STANDBY) + if (snd_soc_dapm_get_bias_level(dapm) <= SND_SOC_BIAS_STANDBY) regmap_write(rt715->regmap, RT715_SET_AUDIO_POWER_STATE, AC_PWRST_D0); @@ -206,7 +205,7 @@ static int rt715_set_amp_gain_put(struct snd_kcontrol *kcontrol, } /* D0:power on state, D3: power saving mode */ - if (dapm->bias_level <= SND_SOC_BIAS_STANDBY) + if (snd_soc_dapm_get_bias_level(dapm) <= SND_SOC_BIAS_STANDBY) regmap_write(rt715->regmap, RT715_SET_AUDIO_POWER_STATE, AC_PWRST_D3); return k_vol_changed; @@ -250,8 +249,7 @@ static int rt715_set_main_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); - struct snd_soc_dapm_context *dapm = - snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct rt715_priv *rt715 = snd_soc_component_get_drvdata(component); static const unsigned int capture_reg_H[] = { RT715_SET_GAIN_MIC_ADC_H, RT715_SET_GAIN_LINE_ADC_H, @@ -274,7 +272,7 @@ static int rt715_set_main_switch_put(struct snd_kcontrol *kcontrol, addr_l = capture_reg_L[j]; rt715_get_gain(rt715, addr_h, addr_l, val_h, &read_rl, &read_ll); - if (dapm->bias_level <= SND_SOC_BIAS_STANDBY) + if (snd_soc_dapm_get_bias_level(dapm) <= SND_SOC_BIAS_STANDBY) regmap_write(rt715->regmap, RT715_SET_AUDIO_POWER_STATE, AC_PWRST_D0); @@ -322,7 +320,7 @@ static int rt715_set_main_switch_put(struct snd_kcontrol *kcontrol, } /* D0:power on state, D3: power saving mode */ - if (dapm->bias_level <= SND_SOC_BIAS_STANDBY) + if (snd_soc_dapm_get_bias_level(dapm) <= SND_SOC_BIAS_STANDBY) regmap_write(rt715->regmap, RT715_SET_AUDIO_POWER_STATE, AC_PWRST_D3); return k_changed; @@ -358,8 +356,7 @@ static int rt715_set_main_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); - struct snd_soc_dapm_context *dapm = - snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct rt715_priv *rt715 = snd_soc_component_get_drvdata(component); static const unsigned int capture_reg_H[] = { RT715_SET_GAIN_MIC_ADC_H, RT715_SET_GAIN_LINE_ADC_H, @@ -381,7 +378,7 @@ static int rt715_set_main_vol_put(struct snd_kcontrol *kcontrol, addr_l = capture_reg_L[j]; rt715_get_gain(rt715, addr_h, addr_l, val_h, &read_rl, &read_ll); - if (dapm->bias_level <= SND_SOC_BIAS_STANDBY) + if (snd_soc_dapm_get_bias_level(dapm) <= SND_SOC_BIAS_STANDBY) regmap_write(rt715->regmap, RT715_SET_AUDIO_POWER_STATE, AC_PWRST_D0); @@ -431,7 +428,7 @@ static int rt715_set_main_vol_put(struct snd_kcontrol *kcontrol, } /* D0:power on state, D3: power saving mode */ - if (dapm->bias_level <= SND_SOC_BIAS_STANDBY) + if (snd_soc_dapm_get_bias_level(dapm) <= SND_SOC_BIAS_STANDBY) regmap_write(rt715->regmap, RT715_SET_AUDIO_POWER_STATE, AC_PWRST_D3); return k_changed; @@ -546,8 +543,7 @@ static const struct snd_kcontrol_new rt715_snd_controls[] = { static int rt715_mux_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_component *component = - snd_soc_dapm_kcontrol_component(kcontrol); + struct snd_soc_component *component = snd_soc_dapm_kcontrol_to_component(kcontrol); struct rt715_priv *rt715 = snd_soc_component_get_drvdata(component); struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; unsigned int reg, val; @@ -577,10 +573,8 @@ static int rt715_mux_get(struct snd_kcontrol *kcontrol, static int rt715_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_component *component = - snd_soc_dapm_kcontrol_component(kcontrol); - struct snd_soc_dapm_context *dapm = - snd_soc_dapm_kcontrol_dapm(kcontrol); + struct snd_soc_component *component = snd_soc_dapm_kcontrol_to_component(kcontrol); + struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kcontrol); struct rt715_priv *rt715 = snd_soc_component_get_drvdata(component); struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; unsigned int *item = ucontrol->value.enumerated.item; @@ -752,13 +746,12 @@ static const struct snd_soc_dapm_route rt715_audio_map[] = { static int rt715_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { - struct snd_soc_dapm_context *dapm = - snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct rt715_priv *rt715 = snd_soc_component_get_drvdata(component); switch (level) { case SND_SOC_BIAS_PREPARE: - if (dapm->bias_level == SND_SOC_BIAS_STANDBY) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_STANDBY) { regmap_write(rt715->regmap, RT715_SET_AUDIO_POWER_STATE, AC_PWRST_D0); diff --git a/sound/soc/codecs/rt721-sdca.c b/sound/soc/codecs/rt721-sdca.c index 5f7b505d541479..8233532a1752a3 100644 --- a/sound/soc/codecs/rt721-sdca.c +++ b/sound/soc/codecs/rt721-sdca.c @@ -746,8 +746,7 @@ static const struct snd_kcontrol_new rt721_sdca_controls[] = { static int rt721_sdca_adc_mux_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_component *component = - snd_soc_dapm_kcontrol_component(kcontrol); + struct snd_soc_component *component = snd_soc_dapm_kcontrol_to_component(kcontrol); struct rt721_sdca_priv *rt721 = snd_soc_component_get_drvdata(component); unsigned int val = 0, mask_sft, mask; @@ -786,10 +785,8 @@ static int rt721_sdca_adc_mux_get(struct snd_kcontrol *kcontrol, static int rt721_sdca_adc_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_component *component = - snd_soc_dapm_kcontrol_component(kcontrol); - struct snd_soc_dapm_context *dapm = - snd_soc_dapm_kcontrol_dapm(kcontrol); + struct snd_soc_component *component = snd_soc_dapm_kcontrol_to_component(kcontrol); + struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kcontrol); struct rt721_sdca_priv *rt721 = snd_soc_component_get_drvdata(component); struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; unsigned int *item = ucontrol->value.enumerated.item; diff --git a/sound/soc/codecs/simple-mux.c b/sound/soc/codecs/simple-mux.c index 3906964401557d..069555f35f7359 100644 --- a/sound/soc/codecs/simple-mux.c +++ b/sound/soc/codecs/simple-mux.c @@ -34,7 +34,7 @@ static SOC_ENUM_SINGLE_EXT_DECL(simple_mux_enum, simple_mux_texts); static int simple_mux_control_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol); + struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kcontrol); struct snd_soc_component *c = snd_soc_dapm_to_component(dapm); struct simple_mux *priv = snd_soc_component_get_drvdata(c); @@ -46,7 +46,7 @@ static int simple_mux_control_get(struct snd_kcontrol *kcontrol, static int simple_mux_control_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol); + struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kcontrol); struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; struct snd_soc_component *c = snd_soc_dapm_to_component(dapm); struct simple_mux *priv = snd_soc_component_get_drvdata(c); @@ -59,7 +59,8 @@ static int simple_mux_control_put(struct snd_kcontrol *kcontrol, priv->mux = ucontrol->value.enumerated.item[0]; - if (priv->idle_state != MUX_IDLE_AS_IS && dapm->bias_level < SND_SOC_BIAS_PREPARE) + if (priv->idle_state != MUX_IDLE_AS_IS && + snd_soc_dapm_get_bias_level(dapm) < SND_SOC_BIAS_PREPARE) return 0; gpiod_set_value_cansleep(priv->gpiod_mux, priv->mux); diff --git a/sound/soc/codecs/sma1303.c b/sound/soc/codecs/sma1303.c index ebe22325fc57a2..06de2b4fce5e2b 100644 --- a/sound/soc/codecs/sma1303.c +++ b/sound/soc/codecs/sma1303.c @@ -518,7 +518,7 @@ static int sma1303_aif_in_event(struct snd_soc_dapm_widget *w, struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); struct sma1303_priv *sma1303 = snd_soc_component_get_drvdata(component); - unsigned int mux = dapm_kcontrol_get_value(w->kcontrols[0]); + unsigned int mux = snd_soc_dapm_kcontrol_get_value(w->kcontrols[0]); int ret = 0; bool change = false, temp = false; @@ -588,7 +588,7 @@ static int sma1303_aif_out_event(struct snd_soc_dapm_widget *w, struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); struct sma1303_priv *sma1303 = snd_soc_component_get_drvdata(component); - unsigned int mux = dapm_kcontrol_get_value(w->kcontrols[0]); + unsigned int mux = snd_soc_dapm_kcontrol_get_value(w->kcontrols[0]); int ret = 0; bool change = false, temp = false; @@ -1557,8 +1557,7 @@ static void sma1303_check_fault_worker(struct work_struct *work) static int sma1303_probe(struct snd_soc_component *component) { - struct snd_soc_dapm_context *dapm = - snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); snd_soc_dapm_sync(dapm); diff --git a/sound/soc/codecs/sma1307.c b/sound/soc/codecs/sma1307.c index 5ac033e0ba808a..4bb59e5c089153 100644 --- a/sound/soc/codecs/sma1307.c +++ b/sound/soc/codecs/sma1307.c @@ -790,10 +790,9 @@ static int sma1307_power_event(struct snd_soc_dapm_widget *w, static int sma1307_dapm_aif_in_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_context *dapm = - snd_soc_dapm_kcontrol_dapm(kcontrol); - struct sma1307_priv *sma1307 = - snd_soc_component_get_drvdata(dapm->component); + struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kcontrol); + struct snd_soc_component *component = snd_soc_dapm_to_component(dapm); + struct sma1307_priv *sma1307 = snd_soc_component_get_drvdata(component); ucontrol->value.enumerated.item[0] = (unsigned int)sma1307->dapm_aif_in; snd_soc_dapm_put_enum_double(kcontrol, ucontrol); @@ -804,10 +803,9 @@ static int sma1307_dapm_aif_in_get(struct snd_kcontrol *kcontrol, static int sma1307_dapm_aif_in_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_context *dapm = - snd_soc_dapm_kcontrol_dapm(kcontrol); - struct sma1307_priv *sma1307 = - snd_soc_component_get_drvdata(dapm->component); + struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kcontrol); + struct snd_soc_component *component = snd_soc_dapm_to_component(dapm); + struct sma1307_priv *sma1307 = snd_soc_component_get_drvdata(component); int val = (int)ucontrol->value.enumerated.item[0]; bool change; @@ -830,10 +828,9 @@ static int sma1307_dapm_aif_in_put(struct snd_kcontrol *kcontrol, static int sma1307_dapm_sdo_setting_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_context *dapm = - snd_soc_dapm_kcontrol_dapm(kcontrol); - struct sma1307_priv *sma1307 = - snd_soc_component_get_drvdata(dapm->component); + struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kcontrol); + struct snd_soc_component *component = snd_soc_dapm_to_component(dapm); + struct sma1307_priv *sma1307 = snd_soc_component_get_drvdata(component); ucontrol->value.enumerated.item[0] = (unsigned int)sma1307->dapm_sdo_setting; @@ -845,10 +842,9 @@ static int sma1307_dapm_sdo_setting_get(struct snd_kcontrol *kcontrol, static int sma1307_dapm_sdo_setting_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_context *dapm = - snd_soc_dapm_kcontrol_dapm(kcontrol); - struct sma1307_priv *sma1307 = - snd_soc_component_get_drvdata(dapm->component); + struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kcontrol); + struct snd_soc_component *component = snd_soc_dapm_to_component(dapm); + struct sma1307_priv *sma1307 = snd_soc_component_get_drvdata(component); int val = (int)ucontrol->value.enumerated.item[0]; bool change; @@ -871,10 +867,9 @@ static int sma1307_dapm_sdo_setting_put(struct snd_kcontrol *kcontrol, static int sma1307_dapm_aif_out_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_context *dapm = - snd_soc_dapm_kcontrol_dapm(kcontrol); - struct sma1307_priv *sma1307 = - snd_soc_component_get_drvdata(dapm->component); + struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kcontrol); + struct snd_soc_component *component = snd_soc_dapm_to_component(dapm); + struct sma1307_priv *sma1307 = snd_soc_component_get_drvdata(component); unsigned int val = 0; if (!strcmp(kcontrol->id.name, SMA1307_AIF_OUT0_NAME)) { @@ -895,10 +890,9 @@ static int sma1307_dapm_aif_out_get(struct snd_kcontrol *kcontrol, static int sma1307_dapm_aif_out_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_context *dapm = - snd_soc_dapm_kcontrol_dapm(kcontrol); - struct sma1307_priv *sma1307 = - snd_soc_component_get_drvdata(dapm->component); + struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kcontrol); + struct snd_soc_component *component = snd_soc_dapm_to_component(dapm); + struct sma1307_priv *sma1307 = snd_soc_component_get_drvdata(component); int val = (int)ucontrol->value.enumerated.item[0]; bool change; @@ -933,10 +927,9 @@ static int sma1307_dapm_aif_out_put(struct snd_kcontrol *kcontrol, static int sma1307_dapm_sdo_enable_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_context *dapm = - snd_soc_dapm_kcontrol_dapm(kcontrol); - struct sma1307_priv *sma1307 = - snd_soc_component_get_drvdata(dapm->component); + struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kcontrol); + struct snd_soc_component *component = snd_soc_dapm_to_component(dapm); + struct sma1307_priv *sma1307 = snd_soc_component_get_drvdata(component); ucontrol->value.integer.value[0] = (long)sma1307->dapm_sdo_en; snd_soc_dapm_put_volsw(kcontrol, ucontrol); @@ -947,10 +940,9 @@ static int sma1307_dapm_sdo_enable_get(struct snd_kcontrol *kcontrol, static int sma1307_dapm_sdo_enable_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_context *dapm = - snd_soc_dapm_kcontrol_dapm(kcontrol); - struct sma1307_priv *sma1307 = - snd_soc_component_get_drvdata(dapm->component); + struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kcontrol); + struct snd_soc_component *component = snd_soc_dapm_to_component(dapm); + struct sma1307_priv *sma1307 = snd_soc_component_get_drvdata(component); int val = (int)ucontrol->value.integer.value[0]; bool change; @@ -1857,8 +1849,7 @@ static void sma1307_set_default(struct snd_soc_component *component) static int sma1307_probe(struct snd_soc_component *component) { - struct snd_soc_dapm_context *dapm = - snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); snd_soc_dapm_sync(dapm); diff --git a/sound/soc/codecs/ssm2518.c b/sound/soc/codecs/ssm2518.c index 06016e88dd2705..9008e5416004fc 100644 --- a/sound/soc/codecs/ssm2518.c +++ b/sound/soc/codecs/ssm2518.c @@ -500,6 +500,7 @@ static int ssm2518_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { struct ssm2518 *ssm2518 = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); int ret = 0; switch (level) { @@ -508,7 +509,7 @@ static int ssm2518_set_bias_level(struct snd_soc_component *component, case SND_SOC_BIAS_PREPARE: break; case SND_SOC_BIAS_STANDBY: - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) ret = ssm2518_set_power(ssm2518, true); break; case SND_SOC_BIAS_OFF: diff --git a/sound/soc/codecs/ssm2602.c b/sound/soc/codecs/ssm2602.c index c29324403e9d5f..fccd2eacd7a6ac 100644 --- a/sound/soc/codecs/ssm2602.c +++ b/sound/soc/codecs/ssm2602.c @@ -562,7 +562,7 @@ static int ssm2602_resume(struct snd_soc_component *component) static int ssm2602_component_probe(struct snd_soc_component *component) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct ssm2602_priv *ssm2602 = snd_soc_component_get_drvdata(component); int ret; @@ -587,7 +587,7 @@ static int ssm2602_component_probe(struct snd_soc_component *component) static int ssm2604_component_probe(struct snd_soc_component *component) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); int ret; ret = snd_soc_dapm_new_controls(dapm, ssm2604_dapm_widgets, diff --git a/sound/soc/codecs/ssm4567.c b/sound/soc/codecs/ssm4567.c index 3e09c85abedbd1..15f88624faebb4 100644 --- a/sound/soc/codecs/ssm4567.c +++ b/sound/soc/codecs/ssm4567.c @@ -369,6 +369,7 @@ static int ssm4567_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { struct ssm4567 *ssm4567 = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); int ret = 0; switch (level) { @@ -377,7 +378,7 @@ static int ssm4567_set_bias_level(struct snd_soc_component *component, case SND_SOC_BIAS_PREPARE: break; case SND_SOC_BIAS_STANDBY: - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) ret = ssm4567_set_power(ssm4567, true); break; case SND_SOC_BIAS_OFF: diff --git a/sound/soc/codecs/sta32x.c b/sound/soc/codecs/sta32x.c index 97f55e556fa39a..b9f9784f51643a 100644 --- a/sound/soc/codecs/sta32x.c +++ b/sound/soc/codecs/sta32x.c @@ -799,6 +799,7 @@ static int sta32x_set_bias_level(struct snd_soc_component *component, { int ret; struct sta32x_priv *sta32x = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); dev_dbg(component->dev, "level = %d\n", level); switch (level) { @@ -813,7 +814,7 @@ static int sta32x_set_bias_level(struct snd_soc_component *component, break; case SND_SOC_BIAS_STANDBY: - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) { ret = regulator_bulk_enable(ARRAY_SIZE(sta32x->supplies), sta32x->supplies); if (ret != 0) { @@ -870,6 +871,7 @@ static struct snd_soc_dai_driver sta32x_dai = { static int sta32x_probe(struct snd_soc_component *component) { + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct sta32x_priv *sta32x = snd_soc_component_get_drvdata(component); struct sta32x_platform_data *pdata = sta32x->pdata; int i, ret = 0, thermal = 0; @@ -974,7 +976,7 @@ static int sta32x_probe(struct snd_soc_component *component) if (sta32x->pdata->needs_esd_watchdog) INIT_DELAYED_WORK(&sta32x->watchdog_work, sta32x_watchdog); - snd_soc_component_force_bias_level(component, SND_SOC_BIAS_STANDBY); + snd_soc_dapm_force_bias_level(dapm, SND_SOC_BIAS_STANDBY); /* Bias level configuration will have done an extra enable */ regulator_bulk_disable(ARRAY_SIZE(sta32x->supplies), sta32x->supplies); diff --git a/sound/soc/codecs/sta350.c b/sound/soc/codecs/sta350.c index 29bdfa662ebd8f..71af82b099c016 100644 --- a/sound/soc/codecs/sta350.c +++ b/sound/soc/codecs/sta350.c @@ -830,6 +830,7 @@ static int sta350_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { struct sta350_priv *sta350 = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); int ret; dev_dbg(component->dev, "level = %d\n", level); @@ -845,7 +846,7 @@ static int sta350_set_bias_level(struct snd_soc_component *component, break; case SND_SOC_BIAS_STANDBY: - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) { ret = regulator_bulk_enable( ARRAY_SIZE(sta350->supplies), sta350->supplies); @@ -905,6 +906,7 @@ static struct snd_soc_dai_driver sta350_dai = { static int sta350_probe(struct snd_soc_component *component) { + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct sta350_priv *sta350 = snd_soc_component_get_drvdata(component); struct sta350_platform_data *pdata = sta350->pdata; int i, ret = 0, thermal = 0; @@ -1028,7 +1030,7 @@ static int sta350_probe(struct snd_soc_component *component) sta350->coef_shadow[60] = 0x400000; sta350->coef_shadow[61] = 0x400000; - snd_soc_component_force_bias_level(component, SND_SOC_BIAS_STANDBY); + snd_soc_dapm_force_bias_level(dapm, SND_SOC_BIAS_STANDBY); /* Bias level configuration will have done an extra enable */ regulator_bulk_disable(ARRAY_SIZE(sta350->supplies), sta350->supplies); diff --git a/sound/soc/codecs/sta529.c b/sound/soc/codecs/sta529.c index f7718491c89961..8c3b2652b02e29 100644 --- a/sound/soc/codecs/sta529.c +++ b/sound/soc/codecs/sta529.c @@ -155,6 +155,7 @@ static int sta529_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { struct sta529 *sta529 = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); switch (level) { case SND_SOC_BIAS_ON: @@ -165,7 +166,7 @@ static int sta529_set_bias_level(struct snd_soc_component *component, enum FFX_CLK_ENB); break; case SND_SOC_BIAS_STANDBY: - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) regcache_sync(sta529->regmap); snd_soc_component_update_bits(component, STA529_FFXCFG0, POWER_CNTLMSAK, POWER_STDBY); diff --git a/sound/soc/codecs/tas2781-comlib-i2c.c b/sound/soc/codecs/tas2781-comlib-i2c.c index b3fd7350143bdb..e24d56a14cfda1 100644 --- a/sound/soc/codecs/tas2781-comlib-i2c.c +++ b/sound/soc/codecs/tas2781-comlib-i2c.c @@ -320,7 +320,7 @@ void tasdevice_reset(struct tasdevice_priv *tas_dev) for (i = 0; i < tas_dev->ndev; i++) { ret = tasdevice_dev_write(tas_dev, i, TASDEVICE_REG_SWRESET, - tas_dev->chip_id >= TAS5825 ? + tas_dev->chip_id >= TAS5802 ? TAS5825_REG_SWRESET_RESET : TASDEVICE_REG_SWRESET_RESET); if (ret < 0) diff --git a/sound/soc/codecs/tas2781-i2c.c b/sound/soc/codecs/tas2781-i2c.c index 7bd98ff5a25034..d1c76ab0144d19 100644 --- a/sound/soc/codecs/tas2781-i2c.c +++ b/sound/soc/codecs/tas2781-i2c.c @@ -105,15 +105,20 @@ static const struct i2c_device_id tasdevice_id[] = { { "tas2120", TAS2120 }, { "tas2320", TAS2320 }, { "tas2563", TAS2563 }, + { "tas2568", TAS2568 }, { "tas2570", TAS2570 }, { "tas2572", TAS2572 }, + { "tas2574", TAS2574 }, { "tas2781", TAS2781 }, { "tas5802", TAS5802 }, + { "tas5806m", TAS5806M }, + { "tas5806md", TAS5806MD }, { "tas5815", TAS5815 }, { "tas5822", TAS5822 }, { "tas5825", TAS5825 }, { "tas5827", TAS5827 }, { "tas5828", TAS5828 }, + { "tas5830", TAS5830 }, {} }; MODULE_DEVICE_TABLE(i2c, tasdevice_id); @@ -125,15 +130,20 @@ static const struct of_device_id tasdevice_of_match[] = { { .compatible = "ti,tas2120" }, { .compatible = "ti,tas2320" }, { .compatible = "ti,tas2563" }, + { .compatible = "ti,tas2568" }, { .compatible = "ti,tas2570" }, { .compatible = "ti,tas2572" }, + { .compatible = "ti,tas2574" }, { .compatible = "ti,tas2781" }, { .compatible = "ti,tas5802" }, + { .compatible = "ti,tas5806m" }, + { .compatible = "ti,tas5806md" }, { .compatible = "ti,tas5815" }, { .compatible = "ti,tas5822" }, { .compatible = "ti,tas5825" }, { .compatible = "ti,tas5827" }, { .compatible = "ti,tas5828" }, + { .compatible = "ti,tas5830" }, {}, }; MODULE_DEVICE_TABLE(of, tasdevice_of_match); @@ -1390,7 +1400,7 @@ static int tasdevice_create_cali_ctrls(struct tasdevice_priv *priv) /* * Alloc kcontrol via devm_kzalloc(), which don't manually - * free the kcontrol。 + * free the kcontrol. */ cali_ctrls = devm_kcalloc(priv->dev, nctrls, sizeof(cali_ctrls[0]), GFP_KERNEL); @@ -1643,8 +1653,10 @@ static void tasdevice_fw_ready(const struct firmware *fmw, case TAS2118: case TAS2120: case TAS2320: + case TAS2568: case TAS2570: case TAS2572: + case TAS2574: goto out; } if (tas_priv->name_prefix) @@ -1670,9 +1682,7 @@ static void tasdevice_fw_ready(const struct firmware *fmw, } tas_priv->fw_state = TASDEVICE_DSP_FW_ALL_OK; - /* There is no calibration required for - * TAS5802/TAS5815/TAS5822/TAS5825/TAS5827/TAS5828. - */ + /* There is no calibration required for TAS58XX. */ if (tas_priv->chip_id < TAS5802) { ret = tasdevice_create_cali_ctrls(tas_priv); if (ret) { @@ -1728,11 +1738,14 @@ static void tasdevice_fw_ready(const struct firmware *fmw, case TAS2563: case TAS2781: case TAS5802: + case TAS5806M: + case TAS5806MD: case TAS5815: case TAS5822: case TAS5825: case TAS5827: case TAS5828: + case TAS5830: /* If DSP FW fail, DSP kcontrol won't be created. */ tasdevice_dsp_remove(tas_priv); } @@ -1883,8 +1896,10 @@ static int tasdevice_codec_probe(struct snd_soc_component *codec) case TAS2118: case TAS2120: case TAS2320: + case TAS2568: case TAS2570: case TAS2572: + case TAS2574: p = (struct snd_kcontrol_new *)tas2x20_snd_controls; size = ARRAY_SIZE(tas2x20_snd_controls); tas_priv->dvc_tlv_table = tas2x20_dvc_table; @@ -1894,11 +1909,14 @@ static int tasdevice_codec_probe(struct snd_soc_component *codec) size = ARRAY_SIZE(tas2781_snd_controls); break; case TAS5802: + case TAS5806M: + case TAS5806MD: case TAS5815: case TAS5822: case TAS5825: case TAS5827: case TAS5828: + case TAS5830: p = (struct snd_kcontrol_new *)tas5825_snd_controls; size = ARRAY_SIZE(tas5825_snd_controls); break; @@ -2072,15 +2090,20 @@ static const struct acpi_device_id tasdevice_acpi_match[] = { { "TXNW2120", TAS2120 }, { "TXNW2320", TAS2320 }, { "TXNW2563", TAS2563 }, + { "TXNW2568", TAS2568 }, { "TXNW2570", TAS2570 }, { "TXNW2572", TAS2572 }, + { "TXNW2574", TAS2574 }, { "TXNW2781", TAS2781 }, { "TXNW5802", TAS5802 }, + { "TXNW806M", TAS5806M }, + { "TXNW806D", TAS5806MD }, { "TXNW5815", TAS5815 }, { "TXNW5822", TAS5822 }, { "TXNW5825", TAS5825 }, { "TXNW5827", TAS5827 }, { "TXNW5828", TAS5828 }, + { "TXNW5830", TAS5830 }, {}, }; diff --git a/sound/soc/codecs/tas571x.c b/sound/soc/codecs/tas571x.c index ca68651e5f756a..19ccf8641e16ae 100644 --- a/sound/soc/codecs/tas571x.c +++ b/sound/soc/codecs/tas571x.c @@ -322,6 +322,7 @@ static int tas571x_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { struct tas571x_private *priv = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); int ret; switch (level) { @@ -330,7 +331,7 @@ static int tas571x_set_bias_level(struct snd_soc_component *component, case SND_SOC_BIAS_PREPARE: break; case SND_SOC_BIAS_STANDBY: - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) { if (!IS_ERR(priv->mclk)) { ret = clk_prepare_enable(priv->mclk); if (ret) { diff --git a/sound/soc/codecs/tas6424.c b/sound/soc/codecs/tas6424.c index 9be054837f68eb..85ecc246896fbb 100644 --- a/sound/soc/codecs/tas6424.c +++ b/sound/soc/codecs/tas6424.c @@ -346,6 +346,8 @@ static int tas6424_power_on(struct snd_soc_component *component) static int tas6424_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); + dev_dbg(component->dev, "%s() level=%d\n", __func__, level); switch (level) { @@ -353,7 +355,7 @@ static int tas6424_set_bias_level(struct snd_soc_component *component, case SND_SOC_BIAS_PREPARE: break; case SND_SOC_BIAS_STANDBY: - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) tas6424_power_on(component); break; case SND_SOC_BIAS_OFF: diff --git a/sound/soc/codecs/tlv320adc3xxx.c b/sound/soc/codecs/tlv320adc3xxx.c index 02ac0dbd9af6b6..270eee1ea5347f 100644 --- a/sound/soc/codecs/tlv320adc3xxx.c +++ b/sound/soc/codecs/tlv320adc3xxx.c @@ -1193,7 +1193,7 @@ static int adc3xxx_hw_params(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct snd_soc_component *component = dai->component; - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(dai->component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(dai->component); struct adc3xxx *adc3xxx = snd_soc_component_get_drvdata(component); int i, width = 16; u8 iface_len, bdiv; @@ -1299,7 +1299,7 @@ static int adc3xxx_set_dai_sysclk(struct snd_soc_dai *codec_dai, static int adc3xxx_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) { struct snd_soc_component *component = codec_dai->component; - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct adc3xxx *adc3xxx = snd_soc_component_get_drvdata(component); u8 clkdir = 0, format = 0; int master = 0; diff --git a/sound/soc/codecs/tlv320aic31xx.c b/sound/soc/codecs/tlv320aic31xx.c index 4b3f9128ec37e6..4362c2c06ce8d3 100644 --- a/sound/soc/codecs/tlv320aic31xx.c +++ b/sound/soc/codecs/tlv320aic31xx.c @@ -799,7 +799,7 @@ static int aic31xx_add_controls(struct snd_soc_component *component) static int aic31xx_add_widgets(struct snd_soc_component *component) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct aic31xx_priv *aic31xx = snd_soc_component_get_drvdata(component); int ret = 0; @@ -1030,7 +1030,7 @@ static int aic31xx_dac_mute(struct snd_soc_dai *codec_dai, int mute, static int aic31xx_clock_master_routes(struct snd_soc_component *component, unsigned int fmt) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct aic31xx_priv *aic31xx = snd_soc_component_get_drvdata(component); int ret; @@ -1316,18 +1316,20 @@ static void aic31xx_power_off(struct snd_soc_component *component) static int aic31xx_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); + dev_dbg(component->dev, "## %s: %d -> %d\n", __func__, - snd_soc_component_get_bias_level(component), level); + snd_soc_dapm_get_bias_level(dapm), level); switch (level) { case SND_SOC_BIAS_ON: break; case SND_SOC_BIAS_PREPARE: - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_STANDBY) + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_STANDBY) aic31xx_clk_on(component); break; case SND_SOC_BIAS_STANDBY: - switch (snd_soc_component_get_bias_level(component)) { + switch (snd_soc_dapm_get_bias_level(dapm)) { case SND_SOC_BIAS_OFF: aic31xx_power_on(component); break; @@ -1339,7 +1341,7 @@ static int aic31xx_set_bias_level(struct snd_soc_component *component, } break; case SND_SOC_BIAS_OFF: - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_STANDBY) + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_STANDBY) aic31xx_power_off(component); break; } diff --git a/sound/soc/codecs/tlv320aic32x4.c b/sound/soc/codecs/tlv320aic32x4.c index 715a07ab97b9f9..d8509455721511 100644 --- a/sound/soc/codecs/tlv320aic32x4.c +++ b/sound/soc/codecs/tlv320aic32x4.c @@ -883,6 +883,7 @@ static int aic32x4_mute(struct snd_soc_dai *dai, int mute, int direction) static int aic32x4_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); int ret; static struct clk_bulk_data clocks[] = { @@ -907,7 +908,7 @@ static int aic32x4_set_bias_level(struct snd_soc_component *component, break; case SND_SOC_BIAS_STANDBY: /* Initial cold start */ - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) break; clk_bulk_disable_unprepare(ARRAY_SIZE(clocks), clocks); diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index eea8ca285f8e0f..ce22298b43efc1 100644 --- a/sound/soc/codecs/tlv320aic3x.c +++ b/sound/soc/codecs/tlv320aic3x.c @@ -163,8 +163,8 @@ EXPORT_SYMBOL_GPL(aic3x_regmap); static int snd_soc_dapm_put_volsw_aic3x(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_component *component = snd_soc_dapm_kcontrol_component(kcontrol); - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_component *component = snd_soc_dapm_kcontrol_to_component(kcontrol); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; unsigned int reg = mc->reg; @@ -1009,7 +1009,7 @@ static const struct snd_soc_dapm_route intercon_3007[] = { static int aic3x_add_widgets(struct snd_soc_component *component) { struct aic3x_priv *aic3x = snd_soc_component_get_drvdata(component); - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); switch (aic3x->model) { case AIC3X_MODEL_3X: @@ -1449,13 +1449,14 @@ static int aic3x_set_power(struct snd_soc_component *component, int power) static int aic3x_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct aic3x_priv *aic3x = snd_soc_component_get_drvdata(component); switch (level) { case SND_SOC_BIAS_ON: break; case SND_SOC_BIAS_PREPARE: - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_STANDBY && + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_STANDBY && aic3x->master) { /* enable pll */ snd_soc_component_update_bits(component, AIC3X_PLL_PROGA_REG, @@ -1465,7 +1466,7 @@ static int aic3x_set_bias_level(struct snd_soc_component *component, case SND_SOC_BIAS_STANDBY: if (!aic3x->power) aic3x_set_power(component, 1); - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_PREPARE && + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_PREPARE && aic3x->master) { /* disable pll */ snd_soc_component_update_bits(component, AIC3X_PLL_PROGA_REG, diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c index 210c11ddd5a81b..605da1259fc600 100644 --- a/sound/soc/codecs/tlv320dac33.c +++ b/sound/soc/codecs/tlv320dac33.c @@ -623,6 +623,7 @@ static const struct snd_soc_dapm_route audio_map[] = { static int dac33_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); int ret; switch (level) { @@ -631,7 +632,7 @@ static int dac33_set_bias_level(struct snd_soc_component *component, case SND_SOC_BIAS_PREPARE: break; case SND_SOC_BIAS_STANDBY: - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) { /* Coming from OFF, switch on the component */ ret = dac33_hard_power(component, 1); if (ret != 0) @@ -642,7 +643,7 @@ static int dac33_set_bias_level(struct snd_soc_component *component, break; case SND_SOC_BIAS_OFF: /* Do not power off, when the component is already off */ - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) return 0; ret = dac33_hard_power(component, 0); if (ret != 0) diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c index afffb0af550859..9476cdfd4dde96 100644 --- a/sound/soc/codecs/twl4030.c +++ b/sound/soc/codecs/twl4030.c @@ -1570,13 +1570,15 @@ static const struct snd_soc_dapm_route intercon[] = { static int twl4030_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); + switch (level) { case SND_SOC_BIAS_ON: break; case SND_SOC_BIAS_PREPARE: break; case SND_SOC_BIAS_STANDBY: - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) twl4030_codec_enable(component, 1); break; case SND_SOC_BIAS_OFF: diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c index fe813e09607136..e10c51092a3587 100644 --- a/sound/soc/codecs/twl6040.c +++ b/sound/soc/codecs/twl6040.c @@ -323,7 +323,7 @@ static irqreturn_t twl6040_audio_handler(int irq, void *data) static int twl6040_soc_dapm_put_vibra_enum(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_component *component = snd_soc_dapm_kcontrol_component(kcontrol); + struct snd_soc_component *component = snd_soc_dapm_kcontrol_to_component(kcontrol); struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; unsigned int val; @@ -521,7 +521,7 @@ static int twl6040_pll_put_enum(struct snd_kcontrol *kcontrol, int twl6040_get_dl1_gain(struct snd_soc_component *component) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); if (snd_soc_dapm_get_pin_status(dapm, "EP")) return -1; /* -1dB */ @@ -1097,6 +1097,7 @@ static struct snd_soc_dai_driver twl6040_dai[] = { static int twl6040_probe(struct snd_soc_component *component) { struct twl6040_data *priv; + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct platform_device *pdev = to_platform_device(component->dev); int ret = 0; @@ -1125,7 +1126,7 @@ static int twl6040_probe(struct snd_soc_component *component) return ret; } - snd_soc_component_force_bias_level(component, SND_SOC_BIAS_STANDBY); + snd_soc_dapm_force_bias_level(dapm, SND_SOC_BIAS_STANDBY); twl6040_init_chip(component); return 0; diff --git a/sound/soc/codecs/uda1380.c b/sound/soc/codecs/uda1380.c index c179d865b93836..9e9c540a45ca97 100644 --- a/sound/soc/codecs/uda1380.c +++ b/sound/soc/codecs/uda1380.c @@ -588,6 +588,7 @@ static void uda1380_pcm_shutdown(struct snd_pcm_substream *substream, static int uda1380_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); int pm = uda1380_read_reg_cache(component, UDA1380_PM); int reg; struct uda1380_platform_data *pdata = component->dev->platform_data; @@ -599,7 +600,7 @@ static int uda1380_set_bias_level(struct snd_soc_component *component, uda1380_write(component, UDA1380_PM, R02_PON_BIAS | pm); break; case SND_SOC_BIAS_STANDBY: - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) { if (gpio_is_valid(pdata->gpio_power)) { gpio_set_value(pdata->gpio_power, 1); mdelay(1); diff --git a/sound/soc/codecs/wcd9335.c b/sound/soc/codecs/wcd9335.c index 5485c558b879d0..640e43ee197519 100644 --- a/sound/soc/codecs/wcd9335.c +++ b/sound/soc/codecs/wcd9335.c @@ -1260,8 +1260,9 @@ static const struct snd_kcontrol_new sb_tx8_mux = static int slim_rx_mux_get(struct snd_kcontrol *kc, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_widget *w = snd_soc_dapm_kcontrol_widget(kc); - struct wcd9335_codec *wcd = dev_get_drvdata(w->dapm->dev); + struct snd_soc_dapm_widget *w = snd_soc_dapm_kcontrol_to_widget(kc); + struct device *dev = snd_soc_dapm_to_dev(w->dapm); + struct wcd9335_codec *wcd = dev_get_drvdata(dev); u32 port_id = w->shift; ucontrol->value.enumerated.item[0] = wcd->rx_port_value[port_id]; @@ -1272,8 +1273,9 @@ static int slim_rx_mux_get(struct snd_kcontrol *kc, static int slim_rx_mux_put(struct snd_kcontrol *kc, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_widget *w = snd_soc_dapm_kcontrol_widget(kc); - struct wcd9335_codec *wcd = dev_get_drvdata(w->dapm->dev); + struct snd_soc_dapm_widget *w = snd_soc_dapm_kcontrol_to_widget(kc); + struct device *dev = snd_soc_dapm_to_dev(w->dapm); + struct wcd9335_codec *wcd = dev_get_drvdata(dev); struct soc_enum *e = (struct soc_enum *)kc->private_value; struct snd_soc_dapm_update *update = NULL; u32 port_id = w->shift; @@ -1323,9 +1325,10 @@ static int slim_tx_mixer_get(struct snd_kcontrol *kc, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kc); - struct wcd9335_codec *wcd = dev_get_drvdata(dapm->dev); - struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_widget(kc); + struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kc); + struct device *dev = snd_soc_dapm_to_dev(dapm); + struct wcd9335_codec *wcd = dev_get_drvdata(dev); + struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_to_widget(kc); struct soc_mixer_control *mixer = (struct soc_mixer_control *)kc->private_value; int dai_id = widget->shift; @@ -1340,8 +1343,9 @@ static int slim_tx_mixer_put(struct snd_kcontrol *kc, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_widget(kc); - struct wcd9335_codec *wcd = dev_get_drvdata(widget->dapm->dev); + struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_to_widget(kc); + struct device *dev = snd_soc_dapm_to_dev(widget->dapm); + struct wcd9335_codec *wcd = dev_get_drvdata(dev); struct snd_soc_dapm_update *update = NULL; struct soc_mixer_control *mixer = (struct soc_mixer_control *)kc->private_value; @@ -1474,7 +1478,7 @@ static const struct snd_kcontrol_new aif3_cap_mixer[] = { static int wcd9335_put_dec_enum(struct snd_kcontrol *kc, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kc); + struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kc); struct snd_soc_component *component = snd_soc_dapm_to_component(dapm); struct soc_enum *e = (struct soc_enum *)kc->private_value; unsigned int val, reg, sel; @@ -1529,7 +1533,7 @@ static int wcd9335_int_dem_inp_mux_put(struct snd_kcontrol *kc, struct snd_soc_component *component; int reg, val; - component = snd_soc_dapm_kcontrol_component(kc); + component = snd_soc_dapm_kcontrol_to_component(kc); val = ucontrol->value.enumerated.item[0]; if (e->reg == WCD9335_CDC_RX0_RX_PATH_SEC0) diff --git a/sound/soc/codecs/wcd934x.c b/sound/soc/codecs/wcd934x.c index e8df380bdff386..c8db33f78a1b50 100644 --- a/sound/soc/codecs/wcd934x.c +++ b/sound/soc/codecs/wcd934x.c @@ -3250,9 +3250,10 @@ static int wcd934x_rx_hph_mode_put(struct snd_kcontrol *kc, static int slim_rx_mux_get(struct snd_kcontrol *kc, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kc); - struct snd_soc_dapm_widget *w = snd_soc_dapm_kcontrol_widget(kc); - struct wcd934x_codec *wcd = dev_get_drvdata(dapm->dev); + struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kc); + struct snd_soc_dapm_widget *w = snd_soc_dapm_kcontrol_to_widget(kc); + struct device *dev = snd_soc_dapm_to_dev(dapm); + struct wcd934x_codec *wcd = dev_get_drvdata(dev); ucontrol->value.enumerated.item[0] = wcd->rx_port_value[w->shift]; @@ -3287,8 +3288,9 @@ static int slim_rx_mux_to_dai_id(int mux) static int slim_rx_mux_put(struct snd_kcontrol *kc, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_widget *w = snd_soc_dapm_kcontrol_widget(kc); - struct wcd934x_codec *wcd = dev_get_drvdata(w->dapm->dev); + struct snd_soc_dapm_widget *w = snd_soc_dapm_kcontrol_to_widget(kc); + struct device *dev = snd_soc_dapm_to_dev(w->dapm); + struct wcd934x_codec *wcd = dev_get_drvdata(dev); struct soc_enum *e = (struct soc_enum *)kc->private_value; struct snd_soc_dapm_update *update = NULL; struct wcd934x_slim_ch *ch, *c; @@ -3355,7 +3357,7 @@ static int wcd934x_int_dem_inp_mux_put(struct snd_kcontrol *kc, struct snd_soc_component *component; int reg, val; - component = snd_soc_dapm_kcontrol_component(kc); + component = snd_soc_dapm_kcontrol_to_component(kc); val = ucontrol->value.enumerated.item[0]; if (e->reg == WCD934X_CDC_RX0_RX_PATH_SEC0) reg = WCD934X_CDC_RX0_RX_PATH_CFG0; @@ -3388,7 +3390,7 @@ static int wcd934x_dec_enum_put(struct snd_kcontrol *kcontrol, u16 mic_sel_reg = 0; u8 mic_sel; - comp = snd_soc_dapm_kcontrol_component(kcontrol); + comp = snd_soc_dapm_kcontrol_to_component(kcontrol); val = ucontrol->value.enumerated.item[0]; if (val > e->items - 1) @@ -3767,8 +3769,9 @@ static const struct snd_kcontrol_new cdc_if_tx13_inp1_mux = static int slim_tx_mixer_get(struct snd_kcontrol *kc, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kc); - struct wcd934x_codec *wcd = dev_get_drvdata(dapm->dev); + struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kc); + struct device *dev = snd_soc_dapm_to_dev(dapm); + struct wcd934x_codec *wcd = dev_get_drvdata(dev); struct soc_mixer_control *mixer = (struct soc_mixer_control *)kc->private_value; int port_id = mixer->shift; @@ -3781,8 +3784,9 @@ static int slim_tx_mixer_get(struct snd_kcontrol *kc, static int slim_tx_mixer_put(struct snd_kcontrol *kc, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_widget(kc); - struct wcd934x_codec *wcd = dev_get_drvdata(widget->dapm->dev); + struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_to_widget(kc); + struct device *dev = snd_soc_dapm_to_dev(widget->dapm); + struct wcd934x_codec *wcd = dev_get_drvdata(dev); struct snd_soc_dapm_update *update = NULL; struct soc_mixer_control *mixer = (struct soc_mixer_control *)kc->private_value; diff --git a/sound/soc/codecs/wcd937x.c b/sound/soc/codecs/wcd937x.c index e7b9ba284cd34f..f1dced57a59b25 100644 --- a/sound/soc/codecs/wcd937x.c +++ b/sound/soc/codecs/wcd937x.c @@ -2473,7 +2473,7 @@ static int wcd937x_irq_init(struct wcd937x_priv *wcd, struct device *dev) static int wcd937x_soc_codec_probe(struct snd_soc_component *component) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(component); struct sdw_slave *tx_sdw_dev = wcd937x->tx_sdw_dev; struct device *dev = component->dev; @@ -2746,7 +2746,8 @@ static int wcd937x_bind(struct device *dev) wcd937x->rxdev = of_sdw_find_device_by_node(wcd937x->rxnode); if (!wcd937x->rxdev) { dev_err(dev, "could not find slave with matching of node\n"); - return -EINVAL; + ret = -EINVAL; + goto err_component_unbind; } wcd937x->sdw_priv[AIF1_PB] = dev_get_drvdata(wcd937x->rxdev); @@ -2755,7 +2756,8 @@ static int wcd937x_bind(struct device *dev) wcd937x->txdev = of_sdw_find_device_by_node(wcd937x->txnode); if (!wcd937x->txdev) { dev_err(dev, "could not find txslave with matching of node\n"); - return -EINVAL; + ret = -EINVAL; + goto err_put_rxdev; } wcd937x->sdw_priv[AIF1_CAP] = dev_get_drvdata(wcd937x->txdev); @@ -2763,7 +2765,8 @@ static int wcd937x_bind(struct device *dev) wcd937x->tx_sdw_dev = dev_to_sdw_dev(wcd937x->txdev); if (!wcd937x->tx_sdw_dev) { dev_err(dev, "could not get txslave with matching of dev\n"); - return -EINVAL; + ret = -EINVAL; + goto err_put_txdev; } /* @@ -2773,31 +2776,35 @@ static int wcd937x_bind(struct device *dev) if (!device_link_add(wcd937x->rxdev, wcd937x->txdev, DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME)) { dev_err(dev, "Could not devlink TX and RX\n"); - return -EINVAL; + ret = -EINVAL; + goto err_put_txdev; } if (!device_link_add(dev, wcd937x->txdev, DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME)) { dev_err(dev, "Could not devlink WCD and TX\n"); - return -EINVAL; + ret = -EINVAL; + goto err_remove_link1; } if (!device_link_add(dev, wcd937x->rxdev, DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME)) { dev_err(dev, "Could not devlink WCD and RX\n"); - return -EINVAL; + ret = -EINVAL; + goto err_remove_link2; } wcd937x->regmap = wcd937x->sdw_priv[AIF1_CAP]->regmap; if (!wcd937x->regmap) { dev_err(dev, "could not get TX device regmap\n"); - return -EINVAL; + ret = -EINVAL; + goto err_remove_link3; } ret = wcd937x_irq_init(wcd937x, dev); if (ret) { dev_err(dev, "IRQ init failed: %d\n", ret); - return ret; + goto err_remove_link3; } wcd937x->sdw_priv[AIF1_PB]->slave_irq = wcd937x->virq; @@ -2807,10 +2814,26 @@ static int wcd937x_bind(struct device *dev) ret = snd_soc_register_component(dev, &soc_codec_dev_wcd937x, wcd937x_dais, ARRAY_SIZE(wcd937x_dais)); - if (ret) + if (ret) { dev_err(dev, "Codec registration failed\n"); + goto err_remove_link3; + } return ret; + +err_remove_link3: + device_link_remove(dev, wcd937x->rxdev); +err_remove_link2: + device_link_remove(dev, wcd937x->txdev); +err_remove_link1: + device_link_remove(wcd937x->rxdev, wcd937x->txdev); +err_put_txdev: + put_device(wcd937x->txdev); +err_put_rxdev: + put_device(wcd937x->rxdev); +err_component_unbind: + component_unbind_all(dev, wcd937x); + return ret; } static void wcd937x_unbind(struct device *dev) @@ -2823,6 +2846,8 @@ static void wcd937x_unbind(struct device *dev) device_link_remove(wcd937x->rxdev, wcd937x->txdev); component_unbind_all(dev, wcd937x); mutex_destroy(&wcd937x->micb_lock); + put_device(wcd937x->txdev); + put_device(wcd937x->rxdev); } static const struct component_master_ops wcd937x_comp_ops = { diff --git a/sound/soc/codecs/wcd939x-sdw.c b/sound/soc/codecs/wcd939x-sdw.c index d369100a245742..da342a0c95a52b 100644 --- a/sound/soc/codecs/wcd939x-sdw.c +++ b/sound/soc/codecs/wcd939x-sdw.c @@ -1400,12 +1400,18 @@ static int wcd9390_probe(struct sdw_slave *pdev, const struct sdw_device_id *id) ret = component_add(dev, &wcd_sdw_component_ops); if (ret) - return ret; + goto err_free_regmap; /* Set suspended until aggregate device is bind */ pm_runtime_set_suspended(dev); return 0; + +err_free_regmap: + if (wcd->regmap) + regmap_exit(wcd->regmap); + + return ret; } static int wcd9390_remove(struct sdw_slave *pdev) diff --git a/sound/soc/codecs/wm0010.c b/sound/soc/codecs/wm0010.c index 9e67fbfc2ccaf8..7511c71695c6cc 100644 --- a/sound/soc/codecs/wm0010.c +++ b/sound/soc/codecs/wm0010.c @@ -723,16 +723,17 @@ static int wm0010_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { struct wm0010_priv *wm0010 = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); switch (level) { case SND_SOC_BIAS_ON: - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_PREPARE) + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_PREPARE) wm0010_boot(component); break; case SND_SOC_BIAS_PREPARE: break; case SND_SOC_BIAS_STANDBY: - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_PREPARE) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_PREPARE) { mutex_lock(&wm0010->lock); wm0010_halt(component); mutex_unlock(&wm0010->lock); diff --git a/sound/soc/codecs/wm5100.c b/sound/soc/codecs/wm5100.c index 2d0a20f2fd8c2c..96fd098a9d362b 100644 --- a/sound/soc/codecs/wm5100.c +++ b/sound/soc/codecs/wm5100.c @@ -2101,7 +2101,7 @@ static void wm5100_micd_irq(struct wm5100_priv *wm5100) int wm5100_detect(struct snd_soc_component *component, struct snd_soc_jack *jack) { struct wm5100_priv *wm5100 = snd_soc_component_get_drvdata(component); - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); if (jack) { wm5100->jack = jack; @@ -2329,7 +2329,7 @@ static void wm5100_free_gpio(struct i2c_client *i2c) static int wm5100_probe(struct snd_soc_component *component) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct i2c_client *i2c = to_i2c_client(component->dev); struct wm5100_priv *wm5100 = snd_soc_component_get_drvdata(component); int ret, i; diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c index 4f5b4b85c2fe94..b4d4137c05b4b8 100644 --- a/sound/soc/codecs/wm5102.c +++ b/sound/soc/codecs/wm5102.c @@ -1949,7 +1949,7 @@ static irqreturn_t wm5102_adsp2_irq(int irq, void *data) static int wm5102_component_probe(struct snd_soc_component *component) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct wm5102_priv *priv = snd_soc_component_get_drvdata(component); struct arizona *arizona = priv->core.arizona; int ret; @@ -1971,7 +1971,7 @@ static int wm5102_component_probe(struct snd_soc_component *component) arizona_init_gpio(component); - snd_soc_component_disable_pin(component, "HAPTICS"); + snd_soc_dapm_disable_pin(dapm, "HAPTICS"); priv->core.arizona->dapm = dapm; diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c index 29b805128ae55c..7a311c869bd312 100644 --- a/sound/soc/codecs/wm5110.c +++ b/sound/soc/codecs/wm5110.c @@ -403,7 +403,7 @@ static int wm5110_put_dre(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct arizona *arizona = dev_get_drvdata(component->dev->parent); struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; @@ -468,7 +468,7 @@ static int wm5110_in_pga_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); int ret; /* @@ -488,7 +488,7 @@ static int wm5110_in_pga_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); int ret; /* @@ -2297,7 +2297,7 @@ static irqreturn_t wm5110_adsp2_irq(int irq, void *data) static int wm5110_component_probe(struct snd_soc_component *component) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct wm5110_priv *priv = snd_soc_component_get_drvdata(component); struct arizona *arizona = priv->core.arizona; int i, ret; @@ -2324,7 +2324,7 @@ static int wm5110_component_probe(struct snd_soc_component *component) if (ret) goto err_adsp2_codec_probe; - snd_soc_component_disable_pin(component, "HAPTICS"); + snd_soc_dapm_disable_pin(dapm, "HAPTICS"); return 0; diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c index fda753152a68b9..ad68ff1790e018 100644 --- a/sound/soc/codecs/wm8350.c +++ b/sound/soc/codecs/wm8350.c @@ -1075,6 +1075,7 @@ static int wm8350_set_fll(struct snd_soc_dai *codec_dai, static int wm8350_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct wm8350_data *priv = snd_soc_component_get_drvdata(component); struct wm8350 *wm8350 = priv->wm8350; struct wm8350_audio_platform_data *platform = @@ -1099,7 +1100,7 @@ static int wm8350_set_bias_level(struct snd_soc_component *component, break; case SND_SOC_BIAS_STANDBY: - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) { ret = regulator_bulk_enable(ARRAY_SIZE(priv->supplies), priv->supplies); if (ret != 0) diff --git a/sound/soc/codecs/wm8400.c b/sound/soc/codecs/wm8400.c index 096f8fdbdff54b..0eecc8657a38d5 100644 --- a/sound/soc/codecs/wm8400.c +++ b/sound/soc/codecs/wm8400.c @@ -1111,6 +1111,7 @@ static int wm8400_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { struct wm8400_priv *wm8400 = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); u16 val; int ret; @@ -1126,7 +1127,7 @@ static int wm8400_set_bias_level(struct snd_soc_component *component, break; case SND_SOC_BIAS_STANDBY: - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) { ret = regulator_bulk_enable(ARRAY_SIZE(power), &power[0]); if (ret != 0) { diff --git a/sound/soc/codecs/wm8510.c b/sound/soc/codecs/wm8510.c index 79adbcc90d4a78..bebee333d3fd89 100644 --- a/sound/soc/codecs/wm8510.c +++ b/sound/soc/codecs/wm8510.c @@ -504,6 +504,7 @@ static int wm8510_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { struct wm8510_priv *wm8510 = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); u16 power1 = snd_soc_component_read(component, WM8510_POWER1) & ~0x3; switch (level) { @@ -516,7 +517,7 @@ static int wm8510_set_bias_level(struct snd_soc_component *component, case SND_SOC_BIAS_STANDBY: power1 |= WM8510_POWER1_BIASEN | WM8510_POWER1_BUFIOEN; - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) { regcache_sync(wm8510->regmap); /* Initial cap charge at VMID 5k */ diff --git a/sound/soc/codecs/wm8523.c b/sound/soc/codecs/wm8523.c index 6671e13c320c68..f003f19766e28c 100644 --- a/sound/soc/codecs/wm8523.c +++ b/sound/soc/codecs/wm8523.c @@ -317,6 +317,7 @@ static int wm8523_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { struct wm8523_priv *wm8523 = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); int ret; switch (level) { @@ -330,7 +331,7 @@ static int wm8523_set_bias_level(struct snd_soc_component *component, break; case SND_SOC_BIAS_STANDBY: - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) { ret = regulator_bulk_enable(ARRAY_SIZE(wm8523->supplies), wm8523->supplies); if (ret != 0) { diff --git a/sound/soc/codecs/wm8580.c b/sound/soc/codecs/wm8580.c index f0cf121b09de18..2be265bb075192 100644 --- a/sound/soc/codecs/wm8580.c +++ b/sound/soc/codecs/wm8580.c @@ -820,13 +820,15 @@ static int wm8580_mute(struct snd_soc_dai *codec_dai, int mute, int direction) static int wm8580_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); + switch (level) { case SND_SOC_BIAS_ON: case SND_SOC_BIAS_PREPARE: break; case SND_SOC_BIAS_STANDBY: - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) { /* Power up and get individual control of the DACs */ snd_soc_component_update_bits(component, WM8580_PWRDN1, WM8580_PWRDN1_PWDN | @@ -907,7 +909,7 @@ static struct snd_soc_dai_driver wm8580_dai[] = { static int wm8580_probe(struct snd_soc_component *component) { struct wm8580_priv *wm8580 = snd_soc_component_get_drvdata(component); - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); int ret = 0; switch (wm8580->drvdata->num_dacs) { diff --git a/sound/soc/codecs/wm8711.c b/sound/soc/codecs/wm8711.c index 481088987742ae..2bab9d189519dd 100644 --- a/sound/soc/codecs/wm8711.c +++ b/sound/soc/codecs/wm8711.c @@ -298,6 +298,7 @@ static int wm8711_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { struct wm8711_priv *wm8711 = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); u16 reg = snd_soc_component_read(component, WM8711_PWR) & 0xff7f; switch (level) { @@ -307,7 +308,7 @@ static int wm8711_set_bias_level(struct snd_soc_component *component, case SND_SOC_BIAS_PREPARE: break; case SND_SOC_BIAS_STANDBY: - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) regcache_sync(wm8711->regmap); snd_soc_component_write(component, WM8711_PWR, reg | 0x0040); diff --git a/sound/soc/codecs/wm8728.c b/sound/soc/codecs/wm8728.c index ea0a588da40f39..4c1a80561f06f3 100644 --- a/sound/soc/codecs/wm8728.c +++ b/sound/soc/codecs/wm8728.c @@ -161,13 +161,14 @@ static int wm8728_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { struct wm8728_priv *wm8728 = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); u16 reg; switch (level) { case SND_SOC_BIAS_ON: case SND_SOC_BIAS_PREPARE: case SND_SOC_BIAS_STANDBY: - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) { /* Power everything up... */ reg = snd_soc_component_read(component, WM8728_DACCTL); snd_soc_component_write(component, WM8728_DACCTL, reg & ~0x4); diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c index 0318dac1e50483..a03bbde5d85270 100644 --- a/sound/soc/codecs/wm8731.c +++ b/sound/soc/codecs/wm8731.c @@ -362,7 +362,7 @@ static int wm8731_set_dai_sysclk(struct snd_soc_dai *codec_dai, int clk_id, unsigned int freq, int dir) { struct snd_soc_component *component = codec_dai->component; - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct wm8731_priv *wm8731 = snd_soc_component_get_drvdata(component); switch (clk_id) { @@ -465,6 +465,7 @@ static int wm8731_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { struct wm8731_priv *wm8731 = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); int ret; u16 reg; @@ -479,7 +480,7 @@ static int wm8731_set_bias_level(struct snd_soc_component *component, case SND_SOC_BIAS_PREPARE: break; case SND_SOC_BIAS_STANDBY: - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) { ret = regulator_bulk_enable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies); if (ret != 0) diff --git a/sound/soc/codecs/wm8737.c b/sound/soc/codecs/wm8737.c index f7e48f27649de5..fee8a37ed1df25 100644 --- a/sound/soc/codecs/wm8737.c +++ b/sound/soc/codecs/wm8737.c @@ -452,6 +452,7 @@ static int wm8737_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { struct wm8737_priv *wm8737 = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); int ret; switch (level) { @@ -465,7 +466,7 @@ static int wm8737_set_bias_level(struct snd_soc_component *component, break; case SND_SOC_BIAS_STANDBY: - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) { ret = regulator_bulk_enable(ARRAY_SIZE(wm8737->supplies), wm8737->supplies); if (ret != 0) { @@ -537,6 +538,7 @@ static struct snd_soc_dai_driver wm8737_dai = { static int wm8737_probe(struct snd_soc_component *component) { struct wm8737_priv *wm8737 = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); int ret; ret = regulator_bulk_enable(ARRAY_SIZE(wm8737->supplies), @@ -557,7 +559,7 @@ static int wm8737_probe(struct snd_soc_component *component) snd_soc_component_update_bits(component, WM8737_RIGHT_PGA_VOLUME, WM8737_RVU, WM8737_RVU); - snd_soc_component_force_bias_level(component, SND_SOC_BIAS_STANDBY); + snd_soc_dapm_force_bias_level(dapm, SND_SOC_BIAS_STANDBY); /* Bias level configuration will have done an extra enable */ regulator_bulk_disable(ARRAY_SIZE(wm8737->supplies), wm8737->supplies); diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c index 312be0721b5d85..0e1d3ebb15c49c 100644 --- a/sound/soc/codecs/wm8750.c +++ b/sound/soc/codecs/wm8750.c @@ -621,6 +621,7 @@ static int wm8750_mute(struct snd_soc_dai *dai, int mute, int direction) static int wm8750_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); u16 pwr_reg = snd_soc_component_read(component, WM8750_PWR1) & 0xfe3e; switch (level) { @@ -631,7 +632,7 @@ static int wm8750_set_bias_level(struct snd_soc_component *component, case SND_SOC_BIAS_PREPARE: break; case SND_SOC_BIAS_STANDBY: - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) { snd_soc_component_cache_sync(component); /* Set VMID to 5k */ diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c index bdd38ee5aed778..a532a95e804805 100644 --- a/sound/soc/codecs/wm8753.c +++ b/sound/soc/codecs/wm8753.c @@ -1331,6 +1331,7 @@ static int wm8753_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { struct wm8753_priv *wm8753 = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); u16 pwr_reg = snd_soc_component_read(component, WM8753_PWR1) & 0xfe3e; switch (level) { @@ -1343,7 +1344,7 @@ static int wm8753_set_bias_level(struct snd_soc_component *component, flush_delayed_work(&wm8753->charge_work); break; case SND_SOC_BIAS_STANDBY: - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) { /* set vmid to 5k for quick power up */ snd_soc_component_write(component, WM8753_PWR1, pwr_reg | 0x01c1); schedule_delayed_work(&wm8753->charge_work, diff --git a/sound/soc/codecs/wm8770.c b/sound/soc/codecs/wm8770.c index 5685c3bb555595..d382b476c89c40 100644 --- a/sound/soc/codecs/wm8770.c +++ b/sound/soc/codecs/wm8770.c @@ -497,6 +497,7 @@ static int wm8770_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { int ret; + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct wm8770_priv *wm8770; wm8770 = snd_soc_component_get_drvdata(component); @@ -507,7 +508,7 @@ static int wm8770_set_bias_level(struct snd_soc_component *component, case SND_SOC_BIAS_PREPARE: break; case SND_SOC_BIAS_STANDBY: - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) { ret = regulator_bulk_enable(ARRAY_SIZE(wm8770->supplies), wm8770->supplies); if (ret) { diff --git a/sound/soc/codecs/wm8776.c b/sound/soc/codecs/wm8776.c index 7b73c825aed46a..c3f340657f0cc3 100644 --- a/sound/soc/codecs/wm8776.c +++ b/sound/soc/codecs/wm8776.c @@ -334,6 +334,7 @@ static int wm8776_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { struct wm8776_priv *wm8776 = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); switch (level) { case SND_SOC_BIAS_ON: @@ -341,7 +342,7 @@ static int wm8776_set_bias_level(struct snd_soc_component *component, case SND_SOC_BIAS_PREPARE: break; case SND_SOC_BIAS_STANDBY: - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) { regcache_sync(wm8776->regmap); /* Disable the global powerdown; DAPM does the rest */ diff --git a/sound/soc/codecs/wm8804.c b/sound/soc/codecs/wm8804.c index 48700cc25cb084..94aa3c8de0ab6d 100644 --- a/sound/soc/codecs/wm8804.c +++ b/sound/soc/codecs/wm8804.c @@ -157,8 +157,8 @@ static int wm8804_aif_event(struct snd_soc_dapm_widget *w, static int txsrc_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_component *component = snd_soc_dapm_kcontrol_component(kcontrol); - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_component *component = snd_soc_dapm_kcontrol_to_component(kcontrol); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; unsigned int val = ucontrol->value.enumerated.item[0] << e->shift_l; unsigned int mask = 1 << e->shift_l; diff --git a/sound/soc/codecs/wm8900.c b/sound/soc/codecs/wm8900.c index 6fb25588ca8195..fea629541acda5 100644 --- a/sound/soc/codecs/wm8900.c +++ b/sound/soc/codecs/wm8900.c @@ -1023,6 +1023,7 @@ static struct snd_soc_dai_driver wm8900_dai = { static int wm8900_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); u16 reg; switch (level) { @@ -1041,7 +1042,7 @@ static int wm8900_set_bias_level(struct snd_soc_component *component, case SND_SOC_BIAS_STANDBY: /* Charge capacitors if initial power up */ - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) { /* STARTUP_BIAS_ENA on */ snd_soc_component_write(component, WM8900_REG_POWER1, WM8900_REG_POWER1_STARTUP_BIAS_ENA); @@ -1115,6 +1116,7 @@ static int wm8900_set_bias_level(struct snd_soc_component *component, static int wm8900_suspend(struct snd_soc_component *component) { struct wm8900_priv *wm8900 = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); int fll_out = wm8900->fll_out; int fll_in = wm8900->fll_in; int ret; @@ -1129,7 +1131,7 @@ static int wm8900_suspend(struct snd_soc_component *component) wm8900->fll_out = fll_out; wm8900->fll_in = fll_in; - snd_soc_component_force_bias_level(component, SND_SOC_BIAS_OFF); + snd_soc_dapm_force_bias_level(dapm, SND_SOC_BIAS_OFF); return 0; } @@ -1137,6 +1139,7 @@ static int wm8900_suspend(struct snd_soc_component *component) static int wm8900_resume(struct snd_soc_component *component) { struct wm8900_priv *wm8900 = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); int ret; wm8900_reset(component); @@ -1147,7 +1150,7 @@ static int wm8900_resume(struct snd_soc_component *component) return ret; } - snd_soc_component_force_bias_level(component, SND_SOC_BIAS_STANDBY); + snd_soc_dapm_force_bias_level(dapm, SND_SOC_BIAS_STANDBY); /* Restart the FLL? */ if (wm8900->fll_out) { @@ -1169,6 +1172,7 @@ static int wm8900_resume(struct snd_soc_component *component) static int wm8900_probe(struct snd_soc_component *component) { + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); int reg; reg = snd_soc_component_read(component, WM8900_REG_ID); @@ -1180,7 +1184,7 @@ static int wm8900_probe(struct snd_soc_component *component) wm8900_reset(component); /* Turn the chip on */ - snd_soc_component_force_bias_level(component, SND_SOC_BIAS_STANDBY); + snd_soc_dapm_force_bias_level(dapm, SND_SOC_BIAS_STANDBY); /* Latch the volume update bits */ snd_soc_component_update_bits(component, WM8900_REG_LINVOL, 0x100, 0x100); diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c index ff91dd1824e600..f73f6ad06b3830 100644 --- a/sound/soc/codecs/wm8903.c +++ b/sound/soc/codecs/wm8903.c @@ -369,7 +369,7 @@ static void wm8903_seq_notifier(struct snd_soc_component *component, static int wm8903_class_w_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_component *component = snd_soc_dapm_kcontrol_component(kcontrol); + struct snd_soc_component *component = snd_soc_dapm_kcontrol_to_component(kcontrol); struct wm8903_priv *wm8903 = snd_soc_component_get_drvdata(component); u16 reg; int ret; @@ -1099,6 +1099,8 @@ static const struct snd_soc_dapm_route wm8903_intercon[] = { static int wm8903_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); + switch (level) { case SND_SOC_BIAS_ON: break; @@ -1110,7 +1112,7 @@ static int wm8903_set_bias_level(struct snd_soc_component *component, break; case SND_SOC_BIAS_STANDBY: - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) { snd_soc_component_update_bits(component, WM8903_BIAS_CONTROL_0, WM8903_POBCTRL | WM8903_ISEL_MASK | WM8903_STARTUP_BIAS_ENA | diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c index e16b28b7224373..4c73a340f25feb 100644 --- a/sound/soc/codecs/wm8904.c +++ b/sound/soc/codecs/wm8904.c @@ -1246,7 +1246,7 @@ static const struct snd_soc_dapm_route wm8912_intercon[] = { static int wm8904_add_widgets(struct snd_soc_component *component) { struct wm8904_priv *wm8904 = snd_soc_component_get_drvdata(component); - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); snd_soc_dapm_new_controls(dapm, wm8904_core_dapm_widgets, ARRAY_SIZE(wm8904_core_dapm_widgets)); @@ -1934,6 +1934,7 @@ static int wm8904_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { struct wm8904_priv *wm8904 = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); int ret; switch (level) { @@ -1952,7 +1953,7 @@ static int wm8904_set_bias_level(struct snd_soc_component *component, break; case SND_SOC_BIAS_STANDBY: - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) { ret = regulator_bulk_enable(ARRAY_SIZE(wm8904->supplies), wm8904->supplies); if (ret != 0) { @@ -2114,7 +2115,7 @@ static void wm8904_handle_retune_mobile_pdata(struct snd_soc_component *componen static void wm8904_handle_dmic_pdata(struct snd_soc_component *component) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct wm8904_priv *wm8904 = snd_soc_component_get_drvdata(component); struct wm8904_pdata *pdata = wm8904->pdata; unsigned int dmic_src; @@ -2161,7 +2162,7 @@ static void wm8904_handle_dmic_pdata(struct snd_soc_component *component) static void wm8904_handle_pdata(struct snd_soc_component *component) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct wm8904_priv *wm8904 = snd_soc_component_get_drvdata(component); struct wm8904_pdata *pdata = wm8904->pdata; int ret, i; diff --git a/sound/soc/codecs/wm8940.c b/sound/soc/codecs/wm8940.c index 94873ea630146b..2f55d0c572a4f0 100644 --- a/sound/soc/codecs/wm8940.c +++ b/sound/soc/codecs/wm8940.c @@ -476,6 +476,7 @@ static int wm8940_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { struct wm8940_priv *wm8940 = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); u16 val; u16 pwr_reg = snd_soc_component_read(component, WM8940_POWER1) & 0x1F0; int ret = 0; @@ -498,7 +499,7 @@ static int wm8940_set_bias_level(struct snd_soc_component *component, ret = snd_soc_component_write(component, WM8940_POWER1, pwr_reg | 0x1); break; case SND_SOC_BIAS_STANDBY: - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) { ret = regcache_sync(wm8940->regmap); if (ret < 0) { dev_err(component->dev, "Failed to sync cache: %d\n", ret); @@ -761,6 +762,7 @@ static struct snd_soc_dai_driver wm8940_dai = { static int wm8940_probe(struct snd_soc_component *component) { + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct wm8940_setup_data *pdata = component->dev->platform_data; int ret; u16 reg; @@ -782,7 +784,7 @@ static int wm8940_probe(struct snd_soc_component *component) return ret; } - snd_soc_component_force_bias_level(component, SND_SOC_BIAS_STANDBY); + snd_soc_dapm_force_bias_level(dapm, SND_SOC_BIAS_STANDBY); ret = snd_soc_component_write(component, WM8940_POWER1, 0x180); if (ret < 0) diff --git a/sound/soc/codecs/wm8955.c b/sound/soc/codecs/wm8955.c index 82944cf6e3cf05..e1c61e026cbca0 100644 --- a/sound/soc/codecs/wm8955.c +++ b/sound/soc/codecs/wm8955.c @@ -764,6 +764,7 @@ static int wm8955_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { struct wm8955_priv *wm8955 = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); int ret; switch (level) { @@ -783,7 +784,7 @@ static int wm8955_set_bias_level(struct snd_soc_component *component, break; case SND_SOC_BIAS_STANDBY: - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) { ret = regulator_bulk_enable(ARRAY_SIZE(wm8955->supplies), wm8955->supplies); if (ret != 0) { @@ -866,6 +867,7 @@ static struct snd_soc_dai_driver wm8955_dai = { static int wm8955_probe(struct snd_soc_component *component) { + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct wm8955_priv *wm8955 = snd_soc_component_get_drvdata(component); struct wm8955_pdata *pdata = dev_get_platdata(component->dev); int ret, i; @@ -927,7 +929,7 @@ static int wm8955_probe(struct snd_soc_component *component) WM8955_DMEN, WM8955_DMEN); } - snd_soc_component_force_bias_level(component, SND_SOC_BIAS_STANDBY); + snd_soc_dapm_force_bias_level(dapm, SND_SOC_BIAS_STANDBY); /* Bias level configuration will have done an extra enable */ regulator_bulk_disable(ARRAY_SIZE(wm8955->supplies), wm8955->supplies); diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c index 740c3f7da2a508..384e8e7034468e 100644 --- a/sound/soc/codecs/wm8960.c +++ b/sound/soc/codecs/wm8960.c @@ -488,7 +488,7 @@ static int wm8960_add_widgets(struct snd_soc_component *component) { struct wm8960_priv *wm8960 = snd_soc_component_get_drvdata(component); struct wm8960_data *pdata = &wm8960->pdata; - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct snd_soc_dapm_widget *w; snd_soc_dapm_new_controls(dapm, wm8960_dapm_widgets, @@ -913,6 +913,7 @@ static int wm8960_set_bias_level_out3(struct snd_soc_component *component, enum snd_soc_bias_level level) { struct wm8960_priv *wm8960 = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); u16 pm2 = snd_soc_component_read(component, WM8960_POWER2); int ret; ktime_t tout; @@ -922,7 +923,7 @@ static int wm8960_set_bias_level_out3(struct snd_soc_component *component, break; case SND_SOC_BIAS_PREPARE: - switch (snd_soc_component_get_bias_level(component)) { + switch (snd_soc_dapm_get_bias_level(dapm)) { case SND_SOC_BIAS_STANDBY: if (!IS_ERR(wm8960->mclk)) { ret = clk_prepare_enable(wm8960->mclk); @@ -961,7 +962,7 @@ static int wm8960_set_bias_level_out3(struct snd_soc_component *component, break; case SND_SOC_BIAS_STANDBY: - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) { /* ensure discharge is complete */ tout = WM8960_DSCH_TOUT - ktime_ms_delta(ktime_get(), wm8960->dsch_start); if (tout > 0) @@ -1009,6 +1010,7 @@ static int wm8960_set_bias_level_capless(struct snd_soc_component *component, enum snd_soc_bias_level level) { struct wm8960_priv *wm8960 = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); u16 pm2 = snd_soc_component_read(component, WM8960_POWER2); int reg, ret; @@ -1017,7 +1019,7 @@ static int wm8960_set_bias_level_capless(struct snd_soc_component *component, break; case SND_SOC_BIAS_PREPARE: - switch (snd_soc_component_get_bias_level(component)) { + switch (snd_soc_dapm_get_bias_level(dapm)) { case SND_SOC_BIAS_STANDBY: /* Enable anti pop mode */ snd_soc_component_update_bits(component, WM8960_APOP1, @@ -1100,7 +1102,7 @@ static int wm8960_set_bias_level_capless(struct snd_soc_component *component, break; case SND_SOC_BIAS_STANDBY: - switch (snd_soc_component_get_bias_level(component)) { + switch (snd_soc_dapm_get_bias_level(dapm)) { case SND_SOC_BIAS_PREPARE: /* Disable HP discharge */ snd_soc_component_update_bits(component, WM8960_APOP2, diff --git a/sound/soc/codecs/wm8961.c b/sound/soc/codecs/wm8961.c index 1ec7c5e8fd6909..cfb8cfc918732d 100644 --- a/sound/soc/codecs/wm8961.c +++ b/sound/soc/codecs/wm8961.c @@ -743,6 +743,7 @@ static int wm8961_set_clkdiv(struct snd_soc_dai *dai, int div_id, int div) static int wm8961_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); u16 reg; /* This is all slightly unusual since we have no bypass paths @@ -755,7 +756,7 @@ static int wm8961_set_bias_level(struct snd_soc_component *component, break; case SND_SOC_BIAS_PREPARE: - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_STANDBY) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_STANDBY) { /* Enable bias generation */ reg = snd_soc_component_read(component, WM8961_ANTI_POP); reg |= WM8961_BUFIOEN | WM8961_BUFDCOPEN; @@ -770,7 +771,7 @@ static int wm8961_set_bias_level(struct snd_soc_component *component, break; case SND_SOC_BIAS_STANDBY: - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_PREPARE) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_PREPARE) { /* VREF off */ reg = snd_soc_component_read(component, WM8961_PWR_MGMT_1); reg &= ~WM8961_VREF; diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c index a5ad916966b27a..e9e317ce689826 100644 --- a/sound/soc/codecs/wm8962.c +++ b/sound/soc/codecs/wm8962.c @@ -2419,7 +2419,7 @@ static int wm8962_add_widgets(struct snd_soc_component *component) { struct wm8962_priv *wm8962 = snd_soc_component_get_drvdata(component); struct wm8962_pdata *pdata = &wm8962->pdata; - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); snd_soc_add_component_controls(component, wm8962_snd_controls, ARRAY_SIZE(wm8962_snd_controls)); @@ -2466,6 +2466,7 @@ static const int sysclk_rates[] = { static void wm8962_configure_bclk(struct snd_soc_component *component) { + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct wm8962_priv *wm8962 = snd_soc_component_get_drvdata(component); int best, min_diff, diff; int dspclk, i; @@ -2505,7 +2506,7 @@ static void wm8962_configure_bclk(struct snd_soc_component *component) * So we here provisionally enable it and then disable it afterward * if current bias_level hasn't reached SND_SOC_BIAS_ON. */ - if (snd_soc_component_get_bias_level(component) != SND_SOC_BIAS_ON) + if (snd_soc_dapm_get_bias_level(dapm) != SND_SOC_BIAS_ON) snd_soc_component_update_bits(component, WM8962_CLOCKING2, WM8962_SYSCLK_ENA_MASK, WM8962_SYSCLK_ENA); @@ -2519,7 +2520,7 @@ static void wm8962_configure_bclk(struct snd_soc_component *component) usleep_range(500, 1000); dspclk = snd_soc_component_read(component, WM8962_CLOCKING1); - if (snd_soc_component_get_bias_level(component) != SND_SOC_BIAS_ON) + if (snd_soc_dapm_get_bias_level(dapm) != SND_SOC_BIAS_ON) snd_soc_component_update_bits(component, WM8962_CLOCKING2, WM8962_SYSCLK_ENA_MASK, 0); @@ -2579,6 +2580,8 @@ static void wm8962_configure_bclk(struct snd_soc_component *component) static int wm8962_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); + switch (level) { case SND_SOC_BIAS_ON: break; @@ -2596,7 +2599,7 @@ static int wm8962_set_bias_level(struct snd_soc_component *component, snd_soc_component_update_bits(component, WM8962_PWR_MGMT_1, WM8962_VMID_SEL_MASK, 0x100); - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) msleep(100); break; @@ -2629,6 +2632,7 @@ static int wm8962_hw_params(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct snd_soc_component *component = dai->component; + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct wm8962_priv *wm8962 = snd_soc_component_get_drvdata(component); int i; int aif0 = 0; @@ -2679,7 +2683,7 @@ static int wm8962_hw_params(struct snd_pcm_substream *substream, dev_dbg(component->dev, "hw_params set BCLK %dHz LRCLK %dHz\n", wm8962->bclk, wm8962->lrclk); - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_ON) + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_ON) wm8962_configure_bclk(component); return 0; @@ -3193,7 +3197,7 @@ static irqreturn_t wm8962_irq(int irq, void *data) int wm8962_mic_detect(struct snd_soc_component *component, struct snd_soc_jack *jack) { struct wm8962_priv *wm8962 = snd_soc_component_get_drvdata(component); - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); int irq_mask, enable; wm8962->jack = jack; @@ -3239,7 +3243,7 @@ static void wm8962_beep_work(struct work_struct *work) struct wm8962_priv *wm8962 = container_of(work, struct wm8962_priv, beep_work); struct snd_soc_component *component = wm8962->component; - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); int i; int reg = 0; int best = 0; @@ -3488,7 +3492,7 @@ static void wm8962_free_gpio(struct snd_soc_component *component) static int wm8962_probe(struct snd_soc_component *component) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); int ret; struct wm8962_priv *wm8962 = snd_soc_component_get_drvdata(component); int i; @@ -3543,7 +3547,7 @@ static int wm8962_probe(struct snd_soc_component *component) } if (!dmicclk || !dmicdat) { dev_dbg(component->dev, "DMIC not in use, disabling\n"); - snd_soc_dapm_nc_pin(dapm, "DMICDAT"); + snd_soc_dapm_disable_pin(dapm, "DMICDAT"); } if (dmicclk != dmicdat) dev_warn(component->dev, "DMIC GPIOs partially configured\n"); diff --git a/sound/soc/codecs/wm8971.c b/sound/soc/codecs/wm8971.c index 62dcddeb78b324..46aa556b44fa76 100644 --- a/sound/soc/codecs/wm8971.c +++ b/sound/soc/codecs/wm8971.c @@ -561,6 +561,7 @@ static int wm8971_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { struct wm8971_priv *wm8971 = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); u16 pwr_reg = snd_soc_component_read(component, WM8971_PWR1) & 0xfe3e; switch (level) { @@ -573,7 +574,7 @@ static int wm8971_set_bias_level(struct snd_soc_component *component, flush_delayed_work(&wm8971->charge_work); break; case SND_SOC_BIAS_STANDBY: - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) { snd_soc_component_cache_sync(component); /* charge output caps - set vmid to 5k for quick power up */ snd_soc_component_write(component, WM8971_PWR1, pwr_reg | 0x01c0); diff --git a/sound/soc/codecs/wm8974.c b/sound/soc/codecs/wm8974.c index db16d893a23514..0bb5e947f46dcb 100644 --- a/sound/soc/codecs/wm8974.c +++ b/sound/soc/codecs/wm8974.c @@ -583,6 +583,7 @@ static int wm8974_mute(struct snd_soc_dai *dai, int mute, int direction) static int wm8974_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); u16 power1 = snd_soc_component_read(component, WM8974_POWER1) & ~0x3; switch (level) { @@ -595,7 +596,7 @@ static int wm8974_set_bias_level(struct snd_soc_component *component, case SND_SOC_BIAS_STANDBY: power1 |= WM8974_POWER1_BIASEN | WM8974_POWER1_BUFIOEN; - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) { regcache_sync(dev_get_regmap(component->dev, NULL)); /* Initial cap charge at VMID 5k */ diff --git a/sound/soc/codecs/wm8978.c b/sound/soc/codecs/wm8978.c index 8c45ba6fc4c3ab..935761e5086504 100644 --- a/sound/soc/codecs/wm8978.c +++ b/sound/soc/codecs/wm8978.c @@ -853,6 +853,7 @@ static int wm8978_mute(struct snd_soc_dai *dai, int mute, int direction) static int wm8978_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); u16 power1 = snd_soc_component_read(component, WM8978_POWER_MANAGEMENT_1) & ~3; switch (level) { @@ -865,7 +866,7 @@ static int wm8978_set_bias_level(struct snd_soc_component *component, /* bit 3: enable bias, bit 2: enable I/O tie off buffer */ power1 |= 0xc; - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) { /* Initial cap charge at VMID 5k */ snd_soc_component_write(component, WM8978_POWER_MANAGEMENT_1, power1 | 0x3); @@ -924,8 +925,9 @@ static struct snd_soc_dai_driver wm8978_dai = { static int wm8978_suspend(struct snd_soc_component *component) { struct wm8978_priv *wm8978 = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); - snd_soc_component_force_bias_level(component, SND_SOC_BIAS_OFF); + snd_soc_dapm_force_bias_level(dapm, SND_SOC_BIAS_OFF); /* Also switch PLL off */ snd_soc_component_write(component, WM8978_POWER_MANAGEMENT_1, 0); @@ -937,11 +939,12 @@ static int wm8978_suspend(struct snd_soc_component *component) static int wm8978_resume(struct snd_soc_component *component) { struct wm8978_priv *wm8978 = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); /* Sync reg_cache with the hardware */ regcache_sync(wm8978->regmap); - snd_soc_component_force_bias_level(component, SND_SOC_BIAS_STANDBY); + snd_soc_dapm_force_bias_level(dapm, SND_SOC_BIAS_STANDBY); if (wm8978->f_pllout) /* Switch PLL on */ diff --git a/sound/soc/codecs/wm8983.c b/sound/soc/codecs/wm8983.c index c9e516f17c3636..cd34f71cf42aec 100644 --- a/sound/soc/codecs/wm8983.c +++ b/sound/soc/codecs/wm8983.c @@ -848,6 +848,7 @@ static int wm8983_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { struct wm8983_priv *wm8983 = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); int ret; switch (level) { @@ -859,7 +860,7 @@ static int wm8983_set_bias_level(struct snd_soc_component *component, 1 << WM8983_VMIDSEL_SHIFT); break; case SND_SOC_BIAS_STANDBY: - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) { ret = regcache_sync(wm8983->regmap); if (ret < 0) { dev_err(component->dev, "Failed to sync cache: %d\n", ret); diff --git a/sound/soc/codecs/wm8985.c b/sound/soc/codecs/wm8985.c index b8b161c777ec48..be23c0c608d142 100644 --- a/sound/soc/codecs/wm8985.c +++ b/sound/soc/codecs/wm8985.c @@ -564,7 +564,7 @@ static const struct snd_soc_dapm_route wm8985_aux_dapm_routes[] = { static int wm8985_add_widgets(struct snd_soc_component *component) { struct wm8985_priv *wm8985 = snd_soc_component_get_drvdata(component); - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); switch (wm8985->dev_type) { case WM8758: @@ -948,6 +948,7 @@ static int wm8985_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { int ret; + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct wm8985_priv *wm8985; wm8985 = snd_soc_component_get_drvdata(component); @@ -960,7 +961,7 @@ static int wm8985_set_bias_level(struct snd_soc_component *component, 1 << WM8985_VMIDSEL_SHIFT); break; case SND_SOC_BIAS_STANDBY: - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) { ret = regulator_bulk_enable(ARRAY_SIZE(wm8985->supplies), wm8985->supplies); if (ret) { diff --git a/sound/soc/codecs/wm8988.c b/sound/soc/codecs/wm8988.c index cf6d642b7bfea8..9bffe7a6ccecf6 100644 --- a/sound/soc/codecs/wm8988.c +++ b/sound/soc/codecs/wm8988.c @@ -723,6 +723,7 @@ static int wm8988_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { struct wm8988_priv *wm8988 = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); u16 pwr_reg = snd_soc_component_read(component, WM8988_PWR1) & ~0x1c1; switch (level) { @@ -735,7 +736,7 @@ static int wm8988_set_bias_level(struct snd_soc_component *component, break; case SND_SOC_BIAS_STANDBY: - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) { regcache_sync(wm8988->regmap); /* VREF, VMID=2x5k */ diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c index 081876f7c73ee1..9f2b42025ec9fb 100644 --- a/sound/soc/codecs/wm8990.c +++ b/sound/soc/codecs/wm8990.c @@ -1017,6 +1017,7 @@ static int wm8990_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { struct wm8990_priv *wm8990 = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); int ret; switch (level) { @@ -1030,7 +1031,7 @@ static int wm8990_set_bias_level(struct snd_soc_component *component, break; case SND_SOC_BIAS_STANDBY: - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) { ret = regcache_sync(wm8990->regmap); if (ret < 0) { dev_err(component->dev, "Failed to sync cache: %d\n", ret); @@ -1184,10 +1185,12 @@ static struct snd_soc_dai_driver wm8990_dai = { */ static int wm8990_probe(struct snd_soc_component *component) { + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); + wm8990_reset(component); /* charge output caps */ - snd_soc_component_force_bias_level(component, SND_SOC_BIAS_STANDBY); + snd_soc_dapm_force_bias_level(dapm, SND_SOC_BIAS_STANDBY); snd_soc_component_update_bits(component, WM8990_AUDIO_INTERFACE_4, WM8990_ALRCGPIO1, WM8990_ALRCGPIO1); diff --git a/sound/soc/codecs/wm8991.c b/sound/soc/codecs/wm8991.c index 0ab0a50340b1d5..b8ed2a3e699b1c 100644 --- a/sound/soc/codecs/wm8991.c +++ b/sound/soc/codecs/wm8991.c @@ -1081,6 +1081,7 @@ static int wm8991_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { struct wm8991_priv *wm8991 = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); u16 val; switch (level) { @@ -1095,7 +1096,7 @@ static int wm8991_set_bias_level(struct snd_soc_component *component, break; case SND_SOC_BIAS_STANDBY: - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) { regcache_sync(wm8991->regmap); /* Enable all output discharge bits */ snd_soc_component_write(component, WM8991_ANTIPOP1, WM8991_DIS_LLINE | diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c index 75d923c2c9cac8..1c9299979898bb 100644 --- a/sound/soc/codecs/wm8993.c +++ b/sound/soc/codecs/wm8993.c @@ -973,6 +973,7 @@ static int wm8993_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { struct wm8993_priv *wm8993 = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); int ret; wm_hubs_set_bias_level(component, level); @@ -988,7 +989,7 @@ static int wm8993_set_bias_level(struct snd_soc_component *component, break; case SND_SOC_BIAS_STANDBY: - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) { ret = regulator_bulk_enable(ARRAY_SIZE(wm8993->supplies), wm8993->supplies); if (ret != 0) @@ -1482,7 +1483,7 @@ static struct snd_soc_dai_driver wm8993_dai = { static int wm8993_probe(struct snd_soc_component *component) { struct wm8993_priv *wm8993 = snd_soc_component_get_drvdata(component); - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); wm8993->hubs_data.hp_startup_mode = 1; wm8993->hubs_data.dcs_codes_l = -2; @@ -1536,7 +1537,7 @@ static int wm8993_probe(struct snd_soc_component *component) * VMID as an output and can disable it. */ if (wm8993->pdata.lineout1_diff && wm8993->pdata.lineout2_diff) - dapm->idle_bias = false; + snd_soc_dapm_set_idle_bias(dapm, false); return 0; @@ -1546,6 +1547,7 @@ static int wm8993_probe(struct snd_soc_component *component) static int wm8993_suspend(struct snd_soc_component *component) { struct wm8993_priv *wm8993 = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); int fll_fout = wm8993->fll_fout; int fll_fref = wm8993->fll_fref; int ret; @@ -1560,7 +1562,7 @@ static int wm8993_suspend(struct snd_soc_component *component) wm8993->fll_fout = fll_fout; wm8993->fll_fref = fll_fref; - snd_soc_component_force_bias_level(component, SND_SOC_BIAS_OFF); + snd_soc_dapm_force_bias_level(dapm, SND_SOC_BIAS_OFF); return 0; } @@ -1568,9 +1570,10 @@ static int wm8993_suspend(struct snd_soc_component *component) static int wm8993_resume(struct snd_soc_component *component) { struct wm8993_priv *wm8993 = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); int ret; - snd_soc_component_force_bias_level(component, SND_SOC_BIAS_STANDBY); + snd_soc_dapm_force_bias_level(dapm, SND_SOC_BIAS_STANDBY); /* Restart the FLL? */ if (wm8993->fll_fout) { diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 616d7d7e50aa71..1d64c7c42ed122 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -214,7 +214,7 @@ static int configure_aif_clock(struct snd_soc_component *component, int aif) static int configure_clock(struct snd_soc_component *component) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component); int change, new; @@ -1515,7 +1515,7 @@ SOC_DAPM_SINGLE("AIF1.1 Switch", WM8994_DAC2_RIGHT_MIXER_ROUTING, static int wm8994_put_class_w(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_component *component = snd_soc_dapm_kcontrol_component(kcontrol); + struct snd_soc_component *component = snd_soc_dapm_kcontrol_to_component(kcontrol); int ret; ret = snd_soc_dapm_put_volsw(kcontrol, ucontrol); @@ -2615,6 +2615,7 @@ static int wm8994_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct wm8994 *control = wm8994->wm8994; wm_hubs_set_bias_level(component, level); @@ -2637,12 +2638,12 @@ static int wm8994_set_bias_level(struct snd_soc_component *component, break; } - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_STANDBY) + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_STANDBY) active_reference(component); break; case SND_SOC_BIAS_STANDBY: - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) { switch (control->type) { case WM8958: if (control->revision == 0) { @@ -2666,7 +2667,7 @@ static int wm8994_set_bias_level(struct snd_soc_component *component, WM8994_LINEOUT2_DISCH); } - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_PREPARE) + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_PREPARE) active_dereference(component); /* MICBIAS into bypass mode on newer devices */ @@ -2686,7 +2687,7 @@ static int wm8994_set_bias_level(struct snd_soc_component *component, break; case SND_SOC_BIAS_OFF: - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_STANDBY) + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_STANDBY) wm8994->cur_fw = NULL; break; } @@ -2697,7 +2698,7 @@ static int wm8994_set_bias_level(struct snd_soc_component *component, int wm8994_vmid_mode(struct snd_soc_component *component, enum wm8994_vmid_mode mode) { struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component); - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); switch (mode) { case WM8994_VMID_NORMAL: @@ -3299,6 +3300,7 @@ static struct snd_soc_dai_driver wm8994_dai[] = { static int wm8994_component_suspend(struct snd_soc_component *component) { struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); int i, ret; for (i = 0; i < ARRAY_SIZE(wm8994->fll); i++) { @@ -3310,7 +3312,7 @@ static int wm8994_component_suspend(struct snd_soc_component *component) i + 1, ret); } - snd_soc_component_force_bias_level(component, SND_SOC_BIAS_OFF); + snd_soc_dapm_force_bias_level(dapm, SND_SOC_BIAS_OFF); return 0; } @@ -3503,7 +3505,7 @@ static void wm8994_handle_pdata(struct wm8994_priv *wm8994) int wm8994_mic_detect(struct snd_soc_component *component, struct snd_soc_jack *jack, int micbias) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component); struct wm8994_micdet *micdet; struct wm8994 *control = wm8994->wm8994; @@ -3653,7 +3655,7 @@ static irqreturn_t wm8994_mic_irq(int irq, void *data) /* Should be called with accdet_lock held */ static void wm1811_micd_stop(struct snd_soc_component *component) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component); if (!wm8994->jackdet) @@ -3773,7 +3775,7 @@ static void wm1811_mic_work(struct work_struct *work) mic_work.work); struct wm8994 *control = wm8994->wm8994; struct snd_soc_component *component = wm8994->hubs.component; - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); pm_runtime_get_sync(component->dev); @@ -3812,7 +3814,7 @@ static irqreturn_t wm1811_jackdet_irq(int irq, void *data) struct wm8994_priv *wm8994 = data; struct wm8994 *control = wm8994->wm8994; struct snd_soc_component *component = wm8994->hubs.component; - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); int reg, delay; bool present; @@ -3928,7 +3930,7 @@ int wm8958_mic_detect(struct snd_soc_component *component, struct snd_soc_jack * wm1811_micdet_cb det_cb, void *det_cb_data, wm1811_mic_id_cb id_cb, void *id_cb_data) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component); struct wm8994 *control = wm8994->wm8994; u16 micd_lvl_sel; @@ -3980,7 +3982,7 @@ int wm8958_mic_detect(struct snd_soc_component *component, struct snd_soc_jack * snd_soc_component_update_bits(component, WM8958_MIC_DETECT_2, WM8958_MICD_LVL_SEL_MASK, micd_lvl_sel); - WARN_ON(snd_soc_component_get_bias_level(component) > SND_SOC_BIAS_STANDBY); + WARN_ON(snd_soc_dapm_get_bias_level(dapm) > SND_SOC_BIAS_STANDBY); /* * If we can use jack detection start off with that, @@ -4148,7 +4150,7 @@ static irqreturn_t wm8994_temp_shut(int irq, void *data) static int wm8994_component_probe(struct snd_soc_component *component) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct wm8994 *control = dev_get_drvdata(component->dev->parent); struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component); unsigned int reg; @@ -4183,7 +4185,7 @@ static int wm8994_component_probe(struct snd_soc_component *component) wm8994->micdet_irq = control->pdata.micdet_irq; /* By default use idle_bias false, will override for WM8994 */ - dapm->idle_bias = false; + snd_soc_dapm_set_idle_bias(dapm, false); /* Set revision-specific configuration */ switch (control->type) { @@ -4191,7 +4193,7 @@ static int wm8994_component_probe(struct snd_soc_component *component) /* Single ended line outputs should have VMID on. */ if (!control->pdata.lineout1_diff || !control->pdata.lineout2_diff) - dapm->idle_bias = true; + snd_soc_dapm_set_idle_bias(dapm, true); switch (control->revision) { case 2: diff --git a/sound/soc/codecs/wm8995.c b/sound/soc/codecs/wm8995.c index a88170a3ed914d..104ce09c02e05e 100644 --- a/sound/soc/codecs/wm8995.c +++ b/sound/soc/codecs/wm8995.c @@ -547,7 +547,7 @@ static int check_clk_sys(struct snd_soc_dapm_widget *source, static int wm8995_put_class_w(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_component *component = snd_soc_dapm_kcontrol_component(kcontrol); + struct snd_soc_component *component = snd_soc_dapm_kcontrol_to_component(kcontrol); int ret; ret = snd_soc_dapm_put_volsw(kcontrol, ucontrol); @@ -718,7 +718,7 @@ static int configure_aif_clock(struct snd_soc_component *component, int aif) static int configure_clock(struct snd_soc_component *component) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct wm8995_priv *wm8995; int change, new; @@ -1955,6 +1955,7 @@ static int wm8995_set_dai_sysclk(struct snd_soc_dai *dai, static int wm8995_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct wm8995_priv *wm8995; int ret; @@ -1964,7 +1965,7 @@ static int wm8995_set_bias_level(struct snd_soc_component *component, case SND_SOC_BIAS_PREPARE: break; case SND_SOC_BIAS_STANDBY: - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) { ret = regulator_bulk_enable(ARRAY_SIZE(wm8995->supplies), wm8995->supplies); if (ret) diff --git a/sound/soc/codecs/wm8996.c b/sound/soc/codecs/wm8996.c index 7cc2fb5b811e21..2d9cbf66f7d40d 100644 --- a/sound/soc/codecs/wm8996.c +++ b/sound/soc/codecs/wm8996.c @@ -1572,6 +1572,7 @@ static int wm8996_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { struct wm8996_priv *wm8996 = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); int ret; switch (level) { @@ -1586,7 +1587,7 @@ static int wm8996_set_bias_level(struct snd_soc_component *component, break; case SND_SOC_BIAS_STANDBY: - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) { ret = regulator_bulk_enable(ARRAY_SIZE(wm8996->supplies), wm8996->supplies); if (ret != 0) { @@ -2238,7 +2239,7 @@ int wm8996_detect(struct snd_soc_component *component, struct snd_soc_jack *jack wm8996_polarity_fn polarity_cb) { struct wm8996_priv *wm8996 = snd_soc_component_get_drvdata(component); - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); wm8996->jack = jack; wm8996->detecting = true; @@ -2283,7 +2284,7 @@ EXPORT_SYMBOL_GPL(wm8996_detect); static void wm8996_hpdet_irq(struct snd_soc_component *component) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct wm8996_priv *wm8996 = snd_soc_component_get_drvdata(component); int val, reg, report; @@ -2343,7 +2344,7 @@ static void wm8996_hpdet_irq(struct snd_soc_component *component) static void wm8996_hpdet_start(struct snd_soc_component *component) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); /* Unclamp the output, we can't measure while we're shorting it */ snd_soc_component_update_bits(component, WM8996_ANALOGUE_HP_1, diff --git a/sound/soc/codecs/wm8997.c b/sound/soc/codecs/wm8997.c index 5389c363b14e0a..83106523385a5a 100644 --- a/sound/soc/codecs/wm8997.c +++ b/sound/soc/codecs/wm8997.c @@ -1055,7 +1055,7 @@ static struct snd_soc_dai_driver wm8997_dai[] = { static int wm8997_component_probe(struct snd_soc_component *component) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct wm8997_priv *priv = snd_soc_component_get_drvdata(component); struct arizona *arizona = priv->core.arizona; int ret; @@ -1066,7 +1066,7 @@ static int wm8997_component_probe(struct snd_soc_component *component) if (ret < 0) return ret; - snd_soc_component_disable_pin(component, "HAPTICS"); + snd_soc_dapm_disable_pin(dapm, "HAPTICS"); priv->core.arizona->dapm = dapm; diff --git a/sound/soc/codecs/wm8998.c b/sound/soc/codecs/wm8998.c index b72b8a64be8fac..8e6f03d00c715a 100644 --- a/sound/soc/codecs/wm8998.c +++ b/sound/soc/codecs/wm8998.c @@ -101,8 +101,8 @@ static int wm8998_asrc_ev(struct snd_soc_dapm_widget *w, static int wm8998_inmux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_component *component = snd_soc_dapm_kcontrol_component(kcontrol); - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_component *component = snd_soc_dapm_kcontrol_to_component(kcontrol); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct wm8998_priv *wm8998 = snd_soc_component_get_drvdata(component); struct arizona *arizona = wm8998->core.arizona; struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; @@ -1279,7 +1279,7 @@ static int wm8998_set_fll(struct snd_soc_component *component, int fll_id, static int wm8998_component_probe(struct snd_soc_component *component) { struct wm8998_priv *priv = snd_soc_component_get_drvdata(component); - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct arizona *arizona = priv->core.arizona; int ret; @@ -1292,7 +1292,7 @@ static int wm8998_component_probe(struct snd_soc_component *component) arizona_init_gpio(component); - snd_soc_component_disable_pin(component, "HAPTICS"); + snd_soc_dapm_disable_pin(dapm, "HAPTICS"); return 0; } diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c index 9b5497a128e863..5bfe43c6c1f409 100644 --- a/sound/soc/codecs/wm9081.c +++ b/sound/soc/codecs/wm9081.c @@ -816,6 +816,7 @@ static int wm9081_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { struct wm9081_priv *wm9081 = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); switch (level) { case SND_SOC_BIAS_ON: @@ -833,7 +834,7 @@ static int wm9081_set_bias_level(struct snd_soc_component *component, case SND_SOC_BIAS_STANDBY: /* Initial cold start */ - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) { regcache_cache_only(wm9081->regmap, false); regcache_sync(wm9081->regmap); diff --git a/sound/soc/codecs/wm9090.c b/sound/soc/codecs/wm9090.c index 26191bcc161deb..5182f0839b7ceb 100644 --- a/sound/soc/codecs/wm9090.c +++ b/sound/soc/codecs/wm9090.c @@ -409,7 +409,7 @@ static const struct snd_soc_dapm_route audio_map_in2_diff[] = { static int wm9090_add_controls(struct snd_soc_component *component) { struct wm9090_priv *wm9090 = snd_soc_component_get_drvdata(component); - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); int i; snd_soc_dapm_new_controls(dapm, wm9090_dapm_widgets, @@ -463,6 +463,7 @@ static int wm9090_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { struct wm9090_priv *wm9090 = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); switch (level) { case SND_SOC_BIAS_ON: @@ -480,7 +481,7 @@ static int wm9090_set_bias_level(struct snd_soc_component *component, break; case SND_SOC_BIAS_STANDBY: - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) { /* Restore the register cache */ regcache_sync(wm9090->regmap); } diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c index 8ff4b5f13b3a4b..83cd42fa0c281c 100644 --- a/sound/soc/codecs/wm9712.c +++ b/sound/soc/codecs/wm9712.c @@ -215,7 +215,7 @@ static const unsigned int wm9712_mixer_mute_regs[] = { static int wm9712_hp_mixer_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol); + struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kcontrol); struct snd_soc_component *component = snd_soc_dapm_to_component(dapm); struct wm9712_priv *wm9712 = snd_soc_component_get_drvdata(component); unsigned int val = ucontrol->value.integer.value[0]; @@ -259,7 +259,7 @@ static int wm9712_hp_mixer_put(struct snd_kcontrol *kcontrol, static int wm9712_hp_mixer_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol); + struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kcontrol); struct snd_soc_component *component = snd_soc_dapm_to_component(dapm); struct wm9712_priv *wm9712 = snd_soc_component_get_drvdata(component); struct soc_mixer_control *mc = @@ -611,6 +611,7 @@ static int wm9712_set_bias_level(struct snd_soc_component *component, static int wm9712_soc_resume(struct snd_soc_component *component) { struct wm9712_priv *wm9712 = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); int ret; ret = snd_ac97_reset(wm9712->ac97, true, WM9712_VENDOR_ID, @@ -618,7 +619,7 @@ static int wm9712_soc_resume(struct snd_soc_component *component) if (ret < 0) return ret; - snd_soc_component_force_bias_level(component, SND_SOC_BIAS_STANDBY); + snd_soc_dapm_force_bias_level(dapm, SND_SOC_BIAS_STANDBY); if (ret == 0) snd_soc_component_cache_sync(component); diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c index 5f1b0f5c1a5886..b3bbecf074eed4 100644 --- a/sound/soc/codecs/wm9713.c +++ b/sound/soc/codecs/wm9713.c @@ -224,7 +224,7 @@ static const unsigned int wm9713_mixer_mute_regs[] = { static int wm9713_hp_mixer_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol); + struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kcontrol); struct snd_soc_component *component = snd_soc_dapm_to_component(dapm); struct wm9713_priv *wm9713 = snd_soc_component_get_drvdata(component); unsigned int val = ucontrol->value.integer.value[0]; @@ -268,7 +268,7 @@ static int wm9713_hp_mixer_put(struct snd_kcontrol *kcontrol, static int wm9713_hp_mixer_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol); + struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kcontrol); struct snd_soc_component *component = snd_soc_dapm_to_component(dapm); struct wm9713_priv *wm9713 = snd_soc_component_get_drvdata(component); struct soc_mixer_control *mc = @@ -1176,6 +1176,7 @@ static int wm9713_soc_suspend(struct snd_soc_component *component) static int wm9713_soc_resume(struct snd_soc_component *component) { struct wm9713_priv *wm9713 = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); int ret; ret = snd_ac97_reset(wm9713->ac97, true, WM9713_VENDOR_ID, @@ -1183,7 +1184,7 @@ static int wm9713_soc_resume(struct snd_soc_component *component) if (ret < 0) return ret; - snd_soc_component_force_bias_level(component, SND_SOC_BIAS_STANDBY); + snd_soc_dapm_force_bias_level(dapm, SND_SOC_BIAS_STANDBY); /* do we need to re-start the PLL ? */ if (wm9713->pll_in) diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index b1b1459073af99..17cec79245d437 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c @@ -953,7 +953,7 @@ int wm_adsp2_preloader_put(struct snd_kcontrol *kcontrol, { struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); struct wm_adsp *dsps = snd_soc_component_get_drvdata(component); - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; struct wm_adsp *dsp = &dsps[mc->shift - 1]; @@ -965,9 +965,9 @@ int wm_adsp2_preloader_put(struct snd_kcontrol *kcontrol, snprintf(preload, ARRAY_SIZE(preload), "%s Preload", dsp->cs_dsp.name); if (ucontrol->value.integer.value[0] || dsp->toggle_preload) - snd_soc_component_force_enable_pin(component, preload); + snd_soc_dapm_force_enable_pin(dapm, preload); else - snd_soc_component_disable_pin(component, preload); + snd_soc_dapm_disable_pin(dapm, preload); snd_soc_dapm_sync(dapm); @@ -976,7 +976,7 @@ int wm_adsp2_preloader_put(struct snd_kcontrol *kcontrol, dsp->preloaded = ucontrol->value.integer.value[0]; if (dsp->toggle_preload) { - snd_soc_component_disable_pin(component, preload); + snd_soc_dapm_disable_pin(dapm, preload); snd_soc_dapm_sync(dapm); } @@ -1121,11 +1121,12 @@ EXPORT_SYMBOL_GPL(wm_adsp_event); int wm_adsp2_component_probe(struct wm_adsp *dsp, struct snd_soc_component *component) { + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); char preload[32]; if (!dsp->cs_dsp.no_core_startstop) { snprintf(preload, ARRAY_SIZE(preload), "%s Preload", dsp->cs_dsp.name); - snd_soc_component_disable_pin(component, preload); + snd_soc_dapm_disable_pin(dapm, preload); } cs_dsp_init_debugfs(&dsp->cs_dsp, component->debugfs_root); @@ -1560,7 +1561,7 @@ static int wm_adsp_buffer_parse_coeff(struct cs_dsp_coeff_ctl *cs_ctl) for (i = 0; i < 5; ++i) { ret = cs_dsp_coeff_read_ctrl(cs_ctl, 0, &coeff_v1, - min(cs_ctl->len, sizeof(coeff_v1))); + min((size_t)cs_ctl->len, sizeof(coeff_v1))); if (ret < 0) return ret; diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c index ecc4835a7ecd5f..f80dfc488e3ce8 100644 --- a/sound/soc/codecs/wm_hubs.c +++ b/sound/soc/codecs/wm_hubs.c @@ -694,7 +694,7 @@ EXPORT_SYMBOL_GPL(wm_hubs_update_class_w); static int class_w_put_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_component *component = snd_soc_dapm_kcontrol_component(kcontrol); + struct snd_soc_component *component = snd_soc_dapm_kcontrol_to_component(kcontrol); int ret; ret = snd_soc_dapm_put_volsw(kcontrol, ucontrol); @@ -714,7 +714,7 @@ static int class_w_put_volsw(struct snd_kcontrol *kcontrol, static int class_w_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_component *component = snd_soc_dapm_kcontrol_component(kcontrol); + struct snd_soc_component *component = snd_soc_dapm_kcontrol_to_component(kcontrol); int ret; ret = snd_soc_dapm_put_enum_double(kcontrol, ucontrol); @@ -1112,7 +1112,7 @@ static const struct snd_soc_dapm_route lineout2_se_routes[] = { int wm_hubs_add_analogue_controls(struct snd_soc_component *component) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); /* Latch volume update bits & default ZC on */ snd_soc_component_update_bits(component, WM8993_LEFT_LINE_INPUT_1_2_VOLUME, @@ -1156,7 +1156,7 @@ int wm_hubs_add_analogue_routes(struct snd_soc_component *component, int lineout1_diff, int lineout2_diff) { struct wm_hubs_data *hubs = snd_soc_component_get_drvdata(component); - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); hubs->component = component; diff --git a/sound/soc/codecs/wsa881x.c b/sound/soc/codecs/wsa881x.c index e249de7f91d91f..d7aca6567c2de1 100644 --- a/sound/soc/codecs/wsa881x.c +++ b/sound/soc/codecs/wsa881x.c @@ -1112,8 +1112,7 @@ static int wsa881x_probe(struct sdw_slave *pdev, if (!wsa881x) return -ENOMEM; - wsa881x->sd_n = devm_gpiod_get_optional(dev, "powerdown", - GPIOD_FLAGS_BIT_NONEXCLUSIVE); + wsa881x->sd_n = devm_gpiod_get_optional(dev, "powerdown", 0); if (IS_ERR(wsa881x->sd_n)) return dev_err_probe(dev, PTR_ERR(wsa881x->sd_n), "Shutdown Control GPIO not found\n"); diff --git a/sound/soc/codecs/wsa883x.c b/sound/soc/codecs/wsa883x.c index 96dd66c4b88dea..c3046e260cb958 100644 --- a/sound/soc/codecs/wsa883x.c +++ b/sound/soc/codecs/wsa883x.c @@ -1572,13 +1572,10 @@ static int wsa883x_get_reset(struct device *dev, struct wsa883x_priv *wsa883x) if (IS_ERR(wsa883x->sd_reset)) return dev_err_probe(dev, PTR_ERR(wsa883x->sd_reset), "Failed to get reset\n"); - /* - * if sd_reset: NULL, so use the backwards compatible way for powerdown-gpios, - * which does not handle sharing GPIO properly. - */ + + /* if sd_reset: NULL, so use the backwards compatible way for powerdown-gpios */ if (!wsa883x->sd_reset) { wsa883x->sd_n = devm_gpiod_get_optional(dev, "powerdown", - GPIOD_FLAGS_BIT_NONEXCLUSIVE | GPIOD_OUT_HIGH); if (IS_ERR(wsa883x->sd_n)) return dev_err_probe(dev, PTR_ERR(wsa883x->sd_n), diff --git a/sound/soc/fsl/fsl-asoc-card.c b/sound/soc/fsl/fsl-asoc-card.c index 71113886e494b9..2c7eb0baa0f361 100644 --- a/sound/soc/fsl/fsl-asoc-card.c +++ b/sound/soc/fsl/fsl-asoc-card.c @@ -536,7 +536,7 @@ static int hp_jack_event(struct notifier_block *nb, unsigned long event, void *data) { struct snd_soc_jack *jack = (struct snd_soc_jack *)data; - struct snd_soc_dapm_context *dapm = &jack->card->dapm; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(jack->card); if (event & SND_JACK_HEADPHONE) /* Disable speaker if headphone is plugged in */ @@ -553,7 +553,7 @@ static int mic_jack_event(struct notifier_block *nb, unsigned long event, void *data) { struct snd_soc_jack *jack = (struct snd_soc_jack *)data; - struct snd_soc_dapm_context *dapm = &jack->card->dapm; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(jack->card); if (event & SND_JACK_MICROPHONE) /* Disable dmic if microphone is plugged in */ diff --git a/sound/soc/fsl/fsl_micfil.c b/sound/soc/fsl/fsl_micfil.c index 1ea543863101e3..d6cde2757c6d55 100644 --- a/sound/soc/fsl/fsl_micfil.c +++ b/sound/soc/fsl/fsl_micfil.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -92,6 +93,9 @@ struct fsl_micfil_soc_data { bool volume_sx; u64 formats; int fifo_offset; + enum quality default_quality; + /* stores const value in formula to calculate range */ + int rangeadj_const[3][2]; }; static struct fsl_micfil_soc_data fsl_micfil_imx8mm = { @@ -102,6 +106,7 @@ static struct fsl_micfil_soc_data fsl_micfil_imx8mm = { .formats = SNDRV_PCM_FMTBIT_S16_LE, .volume_sx = true, .fifo_offset = 0, + .default_quality = QUALITY_VLOW0, }; static struct fsl_micfil_soc_data fsl_micfil_imx8mp = { @@ -112,6 +117,8 @@ static struct fsl_micfil_soc_data fsl_micfil_imx8mp = { .formats = SNDRV_PCM_FMTBIT_S32_LE, .volume_sx = false, .fifo_offset = 0, + .default_quality = QUALITY_MEDIUM, + .rangeadj_const = {{27, 7}, {27, 7}, {26, 7}}, }; static struct fsl_micfil_soc_data fsl_micfil_imx93 = { @@ -124,6 +131,8 @@ static struct fsl_micfil_soc_data fsl_micfil_imx93 = { .use_verid = true, .volume_sx = false, .fifo_offset = 0, + .default_quality = QUALITY_MEDIUM, + .rangeadj_const = {{30, 6}, {30, 6}, {29, 6}}, }; static struct fsl_micfil_soc_data fsl_micfil_imx943 = { @@ -136,6 +145,8 @@ static struct fsl_micfil_soc_data fsl_micfil_imx943 = { .use_verid = true, .volume_sx = false, .fifo_offset = -4, + .default_quality = QUALITY_MEDIUM, + .rangeadj_const = {{34, 6}, {34, 6}, {33, 6}}, }; static const struct of_device_id fsl_micfil_dt_ids[] = { @@ -162,9 +173,69 @@ static const struct soc_enum fsl_micfil_quality_enum = static DECLARE_TLV_DB_SCALE(gain_tlv, 0, 100, 0); +static int micfil_get_max_range(struct fsl_micfil *micfil) +{ + int max_range; + + switch (micfil->quality) { + case QUALITY_HIGH: + case QUALITY_VLOW0: + max_range = micfil->soc->rangeadj_const[0][0] - micfil->soc->rangeadj_const[0][1] * + ilog2(2 * MICFIL_OSR_DEFAULT); + break; + case QUALITY_MEDIUM: + case QUALITY_VLOW1: + max_range = micfil->soc->rangeadj_const[1][0] - micfil->soc->rangeadj_const[1][1] * + ilog2(MICFIL_OSR_DEFAULT); + break; + case QUALITY_LOW: + case QUALITY_VLOW2: + max_range = micfil->soc->rangeadj_const[2][0] - micfil->soc->rangeadj_const[2][1] * + ilog2(MICFIL_OSR_DEFAULT); + break; + default: + return 0; + } + max_range = max_range < 0 ? 0 : max_range; + + return max_range; +} + +static int micfil_range_set(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *cmpnt = snd_kcontrol_chip(kcontrol); + struct fsl_micfil *micfil = snd_soc_component_get_drvdata(cmpnt); + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + unsigned int shift = mc->shift; + int max_range, new_range; + + new_range = ucontrol->value.integer.value[0]; + max_range = micfil_get_max_range(micfil); + if (new_range > max_range) + dev_warn(&micfil->pdev->dev, "range makes channel %d data unreliable\n", shift / 4); + + regmap_update_bits(micfil->regmap, REG_MICFIL_OUT_CTRL, 0xF << shift, new_range << shift); + + return 0; +} + static int micfil_set_quality(struct fsl_micfil *micfil) { - u32 qsel; + int range, max_range; + u32 qsel, val; + int i; + + if (!micfil->soc->volume_sx) { + regmap_read(micfil->regmap, REG_MICFIL_OUT_CTRL, &val); + max_range = micfil_get_max_range(micfil); + for (i = 0; i < micfil->soc->fifos; i++) { + range = (val >> MICFIL_OUTGAIN_CHX_SHIFT(i)) & 0xF; + if (range > max_range) + dev_warn(&micfil->pdev->dev, "please reset channel %d range\n", i); + } + } switch (micfil->quality) { case QUALITY_HIGH: @@ -362,23 +433,31 @@ static int hwvad_detected(struct snd_kcontrol *kcontrol, return 0; } -static const struct snd_kcontrol_new fsl_micfil_volume_controls[] = { - SOC_SINGLE_TLV("CH0 Volume", REG_MICFIL_OUT_CTRL, - MICFIL_OUTGAIN_CHX_SHIFT(0), 0xF, 0, gain_tlv), - SOC_SINGLE_TLV("CH1 Volume", REG_MICFIL_OUT_CTRL, - MICFIL_OUTGAIN_CHX_SHIFT(1), 0xF, 0, gain_tlv), - SOC_SINGLE_TLV("CH2 Volume", REG_MICFIL_OUT_CTRL, - MICFIL_OUTGAIN_CHX_SHIFT(2), 0xF, 0, gain_tlv), - SOC_SINGLE_TLV("CH3 Volume", REG_MICFIL_OUT_CTRL, - MICFIL_OUTGAIN_CHX_SHIFT(3), 0xF, 0, gain_tlv), - SOC_SINGLE_TLV("CH4 Volume", REG_MICFIL_OUT_CTRL, - MICFIL_OUTGAIN_CHX_SHIFT(4), 0xF, 0, gain_tlv), - SOC_SINGLE_TLV("CH5 Volume", REG_MICFIL_OUT_CTRL, - MICFIL_OUTGAIN_CHX_SHIFT(5), 0xF, 0, gain_tlv), - SOC_SINGLE_TLV("CH6 Volume", REG_MICFIL_OUT_CTRL, - MICFIL_OUTGAIN_CHX_SHIFT(6), 0xF, 0, gain_tlv), - SOC_SINGLE_TLV("CH7 Volume", REG_MICFIL_OUT_CTRL, - MICFIL_OUTGAIN_CHX_SHIFT(7), 0xF, 0, gain_tlv), +static const struct snd_kcontrol_new fsl_micfil_range_controls[] = { + SOC_SINGLE_EXT("CH0 Range", REG_MICFIL_OUT_CTRL, + MICFIL_OUTGAIN_CHX_SHIFT(0), 0xF, 0, + snd_soc_get_volsw, micfil_range_set), + SOC_SINGLE_EXT("CH1 Range", REG_MICFIL_OUT_CTRL, + MICFIL_OUTGAIN_CHX_SHIFT(1), 0xF, 0, + snd_soc_get_volsw, micfil_range_set), + SOC_SINGLE_EXT("CH2 Range", REG_MICFIL_OUT_CTRL, + MICFIL_OUTGAIN_CHX_SHIFT(2), 0xF, 0, + snd_soc_get_volsw, micfil_range_set), + SOC_SINGLE_EXT("CH3 Range", REG_MICFIL_OUT_CTRL, + MICFIL_OUTGAIN_CHX_SHIFT(3), 0xF, 0, + snd_soc_get_volsw, micfil_range_set), + SOC_SINGLE_EXT("CH4 Range", REG_MICFIL_OUT_CTRL, + MICFIL_OUTGAIN_CHX_SHIFT(4), 0xF, 0, + snd_soc_get_volsw, micfil_range_set), + SOC_SINGLE_EXT("CH5 Range", REG_MICFIL_OUT_CTRL, + MICFIL_OUTGAIN_CHX_SHIFT(5), 0xF, 0, + snd_soc_get_volsw, micfil_range_set), + SOC_SINGLE_EXT("CH6 Range", REG_MICFIL_OUT_CTRL, + MICFIL_OUTGAIN_CHX_SHIFT(6), 0xF, 0, + snd_soc_get_volsw, micfil_range_set), + SOC_SINGLE_EXT("CH7 Range", REG_MICFIL_OUT_CTRL, + MICFIL_OUTGAIN_CHX_SHIFT(7), 0xF, 0, + snd_soc_get_volsw, micfil_range_set), }; static const struct snd_kcontrol_new fsl_micfil_volume_sx_controls[] = { @@ -890,13 +969,20 @@ static int fsl_micfil_dai_probe(struct snd_soc_dai *cpu_dai) struct fsl_micfil *micfil = dev_get_drvdata(cpu_dai->dev); struct device *dev = cpu_dai->dev; unsigned int val = 0; - int ret, i; + int ret, i, max_range; - micfil->quality = QUALITY_VLOW0; + micfil->quality = micfil->soc->default_quality; micfil->card = cpu_dai->component->card; /* set default gain to 2 */ - regmap_write(micfil->regmap, REG_MICFIL_OUT_CTRL, 0x22222222); + if (micfil->soc->volume_sx) { + regmap_write(micfil->regmap, REG_MICFIL_OUT_CTRL, 0x22222222); + } else { + max_range = micfil_get_max_range(micfil); + for (i = 1; i < micfil->soc->fifos; i++) + max_range |= max_range << 4; + regmap_write(micfil->regmap, REG_MICFIL_OUT_CTRL, max_range); + } /* set DC Remover in bypass mode*/ for (i = 0; i < MICFIL_OUTPUT_CHANNELS; i++) @@ -930,8 +1016,8 @@ static int fsl_micfil_component_probe(struct snd_soc_component *component) snd_soc_add_component_controls(component, fsl_micfil_volume_sx_controls, ARRAY_SIZE(fsl_micfil_volume_sx_controls)); else - snd_soc_add_component_controls(component, fsl_micfil_volume_controls, - ARRAY_SIZE(fsl_micfil_volume_controls)); + snd_soc_add_component_controls(component, fsl_micfil_range_controls, + ARRAY_SIZE(fsl_micfil_range_controls)); return 0; } diff --git a/sound/soc/fsl/fsl_xcvr.c b/sound/soc/fsl/fsl_xcvr.c index 5d804860f7d8c8..06434b2c9a0fb0 100644 --- a/sound/soc/fsl/fsl_xcvr.c +++ b/sound/soc/fsl/fsl_xcvr.c @@ -1421,7 +1421,7 @@ static irqreturn_t irq0_isr(int irq, void *devid) bitrev32(val); } /* clear CS control register */ - memset_io(reg_ctrl, 0, sizeof(val)); + writel_relaxed(0, reg_ctrl); } } else { regmap_read(xcvr->regmap, FSL_XCVR_RX_CS_DATA_0, @@ -1548,28 +1548,24 @@ static int fsl_xcvr_probe(struct platform_device *pdev) xcvr->soc_data = of_device_get_match_data(&pdev->dev); xcvr->ipg_clk = devm_clk_get(dev, "ipg"); - if (IS_ERR(xcvr->ipg_clk)) { - dev_err(dev, "failed to get ipg clock\n"); - return PTR_ERR(xcvr->ipg_clk); - } + if (IS_ERR(xcvr->ipg_clk)) + return dev_err_probe(dev, PTR_ERR(xcvr->ipg_clk), + "failed to get ipg clock\n"); xcvr->phy_clk = devm_clk_get(dev, "phy"); - if (IS_ERR(xcvr->phy_clk)) { - dev_err(dev, "failed to get phy clock\n"); - return PTR_ERR(xcvr->phy_clk); - } + if (IS_ERR(xcvr->phy_clk)) + return dev_err_probe(dev, PTR_ERR(xcvr->phy_clk), + "failed to get phy clock\n"); xcvr->spba_clk = devm_clk_get(dev, "spba"); - if (IS_ERR(xcvr->spba_clk)) { - dev_err(dev, "failed to get spba clock\n"); - return PTR_ERR(xcvr->spba_clk); - } + if (IS_ERR(xcvr->spba_clk)) + return dev_err_probe(dev, PTR_ERR(xcvr->spba_clk), + "failed to get spba clock\n"); xcvr->pll_ipg_clk = devm_clk_get(dev, "pll_ipg"); - if (IS_ERR(xcvr->pll_ipg_clk)) { - dev_err(dev, "failed to get pll_ipg clock\n"); - return PTR_ERR(xcvr->pll_ipg_clk); - } + if (IS_ERR(xcvr->pll_ipg_clk)) + return dev_err_probe(dev, PTR_ERR(xcvr->pll_ipg_clk), + "failed to get pll_ipg clock\n"); fsl_asoc_get_pll_clocks(dev, &xcvr->pll8k_clk, &xcvr->pll11k_clk); @@ -1593,51 +1589,42 @@ static int fsl_xcvr_probe(struct platform_device *pdev) xcvr->regmap = devm_regmap_init_mmio_clk(dev, NULL, regs, &fsl_xcvr_regmap_cfg); - if (IS_ERR(xcvr->regmap)) { - dev_err(dev, "failed to init XCVR regmap: %ld\n", - PTR_ERR(xcvr->regmap)); - return PTR_ERR(xcvr->regmap); - } + if (IS_ERR(xcvr->regmap)) + return dev_err_probe(dev, PTR_ERR(xcvr->regmap), "failed to init XCVR regmap\n"); if (xcvr->soc_data->use_phy) { xcvr->regmap_phy = devm_regmap_init(dev, NULL, xcvr, &fsl_xcvr_regmap_phy_cfg); - if (IS_ERR(xcvr->regmap_phy)) { - dev_err(dev, "failed to init XCVR PHY regmap: %ld\n", - PTR_ERR(xcvr->regmap_phy)); - return PTR_ERR(xcvr->regmap_phy); - } + if (IS_ERR(xcvr->regmap_phy)) + return dev_err_probe(dev, PTR_ERR(xcvr->regmap_phy), + "failed to init XCVR PHY regmap\n"); switch (xcvr->soc_data->pll_ver) { case PLL_MX8MP: xcvr->regmap_pll = devm_regmap_init(dev, NULL, xcvr, &fsl_xcvr_regmap_pllv0_cfg); - if (IS_ERR(xcvr->regmap_pll)) { - dev_err(dev, "failed to init XCVR PLL regmap: %ld\n", - PTR_ERR(xcvr->regmap_pll)); - return PTR_ERR(xcvr->regmap_pll); - } + if (IS_ERR(xcvr->regmap_pll)) + return dev_err_probe(dev, PTR_ERR(xcvr->regmap_pll), + "failed to init XCVR PLL regmap\n"); break; case PLL_MX95: xcvr->regmap_pll = devm_regmap_init(dev, NULL, xcvr, &fsl_xcvr_regmap_pllv1_cfg); - if (IS_ERR(xcvr->regmap_pll)) { - dev_err(dev, "failed to init XCVR PLL regmap: %ld\n", - PTR_ERR(xcvr->regmap_pll)); - return PTR_ERR(xcvr->regmap_pll); - } + if (IS_ERR(xcvr->regmap_pll)) + return dev_err_probe(dev, PTR_ERR(xcvr->regmap_pll), + "failed to init XCVR PLL regmap\n"); break; default: - dev_err(dev, "Error for PLL version %d\n", xcvr->soc_data->pll_ver); - return -EINVAL; + return dev_err_probe(dev, -EINVAL, + "Error for PLL version %d\n", + xcvr->soc_data->pll_ver); } } xcvr->reset = devm_reset_control_get_optional_exclusive(dev, NULL); - if (IS_ERR(xcvr->reset)) { - dev_err(dev, "failed to get XCVR reset control\n"); - return PTR_ERR(xcvr->reset); - } + if (IS_ERR(xcvr->reset)) + return dev_err_probe(dev, PTR_ERR(xcvr->reset), + "failed to get XCVR reset control\n"); /* get IRQs */ irq = platform_get_irq(pdev, 0); @@ -1645,17 +1632,13 @@ static int fsl_xcvr_probe(struct platform_device *pdev) return irq; ret = devm_request_irq(dev, irq, irq0_isr, 0, pdev->name, xcvr); - if (ret) { - dev_err(dev, "failed to claim IRQ0: %i\n", ret); - return ret; - } + if (ret) + return dev_err_probe(dev, ret, "failed to claim IRQ0\n"); rx_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rxfifo"); tx_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "txfifo"); - if (!rx_res || !tx_res) { - dev_err(dev, "could not find rxfifo or txfifo resource\n"); - return -EINVAL; - } + if (!rx_res || !tx_res) + return dev_err_probe(dev, -EINVAL, "could not find rxfifo or txfifo resource\n"); xcvr->dma_prms_rx.chan_name = "rx"; xcvr->dma_prms_tx.chan_name = "tx"; xcvr->dma_prms_rx.addr = rx_res->start; @@ -1678,8 +1661,7 @@ static int fsl_xcvr_probe(struct platform_device *pdev) ret = devm_snd_dmaengine_pcm_register(dev, NULL, 0); if (ret) { pm_runtime_disable(dev); - dev_err(dev, "failed to pcm register\n"); - return ret; + return dev_err_probe(dev, ret, "failed to pcm register\n"); } ret = devm_snd_soc_register_component(dev, &fsl_xcvr_comp, diff --git a/sound/soc/fsl/imx-rpmsg.c b/sound/soc/fsl/imx-rpmsg.c index 7cd3aa4c87060d..53f04d1f32806d 100644 --- a/sound/soc/fsl/imx-rpmsg.c +++ b/sound/soc/fsl/imx-rpmsg.c @@ -72,7 +72,7 @@ static int imx_rpmsg_late_probe(struct snd_soc_card *card) of_property_read_string_index(data->card.dev->of_node, "ignore-suspend-widgets", i, &widgets); - dapm = snd_soc_component_get_dapm(codec_comp); + dapm = snd_soc_component_to_dapm(codec_comp); snd_soc_dapm_ignore_suspend(dapm, widgets); } } diff --git a/sound/soc/generic/audio-graph-card.c b/sound/soc/generic/audio-graph-card.c index a8a3bad3df00de..7720cf1fd6e191 100644 --- a/sound/soc/generic/audio-graph-card.c +++ b/sound/soc/generic/audio-graph-card.c @@ -43,8 +43,8 @@ static int graph_outdrv_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_dapm_context *dapm = w->dapm; - struct simple_util_priv *priv = snd_soc_card_get_drvdata(dapm->card); + struct snd_soc_card *card = snd_soc_dapm_to_card(w->dapm); + struct simple_util_priv *priv = snd_soc_card_get_drvdata(card); switch (event) { case SND_SOC_DAPM_POST_PMU: diff --git a/sound/soc/intel/atom/sst-atom-controls.c b/sound/soc/intel/atom/sst-atom-controls.c index c68965f152e8a5..3629ceaaac17ca 100644 --- a/sound/soc/intel/atom/sst-atom-controls.c +++ b/sound/soc/intel/atom/sst-atom-controls.c @@ -142,7 +142,7 @@ static int sst_slot_enum_info(struct snd_kcontrol *kcontrol, if (uinfo->value.enumerated.item > e->max - 1) uinfo->value.enumerated.item = e->max - 1; - strcpy(uinfo->value.enumerated.name, + strscpy(uinfo->value.enumerated.name, e->texts[uinfo->value.enumerated.item]); return 0; @@ -637,7 +637,7 @@ static int sst_swm_mixer_event(struct snd_soc_dapm_widget *w, * inputs as an IPC to the DSP. */ for (i = 0; i < w->num_kcontrols; i++) { - if (dapm_kcontrol_get_value(w->kcontrols[i])) { + if (snd_soc_dapm_kcontrol_get_value(w->kcontrols[i])) { mc = (struct soc_mixer_control *)(w->kcontrols[i])->private_value; val |= 1 << mc->shift; } @@ -1530,8 +1530,7 @@ static int sst_map_modules_to_pipe(struct snd_soc_component *component) int sst_dsp_init_v2_dpcm(struct snd_soc_component *component) { int i, ret = 0; - struct snd_soc_dapm_context *dapm = - snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct sst_data *drv = snd_soc_component_get_drvdata(component); unsigned int gains = ARRAY_SIZE(sst_gain_controls)/3; @@ -1544,7 +1543,7 @@ int sst_dsp_init_v2_dpcm(struct snd_soc_component *component) ARRAY_SIZE(sst_dapm_widgets)); snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon)); - snd_soc_dapm_new_widgets(dapm->card); + snd_soc_dapm_new_widgets(component->card); for (i = 0; i < gains; i++) { sst_gains[i].mute = SST_GAIN_MUTE_DEFAULT; diff --git a/sound/soc/intel/atom/sst/sst_acpi.c b/sound/soc/intel/atom/sst/sst_acpi.c index 25718063047559..73624e1b138a65 100644 --- a/sound/soc/intel/atom/sst/sst_acpi.c +++ b/sound/soc/intel/atom/sst/sst_acpi.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -356,7 +357,7 @@ static int sst_acpi_probe(struct platform_device *pdev) /* Fill sst platform data */ ctx->pdata = pdata; - strcpy(ctx->firmware_name, mach->fw_filename); + strscpy(ctx->firmware_name, mach->fw_filename); ret = sst_platform_get_resources(ctx); if (ret) diff --git a/sound/soc/intel/avs/boards/da7219.c b/sound/soc/intel/avs/boards/da7219.c index 6782dc7efae310..2b17abcbd2bc0c 100644 --- a/sound/soc/intel/avs/boards/da7219.c +++ b/sound/soc/intel/avs/boards/da7219.c @@ -29,8 +29,7 @@ static const struct snd_kcontrol_new card_controls[] = { static int platform_clock_control(struct snd_soc_dapm_widget *w, struct snd_kcontrol *k, int event) { - struct snd_soc_dapm_context *dapm = w->dapm; - struct snd_soc_card *card = dapm->card; + struct snd_soc_card *card = snd_soc_dapm_to_card(w->dapm); struct snd_soc_dai *codec_dai; int ret = 0; diff --git a/sound/soc/intel/avs/boards/es8336.c b/sound/soc/intel/avs/boards/es8336.c index eb2b40894e3f20..301cfb3cf15b88 100644 --- a/sound/soc/intel/avs/boards/es8336.c +++ b/sound/soc/intel/avs/boards/es8336.c @@ -38,7 +38,7 @@ static const struct acpi_gpio_mapping speaker_gpios[] = { static int avs_es8336_speaker_power_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_card *card = w->dapm->card; + struct snd_soc_card *card = snd_soc_dapm_to_card(w->dapm); struct avs_card_drvdata *data; bool speaker_en; @@ -101,6 +101,7 @@ static int avs_es8336_codec_init(struct snd_soc_pcm_runtime *runtime) struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(runtime, 0); struct snd_soc_component *component = codec_dai->component; struct snd_soc_card *card = runtime->card; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); struct snd_soc_jack_pin *pins; struct avs_card_drvdata *data; struct gpio_desc *gpiod; @@ -132,7 +133,7 @@ static int avs_es8336_codec_init(struct snd_soc_pcm_runtime *runtime) snd_jack_set_key(data->jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE); snd_soc_component_set_jack(component, &data->jack, NULL); - card->dapm.idle_bias = false; + snd_soc_dapm_set_idle_bias(dapm, false); return 0; } diff --git a/sound/soc/intel/avs/boards/nau8825.c b/sound/soc/intel/avs/boards/nau8825.c index 9ca400a6412eb1..d44edacbfc9aa3 100644 --- a/sound/soc/intel/avs/boards/nau8825.c +++ b/sound/soc/intel/avs/boards/nau8825.c @@ -23,8 +23,7 @@ static int avs_nau8825_clock_control(struct snd_soc_dapm_widget *w, struct snd_kcontrol *control, int event) { - struct snd_soc_dapm_context *dapm = w->dapm; - struct snd_soc_card *card = dapm->card; + struct snd_soc_card *card = snd_soc_dapm_to_card(w->dapm); struct snd_soc_dai *codec_dai; int ret; diff --git a/sound/soc/intel/avs/boards/rt274.c b/sound/soc/intel/avs/boards/rt274.c index 4055ecc60838f3..a689f4c80867b7 100644 --- a/sound/soc/intel/avs/boards/rt274.c +++ b/sound/soc/intel/avs/boards/rt274.c @@ -27,8 +27,7 @@ static const struct snd_kcontrol_new card_controls[] = { static int avs_rt274_clock_control(struct snd_soc_dapm_widget *w, struct snd_kcontrol *control, int event) { - struct snd_soc_dapm_context *dapm = w->dapm; - struct snd_soc_card *card = dapm->card; + struct snd_soc_card *card = snd_soc_dapm_to_card(w->dapm); struct snd_soc_dai *codec_dai; int ret; @@ -93,6 +92,7 @@ static int avs_rt274_codec_init(struct snd_soc_pcm_runtime *runtime) struct snd_soc_jack_pin *pins; struct snd_soc_jack *jack; struct snd_soc_card *card = runtime->card; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); int num_pins, ret; jack = snd_soc_card_get_drvdata(card); @@ -117,7 +117,7 @@ static int avs_rt274_codec_init(struct snd_soc_pcm_runtime *runtime) return ret; } - card->dapm.idle_bias = false; + snd_soc_dapm_set_idle_bias(dapm, false); return 0; } diff --git a/sound/soc/intel/avs/boards/rt5514.c b/sound/soc/intel/avs/boards/rt5514.c index 00b99e36d23ca1..22139eaad83af1 100644 --- a/sound/soc/intel/avs/boards/rt5514.c +++ b/sound/soc/intel/avs/boards/rt5514.c @@ -33,7 +33,8 @@ static const struct snd_soc_dapm_route card_base_routes[] = { static int avs_rt5514_codec_init(struct snd_soc_pcm_runtime *runtime) { - int ret = snd_soc_dapm_ignore_suspend(&runtime->card->dapm, "DMIC"); + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(runtime->card); + int ret = snd_soc_dapm_ignore_suspend(dapm, "DMIC"); if (ret) dev_err(runtime->dev, "DMIC - Ignore suspend failed = %d\n", ret); diff --git a/sound/soc/intel/avs/boards/rt5640.c b/sound/soc/intel/avs/boards/rt5640.c index 97d1fa944188fa..2990d32f230171 100644 --- a/sound/soc/intel/avs/boards/rt5640.c +++ b/sound/soc/intel/avs/boards/rt5640.c @@ -50,6 +50,7 @@ static int avs_rt5640_codec_init(struct snd_soc_pcm_runtime *runtime) { struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(runtime, 0); struct snd_soc_card *card = runtime->card; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); struct snd_soc_jack_pin *pins; struct snd_soc_jack *jack; int num_pins, ret; @@ -67,7 +68,7 @@ static int avs_rt5640_codec_init(struct snd_soc_pcm_runtime *runtime) return ret; snd_soc_component_set_jack(codec_dai->component, jack, NULL); - card->dapm.idle_bias = false; + snd_soc_dapm_set_idle_bias(dapm, false); return 0; } diff --git a/sound/soc/intel/avs/control.c b/sound/soc/intel/avs/control.c index 2e01dc75a15a75..a8f05de338e0ef 100644 --- a/sound/soc/intel/avs/control.c +++ b/sound/soc/intel/avs/control.c @@ -15,11 +15,10 @@ static struct avs_dev *avs_get_kcontrol_adev(struct snd_kcontrol *kcontrol) { - struct snd_soc_dapm_widget *w; + struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kcontrol); + struct device *dev = snd_soc_dapm_to_dev(dapm); - w = snd_soc_dapm_kcontrol_widget(kcontrol); - - return to_avs_dev(w->dapm->component->dev); + return to_avs_dev(dev); } static struct avs_path_module *avs_get_volume_module(struct avs_dev *adev, u32 id) diff --git a/sound/soc/intel/avs/debugfs.c b/sound/soc/intel/avs/debugfs.c index 3534de46f9e45b..701c247227bf95 100644 --- a/sound/soc/intel/avs/debugfs.c +++ b/sound/soc/intel/avs/debugfs.c @@ -119,16 +119,13 @@ static ssize_t probe_points_read(struct file *file, char __user *to, size_t coun } for (i = 0; i < num_desc; i++) { - ret = snprintf(buf + len, PAGE_SIZE - len, - "Id: %#010x Purpose: %d Node id: %#x\n", - desc[i].id.value, desc[i].purpose, desc[i].node_id.val); - if (ret < 0) - goto free_desc; + ret = scnprintf(buf + len, PAGE_SIZE - len, + "Id: %#010x Purpose: %d Node id: %#x\n", + desc[i].id.value, desc[i].purpose, desc[i].node_id.val); len += ret; } ret = simple_read_from_buffer(to, count, ppos, buf, len); -free_desc: kfree(desc); exit: kfree(buf); diff --git a/sound/soc/intel/avs/path.c b/sound/soc/intel/avs/path.c index 7aa20fcf1a33b5..c8b586aced2061 100644 --- a/sound/soc/intel/avs/path.c +++ b/sound/soc/intel/avs/path.c @@ -210,9 +210,11 @@ int avs_path_set_constraint(struct avs_dev *adev, struct avs_tplg_path_template continue; } - blob = avs_nhlt_config_or_default(adev, module_template); - if (IS_ERR(blob)) - continue; + if (!module_template->nhlt_config) { + blob = avs_nhlt_config_or_default(adev, module_template); + if (IS_ERR(blob)) + continue; + } rlist[i] = path_template->fe_fmt->sampling_freq; clist[i] = path_template->fe_fmt->num_channels; @@ -382,7 +384,10 @@ static int avs_fill_gtw_config(struct avs_dev *adev, struct avs_copier_gtw_cfg * struct acpi_nhlt_config *blob; size_t gtw_size; - blob = avs_nhlt_config_or_default(adev, t); + if (t->nhlt_config) + blob = t->nhlt_config->blob; + else + blob = avs_nhlt_config_or_default(adev, t); if (IS_ERR(blob)) return PTR_ERR(blob); diff --git a/sound/soc/intel/avs/pcm.c b/sound/soc/intel/avs/pcm.c index 80c001120cdd92..4a6deb599c8801 100644 --- a/sound/soc/intel/avs/pcm.c +++ b/sound/soc/intel/avs/pcm.c @@ -1624,7 +1624,7 @@ static int avs_component_hda_probe(struct snd_soc_component *component) return -ENOMEM; cname = dev_name(&codec->core.dev); - dapm = snd_soc_component_get_dapm(component); + dapm = snd_soc_component_to_dapm(component); pcm = list_first_entry(&codec->pcm_list_head, struct hda_pcm, list); for (i = 0; i < pcm_count; i++, pcm = list_next_entry(pcm, list)) { diff --git a/sound/soc/intel/avs/topology.c b/sound/soc/intel/avs/topology.c index dfe8cf50538187..9033f683393c43 100644 --- a/sound/soc/intel/avs/topology.c +++ b/sound/soc/intel/avs/topology.c @@ -350,6 +350,7 @@ AVS_DEFINE_PTR_PARSER(modcfg_base, struct avs_tplg_modcfg_base, modcfgs_base); AVS_DEFINE_PTR_PARSER(modcfg_ext, struct avs_tplg_modcfg_ext, modcfgs_ext); AVS_DEFINE_PTR_PARSER(pplcfg, struct avs_tplg_pplcfg, pplcfgs); AVS_DEFINE_PTR_PARSER(binding, struct avs_tplg_binding, bindings); +AVS_DEFINE_PTR_PARSER(nhlt_config, struct avs_tplg_nhlt_config, nhlt_configs); static int parse_audio_format_bitfield(struct snd_soc_component *comp, void *elem, void *object, u32 offset) @@ -420,6 +421,22 @@ static int parse_link_formatted_string(struct snd_soc_component *comp, void *ele return 0; } +static int avs_parse_nhlt_config_size(struct snd_soc_component *comp, void *elem, void *object, + u32 offset) +{ + struct snd_soc_tplg_vendor_value_elem *tuple = elem; + struct acpi_nhlt_config **blob = (struct acpi_nhlt_config **)((u8 *)object + offset); + u32 size; + + size = le32_to_cpu(tuple->value); + *blob = devm_kzalloc(comp->card->dev, struct_size(*blob, capabilities, size), GFP_KERNEL); + if (!*blob) + return -ENOMEM; + + (*blob)->capabilities_size = size; + return 0; +} + static int parse_dictionary_header(struct snd_soc_component *comp, struct snd_soc_tplg_vendor_array *tuples, @@ -1184,6 +1201,12 @@ static const struct avs_tplg_token_parser module_parsers[] = { .offset = offsetof(struct avs_tplg_module, num_config_ids), .parse = avs_parse_byte_token, }, + { + .token = AVS_TKN_MOD_NHLT_CONFIG_ID_U32, + .type = SND_SOC_TPLG_TUPLE_TYPE_WORD, + .offset = offsetof(struct avs_tplg_module, nhlt_config), + .parse = avs_parse_nhlt_config_ptr, + }, }; static const struct avs_tplg_token_parser init_config_parsers[] = { @@ -1651,12 +1674,14 @@ static const struct avs_tplg_token_parser mod_init_config_parsers[] = { static int avs_tplg_parse_initial_configs(struct snd_soc_component *comp, struct snd_soc_tplg_vendor_array *tuples, - u32 block_size) + u32 block_size, u32 *offset) { struct avs_soc_component *acomp = to_avs_soc_component(comp); struct avs_tplg *tplg = acomp->tplg; int ret, i; + *offset = 0; + /* Parse tuple section telling how many init configs there are. */ ret = parse_dictionary_header(comp, tuples, (void **)&tplg->init_configs, &tplg->num_init_configs, @@ -1666,6 +1691,7 @@ static int avs_tplg_parse_initial_configs(struct snd_soc_component *comp, return ret; block_size -= le32_to_cpu(tuples->size); + *offset += le32_to_cpu(tuples->size); /* With header parsed, move on to parsing entries. */ tuples = avs_tplg_vendor_array_next(tuples); @@ -1681,6 +1707,7 @@ static int avs_tplg_parse_initial_configs(struct snd_soc_component *comp, */ tmp = avs_tplg_vendor_array_next(tuples); esize = le32_to_cpu(tuples->size) + le32_to_cpu(tmp->size); + *offset += esize; ret = parse_dictionary_entries(comp, tuples, esize, config, 1, sizeof(*config), AVS_TKN_INIT_CONFIG_ID_U32, @@ -1692,6 +1719,7 @@ static int avs_tplg_parse_initial_configs(struct snd_soc_component *comp, /* handle raw data section */ init_config_data = (void *)tuples + esize; esize = config->length; + *offset += esize; config->data = devm_kmemdup(comp->card->dev, init_config_data, esize, GFP_KERNEL); if (!config->data) @@ -1704,6 +1732,70 @@ static int avs_tplg_parse_initial_configs(struct snd_soc_component *comp, return 0; } +static const struct avs_tplg_token_parser mod_nhlt_config_parsers[] = { + { + .token = AVS_TKN_NHLT_CONFIG_ID_U32, + .type = SND_SOC_TPLG_TUPLE_TYPE_WORD, + .offset = offsetof(struct avs_tplg_nhlt_config, id), + .parse = avs_parse_word_token, + }, + { + .token = AVS_TKN_NHLT_CONFIG_SIZE_U32, + .type = SND_SOC_TPLG_TUPLE_TYPE_WORD, + .offset = offsetof(struct avs_tplg_nhlt_config, blob), + .parse = avs_parse_nhlt_config_size, + }, +}; + +static int avs_tplg_parse_nhlt_configs(struct snd_soc_component *comp, + struct snd_soc_tplg_vendor_array *tuples, + u32 block_size) +{ + struct avs_soc_component *acomp = to_avs_soc_component(comp); + struct avs_tplg *tplg = acomp->tplg; + int ret, i; + + /* Parse the header section to know how many entries there are. */ + ret = parse_dictionary_header(comp, tuples, (void **)&tplg->nhlt_configs, + &tplg->num_nhlt_configs, + sizeof(*tplg->nhlt_configs), + AVS_TKN_MANIFEST_NUM_NHLT_CONFIGS_U32); + if (ret) + return ret; + + block_size -= le32_to_cpu(tuples->size); + /* With the header parsed, move on to parsing entries. */ + tuples = avs_tplg_vendor_array_next(tuples); + + for (i = 0; i < tplg->num_nhlt_configs && block_size > 0; i++) { + struct avs_tplg_nhlt_config *config; + u32 esize; + + config = &tplg->nhlt_configs[i]; + esize = le32_to_cpu(tuples->size); + + ret = parse_dictionary_entries(comp, tuples, esize, config, 1, sizeof(*config), + AVS_TKN_NHLT_CONFIG_ID_U32, + mod_nhlt_config_parsers, + ARRAY_SIZE(mod_nhlt_config_parsers)); + if (ret) + return ret; + /* With tuples parsed, the blob shall be allocated. */ + if (!config->blob) + return -EINVAL; + + /* Consume the raw data and move to the next entry. */ + memcpy(config->blob->capabilities, (u8 *)tuples + esize, + config->blob->capabilities_size); + esize += config->blob->capabilities_size; + + block_size -= esize; + tuples = avs_tplg_vendor_array_at(tuples, esize); + } + + return 0; +} + static int avs_route_load(struct snd_soc_component *comp, int index, struct snd_soc_dapm_route *route) { @@ -2008,11 +2100,26 @@ static int avs_manifest(struct snd_soc_component *comp, int index, tuples = avs_tplg_vendor_array_at(tuples, offset); /* Initial configs dictionary. */ - ret = avs_tplg_parse_initial_configs(comp, tuples, remaining); + ret = avs_tplg_parse_initial_configs(comp, tuples, remaining, &offset); if (ret < 0) return ret; - return 0; + remaining -= offset; + tuples = avs_tplg_vendor_array_at(tuples, offset); + + ret = avs_tplg_vendor_array_lookup(tuples, remaining, + AVS_TKN_MANIFEST_NUM_NHLT_CONFIGS_U32, &offset); + if (ret == -ENOENT) + return 0; + if (ret) { + dev_err(comp->dev, "NHLT config lookup failed: %d\n", ret); + return ret; + } + + tuples = avs_tplg_vendor_array_at(tuples, offset); + + /* NHLT configs dictionary. */ + return avs_tplg_parse_nhlt_configs(comp, tuples, remaining); } enum { diff --git a/sound/soc/intel/avs/topology.h b/sound/soc/intel/avs/topology.h index 1e83fccf2ea219..1cf7455b6c0107 100644 --- a/sound/soc/intel/avs/topology.h +++ b/sound/soc/intel/avs/topology.h @@ -37,6 +37,8 @@ struct avs_tplg { u32 num_condpath_tmpls; struct avs_tplg_init_config *init_configs; u32 num_init_configs; + struct avs_tplg_nhlt_config *nhlt_configs; + u32 num_nhlt_configs; struct list_head path_tmpl_list; }; @@ -175,6 +177,11 @@ struct avs_tplg_init_config { void *data; }; +struct avs_tplg_nhlt_config { + u32 id; + struct acpi_nhlt_config *blob; +}; + struct avs_tplg_path { u32 id; @@ -216,6 +223,7 @@ struct avs_tplg_module { u32 ctl_id; u32 num_config_ids; u32 *config_ids; + struct avs_tplg_nhlt_config *nhlt_config; struct avs_tplg_pipeline *owner; /* Pipeline modules management. */ diff --git a/sound/soc/intel/boards/bdw-rt5677.c b/sound/soc/intel/boards/bdw-rt5677.c index 9484f341078769..408d20ed8cee89 100644 --- a/sound/soc/intel/boards/bdw-rt5677.c +++ b/sound/soc/intel/boards/bdw-rt5677.c @@ -27,8 +27,7 @@ struct bdw_rt5677_priv { static int bdw_rt5677_event_hp(struct snd_soc_dapm_widget *w, struct snd_kcontrol *k, int event) { - struct snd_soc_dapm_context *dapm = w->dapm; - struct snd_soc_card *card = dapm->card; + struct snd_soc_card *card = snd_soc_dapm_to_card(w->dapm); struct bdw_rt5677_priv *bdw_rt5677 = snd_soc_card_get_drvdata(card); if (SND_SOC_DAPM_EVENT_ON(event)) @@ -228,7 +227,7 @@ static int bdw_rt5677_init(struct snd_soc_pcm_runtime *rtd) struct bdw_rt5677_priv *bdw_rt5677 = snd_soc_card_get_drvdata(rtd->card); struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component; - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); int ret; ret = devm_acpi_dev_add_driver_gpios(component->dev, bdw_rt5677_gpios); @@ -366,7 +365,7 @@ static int bdw_rt5677_suspend_pre(struct snd_soc_card *card) struct snd_soc_dapm_context *dapm; if (bdw_rt5677->component) { - dapm = snd_soc_component_get_dapm(bdw_rt5677->component); + dapm = snd_soc_component_to_dapm(bdw_rt5677->component); snd_soc_dapm_disable_pin(dapm, "MICBIAS1"); } return 0; @@ -378,7 +377,7 @@ static int bdw_rt5677_resume_post(struct snd_soc_card *card) struct snd_soc_dapm_context *dapm; if (bdw_rt5677->component) { - dapm = snd_soc_component_get_dapm(bdw_rt5677->component); + dapm = snd_soc_component_to_dapm(bdw_rt5677->component); snd_soc_dapm_force_enable_pin(dapm, "MICBIAS1"); } return 0; diff --git a/sound/soc/intel/boards/bytcht_cx2072x.c b/sound/soc/intel/boards/bytcht_cx2072x.c index 27b63a853a48e4..0a7e6d2e37cb05 100644 --- a/sound/soc/intel/boards/bytcht_cx2072x.c +++ b/sound/soc/intel/boards/bytcht_cx2072x.c @@ -70,6 +70,7 @@ static const struct acpi_gpio_mapping byt_cht_cx2072x_acpi_gpios[] = { static int byt_cht_cx2072x_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_card *card = rtd->card; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); struct snd_soc_component *codec = snd_soc_rtd_to_codec(rtd, 0)->component; int ret; @@ -77,7 +78,7 @@ static int byt_cht_cx2072x_init(struct snd_soc_pcm_runtime *rtd) byt_cht_cx2072x_acpi_gpios)) dev_warn(rtd->dev, "Unable to add GPIO mapping table\n"); - card->dapm.idle_bias = false; + snd_soc_dapm_set_idle_bias(dapm, false); /* set the default PLL rate, the clock is handled by the codec driver */ ret = snd_soc_dai_set_sysclk(snd_soc_rtd_to_codec(rtd, 0), CX2072X_MCLK_EXTERNAL_PLL, diff --git a/sound/soc/intel/boards/bytcht_es8316.c b/sound/soc/intel/boards/bytcht_es8316.c index 3b5f63112237ea..192e2a394ff3d0 100644 --- a/sound/soc/intel/boards/bytcht_es8316.c +++ b/sound/soc/intel/boards/bytcht_es8316.c @@ -89,7 +89,7 @@ static void log_quirks(struct device *dev) static int byt_cht_es8316_speaker_power_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_card *card = w->dapm->card; + struct snd_soc_card *card = snd_soc_dapm_to_card(w->dapm); struct byt_cht_es8316_private *priv = snd_soc_card_get_drvdata(card); if (SND_SOC_DAPM_EVENT_ON(event)) @@ -174,12 +174,13 @@ static int byt_cht_es8316_init(struct snd_soc_pcm_runtime *runtime) { struct snd_soc_component *codec = snd_soc_rtd_to_codec(runtime, 0)->component; struct snd_soc_card *card = runtime->card; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); struct byt_cht_es8316_private *priv = snd_soc_card_get_drvdata(card); const struct snd_soc_dapm_route *custom_map; int num_routes; int ret; - card->dapm.idle_bias = false; + snd_soc_dapm_set_idle_bias(dapm, false); switch (BYT_CHT_ES8316_MAP(quirk)) { case BYT_CHT_ES8316_INTMIC_IN1_MAP: @@ -192,7 +193,7 @@ static int byt_cht_es8316_init(struct snd_soc_pcm_runtime *runtime) num_routes = ARRAY_SIZE(byt_cht_es8316_intmic_in2_map); break; } - ret = snd_soc_dapm_add_routes(&card->dapm, custom_map, num_routes); + ret = snd_soc_dapm_add_routes(dapm, custom_map, num_routes); if (ret) return ret; @@ -203,7 +204,7 @@ static int byt_cht_es8316_init(struct snd_soc_pcm_runtime *runtime) custom_map = byt_cht_es8316_ssp2_map; num_routes = ARRAY_SIZE(byt_cht_es8316_ssp2_map); } - ret = snd_soc_dapm_add_routes(&card->dapm, custom_map, num_routes); + ret = snd_soc_dapm_add_routes(dapm, custom_map, num_routes); if (ret) return ret; diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c index 1e9b1903fae810..103e0b445603f2 100644 --- a/sound/soc/intel/boards/bytcr_rt5640.c +++ b/sound/soc/intel/boards/bytcr_rt5640.c @@ -257,7 +257,7 @@ static int byt_rt5640_prepare_and_enable_pll1(struct snd_soc_dai *codec_dai, static struct snd_soc_dai *byt_rt5640_get_codec_dai(struct snd_soc_dapm_context *dapm) { - struct snd_soc_card *card = dapm->card; + struct snd_soc_card *card = snd_soc_dapm_to_card(dapm); struct snd_soc_dai *codec_dai; codec_dai = snd_soc_card_get_codec_dai(card, BYT_CODEC_DAI1); @@ -273,7 +273,7 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w, struct snd_kcontrol *k, int event) { struct snd_soc_dapm_context *dapm = w->dapm; - struct snd_soc_card *card = dapm->card; + struct snd_soc_card *card = snd_soc_dapm_to_card(dapm); struct snd_soc_dai *codec_dai; struct byt_rt5640_private *priv = snd_soc_card_get_drvdata(card); int ret; @@ -1317,6 +1317,7 @@ static int byt_rt5640_get_amcr0f28_settings(struct snd_soc_card *card) static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime) { struct snd_soc_card *card = runtime->card; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); struct byt_rt5640_private *priv = snd_soc_card_get_drvdata(card); struct rt5640_set_jack_data *jack_data = &priv->jack_data; struct snd_soc_component *component = snd_soc_rtd_to_codec(runtime, 0)->component; @@ -1324,7 +1325,7 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime) int num_routes = 0; int ret; - card->dapm.idle_bias = false; + snd_soc_dapm_set_idle_bias(dapm, false); jack_data->use_platform_clock = true; /* Start with RC clk for jack-detect (we disable MCLK below) */ @@ -1367,12 +1368,12 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime) break; } - ret = snd_soc_dapm_add_routes(&card->dapm, custom_map, num_routes); + ret = snd_soc_dapm_add_routes(dapm, custom_map, num_routes); if (ret) return ret; if (byt_rt5640_quirk & BYT_RT5640_HSMIC2_ON_IN1) { - ret = snd_soc_dapm_add_routes(&card->dapm, + ret = snd_soc_dapm_add_routes(dapm, byt_rt5640_hsmic2_in1_map, ARRAY_SIZE(byt_rt5640_hsmic2_in1_map)); if (ret) @@ -1380,19 +1381,19 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime) } if (byt_rt5640_quirk & BYT_RT5640_SSP2_AIF2) { - ret = snd_soc_dapm_add_routes(&card->dapm, + ret = snd_soc_dapm_add_routes(dapm, byt_rt5640_ssp2_aif2_map, ARRAY_SIZE(byt_rt5640_ssp2_aif2_map)); } else if (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) { - ret = snd_soc_dapm_add_routes(&card->dapm, + ret = snd_soc_dapm_add_routes(dapm, byt_rt5640_ssp0_aif1_map, ARRAY_SIZE(byt_rt5640_ssp0_aif1_map)); } else if (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2) { - ret = snd_soc_dapm_add_routes(&card->dapm, + ret = snd_soc_dapm_add_routes(dapm, byt_rt5640_ssp0_aif2_map, ARRAY_SIZE(byt_rt5640_ssp0_aif2_map)); } else { - ret = snd_soc_dapm_add_routes(&card->dapm, + ret = snd_soc_dapm_add_routes(dapm, byt_rt5640_ssp2_aif1_map, ARRAY_SIZE(byt_rt5640_ssp2_aif1_map)); } @@ -1400,11 +1401,11 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime) return ret; if (byt_rt5640_quirk & BYT_RT5640_MONO_SPEAKER) { - ret = snd_soc_dapm_add_routes(&card->dapm, + ret = snd_soc_dapm_add_routes(dapm, byt_rt5640_mono_spk_map, ARRAY_SIZE(byt_rt5640_mono_spk_map)); } else if (!(byt_rt5640_quirk & BYT_RT5640_NO_SPEAKERS)) { - ret = snd_soc_dapm_add_routes(&card->dapm, + ret = snd_soc_dapm_add_routes(dapm, byt_rt5640_stereo_spk_map, ARRAY_SIZE(byt_rt5640_stereo_spk_map)); } @@ -1412,7 +1413,7 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime) return ret; if (byt_rt5640_quirk & BYT_RT5640_LINEOUT) { - ret = snd_soc_dapm_add_routes(&card->dapm, + ret = snd_soc_dapm_add_routes(dapm, byt_rt5640_lineout_map, ARRAY_SIZE(byt_rt5640_lineout_map)); if (ret) diff --git a/sound/soc/intel/boards/bytcr_rt5651.c b/sound/soc/intel/boards/bytcr_rt5651.c index ca540a66f22ce0..68cf463f1d5070 100644 --- a/sound/soc/intel/boards/bytcr_rt5651.c +++ b/sound/soc/intel/boards/bytcr_rt5651.c @@ -188,8 +188,7 @@ static int byt_rt5651_prepare_and_enable_pll1(struct snd_soc_dai *codec_dai, static int platform_clock_control(struct snd_soc_dapm_widget *w, struct snd_kcontrol *k, int event) { - struct snd_soc_dapm_context *dapm = w->dapm; - struct snd_soc_card *card = dapm->card; + struct snd_soc_card *card = snd_soc_dapm_to_card(w->dapm); struct snd_soc_dai *codec_dai; struct byt_rt5651_private *priv = snd_soc_card_get_drvdata(card); int ret; @@ -234,7 +233,7 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w, static int rt5651_ext_amp_power_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_card *card = w->dapm->card; + struct snd_soc_card *card = snd_soc_dapm_to_card(w->dapm); struct byt_rt5651_private *priv = snd_soc_card_get_drvdata(card); if (SND_SOC_DAPM_EVENT_ON(event)) @@ -579,6 +578,7 @@ static int byt_rt5651_add_codec_device_props(struct device *i2c_dev, static int byt_rt5651_init(struct snd_soc_pcm_runtime *runtime) { struct snd_soc_card *card = runtime->card; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); struct snd_soc_component *codec = snd_soc_rtd_to_codec(runtime, 0)->component; struct byt_rt5651_private *priv = snd_soc_card_get_drvdata(card); const struct snd_soc_dapm_route *custom_map; @@ -586,7 +586,7 @@ static int byt_rt5651_init(struct snd_soc_pcm_runtime *runtime) int report; int ret; - card->dapm.idle_bias = false; + snd_soc_dapm_set_idle_bias(dapm, false); /* Start with RC clk for jack-detect (we disable MCLK below) */ if (byt_rt5651_quirk & BYT_RT5651_MCLK_EN) @@ -610,24 +610,24 @@ static int byt_rt5651_init(struct snd_soc_pcm_runtime *runtime) custom_map = byt_rt5651_intmic_dmic_map; num_routes = ARRAY_SIZE(byt_rt5651_intmic_dmic_map); } - ret = snd_soc_dapm_add_routes(&card->dapm, custom_map, num_routes); + ret = snd_soc_dapm_add_routes(dapm, custom_map, num_routes); if (ret) return ret; if (byt_rt5651_quirk & BYT_RT5651_SSP2_AIF2) { - ret = snd_soc_dapm_add_routes(&card->dapm, + ret = snd_soc_dapm_add_routes(dapm, byt_rt5651_ssp2_aif2_map, ARRAY_SIZE(byt_rt5651_ssp2_aif2_map)); } else if (byt_rt5651_quirk & BYT_RT5651_SSP0_AIF1) { - ret = snd_soc_dapm_add_routes(&card->dapm, + ret = snd_soc_dapm_add_routes(dapm, byt_rt5651_ssp0_aif1_map, ARRAY_SIZE(byt_rt5651_ssp0_aif1_map)); } else if (byt_rt5651_quirk & BYT_RT5651_SSP0_AIF2) { - ret = snd_soc_dapm_add_routes(&card->dapm, + ret = snd_soc_dapm_add_routes(dapm, byt_rt5651_ssp0_aif2_map, ARRAY_SIZE(byt_rt5651_ssp0_aif2_map)); } else { - ret = snd_soc_dapm_add_routes(&card->dapm, + ret = snd_soc_dapm_add_routes(dapm, byt_rt5651_ssp2_aif1_map, ARRAY_SIZE(byt_rt5651_ssp2_aif1_map)); } diff --git a/sound/soc/intel/boards/bytcr_wm5102.c b/sound/soc/intel/boards/bytcr_wm5102.c index 02b84c877e5f38..4879f79aef292b 100644 --- a/sound/soc/intel/boards/bytcr_wm5102.c +++ b/sound/soc/intel/boards/bytcr_wm5102.c @@ -99,7 +99,7 @@ static void log_quirks(struct device *dev) static int byt_wm5102_spkvdd_power_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_card *card = w->dapm->card; + struct snd_soc_card *card = snd_soc_dapm_to_card(w->dapm); struct byt_wm5102_private *priv = snd_soc_card_get_drvdata(card); gpiod_set_value_cansleep(priv->spkvdd_en_gpio, @@ -150,8 +150,7 @@ static int byt_wm5102_prepare_and_enable_pll1(struct snd_soc_dai *codec_dai, int static int platform_clock_control(struct snd_soc_dapm_widget *w, struct snd_kcontrol *k, int event) { - struct snd_soc_dapm_context *dapm = w->dapm; - struct snd_soc_card *card = dapm->card; + struct snd_soc_card *card = snd_soc_dapm_to_card(w->dapm); struct snd_soc_dai *codec_dai; struct byt_wm5102_private *priv = snd_soc_card_get_drvdata(card); int ret; @@ -283,12 +282,13 @@ static struct snd_soc_jack_pin byt_wm5102_pins[] = { static int byt_wm5102_init(struct snd_soc_pcm_runtime *runtime) { struct snd_soc_card *card = runtime->card; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); struct byt_wm5102_private *priv = snd_soc_card_get_drvdata(card); struct snd_soc_component *component = snd_soc_rtd_to_codec(runtime, 0)->component; const struct snd_soc_dapm_route *custom_map = NULL; int ret, jack_type, num_routes = 0; - card->dapm.idle_bias = false; + snd_soc_dapm_set_idle_bias(dapm, false); ret = snd_soc_add_card_controls(card, byt_wm5102_controls, ARRAY_SIZE(byt_wm5102_controls)); @@ -307,7 +307,7 @@ static int byt_wm5102_init(struct snd_soc_pcm_runtime *runtime) num_routes = ARRAY_SIZE(byt_wm5102_intmic_in1l_hsmic_in2l_map); break; } - ret = snd_soc_dapm_add_routes(&card->dapm, custom_map, num_routes); + ret = snd_soc_dapm_add_routes(dapm, custom_map, num_routes); if (ret) return ret; @@ -321,7 +321,7 @@ static int byt_wm5102_init(struct snd_soc_pcm_runtime *runtime) num_routes = ARRAY_SIZE(byt_wm5102_spk_hpout2_map); break; } - ret = snd_soc_dapm_add_routes(&card->dapm, custom_map, num_routes); + ret = snd_soc_dapm_add_routes(dapm, custom_map, num_routes); if (ret) return ret; @@ -332,7 +332,7 @@ static int byt_wm5102_init(struct snd_soc_pcm_runtime *runtime) custom_map = bytcr_wm5102_ssp0_map; num_routes = ARRAY_SIZE(bytcr_wm5102_ssp0_map); } - ret = snd_soc_dapm_add_routes(&card->dapm, custom_map, num_routes); + ret = snd_soc_dapm_add_routes(dapm, custom_map, num_routes); if (ret) return ret; diff --git a/sound/soc/intel/boards/cht_bsw_max98090_ti.c b/sound/soc/intel/boards/cht_bsw_max98090_ti.c index 36984de8a0679e..ad45b79d3e4b88 100644 --- a/sound/soc/intel/boards/cht_bsw_max98090_ti.c +++ b/sound/soc/intel/boards/cht_bsw_max98090_ti.c @@ -42,8 +42,7 @@ struct cht_mc_private { static int platform_clock_control(struct snd_soc_dapm_widget *w, struct snd_kcontrol *k, int event) { - struct snd_soc_dapm_context *dapm = w->dapm; - struct snd_soc_card *card = dapm->card; + struct snd_soc_card *card = snd_soc_dapm_to_card(w->dapm); struct snd_soc_dai *codec_dai; struct cht_mc_private *ctx = snd_soc_card_get_drvdata(card); int ret; @@ -130,7 +129,7 @@ static int cht_ti_jack_event(struct notifier_block *nb, unsigned long event, void *data) { struct snd_soc_jack *jack = (struct snd_soc_jack *)data; - struct snd_soc_dapm_context *dapm = &jack->card->dapm; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(jack->card); if (event & SND_JACK_MICROPHONE) { snd_soc_dapm_force_enable_pin(dapm, "SHDN"); diff --git a/sound/soc/intel/boards/cht_bsw_rt5645.c b/sound/soc/intel/boards/cht_bsw_rt5645.c index b977a2db73a3a7..249be121be1574 100644 --- a/sound/soc/intel/boards/cht_bsw_rt5645.c +++ b/sound/soc/intel/boards/cht_bsw_rt5645.c @@ -66,8 +66,7 @@ static void log_quirks(struct device *dev) static int platform_clock_control(struct snd_soc_dapm_widget *w, struct snd_kcontrol *k, int event) { - struct snd_soc_dapm_context *dapm = w->dapm; - struct snd_soc_card *card = dapm->card; + struct snd_soc_card *card = snd_soc_dapm_to_card(w->dapm); struct snd_soc_dai *codec_dai; struct cht_mc_private *ctx = snd_soc_card_get_drvdata(card); int ret; @@ -250,6 +249,7 @@ static const struct dmi_system_id cht_rt5645_quirk_table[] = { static int cht_codec_init(struct snd_soc_pcm_runtime *runtime) { struct snd_soc_card *card = runtime->card; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); struct cht_mc_private *ctx = snd_soc_card_get_drvdata(runtime->card); struct snd_soc_component *component = snd_soc_rtd_to_codec(runtime, 0)->component; int jack_type; @@ -275,19 +275,19 @@ static int cht_codec_init(struct snd_soc_pcm_runtime *runtime) } if (cht_rt5645_quirk & CHT_RT5645_SSP2_AIF2) { - ret = snd_soc_dapm_add_routes(&card->dapm, + ret = snd_soc_dapm_add_routes(dapm, cht_rt5645_ssp2_aif2_map, ARRAY_SIZE(cht_rt5645_ssp2_aif2_map)); } else if (cht_rt5645_quirk & CHT_RT5645_SSP0_AIF1) { - ret = snd_soc_dapm_add_routes(&card->dapm, + ret = snd_soc_dapm_add_routes(dapm, cht_rt5645_ssp0_aif1_map, ARRAY_SIZE(cht_rt5645_ssp0_aif1_map)); } else if (cht_rt5645_quirk & CHT_RT5645_SSP0_AIF2) { - ret = snd_soc_dapm_add_routes(&card->dapm, + ret = snd_soc_dapm_add_routes(dapm, cht_rt5645_ssp0_aif2_map, ARRAY_SIZE(cht_rt5645_ssp0_aif2_map)); } else { - ret = snd_soc_dapm_add_routes(&card->dapm, + ret = snd_soc_dapm_add_routes(dapm, cht_rt5645_ssp2_aif1_map, ARRAY_SIZE(cht_rt5645_ssp2_aif1_map)); } diff --git a/sound/soc/intel/boards/cht_bsw_rt5672.c b/sound/soc/intel/boards/cht_bsw_rt5672.c index 54c1894ee96ac5..359723f2700e46 100644 --- a/sound/soc/intel/boards/cht_bsw_rt5672.c +++ b/sound/soc/intel/boards/cht_bsw_rt5672.c @@ -51,8 +51,7 @@ static struct snd_soc_jack_pin cht_bsw_headset_pins[] = { static int platform_clock_control(struct snd_soc_dapm_widget *w, struct snd_kcontrol *k, int event) { - struct snd_soc_dapm_context *dapm = w->dapm; - struct snd_soc_card *card = dapm->card; + struct snd_soc_card *card = snd_soc_dapm_to_card(w->dapm); struct snd_soc_dai *codec_dai; struct cht_mc_private *ctx = snd_soc_card_get_drvdata(card); int ret; @@ -193,6 +192,7 @@ static const struct acpi_gpio_mapping cht_rt5672_gpios[] = { static int cht_codec_init(struct snd_soc_pcm_runtime *runtime) { int ret; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(runtime->card); struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(runtime, 0); struct snd_soc_component *component = codec_dai->component; struct cht_mc_private *ctx = snd_soc_card_get_drvdata(runtime->card); @@ -215,11 +215,11 @@ static int cht_codec_init(struct snd_soc_pcm_runtime *runtime) RT5670_CLK_SEL_I2S1_ASRC); if (ctx->use_ssp0) { - ret = snd_soc_dapm_add_routes(&runtime->card->dapm, + ret = snd_soc_dapm_add_routes(dapm, cht_audio_ssp0_map, ARRAY_SIZE(cht_audio_ssp0_map)); } else { - ret = snd_soc_dapm_add_routes(&runtime->card->dapm, + ret = snd_soc_dapm_add_routes(dapm, cht_audio_ssp2_map, ARRAY_SIZE(cht_audio_ssp2_map)); } diff --git a/sound/soc/intel/boards/sof_board_helpers.c b/sound/soc/intel/boards/sof_board_helpers.c index 2ea1dda446ec2c..f741a1e142bee1 100644 --- a/sound/soc/intel/boards/sof_board_helpers.c +++ b/sound/soc/intel/boards/sof_board_helpers.c @@ -51,16 +51,17 @@ static const struct snd_soc_dapm_route dmic_routes[] = { static int dmic_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_card *card = rtd->card; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); int ret; - ret = snd_soc_dapm_new_controls(&card->dapm, dmic_widgets, + ret = snd_soc_dapm_new_controls(dapm, dmic_widgets, ARRAY_SIZE(dmic_widgets)); if (ret) { dev_err(rtd->dev, "fail to add dmic widgets, ret %d\n", ret); return ret; } - ret = snd_soc_dapm_add_routes(&card->dapm, dmic_routes, + ret = snd_soc_dapm_add_routes(dapm, dmic_routes, ARRAY_SIZE(dmic_routes)); if (ret) { dev_err(rtd->dev, "fail to add dmic routes, ret %d\n", ret); @@ -111,16 +112,17 @@ static const struct snd_soc_dapm_route hda_routes[] = { static int hda_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_card *card = rtd->card; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); int ret; - ret = snd_soc_dapm_new_controls(&card->dapm, hda_widgets, + ret = snd_soc_dapm_new_controls(dapm, hda_widgets, ARRAY_SIZE(hda_widgets)); if (ret) { dev_err(rtd->dev, "fail to add hda widgets, ret %d\n", ret); return ret; } - ret = snd_soc_dapm_add_routes(&card->dapm, hda_routes, + ret = snd_soc_dapm_add_routes(dapm, hda_routes, ARRAY_SIZE(hda_routes)); if (ret) dev_err(rtd->dev, "fail to add hda routes, ret %d\n", ret); diff --git a/sound/soc/intel/boards/sof_cirrus_common.c b/sound/soc/intel/boards/sof_cirrus_common.c index 8db7695b974764..88fc6cb2bfd49b 100644 --- a/sound/soc/intel/boards/sof_cirrus_common.c +++ b/sound/soc/intel/boards/sof_cirrus_common.c @@ -48,9 +48,10 @@ static struct snd_soc_codec_conf cs35l41_codec_conf[CS35L41_MAX_AMPS]; static int cs35l41_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_card *card = rtd->card; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); int ret; - ret = snd_soc_dapm_new_controls(&card->dapm, cs35l41_dapm_widgets, + ret = snd_soc_dapm_new_controls(dapm, cs35l41_dapm_widgets, ARRAY_SIZE(cs35l41_dapm_widgets)); if (ret) { dev_err(rtd->dev, "fail to add dapm controls, ret %d\n", ret); @@ -64,7 +65,7 @@ static int cs35l41_init(struct snd_soc_pcm_runtime *rtd) return ret; } - ret = snd_soc_dapm_add_routes(&card->dapm, cs35l41_dapm_routes, + ret = snd_soc_dapm_add_routes(dapm, cs35l41_dapm_routes, ARRAY_SIZE(cs35l41_dapm_routes)); if (ret) diff --git a/sound/soc/intel/boards/sof_da7219.c b/sound/soc/intel/boards/sof_da7219.c index 9b7082b239c16d..ad845d32f64257 100644 --- a/sound/soc/intel/boards/sof_da7219.c +++ b/sound/soc/intel/boards/sof_da7219.c @@ -29,8 +29,7 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w, struct snd_kcontrol *k, int event) { - struct snd_soc_dapm_context *dapm = w->dapm; - struct snd_soc_card *card = dapm->card; + struct snd_soc_card *card = snd_soc_dapm_to_card(w->dapm); struct sof_card_private *ctx = snd_soc_card_get_drvdata(card); struct snd_soc_dai *codec_dai; int ret = 0; @@ -181,7 +180,7 @@ static void da7219_codec_exit(struct snd_soc_pcm_runtime *rtd) static int card_late_probe(struct snd_soc_card *card) { struct sof_card_private *ctx = snd_soc_card_get_drvdata(card); - struct snd_soc_dapm_context *dapm = &card->dapm; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); int err; if (ctx->amp_type == CODEC_MAX98373) { diff --git a/sound/soc/intel/boards/sof_es8336.c b/sound/soc/intel/boards/sof_es8336.c index 41b7545581e02a..774fff58d51b93 100644 --- a/sound/soc/intel/boards/sof_es8336.c +++ b/sound/soc/intel/boards/sof_es8336.c @@ -155,7 +155,7 @@ static int sof_8336_trigger(struct snd_pcm_substream *substream, int cmd) static int sof_es8316_speaker_power_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_card *card = w->dapm->card; + struct snd_soc_card *card = snd_soc_dapm_to_card(w->dapm); struct sof_es8336_private *priv = snd_soc_card_get_drvdata(card); if (priv->speaker_en == !SND_SOC_DAPM_EVENT_ON(event)) @@ -231,16 +231,17 @@ static struct snd_soc_jack_pin sof_es8316_jack_pins[] = { static int dmic_init(struct snd_soc_pcm_runtime *runtime) { struct snd_soc_card *card = runtime->card; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); int ret; - ret = snd_soc_dapm_new_controls(&card->dapm, dmic_widgets, + ret = snd_soc_dapm_new_controls(dapm, dmic_widgets, ARRAY_SIZE(dmic_widgets)); if (ret) { dev_err(card->dev, "DMic widget addition failed: %d\n", ret); return ret; } - ret = snd_soc_dapm_add_routes(&card->dapm, dmic_map, + ret = snd_soc_dapm_add_routes(dapm, dmic_map, ARRAY_SIZE(dmic_map)); if (ret) dev_err(card->dev, "DMic map addition failed: %d\n", ret); @@ -271,12 +272,13 @@ static int sof_es8316_init(struct snd_soc_pcm_runtime *runtime) { struct snd_soc_component *codec = snd_soc_rtd_to_codec(runtime, 0)->component; struct snd_soc_card *card = runtime->card; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); struct sof_es8336_private *priv = snd_soc_card_get_drvdata(card); const struct snd_soc_dapm_route *custom_map; int num_routes; int ret; - card->dapm.idle_bias = false; + snd_soc_dapm_set_idle_bias(dapm, false); if (quirk & SOC_ES8336_HEADSET_MIC1) { custom_map = sof_es8316_headset_mic1_map; @@ -286,7 +288,7 @@ static int sof_es8316_init(struct snd_soc_pcm_runtime *runtime) num_routes = ARRAY_SIZE(sof_es8316_headset_mic2_map); } - ret = snd_soc_dapm_add_routes(&card->dapm, custom_map, num_routes); + ret = snd_soc_dapm_add_routes(dapm, custom_map, num_routes); if (ret) return ret; diff --git a/sound/soc/intel/boards/sof_maxim_common.c b/sound/soc/intel/boards/sof_maxim_common.c index c98a67ae5e6626..c3d0f697ff8de1 100644 --- a/sound/soc/intel/boards/sof_maxim_common.c +++ b/sound/soc/intel/boards/sof_maxim_common.c @@ -201,8 +201,7 @@ static int max_98373_trigger(struct snd_pcm_substream *substream, int cmd) cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); for_each_rtd_codec_dais(rtd, j, codec_dai) { - struct snd_soc_dapm_context *dapm = - snd_soc_component_get_dapm(cpu_dai->component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(cpu_dai->component); char pin_name[MAX_98373_PIN_NAME]; snprintf(pin_name, ARRAY_SIZE(pin_name), "%s Spk", @@ -239,12 +238,13 @@ static const struct snd_soc_ops max_98373_ops = { static int max_98373_spk_codec_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_card *card = rtd->card; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); unsigned int num_codecs = get_num_codecs(MAX_98373_ACPI_HID); int ret; switch (num_codecs) { case 2: - ret = snd_soc_dapm_new_controls(&card->dapm, maxim_2spk_widgets, + ret = snd_soc_dapm_new_controls(dapm, maxim_2spk_widgets, ARRAY_SIZE(maxim_2spk_widgets)); if (ret) { dev_err(rtd->dev, "fail to add max98373 widgets, ret %d\n", @@ -260,7 +260,7 @@ static int max_98373_spk_codec_init(struct snd_soc_pcm_runtime *rtd) return ret; } - ret = snd_soc_dapm_add_routes(&card->dapm, max_98373_dapm_routes, + ret = snd_soc_dapm_add_routes(dapm, max_98373_dapm_routes, ARRAY_SIZE(max_98373_dapm_routes)); if (ret) { dev_err(rtd->dev, "fail to add max98373 routes, ret %d\n", @@ -416,13 +416,14 @@ static int max_98390_hw_params(struct snd_pcm_substream *substream, static int max_98390_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_card *card = rtd->card; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); unsigned int num_codecs = get_num_codecs(MAX_98390_ACPI_HID); int ret; switch (num_codecs) { case 4: /* add widgets/controls/dapm for tweeter speakers */ - ret = snd_soc_dapm_new_controls(&card->dapm, max_98390_tt_dapm_widgets, + ret = snd_soc_dapm_new_controls(dapm, max_98390_tt_dapm_widgets, ARRAY_SIZE(max_98390_tt_dapm_widgets)); if (ret) { dev_err(rtd->dev, "unable to add tweeter dapm widgets, ret %d\n", @@ -439,7 +440,7 @@ static int max_98390_init(struct snd_soc_pcm_runtime *rtd) return ret; } - ret = snd_soc_dapm_add_routes(&card->dapm, max_98390_tt_dapm_routes, + ret = snd_soc_dapm_add_routes(dapm, max_98390_tt_dapm_routes, ARRAY_SIZE(max_98390_tt_dapm_routes)); if (ret) { dev_err(rtd->dev, "unable to add tweeter dapm routes, ret %d\n", @@ -450,7 +451,7 @@ static int max_98390_init(struct snd_soc_pcm_runtime *rtd) fallthrough; case 2: /* add regular speakers dapm route */ - ret = snd_soc_dapm_new_controls(&card->dapm, maxim_2spk_widgets, + ret = snd_soc_dapm_new_controls(dapm, maxim_2spk_widgets, ARRAY_SIZE(maxim_2spk_widgets)); if (ret) { dev_err(rtd->dev, "fail to add max98390 woofer widgets, ret %d\n", @@ -466,7 +467,7 @@ static int max_98390_init(struct snd_soc_pcm_runtime *rtd) return ret; } - ret = snd_soc_dapm_add_routes(&card->dapm, max_98390_dapm_routes, + ret = snd_soc_dapm_add_routes(dapm, max_98390_dapm_routes, ARRAY_SIZE(max_98390_dapm_routes)); if (ret) { dev_err(rtd->dev, "unable to add dapm routes, ret %d\n", @@ -564,9 +565,10 @@ static struct snd_soc_dai_link_component max_98360a_components[] = { static int max_98357a_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_card *card = rtd->card; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); int ret; - ret = snd_soc_dapm_new_controls(&card->dapm, max_98357a_dapm_widgets, + ret = snd_soc_dapm_new_controls(dapm, max_98357a_dapm_widgets, ARRAY_SIZE(max_98357a_dapm_widgets)); if (ret) { dev_err(rtd->dev, "unable to add dapm controls, ret %d\n", ret); @@ -581,7 +583,7 @@ static int max_98357a_init(struct snd_soc_pcm_runtime *rtd) return ret; } - ret = snd_soc_dapm_add_routes(&card->dapm, max_98357a_dapm_routes, + ret = snd_soc_dapm_add_routes(dapm, max_98357a_dapm_routes, ARRAY_SIZE(max_98357a_dapm_routes)); if (ret) diff --git a/sound/soc/intel/boards/sof_nau8825.c b/sound/soc/intel/boards/sof_nau8825.c index 72ce32e2cd57d9..15ba6f5c697c47 100644 --- a/sound/soc/intel/boards/sof_nau8825.c +++ b/sound/soc/intel/boards/sof_nau8825.c @@ -122,7 +122,7 @@ static const struct snd_soc_ops sof_nau8825_ops = { static int sof_card_late_probe(struct snd_soc_card *card) { struct sof_card_private *ctx = snd_soc_card_get_drvdata(card); - struct snd_soc_dapm_context *dapm = &card->dapm; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); int err; if (ctx->amp_type == CODEC_MAX98373) { diff --git a/sound/soc/intel/boards/sof_nuvoton_common.c b/sound/soc/intel/boards/sof_nuvoton_common.c index ed41cb6f7fa594..b09ecbab2fc9cb 100644 --- a/sound/soc/intel/boards/sof_nuvoton_common.c +++ b/sound/soc/intel/boards/sof_nuvoton_common.c @@ -34,9 +34,10 @@ static struct snd_soc_dai_link_component nau8318_components[] = { static int nau8318_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_card *card = rtd->card; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); int ret; - ret = snd_soc_dapm_new_controls(&card->dapm, nau8318_widgets, + ret = snd_soc_dapm_new_controls(dapm, nau8318_widgets, ARRAY_SIZE(nau8318_widgets)); if (ret) { dev_err(rtd->dev, "fail to add nau8318 widgets, ret %d\n", ret); @@ -50,7 +51,7 @@ static int nau8318_init(struct snd_soc_pcm_runtime *rtd) return ret; } - ret = snd_soc_dapm_add_routes(&card->dapm, nau8318_routes, + ret = snd_soc_dapm_add_routes(dapm, nau8318_routes, ARRAY_SIZE(nau8318_routes)); if (ret) { diff --git a/sound/soc/intel/boards/sof_pcm512x.c b/sound/soc/intel/boards/sof_pcm512x.c index 2f43710c1baeda..359559b6175b2d 100644 --- a/sound/soc/intel/boards/sof_pcm512x.c +++ b/sound/soc/intel/boards/sof_pcm512x.c @@ -177,9 +177,10 @@ static const struct snd_soc_dapm_route dmic_map[] = { static int dmic_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_card *card = rtd->card; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); int ret; - ret = snd_soc_dapm_new_controls(&card->dapm, dmic_widgets, + ret = snd_soc_dapm_new_controls(dapm, dmic_widgets, ARRAY_SIZE(dmic_widgets)); if (ret) { dev_err(card->dev, "DMic widget addition failed: %d\n", ret); @@ -187,7 +188,7 @@ static int dmic_init(struct snd_soc_pcm_runtime *rtd) return ret; } - ret = snd_soc_dapm_add_routes(&card->dapm, dmic_map, + ret = snd_soc_dapm_add_routes(dapm, dmic_map, ARRAY_SIZE(dmic_map)); if (ret) diff --git a/sound/soc/intel/boards/sof_realtek_common.c b/sound/soc/intel/boards/sof_realtek_common.c index 600707d403b9d5..835186cf04d020 100644 --- a/sound/soc/intel/boards/sof_realtek_common.c +++ b/sound/soc/intel/boards/sof_realtek_common.c @@ -186,13 +186,14 @@ static const struct snd_soc_ops rt1011_ops = { static int rt1011_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_card *card = rtd->card; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); unsigned int num_codecs = get_num_codecs(RT1011_ACPI_HID); int ret; switch (num_codecs) { case 2: if (!soc_intel_is_cml()) { - ret = snd_soc_dapm_new_controls(&card->dapm, realtek_2spk_widgets, + ret = snd_soc_dapm_new_controls(dapm, realtek_2spk_widgets, ARRAY_SIZE(realtek_2spk_widgets)); if (ret) { dev_err(rtd->dev, "fail to add rt1011 widgets, ret %d\n", @@ -208,7 +209,7 @@ static int rt1011_init(struct snd_soc_pcm_runtime *rtd) return ret; } - ret = snd_soc_dapm_add_routes(&card->dapm, speaker_map_lr, + ret = snd_soc_dapm_add_routes(dapm, speaker_map_lr, ARRAY_SIZE(speaker_map_lr)); if (ret) { dev_err(rtd->dev, "fail to add rt1011 routes, ret %d\n", @@ -225,24 +226,21 @@ static int rt1011_init(struct snd_soc_pcm_runtime *rtd) */ fallthrough; case 4: - ret = snd_soc_dapm_new_controls(&card->dapm, realtek_4spk_widgets, - num_codecs); + ret = snd_soc_dapm_new_controls(dapm, realtek_4spk_widgets, num_codecs); if (ret) { dev_err(rtd->dev, "fail to add rt1011 widgets, ret %d\n", ret); return ret; } - ret = snd_soc_add_card_controls(card, realtek_4spk_kcontrols, - num_codecs); + ret = snd_soc_add_card_controls(card, realtek_4spk_kcontrols, num_codecs); if (ret) { dev_err(rtd->dev, "fail to add rt1011 controls, ret %d\n", ret); return ret; } - ret = snd_soc_dapm_add_routes(&card->dapm, rt1011_4spk_routes, - num_codecs); + ret = snd_soc_dapm_add_routes(dapm, rt1011_4spk_routes, num_codecs); if (ret) { dev_err(rtd->dev, "fail to add rt1011 routes, ret %d\n", ret); @@ -344,9 +342,10 @@ static const struct snd_soc_ops rt1015p_ops = { static int rt1015p_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_card *card = rtd->card; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); int ret; - ret = snd_soc_dapm_new_controls(&card->dapm, realtek_2spk_widgets, + ret = snd_soc_dapm_new_controls(dapm, realtek_2spk_widgets, ARRAY_SIZE(realtek_2spk_widgets)); if (ret) { dev_err(rtd->dev, "fail to add rt1015p widgets, ret %d\n", ret); @@ -360,7 +359,7 @@ static int rt1015p_init(struct snd_soc_pcm_runtime *rtd) return ret; } - ret = snd_soc_dapm_add_routes(&card->dapm, rt1015p_dapm_routes, + ret = snd_soc_dapm_add_routes(dapm, rt1015p_dapm_routes, ARRAY_SIZE(rt1015p_dapm_routes)); if (ret) dev_err(rtd->dev, "Speaker map addition failed: %d\n", ret); @@ -481,12 +480,13 @@ static struct snd_soc_dai_link_component rt1015_components[] = { static int speaker_codec_init_lr(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_card *card = rtd->card; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); unsigned int num_codecs = get_num_codecs(RT1015_ACPI_HID); int ret; switch (num_codecs) { case 2: - ret = snd_soc_dapm_new_controls(&card->dapm, realtek_2spk_widgets, + ret = snd_soc_dapm_new_controls(dapm, realtek_2spk_widgets, ARRAY_SIZE(realtek_2spk_widgets)); if (ret) { dev_err(rtd->dev, "fail to add rt1015 widgets, ret %d\n", @@ -502,7 +502,7 @@ static int speaker_codec_init_lr(struct snd_soc_pcm_runtime *rtd) return ret; } - ret = snd_soc_dapm_add_routes(&rtd->card->dapm, speaker_map_lr, + ret = snd_soc_dapm_add_routes(dapm, speaker_map_lr, ARRAY_SIZE(speaker_map_lr)); if (ret) { dev_err(rtd->dev, "fail to add rt1015 routes, ret %d\n", @@ -561,9 +561,10 @@ static struct snd_soc_dai_link_component rt1308_components[] = { static int rt1308_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_card *card = rtd->card; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); int ret; - ret = snd_soc_dapm_new_controls(&card->dapm, rt1308_dapm_widgets, + ret = snd_soc_dapm_new_controls(dapm, rt1308_dapm_widgets, ARRAY_SIZE(rt1308_dapm_widgets)); if (ret) { dev_err(rtd->dev, "fail to add dapm controls, ret %d\n", ret); @@ -577,7 +578,7 @@ static int rt1308_init(struct snd_soc_pcm_runtime *rtd) return ret; } - ret = snd_soc_dapm_add_routes(&card->dapm, rt1308_dapm_routes, + ret = snd_soc_dapm_add_routes(dapm, rt1308_dapm_routes, ARRAY_SIZE(rt1308_dapm_routes)); if (ret) @@ -650,9 +651,10 @@ static struct snd_soc_dai_link_component rt1019p_components[] = { static int rt1019p_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_card *card = rtd->card; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); int ret; - ret = snd_soc_dapm_new_controls(&card->dapm, realtek_2spk_widgets, + ret = snd_soc_dapm_new_controls(dapm, realtek_2spk_widgets, ARRAY_SIZE(realtek_2spk_widgets)); if (ret) { dev_err(rtd->dev, "fail to add rt1019p widgets, ret %d\n", ret); @@ -666,7 +668,7 @@ static int rt1019p_init(struct snd_soc_pcm_runtime *rtd) return ret; } - ret = snd_soc_dapm_add_routes(&card->dapm, rt1019p_dapm_routes, + ret = snd_soc_dapm_add_routes(dapm, rt1019p_dapm_routes, ARRAY_SIZE(rt1019p_dapm_routes)); if (ret) { dev_err(rtd->dev, "Speaker map addition failed: %d\n", ret); diff --git a/sound/soc/intel/boards/sof_rt5682.c b/sound/soc/intel/boards/sof_rt5682.c index f60e68bcb2ab9a..649378957b2038 100644 --- a/sound/soc/intel/boards/sof_rt5682.c +++ b/sound/soc/intel/boards/sof_rt5682.c @@ -409,7 +409,7 @@ static const struct snd_soc_ops sof_rt5682_ops = { static int sof_card_late_probe(struct snd_soc_card *card) { struct sof_card_private *ctx = snd_soc_card_get_drvdata(card); - struct snd_soc_dapm_context *dapm = &card->dapm; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); int err; if (ctx->amp_type == CODEC_MAX98373) { @@ -463,9 +463,10 @@ static const struct snd_soc_dapm_route rt5650_spk_dapm_routes[] = { static int rt5650_spk_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_card *card = rtd->card; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); int ret; - ret = snd_soc_dapm_new_controls(&card->dapm, rt5650_spk_widgets, + ret = snd_soc_dapm_new_controls(dapm, rt5650_spk_widgets, ARRAY_SIZE(rt5650_spk_widgets)); if (ret) { dev_err(rtd->dev, "fail to add rt5650 spk widgets, ret %d\n", @@ -481,7 +482,7 @@ static int rt5650_spk_init(struct snd_soc_pcm_runtime *rtd) return ret; } - ret = snd_soc_dapm_add_routes(&card->dapm, rt5650_spk_dapm_routes, + ret = snd_soc_dapm_add_routes(dapm, rt5650_spk_dapm_routes, ARRAY_SIZE(rt5650_spk_dapm_routes)); if (ret) dev_err(rtd->dev, "fail to add dapm routes, ret=%d\n", ret); diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c index e38afc17ece2a0..c726d6c30f640f 100644 --- a/sound/soc/intel/boards/sof_sdw.c +++ b/sound/soc/intel/boards/sof_sdw.c @@ -1208,8 +1208,11 @@ static int sof_card_dai_links_create(struct snd_soc_card *card) struct asoc_sdw_codec_info *ssp_info; struct asoc_sdw_endpoint *sof_ends; struct asoc_sdw_dailink *sof_dais; + struct snd_soc_aux_dev *sof_aux; int num_devs = 0; int num_ends = 0; + int num_aux = 0; + int num_confs; struct snd_soc_dai_link *dai_links; int num_links; int be_id = 0; @@ -1217,12 +1220,14 @@ static int sof_card_dai_links_create(struct snd_soc_card *card) unsigned long ssp_mask; int ret; - ret = asoc_sdw_count_sdw_endpoints(card, &num_devs, &num_ends); + ret = asoc_sdw_count_sdw_endpoints(card, &num_devs, &num_ends, &num_aux); if (ret < 0) { dev_err(dev, "failed to count devices/endpoints: %d\n", ret); return ret; } + num_confs = num_ends; + /* * One per DAI link, worst case is a DAI link for every endpoint, also * add one additional to act as a terminator such that code can iterate @@ -1239,7 +1244,13 @@ static int sof_card_dai_links_create(struct snd_soc_card *card) goto err_dai; } - ret = asoc_sdw_parse_sdw_endpoints(card, sof_dais, sof_ends, &num_devs); + sof_aux = devm_kcalloc(dev, num_aux, sizeof(*sof_aux), GFP_KERNEL); + if (!sof_aux) { + ret = -ENOMEM; + goto err_dai; + } + + ret = asoc_sdw_parse_sdw_endpoints(card, sof_aux, sof_dais, sof_ends, &num_confs); if (ret < 0) goto err_end; @@ -1287,7 +1298,7 @@ static int sof_card_dai_links_create(struct snd_soc_card *card) sdw_be_num, ssp_num, dmic_num, intel_ctx->hdmi.idisp_codec ? hdmi_num : 0, bt_num); - codec_conf = devm_kcalloc(dev, num_devs, sizeof(*codec_conf), GFP_KERNEL); + codec_conf = devm_kcalloc(dev, num_confs, sizeof(*codec_conf), GFP_KERNEL); if (!codec_conf) { ret = -ENOMEM; goto err_end; @@ -1302,9 +1313,11 @@ static int sof_card_dai_links_create(struct snd_soc_card *card) } card->codec_conf = codec_conf; - card->num_configs = num_devs; + card->num_configs = num_confs; card->dai_link = dai_links; card->num_links = num_links; + card->aux_dev = sof_aux; + card->num_aux_devs = num_aux; /* SDW */ if (sdw_be_num) { diff --git a/sound/soc/intel/catpt/device.c b/sound/soc/intel/catpt/device.c index faa916f400693c..d13062c8e907cc 100644 --- a/sound/soc/intel/catpt/device.c +++ b/sound/soc/intel/catpt/device.c @@ -28,7 +28,7 @@ #define CREATE_TRACE_POINTS #include "trace.h" -static int catpt_suspend(struct device *dev) +static int catpt_do_suspend(struct device *dev) { struct catpt_dev *cdev = dev_get_drvdata(dev); struct dma_chan *chan; @@ -72,6 +72,13 @@ static int catpt_suspend(struct device *dev) return catpt_dsp_power_down(cdev); } +/* Do not block the system from suspending, recover on resume() if needed. */ +static int catpt_suspend(struct device *dev) +{ + catpt_do_suspend(dev); + return 0; +} + static int catpt_resume(struct device *dev) { struct catpt_dev *cdev = dev_get_drvdata(dev); @@ -114,7 +121,7 @@ static int catpt_runtime_suspend(struct device *dev) } module_put(dev->driver->owner); - return catpt_suspend(dev); + return catpt_do_suspend(dev); } static int catpt_runtime_resume(struct device *dev) @@ -184,22 +191,25 @@ static int catpt_probe_components(struct catpt_dev *cdev) goto err_boot_fw; } - ret = catpt_register_board(cdev); - if (ret) { - dev_err(cdev->dev, "register board failed: %d\n", ret); - goto err_reg_board; - } - /* reflect actual ADSP state in pm_runtime */ pm_runtime_set_active(cdev->dev); pm_runtime_set_autosuspend_delay(cdev->dev, 2000); pm_runtime_use_autosuspend(cdev->dev); pm_runtime_mark_last_busy(cdev->dev); + /* Enable PM before spawning child device. See catpt_dai_pcm_new(). */ pm_runtime_enable(cdev->dev); + + ret = catpt_register_board(cdev); + if (ret) { + dev_err(cdev->dev, "register board failed: %d\n", ret); + goto err_reg_board; + } + return 0; err_reg_board: + pm_runtime_disable(cdev->dev); snd_soc_unregister_component(cdev->dev); err_boot_fw: catpt_dmac_remove(cdev); diff --git a/sound/soc/intel/catpt/loader.c b/sound/soc/intel/catpt/loader.c index 696d84314eeb5e..f5705cd2c1e113 100644 --- a/sound/soc/intel/catpt/loader.c +++ b/sound/soc/intel/catpt/loader.c @@ -208,6 +208,7 @@ static int catpt_restore_memdumps(struct catpt_dev *cdev, struct dma_chan *chan) for (i = 0; i < cdev->dx_ctx.num_meminfo; i++) { struct catpt_save_meminfo *info; + struct resource r = {}; u32 off; int ret; @@ -216,7 +217,8 @@ static int catpt_restore_memdumps(struct catpt_dev *cdev, struct dma_chan *chan) continue; off = catpt_to_host_offset(info->offset); - if (off < cdev->dram.start || off > cdev->dram.end) + resource_set_range(&r, off, info->size); + if (!resource_contains(&cdev->dram, &r)) continue; dev_dbg(cdev->dev, "restoring memdump: off 0x%08x size %d\n", @@ -239,34 +241,32 @@ static int catpt_restore_fwimage(struct catpt_dev *cdev, struct dma_chan *chan, dma_addr_t paddr, struct catpt_fw_block_hdr *blk) { - struct resource r1, r2, common; + struct resource r1 = {}; int i; print_hex_dump_debug(__func__, DUMP_PREFIX_OFFSET, 8, 4, blk, sizeof(*blk), false); - r1.start = cdev->dram.start + blk->ram_offset; - r1.end = r1.start + blk->size - 1; + resource_set_range(&r1, cdev->dram.start + blk->ram_offset, blk->size); /* advance to data area */ paddr += sizeof(*blk); for (i = 0; i < cdev->dx_ctx.num_meminfo; i++) { struct catpt_save_meminfo *info; + struct resource common = {}; + struct resource r2 = {}; u32 off; int ret; info = &cdev->dx_ctx.meminfo[i]; - if (info->source != CATPT_DX_TYPE_FW_IMAGE) continue; off = catpt_to_host_offset(info->offset); - if (off < cdev->dram.start || off > cdev->dram.end) + resource_set_range(&r2, off, info->size); + if (!resource_contains(&cdev->dram, &r2)) continue; - r2.start = off; - r2.end = r2.start + info->size - 1; - if (!resource_intersection(&r2, &r1, &common)) continue; /* calculate start offset of common data area */ diff --git a/sound/soc/intel/catpt/pcm.c b/sound/soc/intel/catpt/pcm.c index f15385683d9ce9..abd1cb07c60c49 100644 --- a/sound/soc/intel/catpt/pcm.c +++ b/sound/soc/intel/catpt/pcm.c @@ -417,8 +417,10 @@ static int catpt_dai_hw_params(struct snd_pcm_substream *substream, return CATPT_IPC_ERROR(ret); ret = catpt_dai_apply_usettings(dai, stream); - if (ret) + if (ret) { + catpt_ipc_free_stream(cdev, stream->info.stream_hw_id); return ret; + } stream->allocated = true; return 0; @@ -669,7 +671,7 @@ static int catpt_dai_pcm_new(struct snd_soc_pcm_runtime *rtm, return 0; ret = pm_runtime_resume_and_get(cdev->dev); - if (ret < 0 && ret != -EACCES) + if (ret) return ret; ret = catpt_ipc_set_device_format(cdev, &devfmt); @@ -872,7 +874,7 @@ static int catpt_mixer_volume_get(struct snd_kcontrol *kcontrol, int i; ret = pm_runtime_resume_and_get(cdev->dev); - if (ret < 0 && ret != -EACCES) + if (ret) return ret; for (i = 0; i < CATPT_CHANNELS_MAX; i++) { @@ -893,7 +895,7 @@ static int catpt_mixer_volume_put(struct snd_kcontrol *kcontrol, int ret; ret = pm_runtime_resume_and_get(cdev->dev); - if (ret < 0 && ret != -EACCES) + if (ret) return ret; ret = catpt_set_dspvol(cdev, cdev->mixer.mixer_hw_id, @@ -924,7 +926,7 @@ static int catpt_stream_volume_get(struct snd_kcontrol *kcontrol, } ret = pm_runtime_resume_and_get(cdev->dev); - if (ret < 0 && ret != -EACCES) + if (ret) return ret; for (i = 0; i < CATPT_CHANNELS_MAX; i++) { @@ -955,7 +957,7 @@ static int catpt_stream_volume_put(struct snd_kcontrol *kcontrol, } ret = pm_runtime_resume_and_get(cdev->dev); - if (ret < 0 && ret != -EACCES) + if (ret) return ret; ret = catpt_set_dspvol(cdev, stream->info.stream_hw_id, @@ -1031,7 +1033,7 @@ static int catpt_loopback_switch_put(struct snd_kcontrol *kcontrol, } ret = pm_runtime_resume_and_get(cdev->dev); - if (ret < 0 && ret != -EACCES) + if (ret) return ret; ret = catpt_ipc_mute_loopback(cdev, stream->info.stream_hw_id, mute); diff --git a/sound/soc/intel/catpt/sysfs.c b/sound/soc/intel/catpt/sysfs.c index 048253002ec87c..e961e172f9b760 100644 --- a/sound/soc/intel/catpt/sysfs.c +++ b/sound/soc/intel/catpt/sysfs.c @@ -16,7 +16,7 @@ static ssize_t fw_version_show(struct device *dev, int ret; ret = pm_runtime_resume_and_get(cdev->dev); - if (ret < 0 && ret != -EACCES) + if (ret) return ret; ret = catpt_ipc_get_fw_version(cdev, &version); diff --git a/sound/soc/mediatek/Kconfig b/sound/soc/mediatek/Kconfig index 10ca8bccabdd8d..3a1e1fa3fe5cc7 100644 --- a/sound/soc/mediatek/Kconfig +++ b/sound/soc/mediatek/Kconfig @@ -246,6 +246,37 @@ config SND_SOC_MT8188_MT6359 Select Y if you have such device. If unsure select "N". +config SND_SOC_MT8189 + tristate "ASoC support for Mediatek MT8189 chip" + depends on ARCH_MEDIATEK + select SND_SOC_MEDIATEK + help + This adds ASoC driver for Mediatek MT8189 boards + that can be used with other codecs. + Select Y if you have such device. + If unsure select "N". + +config SND_SOC_MT8189_NAU8825 + tristate "ASoc Audio driver for MT8189 with NAU8825 and I2S codec" + depends on SND_SOC_MT8189 + depends on I2C + select SND_SOC_DMIC + select SND_SOC_HDMI_CODEC + select SND_SOC_NAU8825 + select SND_SOC_RT5645 + select SND_SOC_RT9123P + select SND_SOC_RT1015P + select SND_SOC_RT5682S + select SND_SOC_RT5682_I2C + select SND_SOC_CS35L41_I2C + select SND_SOC_AW88081 + select SND_SOC_ES8326 + help + This adds support for ASoC machine driver for MediaTek MT8189 + boards with the NAU8828 and other I2S audio codecs. + Select Y if you have such device. + If unsure select "N". + config SND_SOC_MT8192 tristate "ASoC support for Mediatek MT8192 chip" depends on ARCH_MEDIATEK diff --git a/sound/soc/mediatek/Makefile b/sound/soc/mediatek/Makefile index 4b55434f216851..7cd67bce92e9a4 100644 --- a/sound/soc/mediatek/Makefile +++ b/sound/soc/mediatek/Makefile @@ -10,3 +10,4 @@ obj-$(CONFIG_SND_SOC_MT8188) += mt8188/ obj-$(CONFIG_SND_SOC_MT8192) += mt8192/ obj-$(CONFIG_SND_SOC_MT8195) += mt8195/ obj-$(CONFIG_SND_SOC_MT8365) += mt8365/ +obj-$(CONFIG_SND_SOC_MT8189) += mt8189/ diff --git a/sound/soc/mediatek/common/mtk-afe-platform-driver.c b/sound/soc/mediatek/common/mtk-afe-platform-driver.c index 70fd05d5ff486c..938dd3d46b0039 100644 --- a/sound/soc/mediatek/common/mtk-afe-platform-driver.c +++ b/sound/soc/mediatek/common/mtk-afe-platform-driver.c @@ -48,6 +48,7 @@ EXPORT_SYMBOL_GPL(mtk_afe_combine_sub_dai); int mtk_afe_add_sub_dai_control(struct snd_soc_component *component) { + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component); struct mtk_base_afe_dai *dai; @@ -58,19 +59,19 @@ int mtk_afe_add_sub_dai_control(struct snd_soc_component *component) dai->num_controls); if (dai->dapm_widgets) - snd_soc_dapm_new_controls(&component->dapm, + snd_soc_dapm_new_controls(dapm, dai->dapm_widgets, dai->num_dapm_widgets); } /* add routes after all widgets are added */ list_for_each_entry(dai, &afe->sub_dais, list) { if (dai->dapm_routes) - snd_soc_dapm_add_routes(&component->dapm, + snd_soc_dapm_add_routes(dapm, dai->dapm_routes, dai->num_dapm_routes); } - snd_soc_dapm_new_widgets(component->dapm.card); + snd_soc_dapm_new_widgets(component->card); return 0; diff --git a/sound/soc/mediatek/common/mtk-dsp-sof-common.c b/sound/soc/mediatek/common/mtk-dsp-sof-common.c index bca758dca2c9a6..fd10616a08a065 100644 --- a/sound/soc/mediatek/common/mtk-dsp-sof-common.c +++ b/sound/soc/mediatek/common/mtk-dsp-sof-common.c @@ -139,6 +139,7 @@ static int mtk_sof_check_tplg_be_dai_link_fixup(struct snd_soc_pcm_runtime *rtd, int mtk_sof_card_late_probe(struct snd_soc_card *card) { + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); struct snd_soc_pcm_runtime *rtd; struct snd_soc_component *sof_comp = NULL; struct mtk_soc_card_data *soc_card_data = @@ -204,13 +205,13 @@ int mtk_sof_card_late_probe(struct snd_soc_card *card) snd_soc_dapm_widget_for_each_sink_path(widget, p) { route.source = conn->sof_dma; route.sink = p->sink->name; - snd_soc_dapm_add_routes(&card->dapm, &route, 1); + snd_soc_dapm_add_routes(dapm, &route, 1); } } else if (conn->stream_dir == SNDRV_PCM_STREAM_PLAYBACK && widget) { snd_soc_dapm_widget_for_each_source_path(widget, p) { route.source = p->source->name; route.sink = conn->sof_dma; - snd_soc_dapm_add_routes(&card->dapm, &route, 1); + snd_soc_dapm_add_routes(dapm, &route, 1); } } else { dev_err(cpu_dai->dev, "stream dir and widget not pair\n"); diff --git a/sound/soc/mediatek/mt8186/mt8186-mt6366-common.c b/sound/soc/mediatek/mt8186/mt8186-mt6366-common.c index fa08eb0654d88f..e325d216c00890 100644 --- a/sound/soc/mediatek/mt8186/mt8186-mt6366-common.c +++ b/sound/soc/mediatek/mt8186/mt8186-mt6366-common.c @@ -21,7 +21,7 @@ int mt8186_mt6366_init(struct snd_soc_pcm_runtime *rtd) snd_soc_rtd_to_codec(rtd, 0)->component; struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt_afe); struct mt8186_afe_private *afe_priv = afe->platform_priv; - struct snd_soc_dapm_context *dapm = &rtd->card->dapm; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(rtd->card); int ret; /* set mtkaif protocol */ diff --git a/sound/soc/mediatek/mt8186/mt8186-mt6366.c b/sound/soc/mediatek/mt8186/mt8186-mt6366.c index 45df69809cbabf..2c3033f305eaf9 100644 --- a/sound/soc/mediatek/mt8186/mt8186-mt6366.c +++ b/sound/soc/mediatek/mt8186/mt8186-mt6366.c @@ -88,9 +88,9 @@ static struct snd_soc_codec_conf mt8186_mt6366_rt1019_rt5682s_codec_conf[] = { static int dmic_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol); - struct mtk_soc_card_data *soc_card_data = - snd_soc_card_get_drvdata(dapm->card); + struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kcontrol); + struct snd_soc_card *card = snd_soc_dapm_to_card(dapm); + struct mtk_soc_card_data *soc_card_data = snd_soc_card_get_drvdata(card); struct mt8186_mt6366_rt1019_rt5682s_priv *priv = soc_card_data->mach_priv; ucontrol->value.integer.value[0] = priv->dmic_switch; @@ -100,15 +100,15 @@ static int dmic_get(struct snd_kcontrol *kcontrol, static int dmic_set(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol); - struct mtk_soc_card_data *soc_card_data = - snd_soc_card_get_drvdata(dapm->card); + struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kcontrol); + struct snd_soc_card *card = snd_soc_dapm_to_card(dapm); + struct mtk_soc_card_data *soc_card_data = snd_soc_card_get_drvdata(card); struct mt8186_mt6366_rt1019_rt5682s_priv *priv = soc_card_data->mach_priv; priv->dmic_switch = ucontrol->value.integer.value[0]; if (priv->dmic_sel) { gpiod_set_value(priv->dmic_sel, priv->dmic_switch); - dev_dbg(dapm->card->dev, "dmic_set_value %d\n", + dev_dbg(card->dev, "dmic_set_value %d\n", priv->dmic_switch); } return 0; @@ -140,6 +140,7 @@ static const struct snd_soc_dapm_route dmic_map[] = { static int primary_codec_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_card *card = rtd->card; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); struct mtk_soc_card_data *soc_card_data = snd_soc_card_get_drvdata(card); struct mt8186_mt6366_rt1019_rt5682s_priv *priv = soc_card_data->mach_priv; int ret; @@ -156,7 +157,7 @@ static int primary_codec_init(struct snd_soc_pcm_runtime *rtd) return 0; } - ret = snd_soc_dapm_new_controls(&card->dapm, dmic_widgets, + ret = snd_soc_dapm_new_controls(dapm, dmic_widgets, ARRAY_SIZE(dmic_widgets)); if (ret) { dev_err(card->dev, "DMic widget addition failed: %d\n", ret); @@ -164,7 +165,7 @@ static int primary_codec_init(struct snd_soc_pcm_runtime *rtd) return ret; } - ret = snd_soc_dapm_add_routes(&card->dapm, dmic_map, + ret = snd_soc_dapm_add_routes(dapm, dmic_map, ARRAY_SIZE(dmic_map)); if (ret) diff --git a/sound/soc/mediatek/mt8188/mt8188-mt6359.c b/sound/soc/mediatek/mt8188/mt8188-mt6359.c index c6e7461e8f764c..55ebac0c3cef2a 100644 --- a/sound/soc/mediatek/mt8188/mt8188-mt6359.c +++ b/sound/soc/mediatek/mt8188/mt8188-mt6359.c @@ -684,9 +684,10 @@ static int mt8188_dptx_codec_init(struct snd_soc_pcm_runtime *rtd) static int mt8188_dumb_amp_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_card *card = rtd->card; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); int ret = 0; - ret = snd_soc_dapm_new_controls(&card->dapm, mt8188_dumb_spk_widgets, + ret = snd_soc_dapm_new_controls(dapm, mt8188_dumb_spk_widgets, ARRAY_SIZE(mt8188_dumb_spk_widgets)); if (ret) { dev_err(rtd->dev, "unable to add Dumb Speaker dapm, ret %d\n", ret); @@ -737,10 +738,11 @@ static const struct snd_soc_ops mt8188_max98390_ops = { static int mt8188_max98390_codec_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_card *card = rtd->card; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); int ret; /* add regular speakers dapm route */ - ret = snd_soc_dapm_new_controls(&card->dapm, mt8188_dual_spk_widgets, + ret = snd_soc_dapm_new_controls(dapm, mt8188_dual_spk_widgets, ARRAY_SIZE(mt8188_dual_spk_widgets)); if (ret) { dev_err(rtd->dev, "unable to add Left/Right Speaker widget, ret %d\n", ret); @@ -758,7 +760,7 @@ static int mt8188_max98390_codec_init(struct snd_soc_pcm_runtime *rtd) return 0; /* add widgets/controls/dapm for rear speakers */ - ret = snd_soc_dapm_new_controls(&card->dapm, mt8188_rear_spk_widgets, + ret = snd_soc_dapm_new_controls(dapm, mt8188_rear_spk_widgets, ARRAY_SIZE(mt8188_rear_spk_widgets)); if (ret) { dev_err(rtd->dev, "unable to add Rear Speaker widget, ret %d\n", ret); @@ -779,13 +781,14 @@ static int mt8188_max98390_codec_init(struct snd_soc_pcm_runtime *rtd) static int mt8188_headset_codec_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_card *card = rtd->card; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); struct mtk_soc_card_data *soc_card_data = snd_soc_card_get_drvdata(rtd->card); struct snd_soc_jack *jack = &soc_card_data->card_data->jacks[MT8188_JACK_HEADSET]; struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component; struct mtk_platform_card_data *card_data = soc_card_data->card_data; int ret; - ret = snd_soc_dapm_new_controls(&card->dapm, mt8188_nau8825_widgets, + ret = snd_soc_dapm_new_controls(dapm, mt8188_nau8825_widgets, ARRAY_SIZE(mt8188_nau8825_widgets)); if (ret) { dev_err(rtd->dev, "unable to add nau8825 card widget, ret %d\n", ret); @@ -815,14 +818,14 @@ static int mt8188_headset_codec_init(struct snd_soc_pcm_runtime *rtd) snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE); snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOLUMEUP); snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN); - snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOICECOMMAND); + snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOICECOMMAND); } else { snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE); snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOICECOMMAND); snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP); - snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN); + snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN); } - + ret = snd_soc_component_set_jack(component, jack, NULL); if (ret) { diff --git a/sound/soc/mediatek/mt8189/Makefile b/sound/soc/mediatek/mt8189/Makefile new file mode 100644 index 00000000000000..83a033284182ff --- /dev/null +++ b/sound/soc/mediatek/mt8189/Makefile @@ -0,0 +1,18 @@ +# SPDX-License-Identifier: GPL-2.0 + +# common include path +subdir-ccflags-y += -I$(srctree)/sound/soc/mediatek/common + +# platform driver +snd-soc-mt8189-afe-objs += \ + mt8189-afe-pcm.o \ + mt8189-afe-clk.o \ + mt8189-dai-adda.o \ + mt8189-dai-i2s.o \ + mt8189-dai-pcm.o \ + mt8189-dai-tdm.o + +obj-$(CONFIG_SND_SOC_MT8189) += snd-soc-mt8189-afe.o + +# machine driver +obj-$(CONFIG_SND_SOC_MT8189_NAU8825) += mt8189-nau8825.o diff --git a/sound/soc/mediatek/mt8189/mt8189-afe-clk.c b/sound/soc/mediatek/mt8189/mt8189-afe-clk.c new file mode 100644 index 00000000000000..fc7a7a73b0cf7d --- /dev/null +++ b/sound/soc/mediatek/mt8189/mt8189-afe-clk.c @@ -0,0 +1,750 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * mt8189-afe-clk.c -- Mediatek 8189 afe clock ctrl + * + * Copyright (c) 2025 MediaTek Inc. + * Author: Darren Ye + */ + +#include +#include +#include + +#include "mt8189-afe-common.h" +#include "mt8189-afe-clk.h" + +/* mck */ +struct mt8189_mck_div { + int m_sel_id; + int div_clk_id; +}; + +static const struct mt8189_mck_div mck_div[MT8189_MCK_NUM] = { + [MT8189_I2SIN0_MCK] = { + .m_sel_id = MT8189_CLK_TOP_I2SIN0_M_SEL, + .div_clk_id = MT8189_CLK_TOP_APLL12_DIV_I2SIN0, + }, + [MT8189_I2SIN1_MCK] = { + .m_sel_id = MT8189_CLK_TOP_I2SIN1_M_SEL, + .div_clk_id = MT8189_CLK_TOP_APLL12_DIV_I2SIN1, + }, + [MT8189_I2SOUT0_MCK] = { + .m_sel_id = MT8189_CLK_TOP_I2SOUT0_M_SEL, + .div_clk_id = MT8189_CLK_TOP_APLL12_DIV_I2SOUT0, + }, + [MT8189_I2SOUT1_MCK] = { + .m_sel_id = MT8189_CLK_TOP_I2SOUT1_M_SEL, + .div_clk_id = MT8189_CLK_TOP_APLL12_DIV_I2SOUT1, + }, + [MT8189_FMI2S_MCK] = { + .m_sel_id = MT8189_CLK_TOP_FMI2S_M_SEL, + .div_clk_id = MT8189_CLK_TOP_APLL12_DIV_FMI2S, + }, + [MT8189_TDMOUT_MCK] = { + .m_sel_id = MT8189_CLK_TOP_TDMOUT_M_SEL, + .div_clk_id = MT8189_CLK_TOP_APLL12_DIV_TDMOUT_M, + }, + [MT8189_TDMOUT_BCK] = { + .m_sel_id = -1, + .div_clk_id = MT8189_CLK_TOP_APLL12_DIV_TDMOUT_B, + }, +}; + +static const char *aud_clks[MT8189_CLK_NUM] = { + [MT8189_CLK_TOP_MUX_AUDIOINTBUS] = "top_aud_intbus", + [MT8189_CLK_TOP_MUX_AUD_ENG1] = "top_aud_eng1", + [MT8189_CLK_TOP_MUX_AUD_ENG2] = "top_aud_eng2", + [MT8189_CLK_TOP_MUX_AUDIO_H] = "top_aud_h", + /* pll */ + [MT8189_CLK_TOP_APLL1_CK] = "apll1", + [MT8189_CLK_TOP_APLL2_CK] = "apll2", + /* divider */ + [MT8189_CLK_TOP_APLL1_D4] = "apll1_d4", + [MT8189_CLK_TOP_APLL2_D4] = "apll2_d4", + [MT8189_CLK_TOP_APLL12_DIV_I2SIN0] = "apll12_div_i2sin0", + [MT8189_CLK_TOP_APLL12_DIV_I2SIN1] = "apll12_div_i2sin1", + [MT8189_CLK_TOP_APLL12_DIV_I2SOUT0] = "apll12_div_i2sout0", + [MT8189_CLK_TOP_APLL12_DIV_I2SOUT1] = "apll12_div_i2sout1", + [MT8189_CLK_TOP_APLL12_DIV_FMI2S] = "apll12_div_fmi2s", + [MT8189_CLK_TOP_APLL12_DIV_TDMOUT_M] = "apll12_div_tdmout_m", + [MT8189_CLK_TOP_APLL12_DIV_TDMOUT_B] = "apll12_div_tdmout_b", + /* mux */ + [MT8189_CLK_TOP_MUX_AUD_1] = "top_apll1", + [MT8189_CLK_TOP_MUX_AUD_2] = "top_apll2", + [MT8189_CLK_TOP_I2SIN0_M_SEL] = "top_i2sin0", + [MT8189_CLK_TOP_I2SIN1_M_SEL] = "top_i2sin1", + [MT8189_CLK_TOP_I2SOUT0_M_SEL] = "top_i2sout0", + [MT8189_CLK_TOP_I2SOUT1_M_SEL] = "top_i2sout1", + [MT8189_CLK_TOP_FMI2S_M_SEL] = "top_fmi2s", + [MT8189_CLK_TOP_TDMOUT_M_SEL] = "top_dptx", + /* top 26m*/ + [MT8189_CLK_TOP_CLK26M] = "clk26m", + /* peri */ + [MT8189_CLK_PERAO_AUDIO_SLV_CK_PERI] = "aud_slv_ck_peri", + [MT8189_CLK_PERAO_AUDIO_MST_CK_PERI] = "aud_mst_ck_peri", + [MT8189_CLK_PERAO_INTBUS_CK_PERI] = "aud_intbus_ck_peri", +}; + +int mt8189_afe_enable_clk(struct mtk_base_afe *afe, struct clk *clk) +{ + int ret; + + ret = clk_prepare_enable(clk); + if (ret) { + dev_err(afe->dev, "failed to enable clk\n"); + return ret; + } + + return 0; +} +EXPORT_SYMBOL_GPL(mt8189_afe_enable_clk); + +void mt8189_afe_disable_clk(struct mtk_base_afe *afe, struct clk *clk) +{ + if (clk) + clk_disable_unprepare(clk); + else + dev_dbg(afe->dev, "NULL clk\n"); +} +EXPORT_SYMBOL_GPL(mt8189_afe_disable_clk); + +static int mt8189_afe_set_clk_rate(struct mtk_base_afe *afe, struct clk *clk, + unsigned int rate) +{ + int ret; + + if (clk) { + ret = clk_set_rate(clk, rate); + if (ret) { + dev_err(afe->dev, "failed to set clk rate\n"); + return ret; + } + } + + return 0; +} + +static int mt8189_afe_set_clk_parent(struct mtk_base_afe *afe, struct clk *clk, + struct clk *parent) +{ + int ret; + + if (clk && parent) { + ret = clk_set_parent(clk, parent); + if (ret) { + dev_dbg(afe->dev, "failed to set clk parent %d\n", ret); + return ret; + } + } + + return 0; +} + +static unsigned int get_top_cg_reg(unsigned int cg_type) +{ + switch (cg_type) { + case MT8189_AUDIO_26M_EN_ON: + case MT8189_AUDIO_F3P25M_EN_ON: + case MT8189_AUDIO_APLL1_EN_ON: + case MT8189_AUDIO_APLL2_EN_ON: + return AUDIO_ENGEN_CON0; + case MT8189_CG_AUDIO_HOPPING_CK: + case MT8189_CG_AUDIO_F26M_CK: + case MT8189_CG_APLL1_CK: + case MT8189_CG_APLL2_CK: + case MT8189_PDN_APLL_TUNER2: + case MT8189_PDN_APLL_TUNER1: + return AUDIO_TOP_CON4; + default: + return 0; + } +} + +static unsigned int get_top_cg_mask(unsigned int cg_type) +{ + switch (cg_type) { + case MT8189_AUDIO_26M_EN_ON: + return AUDIO_26M_EN_ON_MASK_SFT; + case MT8189_AUDIO_F3P25M_EN_ON: + return AUDIO_F3P25M_EN_ON_MASK_SFT; + case MT8189_AUDIO_APLL1_EN_ON: + return AUDIO_APLL1_EN_ON_MASK_SFT; + case MT8189_AUDIO_APLL2_EN_ON: + return AUDIO_APLL2_EN_ON_MASK_SFT; + case MT8189_CG_AUDIO_HOPPING_CK: + return CG_AUDIO_HOPPING_CK_MASK_SFT; + case MT8189_CG_AUDIO_F26M_CK: + return CG_AUDIO_F26M_CK_MASK_SFT; + case MT8189_CG_APLL1_CK: + return CG_APLL1_CK_MASK_SFT; + case MT8189_CG_APLL2_CK: + return CG_APLL2_CK_MASK_SFT; + case MT8189_PDN_APLL_TUNER2: + return PDN_APLL_TUNER2_MASK_SFT; + case MT8189_PDN_APLL_TUNER1: + return PDN_APLL_TUNER1_MASK_SFT; + default: + return 0; + } +} + +static unsigned int get_top_cg_on_val(unsigned int cg_type) +{ + switch (cg_type) { + case MT8189_AUDIO_26M_EN_ON: + case MT8189_AUDIO_F3P25M_EN_ON: + case MT8189_AUDIO_APLL1_EN_ON: + case MT8189_AUDIO_APLL2_EN_ON: + return get_top_cg_mask(cg_type); + case MT8189_CG_AUDIO_HOPPING_CK: + case MT8189_CG_AUDIO_F26M_CK: + case MT8189_CG_APLL1_CK: + case MT8189_CG_APLL2_CK: + case MT8189_PDN_APLL_TUNER2: + case MT8189_PDN_APLL_TUNER1: + return 0; + default: + return 0; + } +} + +static unsigned int get_top_cg_off_val(unsigned int cg_type) +{ + switch (cg_type) { + case MT8189_AUDIO_26M_EN_ON: + case MT8189_AUDIO_F3P25M_EN_ON: + case MT8189_AUDIO_APLL1_EN_ON: + case MT8189_AUDIO_APLL2_EN_ON: + return 0; + case MT8189_CG_AUDIO_HOPPING_CK: + case MT8189_CG_AUDIO_F26M_CK: + case MT8189_CG_APLL1_CK: + case MT8189_CG_APLL2_CK: + case MT8189_PDN_APLL_TUNER2: + case MT8189_PDN_APLL_TUNER1: + return get_top_cg_mask(cg_type); + default: + return get_top_cg_mask(cg_type); + } +} + +static int mt8189_afe_enable_top_cg(struct mtk_base_afe *afe, unsigned int cg_type) +{ + unsigned int reg = get_top_cg_reg(cg_type); + unsigned int mask = get_top_cg_mask(cg_type); + unsigned int val = get_top_cg_on_val(cg_type); + + if (!afe->regmap) { + dev_err(afe->dev, "afe regmap is null !!!\n"); + return 0; + } + + dev_dbg(afe->dev, "reg: 0x%x, mask: 0x%x, val: 0x%x\n", reg, mask, val); + + return regmap_update_bits(afe->regmap, reg, mask, val); +} + +static void mt8189_afe_disable_top_cg(struct mtk_base_afe *afe, unsigned int cg_type) +{ + unsigned int reg = get_top_cg_reg(cg_type); + unsigned int mask = get_top_cg_mask(cg_type); + unsigned int val = get_top_cg_off_val(cg_type); + + if (!afe->regmap) { + dev_warn(afe->dev, "skip regmap\n"); + return; + } + + dev_dbg(afe->dev, "reg: 0x%x, mask: 0x%x, val: 0x%x\n", reg, mask, val); + regmap_update_bits(afe->regmap, reg, mask, val); +} + +static int apll1_mux_setting(struct mtk_base_afe *afe, bool enable) +{ + struct mt8189_afe_private *afe_priv = afe->platform_priv; + int ret; + + dev_dbg(afe->dev, "enable: %d\n", enable); + + if (enable) { + ret = mt8189_afe_enable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_1]); + if (ret) + return ret; + + ret = mt8189_afe_set_clk_parent(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_1], + afe_priv->clk[MT8189_CLK_TOP_APLL1_CK]); + if (ret) + goto clk_ck_mux_aud1_parent_err; + + /* 180.6336 / 4 = 45.1584MHz */ + ret = mt8189_afe_enable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_ENG1]); + if (ret) + goto clk_ck_mux_eng1_err; + + ret = mt8189_afe_set_clk_parent(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_ENG1], + afe_priv->clk[MT8189_CLK_TOP_APLL1_D4]); + if (ret) + goto clk_ck_mux_eng1_parent_err; + + ret = mt8189_afe_enable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUDIO_H]); + if (ret) + goto clk_ck_mux_audio_h_err; + + ret = mt8189_afe_set_clk_parent(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUDIO_H], + afe_priv->clk[MT8189_CLK_TOP_APLL1_CK]); + if (ret) + goto clk_ck_mux_audio_h_parent_err; + } else { + mt8189_afe_set_clk_parent(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_ENG1], + afe_priv->clk[MT8189_CLK_TOP_CLK26M]); + + mt8189_afe_disable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_ENG1]); + + mt8189_afe_set_clk_parent(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_1], + afe_priv->clk[MT8189_CLK_TOP_CLK26M]); + + mt8189_afe_disable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_1]); + mt8189_afe_set_clk_parent(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUDIO_H], + afe_priv->clk[MT8189_CLK_TOP_CLK26M]); + mt8189_afe_disable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUDIO_H]); + } + + return 0; + +clk_ck_mux_audio_h_parent_err: + mt8189_afe_disable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUDIO_H]); +clk_ck_mux_audio_h_err: + mt8189_afe_set_clk_parent(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_ENG1], + afe_priv->clk[MT8189_CLK_TOP_CLK26M]); +clk_ck_mux_eng1_parent_err: + mt8189_afe_disable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_ENG1]); +clk_ck_mux_eng1_err: + mt8189_afe_set_clk_parent(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_1], + afe_priv->clk[MT8189_CLK_TOP_CLK26M]); +clk_ck_mux_aud1_parent_err: + mt8189_afe_disable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_1]); + + return ret; +} + +static int apll2_mux_setting(struct mtk_base_afe *afe, bool enable) +{ + struct mt8189_afe_private *afe_priv = afe->platform_priv; + int ret; + + dev_dbg(afe->dev, "enable: %d\n", enable); + + if (enable) { + ret = mt8189_afe_enable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_2]); + if (ret) + return ret; + + ret = mt8189_afe_set_clk_parent(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_2], + afe_priv->clk[MT8189_CLK_TOP_APLL2_CK]); + if (ret) + goto clk_ck_mux_aud2_parent_err; + + /* 196.608 / 4 = 49.152MHz */ + ret = mt8189_afe_enable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_ENG2]); + if (ret) + goto clk_ck_mux_eng2_err; + + ret = mt8189_afe_set_clk_parent(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_ENG2], + afe_priv->clk[MT8189_CLK_TOP_APLL2_D4]); + if (ret) + goto clk_ck_mux_eng2_parent_err; + + ret = mt8189_afe_enable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUDIO_H]); + if (ret) + goto clk_ck_mux_audio_h_err; + + ret = mt8189_afe_set_clk_parent(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUDIO_H], + afe_priv->clk[MT8189_CLK_TOP_APLL2_CK]); + if (ret) + goto clk_ck_mux_audio_h_parent_err; + } else { + mt8189_afe_set_clk_parent(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_ENG2], + afe_priv->clk[MT8189_CLK_TOP_CLK26M]); + + mt8189_afe_disable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_ENG2]); + + mt8189_afe_set_clk_parent(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_2], + afe_priv->clk[MT8189_CLK_TOP_CLK26M]); + + mt8189_afe_disable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_2]); + mt8189_afe_set_clk_parent(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUDIO_H], + afe_priv->clk[MT8189_CLK_TOP_CLK26M]); + mt8189_afe_disable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUDIO_H]); + } + + return 0; + +clk_ck_mux_audio_h_parent_err: + mt8189_afe_disable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUDIO_H]); +clk_ck_mux_audio_h_err: + mt8189_afe_set_clk_parent(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_ENG2], + afe_priv->clk[MT8189_CLK_TOP_CLK26M]); +clk_ck_mux_eng2_parent_err: + mt8189_afe_disable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_ENG2]); +clk_ck_mux_eng2_err: + mt8189_afe_set_clk_parent(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_2], + afe_priv->clk[MT8189_CLK_TOP_CLK26M]); +clk_ck_mux_aud2_parent_err: + mt8189_afe_disable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_2]); + + return ret; +} + +static int mt8189_afe_disable_apll(struct mtk_base_afe *afe) +{ + struct mt8189_afe_private *afe_priv = afe->platform_priv; + int ret; + + ret = mt8189_afe_enable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUDIO_H]); + if (ret) + return ret; + + ret = mt8189_afe_enable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_1]); + if (ret) + goto clk_ck_mux_aud1_err; + + ret = mt8189_afe_set_clk_parent(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_1], + afe_priv->clk[MT8189_CLK_TOP_CLK26M]); + if (ret) + goto clk_ck_mux_aud1_parent_err; + + ret = mt8189_afe_enable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_2]); + if (ret) + goto clk_ck_mux_aud2_err; + + ret = mt8189_afe_set_clk_parent(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_2], + afe_priv->clk[MT8189_CLK_TOP_CLK26M]); + if (ret) + goto clk_ck_mux_aud2_parent_err; + + mt8189_afe_disable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_1]); + mt8189_afe_disable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_2]); + mt8189_afe_set_clk_parent(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUDIO_H], + afe_priv->clk[MT8189_CLK_TOP_CLK26M]); + mt8189_afe_disable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUDIO_H]); + + return 0; + +clk_ck_mux_aud2_parent_err: + mt8189_afe_disable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_2]); +clk_ck_mux_aud2_err: + mt8189_afe_set_clk_parent(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_1], + afe_priv->clk[MT8189_CLK_TOP_APLL1_CK]); +clk_ck_mux_aud1_parent_err: + mt8189_afe_disable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUD_1]); +clk_ck_mux_aud1_err: + mt8189_afe_disable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUDIO_H]); + + return ret; +} + +int mt8189_apll1_enable(struct mtk_base_afe *afe) +{ + int ret; + + /* setting for APLL */ + ret = apll1_mux_setting(afe, true); + if (ret) + return ret; + + ret = mt8189_afe_enable_top_cg(afe, MT8189_CG_APLL1_CK); + if (ret) + return ret; + + ret = mt8189_afe_enable_top_cg(afe, MT8189_PDN_APLL_TUNER1); + if (ret) + return ret; + + /* sel 44.1kHz:1, apll_div:7, upper bound:3 */ + regmap_update_bits(afe->regmap, AFE_APLL1_TUNER_CFG, + XTAL_EN_128FS_SEL_MASK_SFT | APLL_DIV_MASK_SFT | + UPPER_BOUND_MASK_SFT, + (0x1 << XTAL_EN_128FS_SEL_SFT) | (7 << APLL_DIV_SFT) | + (3 << UPPER_BOUND_SFT)); + + /* apll1 freq tuner enable */ + regmap_update_bits(afe->regmap, AFE_APLL1_TUNER_CFG, + FREQ_TUNER_EN_MASK_SFT, + 0x1 << FREQ_TUNER_EN_SFT); + + /* audio apll1 on */ + ret = mt8189_afe_enable_top_cg(afe, MT8189_AUDIO_APLL1_EN_ON); + if (ret) + return ret; + + return 0; +} + +void mt8189_apll1_disable(struct mtk_base_afe *afe) +{ + /* audio apll1 off */ + mt8189_afe_disable_top_cg(afe, MT8189_AUDIO_APLL1_EN_ON); + + /* apll1 freq tuner disable */ + regmap_update_bits(afe->regmap, AFE_APLL1_TUNER_CFG, + FREQ_TUNER_EN_MASK_SFT, + 0x0); + + mt8189_afe_disable_top_cg(afe, MT8189_PDN_APLL_TUNER1); + mt8189_afe_disable_top_cg(afe, MT8189_CG_APLL1_CK); + apll1_mux_setting(afe, false); +} + +int mt8189_apll2_enable(struct mtk_base_afe *afe) +{ + int ret; + + /* setting for APLL */ + ret = apll2_mux_setting(afe, true); + if (ret) + return ret; + + ret = mt8189_afe_enable_top_cg(afe, MT8189_CG_APLL2_CK); + if (ret) + return ret; + + ret = mt8189_afe_enable_top_cg(afe, MT8189_PDN_APLL_TUNER2); + if (ret) + return ret; + + /* sel 48kHz: 2, apll_div: 7, upper bound: 3*/ + regmap_update_bits(afe->regmap, AFE_APLL2_TUNER_CFG, + XTAL_EN_128FS_SEL_MASK_SFT | APLL_DIV_MASK_SFT | + UPPER_BOUND_MASK_SFT, + (0x2 << XTAL_EN_128FS_SEL_SFT) | (7 << APLL_DIV_SFT) | + (3 << UPPER_BOUND_SFT)); + + /* apll2 freq tuner enable */ + regmap_update_bits(afe->regmap, AFE_APLL2_TUNER_CFG, + FREQ_TUNER_EN_MASK_SFT, + 0x1 << FREQ_TUNER_EN_SFT); + + /* audio apll2 on */ + ret = mt8189_afe_enable_top_cg(afe, MT8189_AUDIO_APLL2_EN_ON); + if (ret) + return ret; + + return 0; +} + +void mt8189_apll2_disable(struct mtk_base_afe *afe) +{ + /* audio apll2 off */ + mt8189_afe_disable_top_cg(afe, MT8189_AUDIO_APLL2_EN_ON); + + /* apll2 freq tuner disable */ + regmap_update_bits(afe->regmap, AFE_APLL2_TUNER_CFG, + FREQ_TUNER_EN_MASK_SFT, + 0x0); + + mt8189_afe_disable_top_cg(afe, MT8189_PDN_APLL_TUNER2); + mt8189_afe_disable_top_cg(afe, MT8189_CG_APLL2_CK); + apll2_mux_setting(afe, false); +} + +int mt8189_get_apll_rate(struct mtk_base_afe *afe, int apll) +{ + struct mt8189_afe_private *afe_priv = afe->platform_priv; + int clk_id; + + if (apll < MT8189_APLL1 || apll > MT8189_APLL2) { + dev_warn(afe->dev, "invalid clk id %d\n", apll); + return 0; + } + + if (apll == MT8189_APLL1) + clk_id = MT8189_CLK_TOP_APLL1_CK; + else + clk_id = MT8189_CLK_TOP_APLL2_CK; + + return clk_get_rate(afe_priv->clk[clk_id]); +} + +int mt8189_get_apll_by_rate(struct mtk_base_afe *afe, int rate) +{ + return (rate % 8000) ? MT8189_APLL1 : MT8189_APLL2; +} + +int mt8189_get_apll_by_name(struct mtk_base_afe *afe, const char *name) +{ + if (strcmp(name, APLL1_W_NAME) == 0) + return MT8189_APLL1; + + return MT8189_APLL2; +} + +int mt8189_mck_enable(struct mtk_base_afe *afe, int mck_id, int rate) +{ + struct mt8189_afe_private *afe_priv = afe->platform_priv; + int apll = mt8189_get_apll_by_rate(afe, rate); + int apll_clk_id = apll == MT8189_APLL1 ? + MT8189_CLK_TOP_MUX_AUD_1 : MT8189_CLK_TOP_MUX_AUD_2; + int m_sel_id; + int div_clk_id; + int ret; + + dev_dbg(afe->dev, "mck_id: %d, rate: %d\n", mck_id, rate); + + if (mck_id >= MT8189_MCK_NUM || mck_id < 0) + return -EINVAL; + + m_sel_id = mck_div[mck_id].m_sel_id; + div_clk_id = mck_div[mck_id].div_clk_id; + + /* select apll */ + if (m_sel_id >= 0) { + ret = mt8189_afe_enable_clk(afe, afe_priv->clk[m_sel_id]); + if (ret) + return ret; + + ret = mt8189_afe_set_clk_parent(afe, afe_priv->clk[m_sel_id], + afe_priv->clk[apll_clk_id]); + if (ret) + return ret; + } + + /* enable div, set rate */ + if (div_clk_id < 0) { + dev_err(afe->dev, "invalid div_clk_id %d\n", div_clk_id); + return -EINVAL; + } + + ret = mt8189_afe_enable_clk(afe, afe_priv->clk[div_clk_id]); + if (ret) + return ret; + + ret = mt8189_afe_set_clk_rate(afe, afe_priv->clk[div_clk_id], rate); + if (ret) + return ret; + + return 0; +} + +int mt8189_mck_disable(struct mtk_base_afe *afe, int mck_id) +{ + struct mt8189_afe_private *afe_priv = afe->platform_priv; + int m_sel_id; + int div_clk_id; + + dev_dbg(afe->dev, "mck_id: %d.\n", mck_id); + + if (mck_id < 0) { + dev_err(afe->dev, "mck_id = %d < 0\n", mck_id); + return -EINVAL; + } + + m_sel_id = mck_div[mck_id].m_sel_id; + div_clk_id = mck_div[mck_id].div_clk_id; + + if (div_clk_id < 0) { + dev_err(afe->dev, "div_clk_id = %d < 0\n", + div_clk_id); + return -EINVAL; + } + + mt8189_afe_disable_clk(afe, afe_priv->clk[div_clk_id]); + + if (m_sel_id >= 0) + mt8189_afe_disable_clk(afe, afe_priv->clk[m_sel_id]); + + return 0; +} + +int mt8189_afe_enable_reg_rw_clk(struct mtk_base_afe *afe) +{ + struct mt8189_afe_private *afe_priv = afe->platform_priv; + + /* bus clock for AFE internal access, like AFE SRAM */ + mt8189_afe_enable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUDIOINTBUS]); + mt8189_afe_set_clk_parent(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUDIOINTBUS], + afe_priv->clk[MT8189_CLK_TOP_CLK26M]); + /* enable audio clock source */ + mt8189_afe_enable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUDIO_H]); + mt8189_afe_set_clk_parent(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUDIO_H], + afe_priv->clk[MT8189_CLK_TOP_CLK26M]); + + return 0; +} + +int mt8189_afe_disable_reg_rw_clk(struct mtk_base_afe *afe) +{ + struct mt8189_afe_private *afe_priv = afe->platform_priv; + + mt8189_afe_disable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUDIO_H]); + mt8189_afe_disable_clk(afe, afe_priv->clk[MT8189_CLK_TOP_MUX_AUDIOINTBUS]); + + return 0; +} + +int mt8189_afe_enable_main_clock(struct mtk_base_afe *afe) +{ + return mt8189_afe_enable_top_cg(afe, MT8189_AUDIO_26M_EN_ON); +} + +void mt8189_afe_disable_main_clock(struct mtk_base_afe *afe) +{ + mt8189_afe_disable_top_cg(afe, MT8189_AUDIO_26M_EN_ON); +} + +static int mt8189_afe_enable_ao_clock(struct mtk_base_afe *afe) +{ + struct mt8189_afe_private *afe_priv = afe->platform_priv; + int ret; + + /* Peri clock AO enable */ + ret = mt8189_afe_enable_clk(afe, afe_priv->clk[MT8189_CLK_PERAO_INTBUS_CK_PERI]); + if (ret) + return ret; + + ret = mt8189_afe_enable_clk(afe, afe_priv->clk[MT8189_CLK_PERAO_AUDIO_SLV_CK_PERI]); + if (ret) + goto err_clk_perao_slv; + + ret = mt8189_afe_enable_clk(afe, afe_priv->clk[MT8189_CLK_PERAO_AUDIO_MST_CK_PERI]); + if (ret) + goto err_clk_perao_mst; + + return 0; + +err_clk_perao_mst: + mt8189_afe_disable_clk(afe, afe_priv->clk[MT8189_CLK_PERAO_AUDIO_SLV_CK_PERI]); +err_clk_perao_slv: + mt8189_afe_disable_clk(afe, afe_priv->clk[MT8189_CLK_PERAO_INTBUS_CK_PERI]); + + return ret; +} + +int mt8189_init_clock(struct mtk_base_afe *afe) +{ + struct mt8189_afe_private *afe_priv = afe->platform_priv; + int ret; + int i; + + afe_priv->clk = devm_kcalloc(afe->dev, MT8189_CLK_NUM, sizeof(*afe_priv->clk), + GFP_KERNEL); + if (!afe_priv->clk) + return -ENOMEM; + + for (i = 0; i < MT8189_CLK_NUM; i++) { + afe_priv->clk[i] = devm_clk_get(afe->dev, aud_clks[i]); + if (IS_ERR(afe_priv->clk[i])) { + dev_err(afe->dev, "devm_clk_get %s fail\n", aud_clks[i]); + return PTR_ERR(afe_priv->clk[i]); + } + } + + ret = mt8189_afe_disable_apll(afe); + if (ret) + return ret; + + ret = mt8189_afe_enable_ao_clock(afe); + if (ret) + return ret; + + return 0; +} diff --git a/sound/soc/mediatek/mt8189/mt8189-afe-clk.h b/sound/soc/mediatek/mt8189/mt8189-afe-clk.h new file mode 100644 index 00000000000000..9ce5d1043feb8d --- /dev/null +++ b/sound/soc/mediatek/mt8189/mt8189-afe-clk.h @@ -0,0 +1,76 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * mt8189-afe-clk.h -- Mediatek 8189 afe clock ctrl definition + * + * Copyright (c) 2025 MediaTek Inc. + * Author: Darren Ye + */ + +#ifndef _MT8189_AFE_CLOCK_CTRL_H_ +#define _MT8189_AFE_CLOCK_CTRL_H_ + +/* APLL */ +#define APLL1_W_NAME "APLL1" +#define APLL2_W_NAME "APLL2" + +enum { + MT8189_APLL1, + MT8189_APLL2, +}; + +enum { + MT8189_CLK_TOP_MUX_AUDIOINTBUS, + MT8189_CLK_TOP_MUX_AUD_ENG1, + MT8189_CLK_TOP_MUX_AUD_ENG2, + MT8189_CLK_TOP_MUX_AUDIO_H, + /* pll */ + MT8189_CLK_TOP_APLL1_CK, + MT8189_CLK_TOP_APLL2_CK, + /* divider */ + MT8189_CLK_TOP_APLL1_D4, + MT8189_CLK_TOP_APLL2_D4, + MT8189_CLK_TOP_APLL12_DIV_I2SIN0, + MT8189_CLK_TOP_APLL12_DIV_I2SIN1, + MT8189_CLK_TOP_APLL12_DIV_I2SOUT0, + MT8189_CLK_TOP_APLL12_DIV_I2SOUT1, + MT8189_CLK_TOP_APLL12_DIV_FMI2S, + MT8189_CLK_TOP_APLL12_DIV_TDMOUT_M, + MT8189_CLK_TOP_APLL12_DIV_TDMOUT_B, + /* mux */ + MT8189_CLK_TOP_MUX_AUD_1, + MT8189_CLK_TOP_MUX_AUD_2, + MT8189_CLK_TOP_I2SIN0_M_SEL, + MT8189_CLK_TOP_I2SIN1_M_SEL, + MT8189_CLK_TOP_I2SOUT0_M_SEL, + MT8189_CLK_TOP_I2SOUT1_M_SEL, + MT8189_CLK_TOP_FMI2S_M_SEL, + MT8189_CLK_TOP_TDMOUT_M_SEL, + /* top 26m */ + MT8189_CLK_TOP_CLK26M, + /* peri */ + MT8189_CLK_PERAO_AUDIO_SLV_CK_PERI, + MT8189_CLK_PERAO_AUDIO_MST_CK_PERI, + MT8189_CLK_PERAO_INTBUS_CK_PERI, + MT8189_CLK_NUM, +}; + +struct mtk_base_afe; + +int mt8189_mck_enable(struct mtk_base_afe *afe, int mck_id, int rate); +int mt8189_mck_disable(struct mtk_base_afe *afe, int mck_id); +int mt8189_get_apll_rate(struct mtk_base_afe *afe, int apll); +int mt8189_get_apll_by_rate(struct mtk_base_afe *afe, int rate); +int mt8189_get_apll_by_name(struct mtk_base_afe *afe, const char *name); +int mt8189_init_clock(struct mtk_base_afe *afe); +int mt8189_afe_enable_clk(struct mtk_base_afe *afe, struct clk *clk); +void mt8189_afe_disable_clk(struct mtk_base_afe *afe, struct clk *clk); +int mt8189_apll1_enable(struct mtk_base_afe *afe); +void mt8189_apll1_disable(struct mtk_base_afe *afe); +int mt8189_apll2_enable(struct mtk_base_afe *afe); +void mt8189_apll2_disable(struct mtk_base_afe *afe); +int mt8189_afe_enable_main_clock(struct mtk_base_afe *afe); +void mt8189_afe_disable_main_clock(struct mtk_base_afe *afe); +int mt8189_afe_enable_reg_rw_clk(struct mtk_base_afe *afe); +int mt8189_afe_disable_reg_rw_clk(struct mtk_base_afe *afe); + +#endif diff --git a/sound/soc/mediatek/mt8189/mt8189-afe-common.h b/sound/soc/mediatek/mt8189/mt8189-afe-common.h new file mode 100644 index 00000000000000..910d90d3d1468c --- /dev/null +++ b/sound/soc/mediatek/mt8189/mt8189-afe-common.h @@ -0,0 +1,240 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * mt8189-afe-common.h -- Mediatek 8189 audio driver definitions + * + * Copyright (c) 2025 MediaTek Inc. + * Author: Darren Ye + */ + +#ifndef _MT_8189_AFE_COMMON_H_ +#define _MT_8189_AFE_COMMON_H_ + +#include + +#include + +#include "mt8189-reg.h" +#include "../common/mtk-base-afe.h" + +enum { + MTK_AFE_RATE_8K, + MTK_AFE_RATE_11K, + MTK_AFE_RATE_12K, + MTK_AFE_RATE_384K, + MTK_AFE_RATE_16K, + MTK_AFE_RATE_22K, + MTK_AFE_RATE_24K, + MTK_AFE_RATE_352K, + MTK_AFE_RATE_32K, + MTK_AFE_RATE_44K, + MTK_AFE_RATE_48K, + MTK_AFE_RATE_88K, + MTK_AFE_RATE_96K, + MTK_AFE_RATE_176K, + MTK_AFE_RATE_192K, + MTK_AFE_RATE_260K, +}; + +/* HW IPM 2.0 */ +enum { + MTK_AFE_IPM2P0_RATE_8K = 0x0, + MTK_AFE_IPM2P0_RATE_11K = 0x1, + MTK_AFE_IPM2P0_RATE_12K = 0x2, + MTK_AFE_IPM2P0_RATE_16K = 0x4, + MTK_AFE_IPM2P0_RATE_22K = 0x5, + MTK_AFE_IPM2P0_RATE_24K = 0x6, + MTK_AFE_IPM2P0_RATE_32K = 0x8, + MTK_AFE_IPM2P0_RATE_44K = 0x9, + MTK_AFE_IPM2P0_RATE_48K = 0xa, + MTK_AFE_IPM2P0_RATE_88K = 0xd, + MTK_AFE_IPM2P0_RATE_96K = 0xe, + MTK_AFE_IPM2P0_RATE_176K = 0x11, + MTK_AFE_IPM2P0_RATE_192K = 0x12, + MTK_AFE_IPM2P0_RATE_352K = 0x15, + MTK_AFE_IPM2P0_RATE_384K = 0x16, +}; + +enum { + MTK_AFE_DAI_MEMIF_RATE_8K, + MTK_AFE_DAI_MEMIF_RATE_16K, + MTK_AFE_DAI_MEMIF_RATE_32K, + MTK_AFE_DAI_MEMIF_RATE_48K, +}; + +enum { + MTK_AFE_PCM_RATE_8K, + MTK_AFE_PCM_RATE_16K, + MTK_AFE_PCM_RATE_32K, + MTK_AFE_PCM_RATE_48K, +}; + +enum { + MTKAIF_PROTOCOL_1, + MTKAIF_PROTOCOL_2, + MTKAIF_PROTOCOL_2_CLK_P2, +}; + +enum { + MT8189_MEMIF_DL0, + MT8189_MEMIF_DL1, + MT8189_MEMIF_DL2, + MT8189_MEMIF_DL3, + MT8189_MEMIF_DL4, + MT8189_MEMIF_DL5, + MT8189_MEMIF_DL6, + MT8189_MEMIF_DL7, + MT8189_MEMIF_DL8, + MT8189_MEMIF_DL23, + MT8189_MEMIF_DL24, + MT8189_MEMIF_DL25, + MT8189_MEMIF_DL_24CH, + MT8189_MEMIF_VUL0, + MT8189_MEMIF_VUL1, + MT8189_MEMIF_VUL2, + MT8189_MEMIF_VUL3, + MT8189_MEMIF_VUL4, + MT8189_MEMIF_VUL5, + MT8189_MEMIF_VUL6, + MT8189_MEMIF_VUL7, + MT8189_MEMIF_VUL8, + MT8189_MEMIF_VUL9, + MT8189_MEMIF_VUL10, + MT8189_MEMIF_VUL24, + MT8189_MEMIF_VUL25, + MT8189_MEMIF_VUL_CM0, + MT8189_MEMIF_VUL_CM1, + MT8189_MEMIF_ETDM_IN0, + MT8189_MEMIF_ETDM_IN1, + MT8189_MEMIF_HDMI, + MT8189_MEMIF_NUM, + MT8189_DAI_ADDA = MT8189_MEMIF_NUM, + MT8189_DAI_ADDA_CH34, + MT8189_DAI_ADDA_CH56, + MT8189_DAI_AP_DMIC, + MT8189_DAI_AP_DMIC_CH34, + MT8189_DAI_I2S_IN0, + MT8189_DAI_I2S_IN1, + MT8189_DAI_I2S_OUT0, + MT8189_DAI_I2S_OUT1, + MT8189_DAI_I2S_OUT4, + MT8189_DAI_PCM_0, + MT8189_DAI_TDM, + MT8189_DAI_TDM_DPTX, + MT8189_DAI_NUM, +}; + +/* update irq ID (= enum) from AFE_IRQ_MCU_STATUS */ +enum { + MT8189_IRQ_0, + MT8189_IRQ_1, + MT8189_IRQ_2, + MT8189_IRQ_3, + MT8189_IRQ_4, + MT8189_IRQ_5, + MT8189_IRQ_6, + MT8189_IRQ_7, + MT8189_IRQ_8, + MT8189_IRQ_9, + MT8189_IRQ_10, + MT8189_IRQ_11, + MT8189_IRQ_12, + MT8189_IRQ_13, + MT8189_IRQ_14, + MT8189_IRQ_15, + MT8189_IRQ_16, + MT8189_IRQ_17, + MT8189_IRQ_18, + MT8189_IRQ_19, + MT8189_IRQ_20, + MT8189_IRQ_21, + MT8189_IRQ_22, + MT8189_IRQ_23, + MT8189_IRQ_24, + MT8189_IRQ_25, + MT8189_IRQ_26, + MT8189_IRQ_31, + MT8189_IRQ_NUM, +}; + +/* update irq ID (= enum) from AFE_IRQ_MCU_STATUS */ +enum { + MT8189_CUS_IRQ_TDM, /* used only for TDM */ + MT8189_CUS_IRQ_NUM, +}; + +enum { + /* AUDIO_ENGEN_CON0 */ + MT8189_AUDIO_26M_EN_ON, + MT8189_AUDIO_F3P25M_EN_ON, + MT8189_AUDIO_APLL1_EN_ON, + MT8189_AUDIO_APLL2_EN_ON, + MT8189_AUDIO_F26M_EN_RST, + MT8189_MULTI_USER_RST, + MT8189_MULTI_USER_BYPASS, + /* AUDIO_TOP_CON4 */ + MT8189_CG_AUDIO_HOPPING_CK, + MT8189_CG_AUDIO_F26M_CK, + MT8189_CG_APLL1_CK, + MT8189_CG_APLL2_CK, + MT8189_PDN_APLL_TUNER2, + MT8189_PDN_APLL_TUNER1, + MT8189_AUDIO_CG_NUM, +}; + +/* MCLK */ +enum { + MT8189_I2SIN0_MCK, + MT8189_I2SIN1_MCK, + MT8189_I2SOUT0_MCK, + MT8189_I2SOUT1_MCK, + MT8189_FMI2S_MCK, + MT8189_TDMOUT_MCK, + MT8189_TDMOUT_BCK, + MT8189_MCK_NUM, +}; + +enum { + CM0, + CM1, + CM_NUM, +}; + +struct clk; + +struct mt8189_afe_private { + struct clk **clk; + struct regmap *pmic_regmap; + + /* dai */ + void *dai_priv[MT8189_DAI_NUM]; + + /* adda */ + int mtkaif_protocol; + int mtkaif_chosen_phase[4]; + int mtkaif_phase_cycle[4]; + int mtkaif_calibration_num_phase; + int mtkaif_dmic; + int mtkaif_dmic_ch34; + + /* add for vs1 voter */ + bool is_adda_dl_on; + bool is_adda_ul_on; + /* adda dl vol idx is at maximum */ + bool is_adda_dl_max_vol; + /* current vote status of vs1 */ + bool is_mt6363_vote; + + /* mck */ + int mck_rate[MT8189_MCK_NUM]; + + /* channel merge */ + unsigned int cm_rate[CM_NUM]; + unsigned int cm_channels; +}; + +int mt8189_dai_adda_register(struct mtk_base_afe *afe); +int mt8189_dai_i2s_register(struct mtk_base_afe *afe); +int mt8189_dai_pcm_register(struct mtk_base_afe *afe); +int mt8189_dai_tdm_register(struct mtk_base_afe *afe); + +#endif diff --git a/sound/soc/mediatek/mt8189/mt8189-afe-pcm.c b/sound/soc/mediatek/mt8189/mt8189-afe-pcm.c new file mode 100644 index 00000000000000..166ece74270ece --- /dev/null +++ b/sound/soc/mediatek/mt8189/mt8189-afe-pcm.c @@ -0,0 +1,2615 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Mediatek ALSA SoC AFE platform driver for 8189 + * + * Copyright (c) 2025 MediaTek Inc. + * Author: Darren Ye + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "mt8189-afe-clk.h" +#include "mt8189-afe-common.h" +#include "mt8189-interconnection.h" + +#include "../common/mtk-afe-fe-dai.h" +#include "../common/mtk-afe-platform-driver.h" + +static const struct snd_pcm_hardware mt8189_afe_hardware = { + .info = (SNDRV_PCM_INFO_MMAP | + SNDRV_PCM_INFO_NO_PERIOD_WAKEUP | + SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_MMAP_VALID), + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE), + .period_bytes_min = 96, + .period_bytes_max = 4 * 48 * 1024, + .periods_min = 2, + .periods_max = 256, + .buffer_bytes_max = 256 * 1024, + .fifo_size = 0, +}; + +static unsigned int mt8189_rate_transform(struct device *dev, unsigned int rate) +{ + switch (rate) { + case 8000: + return MTK_AFE_IPM2P0_RATE_8K; + case 11025: + return MTK_AFE_IPM2P0_RATE_11K; + case 12000: + return MTK_AFE_IPM2P0_RATE_12K; + case 16000: + return MTK_AFE_IPM2P0_RATE_16K; + case 22050: + return MTK_AFE_IPM2P0_RATE_22K; + case 24000: + return MTK_AFE_IPM2P0_RATE_24K; + case 32000: + return MTK_AFE_IPM2P0_RATE_32K; + case 44100: + return MTK_AFE_IPM2P0_RATE_44K; + case 48000: + return MTK_AFE_IPM2P0_RATE_48K; + case 88200: + return MTK_AFE_IPM2P0_RATE_88K; + case 96000: + return MTK_AFE_IPM2P0_RATE_96K; + case 176400: + return MTK_AFE_IPM2P0_RATE_176K; + case 192000: + return MTK_AFE_IPM2P0_RATE_192K; + /* not support 260K */ + case 352800: + return MTK_AFE_IPM2P0_RATE_352K; + case 384000: + return MTK_AFE_IPM2P0_RATE_384K; + default: + dev_warn(dev, "rate %u invalid, use %d!!!\n", + rate, MTK_AFE_IPM2P0_RATE_48K); + return MTK_AFE_IPM2P0_RATE_48K; + } +} + +static inline unsigned int calculate_cm_update(unsigned int rate, + unsigned int ch) +{ + return (((26000000 / rate) - 10) / (ch / 2)) - 1; +} + +static int mt8189_set_cm(struct mtk_base_afe *afe, int id, + bool update, bool swap, unsigned int ch) +{ + struct mt8189_afe_private *afe_priv = afe->platform_priv; + unsigned int rate = afe_priv->cm_rate[id]; + unsigned int rate_val = mt8189_rate_transform(afe->dev, rate); + unsigned int update_val = update ? calculate_cm_update(rate, ch) : 0x64; + int reg = AFE_CM0_CON0 + 0x10 * id; + + dev_dbg(afe->dev, "%s()-0, CM%d, rate %d, update %d, swap %d, ch %d\n", + __func__, id, rate, update, swap, ch); + + /* update cnt */ + regmap_update_bits(afe->regmap, reg, + AFE_CM_UPDATE_CNT_MASK << AFE_CM_UPDATE_CNT_SFT, + update_val << AFE_CM_UPDATE_CNT_SFT); + + /* rate */ + regmap_update_bits(afe->regmap, reg, + AFE_CM_1X_EN_SEL_FS_MASK << AFE_CM_1X_EN_SEL_FS_SFT, + rate_val << AFE_CM_1X_EN_SEL_FS_SFT); + + /* ch num */ + regmap_update_bits(afe->regmap, reg, + AFE_CM_CH_NUM_MASK << AFE_CM_CH_NUM_SFT, + (ch - 1) << AFE_CM_CH_NUM_SFT); + + /* swap */ + regmap_update_bits(afe->regmap, reg, + AFE_CM_BYTE_SWAP_MASK << AFE_CM_BYTE_SWAP_SFT, + swap << AFE_CM_BYTE_SWAP_SFT); + + return 0; +} + +static int mt8189_enable_cm_bypass(struct mtk_base_afe *afe, int id, bool en) +{ + return regmap_update_bits(afe->regmap, AFE_CM0_CON0 + 0x10 * id, + AFE_CM_BYPASS_MODE_MASK << + AFE_CM_BYPASS_MODE_SFT, + en << AFE_CM_BYPASS_MODE_SFT); +} + +static int mt8189_fe_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); + struct snd_pcm_runtime *runtime = substream->runtime; + struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); + int memif_num = cpu_dai->id; + struct mtk_base_afe_memif *memif = &afe->memif[memif_num]; + const struct snd_pcm_hardware *mtk_afe_hardware = afe->mtk_afe_hardware; + int ret; + + dev_dbg(afe->dev, "%s(), memif_num: %d.\n", __func__, memif_num); + + memif->substream = substream; + + snd_pcm_hw_constraint_step(substream->runtime, 0, + SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 16); + + snd_soc_set_runtime_hwparams(substream, mtk_afe_hardware); + + ret = snd_pcm_hw_constraint_integer(runtime, + SNDRV_PCM_HW_PARAM_PERIODS); + if (ret < 0) + dev_warn(afe->dev, "snd_pcm_hw_constraint_integer failed\n"); + + /* dynamic allocate irq to memif */ + if (memif->irq_usage < 0) { + int irq_id = mtk_dynamic_irq_acquire(afe); + + if (irq_id != afe->irqs_size) { + /* link */ + memif->irq_usage = irq_id; + } else { + dev_err(afe->dev, "%s() error: no more asys irq\n", + __func__); + ret = -EBUSY; + } + } + + return ret; +} + +static void mt8189_fe_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); + struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); + int memif_num = cpu_dai->id; + struct mtk_base_afe_memif *memif = &afe->memif[memif_num]; + int irq_id = memif->irq_usage; + + dev_dbg(afe->dev, "%s(), memif_num: %d.\n", __func__, memif_num); + + memif->substream = NULL; + + if (!memif->const_irq) { + mtk_dynamic_irq_release(afe, irq_id); + memif->irq_usage = -1; + memif->substream = NULL; + } +} + +static int mt8189_fe_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); + struct mt8189_afe_private *afe_priv = afe->platform_priv; + int id = dai->id; + int cm; + + switch (id) { + case MT8189_MEMIF_VUL8: + case MT8189_MEMIF_VUL_CM0: + cm = CM0; + break; + case MT8189_MEMIF_VUL9: + case MT8189_MEMIF_VUL_CM1: + cm = CM1; + break; + default: + cm = CM0; + break; + } + + afe_priv->cm_rate[cm] = params_rate(params); + afe_priv->cm_channels = params_channels(params); + + return mtk_afe_fe_hw_params(substream, params, dai); +} + +static int mt8189_fe_trigger(struct snd_pcm_substream *substream, int cmd, + struct snd_soc_dai *dai) +{ + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_pcm_runtime *const runtime = substream->runtime; + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); + struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); + int id = cpu_dai->id; + struct mtk_base_afe_memif *memif = &afe->memif[id]; + int irq_id = memif->irq_usage; + struct mtk_base_afe_irq *irqs = &afe->irqs[irq_id]; + const struct mtk_base_irq_data *irq_data = irqs->irq_data; + unsigned int counter = runtime->period_size; + unsigned int rate = runtime->rate; + unsigned int tmp_reg; + int fs; + int ret; + + dev_dbg(afe->dev, "%s(), %s cmd %d, irq_id %d, dai_id %d\n", __func__, + memif->data->name, cmd, irq_id, id); + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + ret = mtk_memif_set_enable(afe, id); + if (ret) { + dev_err(afe->dev, "id %d, memif enable fail.\n", id); + return ret; + } + + /* + * for small latency record + * ul memif need read some data before irq enable + * the context of this triger ops is atmoic, so it cannot sleep + */ + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) + if ((runtime->period_size * 1000) / rate <= 10) + udelay(300); + + regmap_update_bits(afe->regmap, + irq_data->irq_cnt_reg, + irq_data->irq_cnt_maskbit << + irq_data->irq_cnt_shift, + counter << irq_data->irq_cnt_shift); + + /* set irq fs */ + fs = afe->irq_fs(substream, rate); + if (fs < 0) + return -EINVAL; + + if (irq_data->irq_fs_reg >= 0) + regmap_update_bits(afe->regmap, + irq_data->irq_fs_reg, + irq_data->irq_fs_maskbit << + irq_data->irq_fs_shift, + fs << irq_data->irq_fs_shift); + + /* enable interrupt */ + regmap_update_bits(afe->regmap, + irq_data->irq_en_reg, + 1 << irq_data->irq_en_shift, + 1 << irq_data->irq_en_shift); + + return 0; + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + ret = mtk_memif_set_disable(afe, id); + if (ret) + dev_warn(afe->dev, "id %d, memif disable fail\n", id); + + /* disable interrupt */ + regmap_update_bits(afe->regmap, + irq_data->irq_en_reg, + 1 << irq_data->irq_en_shift, + 0 << irq_data->irq_en_shift); + + /* + * clear pending IRQ, if the register read as one, there is no + * need to write one to clear operation. + */ + regmap_read(afe->regmap, irq_data->irq_clr_reg, &tmp_reg); + regmap_update_bits(afe->regmap, irq_data->irq_clr_reg, + AFE_IRQ_CLR_CFG_MASK_SFT | + AFE_IRQ_MISS_FLAG_CLR_CFG_MASK_SFT, + tmp_reg ^ (AFE_IRQ_CLR_CFG_MASK_SFT | + AFE_IRQ_MISS_FLAG_CLR_CFG_MASK_SFT)); + + return ret; + default: + return -EINVAL; + } +} + +static int mt8189_memif_fs(struct snd_pcm_substream *substream, + unsigned int rate) +{ + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_soc_component *component = + snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME); + struct mtk_base_afe *afe = NULL; + + if (!component) + return -EINVAL; + + afe = snd_soc_component_get_drvdata(component); + if (!afe) + return -EINVAL; + + return mt8189_rate_transform(afe->dev, rate); +} + +static int mt8189_get_dai_fs(struct mtk_base_afe *afe, + int dai_id, unsigned int rate) +{ + return mt8189_rate_transform(afe->dev, rate); +} + +static int mt8189_irq_fs(struct snd_pcm_substream *substream, unsigned int rate) +{ + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_soc_component *component = + snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME); + struct mtk_base_afe *afe = NULL; + + if (!component) + return -EINVAL; + afe = snd_soc_component_get_drvdata(component); + + return mt8189_rate_transform(afe->dev, rate); +} + +static int mt8189_get_memif_pbuf_size(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + + if ((runtime->period_size * 1000) / runtime->rate > 10) + return MT8189_MEMIF_PBUF_SIZE_256_BYTES; + + return MT8189_MEMIF_PBUF_SIZE_32_BYTES; +} + +/* FE DAIs */ +static const struct snd_soc_dai_ops mt8189_memif_dai_ops = { + .startup = mt8189_fe_startup, + .shutdown = mt8189_fe_shutdown, + .hw_params = mt8189_fe_hw_params, + .hw_free = mtk_afe_fe_hw_free, + .prepare = mtk_afe_fe_prepare, + .trigger = mt8189_fe_trigger, +}; + +#define MTK_PCM_RATES (SNDRV_PCM_RATE_8000_48000 | \ + SNDRV_PCM_RATE_88200 | \ + SNDRV_PCM_RATE_96000 | \ + SNDRV_PCM_RATE_176400 | \ + SNDRV_PCM_RATE_192000) + +#define MTK_PCM_DAI_RATES (SNDRV_PCM_RATE_8000 | \ + SNDRV_PCM_RATE_16000 | \ + SNDRV_PCM_RATE_32000 | \ + SNDRV_PCM_RATE_48000) + +#define MTK_PCM_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \ + SNDRV_PCM_FMTBIT_S24_LE | \ + SNDRV_PCM_FMTBIT_S32_LE) + +#define MT8189_FE_DAI_PLAYBACK(_name, _id, max_ch) \ +{ \ + .name = #_name, \ + .id = _id, \ + .playback = { \ + .stream_name = #_name, \ + .channels_min = 1, \ + .channels_max = max_ch, \ + .rates = MTK_PCM_RATES, \ + .formats = MTK_PCM_FORMATS, \ + }, \ + .ops = &mt8189_memif_dai_ops, \ +} + +#define MT8189_FE_DAI_CAPTURE(_name, _id, max_ch) \ +{ \ + .name = #_name, \ + .id = _id, \ + .capture = { \ + .stream_name = #_name, \ + .channels_min = 1, \ + .channels_max = max_ch, \ + .rates = MTK_PCM_RATES, \ + .formats = MTK_PCM_FORMATS, \ + }, \ + .ops = &mt8189_memif_dai_ops, \ +} + +static struct snd_soc_dai_driver mt8189_memif_dai_driver[] = { + /* FE DAIs: memory interfaces to CPU */ + /* Playback */ + MT8189_FE_DAI_PLAYBACK(DL0, MT8189_MEMIF_DL0, 2), + MT8189_FE_DAI_PLAYBACK(DL1, MT8189_MEMIF_DL1, 2), + MT8189_FE_DAI_PLAYBACK(DL2, MT8189_MEMIF_DL2, 2), + MT8189_FE_DAI_PLAYBACK(DL3, MT8189_MEMIF_DL3, 2), + MT8189_FE_DAI_PLAYBACK(DL4, MT8189_MEMIF_DL4, 2), + MT8189_FE_DAI_PLAYBACK(DL5, MT8189_MEMIF_DL5, 2), + MT8189_FE_DAI_PLAYBACK(DL6, MT8189_MEMIF_DL6, 2), + MT8189_FE_DAI_PLAYBACK(DL7, MT8189_MEMIF_DL7, 2), + MT8189_FE_DAI_PLAYBACK(DL8, MT8189_MEMIF_DL8, 2), + MT8189_FE_DAI_PLAYBACK(DL23, MT8189_MEMIF_DL23, 2), + MT8189_FE_DAI_PLAYBACK(DL24, MT8189_MEMIF_DL24, 2), + MT8189_FE_DAI_PLAYBACK(DL25, MT8189_MEMIF_DL25, 2), + MT8189_FE_DAI_PLAYBACK(DL_24CH, MT8189_MEMIF_DL_24CH, 8), + MT8189_FE_DAI_PLAYBACK(HDMI, MT8189_MEMIF_HDMI, 8), + /* Capture */ + MT8189_FE_DAI_CAPTURE(UL0, MT8189_MEMIF_VUL0, 2), + MT8189_FE_DAI_CAPTURE(UL1, MT8189_MEMIF_VUL1, 2), + MT8189_FE_DAI_CAPTURE(UL2, MT8189_MEMIF_VUL2, 2), + MT8189_FE_DAI_CAPTURE(UL3, MT8189_MEMIF_VUL3, 2), + MT8189_FE_DAI_CAPTURE(UL4, MT8189_MEMIF_VUL4, 2), + MT8189_FE_DAI_CAPTURE(UL5, MT8189_MEMIF_VUL5, 2), + MT8189_FE_DAI_CAPTURE(UL6, MT8189_MEMIF_VUL6, 2), + MT8189_FE_DAI_CAPTURE(UL7, MT8189_MEMIF_VUL7, 2), + MT8189_FE_DAI_CAPTURE(UL8, MT8189_MEMIF_VUL8, 2), + MT8189_FE_DAI_CAPTURE(UL9, MT8189_MEMIF_VUL9, 16), + MT8189_FE_DAI_CAPTURE(UL10, MT8189_MEMIF_VUL10, 2), + MT8189_FE_DAI_CAPTURE(UL24, MT8189_MEMIF_VUL24, 2), + MT8189_FE_DAI_CAPTURE(UL25, MT8189_MEMIF_VUL25, 2), + MT8189_FE_DAI_CAPTURE(UL_CM0, MT8189_MEMIF_VUL_CM0, 8), + MT8189_FE_DAI_CAPTURE(UL_CM1, MT8189_MEMIF_VUL_CM1, 16), + MT8189_FE_DAI_CAPTURE(UL_ETDM_IN0, MT8189_MEMIF_ETDM_IN0, 2), + MT8189_FE_DAI_CAPTURE(UL_ETDM_IN1, MT8189_MEMIF_ETDM_IN1, 2), +}; + +static int ul_cm0_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8189_afe_private *afe_priv = afe->platform_priv; + unsigned int channels = afe_priv->cm_channels; + + dev_dbg(afe->dev, "%s(), event 0x%x, name %s, channels %d\n", + __func__, event, w->name, channels); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + mt8189_enable_cm_bypass(afe, CM0, false); + mt8189_set_cm(afe, CM0, true, false, channels); + regmap_update_bits(afe->regmap, AUDIO_TOP_CON0, + PDN_CM0_MASK_SFT, 0 << PDN_CM0_SFT); + + break; + case SND_SOC_DAPM_PRE_PMD: + mt8189_enable_cm_bypass(afe, CM0, true); + regmap_update_bits(afe->regmap, AUDIO_TOP_CON0, + PDN_CM0_MASK_SFT, 1 << PDN_CM0_SFT); + break; + default: + break; + } + + return 0; +} + +static int ul_cm1_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8189_afe_private *afe_priv = afe->platform_priv; + unsigned int channels = afe_priv->cm_channels; + + dev_dbg(afe->dev, "%s(), event 0x%x, name %s, channels %d\n", + __func__, event, w->name, channels); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + mt8189_enable_cm_bypass(afe, CM1, false); + mt8189_set_cm(afe, CM1, true, false, channels); + regmap_update_bits(afe->regmap, AUDIO_TOP_CON0, + PDN_CM1_MASK_SFT, 0 << PDN_CM1_SFT); + break; + case SND_SOC_DAPM_POST_PMD: + mt8189_enable_cm_bypass(afe, CM1, true); + regmap_update_bits(afe->regmap, AUDIO_TOP_CON0, + PDN_CM1_MASK_SFT, 1 << PDN_CM1_SFT); + break; + default: + break; + } + + return 0; +} + +/* + * dma widget & routes + * The mixer controls and routes are by no means fully implemented, + * only the ones that are intended to be used are, as other wise a fully + * interconnected switch bar mixer would introduce way too many unused + * controls. + */ +static const struct snd_kcontrol_new memif_ul0_ch1_mix[] = { + /* Normal record */ + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN018_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN018_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN018_0, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN018_0, + I_ADDA_UL_CH4, 1, 0), + /* AP DMIC */ + SOC_DAPM_SINGLE_AUTODISABLE("AP_DMIC_UL_CH1", AFE_CONN018_0, + I_DMIC0_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("AP_DMIC_UL_CH2", AFE_CONN018_0, + I_DMIC0_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL0_CH1", AFE_CONN018_1, + I_DL0_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1", AFE_CONN018_1, + I_DL1_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1", AFE_CONN018_1, + I_DL2_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1", AFE_CONN018_1, + I_DL3_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH1", AFE_CONN018_1, + I_DL4_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH1", AFE_CONN018_1, + I_DL6_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL7_CH1", AFE_CONN018_1, + I_DL7_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL23_CH1", AFE_CONN018_2, + I_DL23_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH1", AFE_CONN018_1, + I_DL_24CH_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH1", AFE_CONN018_4, + I_PCM_0_CAP_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I2SIN0_CH1", AFE_CONN018_4, + I_I2SIN0_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I2SIN1_CH1", AFE_CONN018_4, + I_I2SIN1_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_0_OUT_CH1", AFE_CONN018_6, + I_SRC_0_OUT_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_2_OUT_CH1", AFE_CONN018_6, + I_SRC_2_OUT_CH1, 1, 0), +}; + +static const struct snd_kcontrol_new memif_ul0_ch2_mix[] = { + /* Normal record */ + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN019_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN019_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN019_0, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN019_0, + I_ADDA_UL_CH4, 1, 0), + /* AP DMIC */ + SOC_DAPM_SINGLE_AUTODISABLE("AP_DMIC_UL_CH2", AFE_CONN019_0, + I_DMIC0_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL0_CH2", AFE_CONN019_1, + I_DL0_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2", AFE_CONN019_1, + I_DL1_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2", AFE_CONN019_1, + I_DL2_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2", AFE_CONN019_1, + I_DL3_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH2", AFE_CONN019_1, + I_DL4_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH2", AFE_CONN019_1, + I_DL6_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL7_CH2", AFE_CONN019_1, + I_DL7_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL23_CH2", AFE_CONN018_2, + I_DL23_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH2", AFE_CONN019_1, + I_DL_24CH_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH1", AFE_CONN019_4, + I_PCM_0_CAP_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH2", AFE_CONN019_4, + I_PCM_0_CAP_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I2SIN0_CH2", AFE_CONN019_4, + I_I2SIN0_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I2SIN1_CH2", AFE_CONN019_4, + I_I2SIN1_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_0_OUT_CH2", AFE_CONN019_6, + I_SRC_0_OUT_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_2_OUT_CH2", AFE_CONN019_6, + I_SRC_2_OUT_CH2, 1, 0), +}; + +static const struct snd_kcontrol_new memif_ul1_ch1_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN020_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL0_CH1", AFE_CONN020_1, + I_DL0_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1", AFE_CONN020_1, + I_DL1_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1", AFE_CONN020_1, + I_DL2_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1", AFE_CONN020_1, + I_DL3_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH1", AFE_CONN020_1, + I_DL4_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH1", AFE_CONN020_1, + I_DL6_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL7_CH1", AFE_CONN020_1, + I_DL7_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL23_CH1", AFE_CONN020_2, + I_DL23_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH1", AFE_CONN020_1, + I_DL_24CH_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH1", AFE_CONN020_4, + I_PCM_0_CAP_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I2SIN0_CH1", AFE_CONN020_4, + I_I2SIN0_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I2SIN1_CH1", AFE_CONN020_4, + I_I2SIN1_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_0_OUT_CH1", AFE_CONN020_6, + I_SRC_0_OUT_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_2_OUT_CH1", AFE_CONN020_6, + I_SRC_2_OUT_CH1, 1, 0), +}; + +static const struct snd_kcontrol_new memif_ul1_ch2_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN021_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL0_CH2", AFE_CONN021_1, + I_DL0_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2", AFE_CONN021_1, + I_DL1_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2", AFE_CONN021_1, + I_DL2_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2", AFE_CONN021_1, + I_DL3_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH2", AFE_CONN021_1, + I_DL4_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH2", AFE_CONN021_1, + I_DL6_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL7_CH2", AFE_CONN021_1, + I_DL7_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL23_CH2", AFE_CONN021_2, + I_DL23_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH2", AFE_CONN021_1, + I_DL_24CH_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH1", AFE_CONN021_4, + I_PCM_0_CAP_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH2", AFE_CONN021_4, + I_PCM_0_CAP_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I2SIN0_CH2", AFE_CONN021_4, + I_I2SIN0_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I2SIN1_CH2", AFE_CONN021_4, + I_I2SIN1_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_0_OUT_CH2", AFE_CONN021_6, + I_SRC_0_OUT_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_2_OUT_CH2", AFE_CONN021_6, + I_SRC_2_OUT_CH2, 1, 0), +}; + +static const struct snd_kcontrol_new memif_ul2_ch1_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN022_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN022_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN022_0, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN022_0, + I_ADDA_UL_CH4, 1, 0), + /* AP DMIC */ + SOC_DAPM_SINGLE_AUTODISABLE("AP_DMIC_UL_CH3", AFE_CONN022_0, + I_DMIC1_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_GAIN1_OUT_CH1", AFE_CONN022_0, + I_GAIN1_OUT_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_1_OUT_CH1", AFE_CONN022_6, + I_SRC_1_OUT_CH1, 1, 0), +}; + +static const struct snd_kcontrol_new memif_ul2_ch2_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN023_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN023_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN023_0, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN023_0, + I_ADDA_UL_CH4, 1, 0), + /* AP DMIC */ + SOC_DAPM_SINGLE_AUTODISABLE("AP_DMIC_UL_CH4", AFE_CONN023_0, + I_DMIC1_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_GAIN1_OUT_CH2", AFE_CONN023_0, + I_GAIN1_OUT_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_1_OUT_CH2", AFE_CONN023_6, + I_SRC_1_OUT_CH2, 1, 0), +}; + +static const struct snd_kcontrol_new memif_ul3_ch1_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN024_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I2SIN1_CH1", AFE_CONN024_4, + I_I2SIN1_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_3_OUT_CH1", AFE_CONN024_6, + I_SRC_3_OUT_CH1, 1, 0), +}; + +static const struct snd_kcontrol_new memif_ul3_ch2_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN025_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I2SIN1_CH2", AFE_CONN025_4, + I_I2SIN1_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_3_OUT_CH2", AFE_CONN025_6, + I_SRC_3_OUT_CH2, 1, 0), +}; + +static const struct snd_kcontrol_new memif_ul4_ch1_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN026_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL0_CH1", AFE_CONN026_1, + I_DL0_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1", AFE_CONN026_1, + I_DL1_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH1", AFE_CONN026_1, + I_DL6_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1", AFE_CONN026_1, + I_DL2_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1", AFE_CONN026_1, + I_DL3_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH1", AFE_CONN026_1, + I_DL_24CH_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH1", AFE_CONN026_4, + I_PCM_0_CAP_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_GAIN0_OUT_CH1", AFE_CONN026_0, + I_GAIN0_OUT_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_3_OUT_CH1", AFE_CONN026_6, + I_SRC_3_OUT_CH1, 1, 0), +}; + +static const struct snd_kcontrol_new memif_ul4_ch2_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN027_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL0_CH2", AFE_CONN027_1, + I_DL0_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2", AFE_CONN027_1, + I_DL1_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH2", AFE_CONN027_1, + I_DL6_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2", AFE_CONN027_1, + I_DL2_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2", AFE_CONN027_1, + I_DL3_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH2", AFE_CONN027_1, + I_DL_24CH_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH1", AFE_CONN027_4, + I_PCM_0_CAP_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH2", AFE_CONN027_4, + I_PCM_0_CAP_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_GAIN0_OUT_CH2", AFE_CONN027_0, + I_GAIN0_OUT_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_3_OUT_CH2", AFE_CONN027_6, + I_SRC_3_OUT_CH2, 1, 0), +}; + +static const struct snd_kcontrol_new memif_ul5_ch1_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN028_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL0_CH1", AFE_CONN028_1, + I_DL0_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1", AFE_CONN028_1, + I_DL1_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH1", AFE_CONN028_1, + I_DL6_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1", AFE_CONN028_1, + I_DL2_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1", AFE_CONN028_1, + I_DL3_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH1", AFE_CONN028_1, + I_DL_24CH_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("GAIN0_OUT_CH1", AFE_CONN028_0, + I_GAIN0_OUT_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_3_OUT_CH1", AFE_CONN028_6, + I_SRC_3_OUT_CH1, 1, 0), +}; + +static const struct snd_kcontrol_new memif_ul5_ch2_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN029_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL0_CH2", AFE_CONN029_1, + I_DL0_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2", AFE_CONN029_1, + I_DL1_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH2", AFE_CONN029_1, + I_DL6_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2", AFE_CONN029_1, + I_DL2_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2", AFE_CONN029_1, + I_DL3_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH2", AFE_CONN029_1, + I_DL_24CH_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH1", AFE_CONN029_4, + I_PCM_0_CAP_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH2", AFE_CONN029_4, + I_PCM_0_CAP_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("GAIN0_OUT_CH2", AFE_CONN029_0, + I_GAIN0_OUT_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_3_OUT_CH2", AFE_CONN029_6, + I_SRC_3_OUT_CH2, 1, 0), +}; + +static const struct snd_kcontrol_new memif_ul6_ch1_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN030_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("AP_DMIC_UL_CH1", AFE_CONN030_0, + I_DMIC0_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL0_CH1", AFE_CONN030_1, + I_DL1_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1", AFE_CONN030_1, + I_DL2_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I2SIN0_CH1", AFE_CONN030_4, + I_I2SIN0_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_4_OUT_CH1", AFE_CONN030_6, + I_SRC_4_OUT_CH1, 1, 0), +}; + +static const struct snd_kcontrol_new memif_ul6_ch2_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN031_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("AP_DMIC_UL_CH2", AFE_CONN031_0, + I_DMIC0_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL0_CH2", AFE_CONN031_1, + I_DL1_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2", AFE_CONN031_1, + I_DL2_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I2SIN0_CH2", AFE_CONN031_4, + I_I2SIN0_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_4_OUT_CH2", AFE_CONN031_6, + I_SRC_4_OUT_CH2, 1, 0), +}; + +static const struct snd_kcontrol_new memif_ul7_ch1_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN032_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN032_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("AP_DMIC_UL_CH3", AFE_CONN032_0, + I_DMIC1_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL0_CH1", AFE_CONN032_1, + I_DL1_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1", AFE_CONN032_1, + I_DL2_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I2SIN0_CH1", AFE_CONN032_4, + I_I2SIN0_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_4_OUT_CH1", AFE_CONN032_6, + I_SRC_4_OUT_CH1, 1, 0), +}; + +static const struct snd_kcontrol_new memif_ul7_ch2_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN033_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN033_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("AP_DMIC_UL_CH4", AFE_CONN033_0, + I_DMIC1_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL0_CH2", AFE_CONN033_1, + I_DL1_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2", AFE_CONN033_1, + I_DL2_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I2SIN0_CH2", AFE_CONN033_4, + I_I2SIN0_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_4_OUT_CH2", AFE_CONN033_6, + I_SRC_4_OUT_CH2, 1, 0), +}; + +static const struct snd_kcontrol_new memif_ul8_ch1_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN034_0, + I_ADDA_UL_CH1, 1, 0), +}; + +static const struct snd_kcontrol_new memif_ul8_ch2_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN035_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH1", AFE_CONN035_4, + I_PCM_0_CAP_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH2", AFE_CONN035_4, + I_PCM_0_CAP_CH2, 1, 0), +}; + +static const struct snd_kcontrol_new memif_ul9_ch1_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN036_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN036_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN036_0, + I_ADDA_UL_CH3, 1, 0), +}; + +static const struct snd_kcontrol_new memif_ul9_ch2_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN037_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN037_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN037_0, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN037_0, + I_ADDA_UL_CH4, 1, 0), +}; + +static const struct snd_kcontrol_new memif_ul24_ch1_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN066_0, + I_ADDA_UL_CH1, 1, 0), +}; + +static const struct snd_kcontrol_new memif_ul24_ch2_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN067_0, + I_ADDA_UL_CH2, 1, 0), +}; + +static const struct snd_kcontrol_new memif_ul_cm0_ch1_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN040_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN040_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN040_0, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN040_0, + I_ADDA_UL_CH4, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("AP_DMIC_UL_CH1", AFE_CONN040_0, + I_DMIC0_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_GAIN1_OUT_CH1", AFE_CONN040_0, + I_GAIN1_OUT_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_0_OUT_CH1", AFE_CONN040_6, + I_SRC_0_OUT_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_1_OUT_CH1", AFE_CONN040_6, + I_SRC_1_OUT_CH1, 1, 0), +}; + +static const struct snd_kcontrol_new memif_ul_cm0_ch2_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN041_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN041_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN041_0, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN041_0, + I_ADDA_UL_CH4, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("AP_DMIC_UL_CH2", AFE_CONN041_0, + I_DMIC0_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_GAIN1_OUT_CH2", AFE_CONN041_0, + I_GAIN1_OUT_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_0_OUT_CH2", AFE_CONN041_6, + I_SRC_0_OUT_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_1_OUT_CH2", AFE_CONN041_6, + I_SRC_1_OUT_CH2, 1, 0), +}; + +static const struct snd_kcontrol_new memif_ul_cm0_ch3_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN042_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN042_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN042_0, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN042_0, + I_ADDA_UL_CH4, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("AP_DMIC_UL_CH3", AFE_CONN042_0, + I_DMIC1_CH1, 1, 0), +}; + +static const struct snd_kcontrol_new memif_ul_cm0_ch4_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN043_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN043_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN043_0, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN043_0, + I_ADDA_UL_CH4, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("AP_DMIC_UL_CH4", AFE_CONN043_0, + I_DMIC1_CH2, 1, 0), +}; + +static const struct snd_kcontrol_new memif_ul_cm0_ch5_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN044_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN044_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN044_0, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN044_0, + I_ADDA_UL_CH4, 1, 0), +}; + +static const struct snd_kcontrol_new memif_ul_cm0_ch6_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN045_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN045_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN045_0, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN045_0, + I_ADDA_UL_CH4, 1, 0), +}; + +static const struct snd_kcontrol_new memif_ul_cm0_ch7_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN046_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN046_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN046_0, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN046_0, + I_ADDA_UL_CH4, 1, 0), +}; + +static const struct snd_kcontrol_new memif_ul_cm0_ch8_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN047_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN047_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN047_0, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN047_0, + I_ADDA_UL_CH4, 1, 0), +}; + +static const struct snd_kcontrol_new memif_ul_cm1_ch1_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN048_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN048_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN048_0, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN048_0, + I_ADDA_UL_CH4, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH5", AFE_CONN048_0, + I_ADDA_UL_CH5, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH6", AFE_CONN048_0, + I_ADDA_UL_CH6, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_0_OUT_CH1", AFE_CONN048_6, + I_SRC_0_OUT_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_3_OUT_CH1", AFE_CONN048_6, + I_SRC_3_OUT_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_4_OUT_CH1", AFE_CONN048_6, + I_SRC_4_OUT_CH1, 1, 0), +}; + +static const struct snd_kcontrol_new memif_ul_cm1_ch2_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN049_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN049_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN049_0, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN049_0, + I_ADDA_UL_CH4, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH5", AFE_CONN049_0, + I_ADDA_UL_CH5, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH6", AFE_CONN049_0, + I_ADDA_UL_CH6, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_0_OUT_CH2", AFE_CONN049_6, + I_SRC_0_OUT_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_3_OUT_CH2", AFE_CONN049_6, + I_SRC_3_OUT_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_4_OUT_CH2", AFE_CONN049_6, + I_SRC_4_OUT_CH2, 1, 0), +}; + +static const struct snd_kcontrol_new memif_ul_cm1_ch3_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN050_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN050_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN050_0, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN050_0, + I_ADDA_UL_CH4, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH5", AFE_CONN050_0, + I_ADDA_UL_CH5, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH6", AFE_CONN050_0, + I_ADDA_UL_CH6, 1, 0), +}; + +static const struct snd_kcontrol_new memif_ul_cm1_ch4_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN051_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN051_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN051_0, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN051_0, + I_ADDA_UL_CH4, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH5", AFE_CONN051_0, + I_ADDA_UL_CH5, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH6", AFE_CONN051_0, + I_ADDA_UL_CH6, 1, 0), +}; + +static const struct snd_kcontrol_new memif_ul_cm1_ch5_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN052_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN052_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN052_0, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN052_0, + I_ADDA_UL_CH4, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH5", AFE_CONN052_0, + I_ADDA_UL_CH5, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH6", AFE_CONN052_0, + I_ADDA_UL_CH6, 1, 0), +}; + +static const struct snd_kcontrol_new memif_ul_cm1_ch6_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN053_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN053_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN053_0, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN053_0, + I_ADDA_UL_CH4, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH5", AFE_CONN053_0, + I_ADDA_UL_CH5, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH6", AFE_CONN053_0, + I_ADDA_UL_CH6, 1, 0), +}; + +static const struct snd_kcontrol_new memif_ul_cm1_ch7_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN054_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN054_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN054_0, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN054_0, + I_ADDA_UL_CH4, 1, 0), +}; + +static const struct snd_kcontrol_new memif_ul_cm1_ch8_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN055_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN055_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN055_0, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN055_0, + I_ADDA_UL_CH4, 1, 0), +}; + +static const struct snd_kcontrol_new memif_ul_cm1_ch9_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN056_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN056_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN056_0, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN056_0, + I_ADDA_UL_CH4, 1, 0), +}; + +static const struct snd_kcontrol_new memif_ul_cm1_ch10_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN057_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN057_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN057_0, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN057_0, + I_ADDA_UL_CH4, 1, 0), +}; + +static const struct snd_kcontrol_new memif_ul_cm1_ch11_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN058_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN058_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN058_0, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN058_0, + I_ADDA_UL_CH4, 1, 0), +}; + +static const struct snd_kcontrol_new memif_ul_cm1_ch12_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN059_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN059_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN059_0, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN059_0, + I_ADDA_UL_CH4, 1, 0), +}; + +static const struct snd_kcontrol_new memif_ul_cm1_ch13_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN060_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN060_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN060_0, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN060_0, + I_ADDA_UL_CH4, 1, 0), +}; + +static const struct snd_kcontrol_new memif_ul_cm1_ch14_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN061_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN061_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN061_0, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN061_0, + I_ADDA_UL_CH4, 1, 0), +}; + +static const struct snd_kcontrol_new memif_ul_cm1_ch15_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN062_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN062_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN062_0, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN062_0, + I_ADDA_UL_CH4, 1, 0), +}; + +static const struct snd_kcontrol_new memif_ul_cm1_ch16_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN063_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN063_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN063_0, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH4", AFE_CONN063_0, + I_ADDA_UL_CH4, 1, 0), +}; + +static const char * const cm0_mux_texts[] = { + "CM0_2CH_PATH", + "CM0_8CH_PATH", +}; + +static const char * const cm1_mux_map_texts[] = { + "CM1_2CH_PATH", + "CM1_16CH_PATH", +}; + +static SOC_ENUM_SINGLE_DECL(ul_cm0_mux_map_enum, + AFE_CM0_CON0, + AFE_CM0_OUTPUT_MUX_SFT, + cm0_mux_texts); +static SOC_ENUM_SINGLE_DECL(ul_cm1_mux_map_enum, + AFE_CM1_CON0, + AFE_CM1_OUTPUT_MUX_SFT, + cm1_mux_map_texts); + +static const struct snd_kcontrol_new ul_cm0_mux_control = + SOC_DAPM_ENUM("CM0_UL_MUX Route", ul_cm0_mux_map_enum); +static const struct snd_kcontrol_new ul_cm1_mux_control = + SOC_DAPM_ENUM("CM1_UL_MUX Route", ul_cm1_mux_map_enum); + +static const struct snd_soc_dapm_widget mt8189_memif_widgets[] = { + /* inter-connections */ + SND_SOC_DAPM_MIXER("UL0_CH1", SND_SOC_NOPM, 0, 0, + memif_ul0_ch1_mix, ARRAY_SIZE(memif_ul0_ch1_mix)), + SND_SOC_DAPM_MIXER("UL0_CH2", SND_SOC_NOPM, 0, 0, + memif_ul0_ch2_mix, ARRAY_SIZE(memif_ul0_ch2_mix)), + + SND_SOC_DAPM_MIXER("UL1_CH1", SND_SOC_NOPM, 0, 0, + memif_ul1_ch1_mix, ARRAY_SIZE(memif_ul1_ch1_mix)), + SND_SOC_DAPM_MIXER("UL1_CH2", SND_SOC_NOPM, 0, 0, + memif_ul1_ch2_mix, ARRAY_SIZE(memif_ul1_ch2_mix)), + + SND_SOC_DAPM_MIXER("UL2_CH1", SND_SOC_NOPM, 0, 0, + memif_ul2_ch1_mix, ARRAY_SIZE(memif_ul2_ch1_mix)), + SND_SOC_DAPM_MIXER("UL2_CH2", SND_SOC_NOPM, 0, 0, + memif_ul2_ch2_mix, ARRAY_SIZE(memif_ul2_ch2_mix)), + + SND_SOC_DAPM_MIXER("UL3_CH1", SND_SOC_NOPM, 0, 0, + memif_ul3_ch1_mix, ARRAY_SIZE(memif_ul3_ch1_mix)), + SND_SOC_DAPM_MIXER("UL3_CH2", SND_SOC_NOPM, 0, 0, + memif_ul3_ch2_mix, ARRAY_SIZE(memif_ul3_ch2_mix)), + + SND_SOC_DAPM_MIXER("UL4_CH1", SND_SOC_NOPM, 0, 0, + memif_ul4_ch1_mix, ARRAY_SIZE(memif_ul4_ch1_mix)), + SND_SOC_DAPM_MIXER("UL4_CH2", SND_SOC_NOPM, 0, 0, + memif_ul4_ch2_mix, ARRAY_SIZE(memif_ul4_ch2_mix)), + + SND_SOC_DAPM_MIXER("UL5_CH1", SND_SOC_NOPM, 0, 0, + memif_ul5_ch1_mix, ARRAY_SIZE(memif_ul5_ch1_mix)), + SND_SOC_DAPM_MIXER("UL5_CH2", SND_SOC_NOPM, 0, 0, + memif_ul5_ch2_mix, ARRAY_SIZE(memif_ul5_ch2_mix)), + + SND_SOC_DAPM_MIXER("UL6_CH1", SND_SOC_NOPM, 0, 0, + memif_ul6_ch1_mix, ARRAY_SIZE(memif_ul6_ch1_mix)), + SND_SOC_DAPM_MIXER("UL6_CH2", SND_SOC_NOPM, 0, 0, + memif_ul6_ch2_mix, ARRAY_SIZE(memif_ul6_ch2_mix)), + + SND_SOC_DAPM_MIXER("UL7_CH1", SND_SOC_NOPM, 0, 0, + memif_ul7_ch1_mix, ARRAY_SIZE(memif_ul7_ch1_mix)), + SND_SOC_DAPM_MIXER("UL7_CH2", SND_SOC_NOPM, 0, 0, + memif_ul7_ch2_mix, ARRAY_SIZE(memif_ul7_ch2_mix)), + + SND_SOC_DAPM_MIXER("UL8_CH1", SND_SOC_NOPM, 0, 0, + memif_ul8_ch1_mix, ARRAY_SIZE(memif_ul8_ch1_mix)), + SND_SOC_DAPM_MIXER("UL8_CH2", SND_SOC_NOPM, 0, 0, + memif_ul8_ch2_mix, ARRAY_SIZE(memif_ul8_ch2_mix)), + + SND_SOC_DAPM_MIXER("UL9_CH1", SND_SOC_NOPM, 0, 0, + memif_ul9_ch1_mix, ARRAY_SIZE(memif_ul9_ch1_mix)), + SND_SOC_DAPM_MIXER("UL9_CH2", SND_SOC_NOPM, 0, 0, + memif_ul9_ch2_mix, ARRAY_SIZE(memif_ul9_ch2_mix)), + + SND_SOC_DAPM_MIXER("UL24_CH1", SND_SOC_NOPM, 0, 0, + memif_ul24_ch1_mix, ARRAY_SIZE(memif_ul24_ch1_mix)), + SND_SOC_DAPM_MIXER("UL24_CH2", SND_SOC_NOPM, 0, 0, + memif_ul24_ch2_mix, ARRAY_SIZE(memif_ul24_ch2_mix)), + + SND_SOC_DAPM_MIXER("UL_CM0_CH1", SND_SOC_NOPM, 0, 0, + memif_ul_cm0_ch1_mix, ARRAY_SIZE(memif_ul_cm0_ch1_mix)), + SND_SOC_DAPM_MIXER("UL_CM0_CH2", SND_SOC_NOPM, 0, 0, + memif_ul_cm0_ch2_mix, ARRAY_SIZE(memif_ul_cm0_ch2_mix)), + SND_SOC_DAPM_MIXER("UL_CM0_CH3", SND_SOC_NOPM, 0, 0, + memif_ul_cm0_ch3_mix, ARRAY_SIZE(memif_ul_cm0_ch3_mix)), + SND_SOC_DAPM_MIXER("UL_CM0_CH4", SND_SOC_NOPM, 0, 0, + memif_ul_cm0_ch4_mix, ARRAY_SIZE(memif_ul_cm0_ch4_mix)), + SND_SOC_DAPM_MIXER("UL_CM0_CH5", SND_SOC_NOPM, 0, 0, + memif_ul_cm0_ch5_mix, ARRAY_SIZE(memif_ul_cm0_ch5_mix)), + SND_SOC_DAPM_MIXER("UL_CM0_CH6", SND_SOC_NOPM, 0, 0, + memif_ul_cm0_ch6_mix, ARRAY_SIZE(memif_ul_cm0_ch6_mix)), + SND_SOC_DAPM_MIXER("UL_CM0_CH7", SND_SOC_NOPM, 0, 0, + memif_ul_cm0_ch7_mix, ARRAY_SIZE(memif_ul_cm0_ch7_mix)), + SND_SOC_DAPM_MIXER("UL_CM0_CH8", SND_SOC_NOPM, 0, 0, + memif_ul_cm0_ch8_mix, ARRAY_SIZE(memif_ul_cm0_ch8_mix)), + SND_SOC_DAPM_MUX_E("CM0_UL_MUX", SND_SOC_NOPM, 0, 0, + &ul_cm0_mux_control, + ul_cm0_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), + + SND_SOC_DAPM_MIXER("UL_CM1_CH1", SND_SOC_NOPM, 0, 0, + memif_ul_cm1_ch1_mix, ARRAY_SIZE(memif_ul_cm1_ch1_mix)), + SND_SOC_DAPM_MIXER("UL_CM1_CH2", SND_SOC_NOPM, 0, 0, + memif_ul_cm1_ch2_mix, ARRAY_SIZE(memif_ul_cm1_ch2_mix)), + SND_SOC_DAPM_MIXER("UL_CM1_CH3", SND_SOC_NOPM, 0, 0, + memif_ul_cm1_ch3_mix, ARRAY_SIZE(memif_ul_cm1_ch3_mix)), + SND_SOC_DAPM_MIXER("UL_CM1_CH4", SND_SOC_NOPM, 0, 0, + memif_ul_cm1_ch4_mix, ARRAY_SIZE(memif_ul_cm1_ch4_mix)), + SND_SOC_DAPM_MIXER("UL_CM1_CH5", SND_SOC_NOPM, 0, 0, + memif_ul_cm1_ch5_mix, ARRAY_SIZE(memif_ul_cm1_ch5_mix)), + SND_SOC_DAPM_MIXER("UL_CM1_CH6", SND_SOC_NOPM, 0, 0, + memif_ul_cm1_ch6_mix, ARRAY_SIZE(memif_ul_cm1_ch6_mix)), + SND_SOC_DAPM_MIXER("UL_CM1_CH7", SND_SOC_NOPM, 0, 0, + memif_ul_cm1_ch7_mix, ARRAY_SIZE(memif_ul_cm1_ch7_mix)), + SND_SOC_DAPM_MIXER("UL_CM1_CH8", SND_SOC_NOPM, 0, 0, + memif_ul_cm1_ch8_mix, ARRAY_SIZE(memif_ul_cm1_ch8_mix)), + SND_SOC_DAPM_MIXER("UL_CM1_CH9", SND_SOC_NOPM, 0, 0, + memif_ul_cm1_ch9_mix, ARRAY_SIZE(memif_ul_cm1_ch9_mix)), + SND_SOC_DAPM_MIXER("UL_CM1_CH10", SND_SOC_NOPM, 0, 0, + memif_ul_cm1_ch10_mix, ARRAY_SIZE(memif_ul_cm1_ch10_mix)), + SND_SOC_DAPM_MIXER("UL_CM1_CH11", SND_SOC_NOPM, 0, 0, + memif_ul_cm1_ch11_mix, ARRAY_SIZE(memif_ul_cm1_ch11_mix)), + SND_SOC_DAPM_MIXER("UL_CM1_CH12", SND_SOC_NOPM, 0, 0, + memif_ul_cm1_ch12_mix, ARRAY_SIZE(memif_ul_cm1_ch12_mix)), + SND_SOC_DAPM_MIXER("UL_CM1_CH13", SND_SOC_NOPM, 0, 0, + memif_ul_cm1_ch13_mix, ARRAY_SIZE(memif_ul_cm1_ch13_mix)), + SND_SOC_DAPM_MIXER("UL_CM1_CH14", SND_SOC_NOPM, 0, 0, + memif_ul_cm1_ch14_mix, ARRAY_SIZE(memif_ul_cm1_ch14_mix)), + SND_SOC_DAPM_MIXER("UL_CM1_CH15", SND_SOC_NOPM, 0, 0, + memif_ul_cm1_ch15_mix, ARRAY_SIZE(memif_ul_cm1_ch15_mix)), + SND_SOC_DAPM_MIXER("UL_CM1_CH16", SND_SOC_NOPM, 0, 0, + memif_ul_cm1_ch16_mix, ARRAY_SIZE(memif_ul_cm1_ch16_mix)), + SND_SOC_DAPM_MUX("CM1_UL_MUX", SND_SOC_NOPM, 0, 0, + &ul_cm1_mux_control), + SND_SOC_DAPM_SUPPLY("CM0_Enable", + AFE_CM0_CON0, AFE_CM0_ON_SFT, 0, + ul_cm0_event, + SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_PRE_PMD), + + SND_SOC_DAPM_SUPPLY("CM1_Enable", + AFE_CM1_CON0, AFE_CM0_ON_SFT, 0, + ul_cm1_event, + SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_PRE_PMD), + + /* dynamic pinctrl */ + SND_SOC_DAPM_PINCTRL("I2S0_PIN", "aud-gpio-i2s0-on", "aud-gpio-i2s0-off"), + SND_SOC_DAPM_PINCTRL("I2S1_PIN", "aud-gpio-i2s1-on", "aud-gpio-i2s1-off"), + SND_SOC_DAPM_PINCTRL("PCM0_PIN", "aud-gpio-pcm-on", "aud-gpio-pcm-off"), + SND_SOC_DAPM_PINCTRL("AP_DMIC0_PIN", "aud-gpio-ap-dmic-on", "aud-gpio-ap-dmic-off"), + SND_SOC_DAPM_PINCTRL("AP_DMIC1_PIN", "aud-gpio-ap-dmic1-on", "aud-gpio-ap-dmic1-off"), +}; + +static const struct snd_soc_dapm_route mt8189_memif_routes[] = { + {"UL0", NULL, "UL0_CH1"}, + {"UL0", NULL, "UL0_CH2"}, + /* Normal record */ + {"UL0_CH1", "ADDA_UL_CH1", "ADDA_UL_Mux"}, + {"UL0_CH1", "ADDA_UL_CH2", "ADDA_UL_Mux"}, + {"UL0_CH1", "ADDA_UL_CH3", "ADDA_CH34_UL_Mux"}, + {"UL0_CH1", "ADDA_UL_CH4", "ADDA_CH34_UL_Mux"}, + {"UL0_CH2", "ADDA_UL_CH1", "ADDA_UL_Mux"}, + {"UL0_CH2", "ADDA_UL_CH2", "ADDA_UL_Mux"}, + {"UL0_CH2", "ADDA_UL_CH3", "ADDA_CH34_UL_Mux"}, + {"UL0_CH2", "ADDA_UL_CH4", "ADDA_CH34_UL_Mux"}, + + {"UL0_CH1", "AP_DMIC_UL_CH1", "AP DMIC Capture"}, + {"UL0_CH1", "AP_DMIC_UL_CH2", "AP DMIC Capture"}, + {"UL0_CH2", "AP_DMIC_UL_CH2", "AP DMIC Capture"}, + + {"UL0_CH1", "I2SIN0_CH1", "I2SIN0"}, + {"UL0_CH2", "I2SIN0_CH2", "I2SIN0"}, + {"UL0_CH1", "I2SIN1_CH1", "I2SIN1"}, + {"UL0_CH2", "I2SIN1_CH2", "I2SIN1"}, + + {"UL0_CH1", "PCM_0_CAP_CH1", "PCM 0 Capture"}, + {"UL0_CH2", "PCM_0_CAP_CH1", "PCM 0 Capture"}, + + {"UL1", NULL, "UL1_CH1"}, + {"UL1", NULL, "UL1_CH2"}, + + {"UL1_CH1", "ADDA_UL_CH1", "ADDA_UL_Mux"}, + {"UL1_CH2", "ADDA_UL_CH2", "ADDA_UL_Mux"}, + + {"UL1_CH1", "I2SIN0_CH1", "I2SIN0"}, + {"UL1_CH2", "I2SIN0_CH2", "I2SIN0"}, + {"UL1_CH1", "I2SIN1_CH1", "I2SIN1"}, + {"UL1_CH2", "I2SIN1_CH2", "I2SIN1"}, + + {"UL1_CH1", "PCM_0_CAP_CH1", "PCM 0 Capture"}, + {"UL1_CH2", "PCM_0_CAP_CH1", "PCM 0 Capture"}, + + {"UL2", NULL, "UL2_CH1"}, + {"UL2", NULL, "UL2_CH2"}, + + {"UL2_CH1", "ADDA_UL_CH1", "ADDA_UL_Mux"}, + {"UL2_CH1", "ADDA_UL_CH2", "ADDA_UL_Mux"}, + {"UL2_CH1", "ADDA_UL_CH3", "ADDA_CH34_UL_Mux"}, + {"UL2_CH1", "ADDA_UL_CH4", "ADDA_CH34_UL_Mux"}, + {"UL2_CH2", "ADDA_UL_CH1", "ADDA_UL_Mux"}, + {"UL2_CH2", "ADDA_UL_CH2", "ADDA_UL_Mux"}, + {"UL2_CH2", "ADDA_UL_CH3", "ADDA_CH34_UL_Mux"}, + {"UL2_CH2", "ADDA_UL_CH4", "ADDA_CH34_UL_Mux"}, + + {"UL2_CH1", "AP_DMIC_UL_CH3", "AP DMIC CH34 Capture"}, + {"UL2_CH2", "AP_DMIC_UL_CH4", "AP DMIC CH34 Capture"}, + + {"UL3", NULL, "UL3_CH1"}, + {"UL3", NULL, "UL3_CH2"}, + + {"UL3_CH1", "ADDA_UL_CH1", "ADDA Capture"}, + {"UL3_CH2", "ADDA_UL_CH2", "ADDA Capture"}, + {"UL3_CH1", "I2SIN1_CH1", "I2SIN1"}, + {"UL3_CH2", "I2SIN1_CH2", "I2SIN1"}, + + {"UL4", NULL, "UL4_CH1"}, + {"UL4", NULL, "UL4_CH2"}, + {"UL4_CH1", "ADDA_UL_CH1", "ADDA Capture"}, + {"UL4_CH2", "ADDA_UL_CH2", "ADDA Capture"}, + + {"UL4_CH1", "PCM_0_CAP_CH1", "PCM 0 Capture"}, + {"UL4_CH2", "PCM_0_CAP_CH1", "PCM 0 Capture"}, + + {"UL5", NULL, "UL5_CH1"}, + {"UL5", NULL, "UL5_CH2"}, + + {"UL5_CH1", "ADDA_UL_CH1", "ADDA Capture"}, + {"UL5_CH2", "ADDA_UL_CH2", "ADDA Capture"}, + + {"UL6", NULL, "UL6_CH1"}, + {"UL6", NULL, "UL6_CH2"}, + {"UL6_CH1", "ADDA_UL_CH1", "ADDA Capture"}, + {"UL6_CH2", "ADDA_UL_CH2", "ADDA Capture"}, + {"UL6_CH1", "I2SIN0_CH1", "I2SIN0"}, + {"UL6_CH2", "I2SIN0_CH2", "I2SIN0"}, + {"UL6_CH1", "AP_DMIC_UL_CH1", "AP DMIC Capture"}, + {"UL6_CH2", "AP_DMIC_UL_CH2", "AP DMIC Capture"}, + + {"UL7", NULL, "UL7_CH1"}, + {"UL7", NULL, "UL7_CH2"}, + {"UL7_CH1", "ADDA_UL_CH1", "ADDA Capture"}, + {"UL7_CH1", "ADDA_UL_CH2", "ADDA Capture"}, + {"UL7_CH2", "ADDA_UL_CH1", "ADDA Capture"}, + {"UL7_CH2", "ADDA_UL_CH2", "ADDA Capture"}, + {"UL7_CH1", "I2SIN0_CH1", "I2SIN0"}, + {"UL7_CH2", "I2SIN0_CH2", "I2SIN0"}, + {"UL7_CH1", "AP_DMIC_UL_CH3", "AP DMIC CH34 Capture"}, + {"UL7_CH2", "AP_DMIC_UL_CH4", "AP DMIC CH34 Capture"}, + + {"UL8", NULL, "CM0_UL_MUX"}, + {"CM0_UL_MUX", "CM0_2CH_PATH", "UL8_CH1"}, + {"CM0_UL_MUX", "CM0_2CH_PATH", "UL8_CH2"}, + {"CM0_UL_MUX", "CM0_8CH_PATH", "UL_CM0_CH1"}, + {"CM0_UL_MUX", "CM0_8CH_PATH", "UL_CM0_CH2"}, + {"CM0_UL_MUX", "CM0_8CH_PATH", "UL_CM0_CH3"}, + {"CM0_UL_MUX", "CM0_8CH_PATH", "UL_CM0_CH4"}, + {"CM0_UL_MUX", "CM0_8CH_PATH", "UL_CM0_CH5"}, + {"CM0_UL_MUX", "CM0_8CH_PATH", "UL_CM0_CH6"}, + {"CM0_UL_MUX", "CM0_8CH_PATH", "UL_CM0_CH7"}, + {"CM0_UL_MUX", "CM0_8CH_PATH", "UL_CM0_CH8"}, + + {"UL_CM0", NULL, "CM0_Enable"}, + + {"UL9", NULL, "CM1_UL_MUX"}, + {"CM1_UL_MUX", "CM1_2CH_PATH", "UL9_CH1"}, + {"CM1_UL_MUX", "CM1_2CH_PATH", "UL9_CH2"}, + {"CM1_UL_MUX", "CM1_16CH_PATH", "UL_CM1_CH1"}, + {"CM1_UL_MUX", "CM1_16CH_PATH", "UL_CM1_CH2"}, + {"CM1_UL_MUX", "CM1_16CH_PATH", "UL_CM1_CH3"}, + {"CM1_UL_MUX", "CM1_16CH_PATH", "UL_CM1_CH4"}, + {"CM1_UL_MUX", "CM1_16CH_PATH", "UL_CM1_CH5"}, + {"CM1_UL_MUX", "CM1_16CH_PATH", "UL_CM1_CH6"}, + {"CM1_UL_MUX", "CM1_16CH_PATH", "UL_CM1_CH7"}, + {"CM1_UL_MUX", "CM1_16CH_PATH", "UL_CM1_CH8"}, + {"CM1_UL_MUX", "CM1_16CH_PATH", "UL_CM1_CH9"}, + {"CM1_UL_MUX", "CM1_16CH_PATH", "UL_CM1_CH10"}, + {"CM1_UL_MUX", "CM1_16CH_PATH", "UL_CM1_CH11"}, + {"CM1_UL_MUX", "CM1_16CH_PATH", "UL_CM1_CH12"}, + {"CM1_UL_MUX", "CM1_16CH_PATH", "UL_CM1_CH13"}, + {"CM1_UL_MUX", "CM1_16CH_PATH", "UL_CM1_CH14"}, + {"CM1_UL_MUX", "CM1_16CH_PATH", "UL_CM1_CH15"}, + {"CM1_UL_MUX", "CM1_16CH_PATH", "UL_CM1_CH16"}, + + {"UL_CM1", NULL, "CM1_Enable"}, + + /* UL9 o36o37 <- ADDA */ + {"UL9_CH1", "ADDA_UL_CH1", "ADDA Capture"}, + {"UL9_CH1", "ADDA_UL_CH2", "ADDA Capture"}, + {"UL9_CH2", "ADDA_UL_CH1", "ADDA Capture"}, + {"UL9_CH2", "ADDA_UL_CH2", "ADDA Capture"}, + + {"UL24", NULL, "UL24_CH1"}, + {"UL24", NULL, "UL24_CH2"}, + {"UL24_CH1", "ADDA_UL_CH1", "ADDA Capture"}, + + {"UL_CM0", NULL, "UL_CM0_CH1"}, + {"UL_CM0", NULL, "UL_CM0_CH2"}, + {"UL_CM0", NULL, "UL_CM0_CH3"}, + {"UL_CM0", NULL, "UL_CM0_CH4"}, + {"UL_CM0", NULL, "UL_CM0_CH5"}, + {"UL_CM0", NULL, "UL_CM0_CH6"}, + {"UL_CM0", NULL, "UL_CM0_CH7"}, + {"UL_CM0", NULL, "UL_CM0_CH8"}, + {"UL_CM0_CH1", "ADDA_UL_CH1", "ADDA Capture"}, + {"UL_CM0_CH1", "ADDA_UL_CH2", "ADDA Capture"}, + {"UL_CM0_CH2", "ADDA_UL_CH1", "ADDA Capture"}, + {"UL_CM0_CH2", "ADDA_UL_CH2", "ADDA Capture"}, + {"UL_CM0_CH3", "ADDA_UL_CH1", "ADDA Capture"}, + {"UL_CM0_CH3", "ADDA_UL_CH2", "ADDA Capture"}, + {"UL_CM0_CH4", "ADDA_UL_CH1", "ADDA Capture"}, + {"UL_CM0_CH4", "ADDA_UL_CH2", "ADDA Capture"}, + {"UL_CM0_CH1", "AP_DMIC_UL_CH1", "AP DMIC Capture"}, + {"UL_CM0_CH2", "AP_DMIC_UL_CH2", "AP DMIC Capture"}, + {"UL_CM0_CH3", "AP_DMIC_UL_CH3", "AP DMIC CH34 Capture"}, + {"UL_CM0_CH4", "AP_DMIC_UL_CH4", "AP DMIC CH34 Capture"}, + + {"UL_CM1", NULL, "UL_CM1_CH1"}, + {"UL_CM1", NULL, "UL_CM1_CH2"}, + {"UL_CM1", NULL, "UL_CM1_CH3"}, + {"UL_CM1", NULL, "UL_CM1_CH4"}, + {"UL_CM1", NULL, "UL_CM1_CH5"}, + {"UL_CM1", NULL, "UL_CM1_CH6"}, + {"UL_CM1", NULL, "UL_CM1_CH7"}, + {"UL_CM1", NULL, "UL_CM1_CH8"}, + {"UL_CM1", NULL, "UL_CM1_CH9"}, + {"UL_CM1", NULL, "UL_CM1_CH10"}, + {"UL_CM1", NULL, "UL_CM1_CH11"}, + {"UL_CM1", NULL, "UL_CM1_CH12"}, + {"UL_CM1", NULL, "UL_CM1_CH13"}, + {"UL_CM1", NULL, "UL_CM1_CH14"}, + {"UL_CM1", NULL, "UL_CM1_CH15"}, + {"UL_CM1", NULL, "UL_CM1_CH16"}, + {"UL_CM1_CH1", "ADDA_UL_CH1", "ADDA Capture"}, + {"UL_CM1_CH1", "ADDA_UL_CH2", "ADDA Capture"}, + {"UL_CM1_CH2", "ADDA_UL_CH1", "ADDA Capture"}, + {"UL_CM1_CH2", "ADDA_UL_CH2", "ADDA Capture"}, + {"UL_CM1_CH3", "ADDA_UL_CH1", "ADDA Capture"}, + {"UL_CM1_CH3", "ADDA_UL_CH2", "ADDA Capture"}, + {"UL_CM1_CH4", "ADDA_UL_CH1", "ADDA Capture"}, + {"UL_CM1_CH4", "ADDA_UL_CH2", "ADDA Capture"}, + {"UL_CM1_CH5", "ADDA_UL_CH1", "ADDA Capture"}, + {"UL_CM1_CH5", "ADDA_UL_CH2", "ADDA Capture"}, + {"UL_CM1_CH6", "ADDA_UL_CH1", "ADDA Capture"}, + {"UL_CM1_CH6", "ADDA_UL_CH2", "ADDA Capture"}, + + /* Audio Pin */ + {"I2SOUT0", NULL, "I2S0_PIN"}, + {"I2SIN0", NULL, "I2S0_PIN"}, + {"I2SOUT1", NULL, "I2S1_PIN"}, + {"I2SIN1", NULL, "I2S1_PIN"}, + {"PCM 0 Playback", NULL, "PCM0_PIN"}, + {"AP DMIC Capture", NULL, "AP_DMIC0_PIN"}, + {"AP DMIC CH34 Capture", NULL, "AP_DMIC1_PIN"}, +}; + +#define MT8189_DL_MEMIF(_id) \ + [MT8189_MEMIF_##_id] = { \ + .name = #_id, \ + .id = MT8189_MEMIF_##_id, \ + .reg_ofs_base = AFE_##_id##_BASE, \ + .reg_ofs_cur = AFE_##_id##_CUR, \ + .reg_ofs_end = AFE_##_id##_END, \ + .reg_ofs_base_msb = AFE_##_id##_BASE_MSB, \ + .reg_ofs_cur_msb = AFE_##_id##_CUR_MSB, \ + .reg_ofs_end_msb = AFE_##_id##_END_MSB, \ + .fs_reg = AFE_##_id##_CON0, \ + .fs_shift = _id##_SEL_FS_SFT, \ + .fs_maskbit = _id##_SEL_FS_MASK, \ + .mono_reg = AFE_##_id##_CON0, \ + .mono_shift = _id##_MONO_SFT, \ + .enable_reg = AFE_##_id##_CON0, \ + .enable_shift = _id##_ON_SFT, \ + .hd_reg = AFE_##_id##_CON0, \ + .hd_shift = _id##_HD_MODE_SFT, \ + .hd_align_reg = AFE_##_id##_CON0, \ + .hd_align_mshift = _id##_HALIGN_SFT, \ + .agent_disable_reg = -1, \ + .agent_disable_shift = -1, \ + .msb_reg = -1, \ + .msb_shift = -1, \ + .pbuf_reg = AFE_##_id##_CON0, \ + .pbuf_mask = _id##_PBUF_SIZE_MASK, \ + .pbuf_shift = _id##_PBUF_SIZE_SFT, \ + .minlen_reg = AFE_##_id##_CON0, \ + .minlen_mask = _id##_MINLEN_MASK, \ + .minlen_shift = _id##_MINLEN_SFT, \ +} + +#define MT8189_MULTI_DL_MEMIF(_id) \ + [MT8189_MEMIF_##_id] = { \ + .name = #_id, \ + .id = MT8189_MEMIF_##_id, \ + .reg_ofs_base = AFE_##_id##_BASE, \ + .reg_ofs_cur = AFE_##_id##_CUR, \ + .reg_ofs_end = AFE_##_id##_END, \ + .reg_ofs_base_msb = AFE_##_id##_BASE_MSB, \ + .reg_ofs_cur_msb = AFE_##_id##_CUR_MSB, \ + .reg_ofs_end_msb = AFE_##_id##_END_MSB, \ + .fs_reg = AFE_##_id##_CON0, \ + .fs_shift = _id##_SEL_FS_SFT, \ + .fs_maskbit = _id##_SEL_FS_MASK, \ + .mono_reg = -1, \ + .mono_shift = -1, \ + .enable_reg = AFE_##_id##_CON0, \ + .enable_shift = _id##_ON_SFT, \ + .hd_reg = AFE_##_id##_CON0, \ + .hd_shift = _id##_HD_MODE_SFT, \ + .hd_align_reg = AFE_##_id##_CON0, \ + .hd_align_mshift = _id##_HALIGN_SFT, \ + .agent_disable_reg = -1, \ + .agent_disable_shift = -1, \ + .msb_reg = -1, \ + .msb_shift = -1, \ + .pbuf_reg = AFE_##_id##_CON0, \ + .pbuf_mask = _id##_PBUF_SIZE_MASK, \ + .pbuf_shift = _id##_PBUF_SIZE_SFT, \ + .minlen_reg = AFE_##_id##_CON0, \ + .minlen_mask = _id##_MINLEN_MASK, \ + .minlen_shift = _id##_MINLEN_SFT, \ + .ch_num_reg = AFE_##_id##_CON0, \ + .ch_num_maskbit = _id##_NUM_MASK, \ + .ch_num_shift = _id##_NUM_SFT, \ +} + +#define MT8189_UL_MEMIF(_id, _fs_shift, _fs_maskbit, _mono_shift) \ + [MT8189_MEMIF_##_id] = { \ + .name = #_id, \ + .id = MT8189_MEMIF_##_id, \ + .reg_ofs_base = AFE_##_id##_BASE, \ + .reg_ofs_cur = AFE_##_id##_CUR, \ + .reg_ofs_end = AFE_##_id##_END, \ + .reg_ofs_base_msb = AFE_##_id##_BASE_MSB, \ + .reg_ofs_cur_msb = AFE_##_id##_CUR_MSB, \ + .reg_ofs_end_msb = AFE_##_id##_END_MSB, \ + .fs_reg = AFE_##_id##_CON0, \ + .fs_shift = _fs_shift, \ + .fs_maskbit = _fs_maskbit, \ + .mono_reg = AFE_##_id##_CON0, \ + .mono_shift = _mono_shift, \ + .enable_reg = AFE_##_id##_CON0, \ + .enable_shift = _id##_ON_SFT, \ + .hd_reg = AFE_##_id##_CON0, \ + .hd_shift = _id##_HD_MODE_SFT, \ + .hd_align_reg = AFE_##_id##_CON0, \ + .hd_align_mshift = _id##_HALIGN_SFT, \ + .agent_disable_reg = -1, \ + .agent_disable_shift = -1, \ + .msb_reg = -1, \ + .msb_shift = -1, \ + } + +/* For convenience with macros: missing register fields */ +#define HDMI_SEL_FS_SFT -1 +#define HDMI_SEL_FS_MASK -1 + +/* For convenience with macros: register name differences */ +#define AFE_HDMI_BASE AFE_HDMI_OUT_BASE +#define AFE_HDMI_CUR AFE_HDMI_OUT_CUR +#define AFE_HDMI_END AFE_HDMI_OUT_END +#define AFE_HDMI_BASE_MSB AFE_HDMI_OUT_BASE_MSB +#define AFE_HDMI_CUR_MSB AFE_HDMI_OUT_CUR_MSB +#define AFE_HDMI_END_MSB AFE_HDMI_OUT_END_MSB +#define AFE_HDMI_CON0 AFE_HDMI_OUT_CON0 +#define HDMI_ON_SFT HDMI_OUT_ON_SFT +#define HDMI_HD_MODE_SFT HDMI_OUT_HD_MODE_SFT +#define HDMI_HALIGN_SFT HDMI_OUT_HALIGN_SFT +#define HDMI_PBUF_SIZE_MASK HDMI_OUT_PBUF_SIZE_MASK +#define HDMI_PBUF_SIZE_SFT HDMI_OUT_PBUF_SIZE_SFT +#define HDMI_MINLEN_MASK HDMI_OUT_MINLEN_MASK +#define HDMI_MINLEN_SFT HDMI_OUT_MINLEN_SFT +#define HDMI_NUM_MASK HDMI_CH_NUM_MASK +#define HDMI_NUM_SFT HDMI_CH_NUM_SFT + +static const struct mtk_base_memif_data memif_data[MT8189_MEMIF_NUM] = { + MT8189_DL_MEMIF(DL0), + MT8189_DL_MEMIF(DL1), + MT8189_DL_MEMIF(DL2), + MT8189_DL_MEMIF(DL3), + MT8189_DL_MEMIF(DL4), + MT8189_DL_MEMIF(DL5), + MT8189_DL_MEMIF(DL6), + MT8189_DL_MEMIF(DL7), + MT8189_DL_MEMIF(DL8), + MT8189_DL_MEMIF(DL23), + MT8189_DL_MEMIF(DL24), + MT8189_DL_MEMIF(DL25), + MT8189_MULTI_DL_MEMIF(DL_24CH), + MT8189_MULTI_DL_MEMIF(HDMI), + MT8189_UL_MEMIF(VUL0, VUL0_SEL_FS_SFT, VUL0_SEL_FS_MASK, VUL0_MONO_SFT), + MT8189_UL_MEMIF(VUL1, VUL1_SEL_FS_SFT, VUL1_SEL_FS_MASK, VUL1_MONO_SFT), + MT8189_UL_MEMIF(VUL2, VUL2_SEL_FS_SFT, VUL2_SEL_FS_MASK, VUL2_MONO_SFT), + MT8189_UL_MEMIF(VUL3, VUL3_SEL_FS_SFT, VUL3_SEL_FS_MASK, VUL3_MONO_SFT), + MT8189_UL_MEMIF(VUL4, VUL4_SEL_FS_SFT, VUL4_SEL_FS_MASK, VUL4_MONO_SFT), + MT8189_UL_MEMIF(VUL5, VUL5_SEL_FS_SFT, VUL5_SEL_FS_MASK, VUL5_MONO_SFT), + MT8189_UL_MEMIF(VUL6, VUL6_SEL_FS_SFT, VUL6_SEL_FS_MASK, VUL6_MONO_SFT), + MT8189_UL_MEMIF(VUL7, VUL7_SEL_FS_SFT, VUL7_SEL_FS_MASK, VUL7_MONO_SFT), + MT8189_UL_MEMIF(VUL8, VUL8_SEL_FS_SFT, VUL8_SEL_FS_MASK, VUL8_MONO_SFT), + MT8189_UL_MEMIF(VUL9, VUL9_SEL_FS_SFT, VUL9_SEL_FS_MASK, VUL9_MONO_SFT), + MT8189_UL_MEMIF(VUL10, VUL10_SEL_FS_SFT, VUL10_SEL_FS_MASK, VUL10_MONO_SFT), + MT8189_UL_MEMIF(VUL24, VUL24_SEL_FS_SFT, VUL24_SEL_FS_MASK, VUL24_MONO_SFT), + MT8189_UL_MEMIF(VUL25, VUL25_SEL_FS_SFT, VUL25_SEL_FS_MASK, VUL25_MONO_SFT), + MT8189_UL_MEMIF(VUL_CM0, -1, -1, -1), + MT8189_UL_MEMIF(VUL_CM1, -1, -1, -1), + MT8189_UL_MEMIF(ETDM_IN0, REG_FS_TIMING_SEL_SFT, REG_FS_TIMING_SEL_MASK, -1), + MT8189_UL_MEMIF(ETDM_IN1, REG_FS_TIMING_SEL_SFT, REG_FS_TIMING_SEL_MASK, -1), +}; + +#define MT8189_AFE_IRQ(_id) \ + [MT8189_IRQ_##_id] = { \ + .id = MT8189_IRQ_##_id, \ + .irq_cnt_reg = AFE_IRQ##_id##_MCU_CFG1, \ + .irq_cnt_shift = AFE_IRQ_CNT_SHIFT, \ + .irq_cnt_maskbit = AFE_IRQ_CNT_MASK, \ + .irq_fs_reg = AFE_IRQ##_id##_MCU_CFG0, \ + .irq_fs_shift = AFE_IRQ##_id##_MCU_FS_SFT, \ + .irq_fs_maskbit = AFE_IRQ##_id##_MCU_FS_MASK, \ + .irq_en_reg = AFE_IRQ##_id##_MCU_CFG0, \ + .irq_en_shift = AFE_IRQ##_id##_MCU_ON_SFT, \ + .irq_clr_reg = AFE_IRQ##_id##_MCU_CFG1, \ + .irq_clr_shift = AFE_IRQ##_id##_CLR_CFG_SFT, \ + } + +#define MT8189_AFE_TDM_IRQ(_id) \ + [MT8189_IRQ_##_id] = { \ + .id = MT8189_CUS_IRQ_TDM, \ + .irq_cnt_reg = AFE_CUSTOM_IRQ0_MCU_CFG1, \ + .irq_cnt_shift = AFE_CUSTOM_IRQ0_MCU_CNT_SFT, \ + .irq_cnt_maskbit = AFE_CUSTOM_IRQ0_MCU_CNT_MASK, \ + .irq_fs_reg = -1, \ + .irq_fs_shift = -1, \ + .irq_fs_maskbit = -1, \ + .irq_en_reg = AFE_CUSTOM_IRQ0_MCU_CFG0, \ + .irq_en_shift = AFE_CUSTOM_IRQ0_MCU_ON_SFT, \ + .irq_clr_reg = AFE_CUSTOM_IRQ0_MCU_CFG1, \ + .irq_clr_shift = AFE_CUSTOM_IRQ0_CLR_CFG_SFT, \ + } + +static const struct mtk_base_irq_data irq_data[MT8189_IRQ_NUM] = { + MT8189_AFE_IRQ(0), + MT8189_AFE_IRQ(1), + MT8189_AFE_IRQ(2), + MT8189_AFE_IRQ(3), + MT8189_AFE_IRQ(4), + MT8189_AFE_IRQ(5), + MT8189_AFE_IRQ(6), + MT8189_AFE_IRQ(7), + MT8189_AFE_IRQ(8), + MT8189_AFE_IRQ(9), + MT8189_AFE_IRQ(10), + MT8189_AFE_IRQ(11), + MT8189_AFE_IRQ(12), + MT8189_AFE_IRQ(13), + MT8189_AFE_IRQ(14), + MT8189_AFE_IRQ(15), + MT8189_AFE_IRQ(16), + MT8189_AFE_IRQ(17), + MT8189_AFE_IRQ(18), + MT8189_AFE_IRQ(19), + MT8189_AFE_IRQ(20), + MT8189_AFE_IRQ(21), + MT8189_AFE_IRQ(22), + MT8189_AFE_IRQ(23), + MT8189_AFE_IRQ(24), + MT8189_AFE_IRQ(25), + MT8189_AFE_IRQ(26), + MT8189_AFE_TDM_IRQ(31), +}; + +static const int memif_irq_usage[MT8189_MEMIF_NUM] = { + /* TODO: verify each memif & irq */ + [MT8189_MEMIF_DL0] = MT8189_IRQ_0, + [MT8189_MEMIF_DL1] = MT8189_IRQ_1, + [MT8189_MEMIF_DL2] = MT8189_IRQ_2, + [MT8189_MEMIF_DL3] = MT8189_IRQ_3, + [MT8189_MEMIF_DL4] = MT8189_IRQ_4, + [MT8189_MEMIF_DL5] = MT8189_IRQ_5, + [MT8189_MEMIF_DL6] = MT8189_IRQ_6, + [MT8189_MEMIF_DL7] = MT8189_IRQ_7, + [MT8189_MEMIF_DL8] = MT8189_IRQ_8, + [MT8189_MEMIF_DL23] = MT8189_IRQ_9, + [MT8189_MEMIF_DL24] = MT8189_IRQ_10, + [MT8189_MEMIF_DL25] = MT8189_IRQ_11, + [MT8189_MEMIF_DL_24CH] = MT8189_IRQ_12, + [MT8189_MEMIF_VUL0] = MT8189_IRQ_13, + [MT8189_MEMIF_VUL1] = MT8189_IRQ_14, + [MT8189_MEMIF_VUL2] = MT8189_IRQ_15, + [MT8189_MEMIF_VUL3] = MT8189_IRQ_16, + [MT8189_MEMIF_VUL4] = MT8189_IRQ_17, + [MT8189_MEMIF_VUL5] = MT8189_IRQ_18, + [MT8189_MEMIF_VUL6] = MT8189_IRQ_19, + [MT8189_MEMIF_VUL7] = MT8189_IRQ_20, + [MT8189_MEMIF_VUL8] = MT8189_IRQ_21, + [MT8189_MEMIF_VUL9] = MT8189_IRQ_22, + [MT8189_MEMIF_VUL10] = MT8189_IRQ_23, + [MT8189_MEMIF_VUL24] = MT8189_IRQ_24, + [MT8189_MEMIF_VUL25] = MT8189_IRQ_25, + [MT8189_MEMIF_VUL_CM0] = MT8189_IRQ_26, + [MT8189_MEMIF_VUL_CM1] = MT8189_IRQ_0, + [MT8189_MEMIF_ETDM_IN0] = MT8189_IRQ_0, + [MT8189_MEMIF_ETDM_IN1] = MT8189_IRQ_0, + [MT8189_MEMIF_HDMI] = MT8189_IRQ_31 +}; + +static bool mt8189_is_volatile_reg(struct device *dev, unsigned int reg) +{ + /* these auto-gen reg has read-only bit, so put it as volatile */ + /* volatile reg cannot be cached, so cannot be set when power off */ + switch (reg) { + case AUDIO_TOP_CON0: + case AUDIO_TOP_CON1: + case AUDIO_TOP_CON2: + case AUDIO_TOP_CON3: + case AUDIO_TOP_CON4: + case AFE_APLL1_TUNER_MON0: + case AFE_APLL2_TUNER_MON0: + case AFE_SPM_CONTROL_ACK: + case AUDIO_TOP_IP_VERSION: + case AUDIO_ENGEN_CON0_MON: + case AFE_CONNSYS_I2S_IPM_VER_MON: + case AFE_CONNSYS_I2S_MON: + case AFE_PCM_INTF_MON: + case AFE_PCM_TOP_IP_VERSION: + case AFE_IRQ_MCU_STATUS: + case AFE_CUSTOM_IRQ_MCU_STATUS: + case AFE_IRQ_MCU_MON0: + case AFE_IRQ_MCU_MON1: + case AFE_IRQ_MCU_MON2: + case AFE_IRQ0_CNT_MON: + case AFE_IRQ1_CNT_MON: + case AFE_IRQ2_CNT_MON: + case AFE_IRQ3_CNT_MON: + case AFE_IRQ4_CNT_MON: + case AFE_IRQ5_CNT_MON: + case AFE_IRQ6_CNT_MON: + case AFE_IRQ7_CNT_MON: + case AFE_IRQ8_CNT_MON: + case AFE_IRQ9_CNT_MON: + case AFE_IRQ10_CNT_MON: + case AFE_IRQ11_CNT_MON: + case AFE_IRQ12_CNT_MON: + case AFE_IRQ13_CNT_MON: + case AFE_IRQ14_CNT_MON: + case AFE_IRQ15_CNT_MON: + case AFE_IRQ16_CNT_MON: + case AFE_IRQ17_CNT_MON: + case AFE_IRQ18_CNT_MON: + case AFE_IRQ19_CNT_MON: + case AFE_IRQ20_CNT_MON: + case AFE_IRQ21_CNT_MON: + case AFE_IRQ22_CNT_MON: + case AFE_IRQ23_CNT_MON: + case AFE_IRQ24_CNT_MON: + case AFE_IRQ25_CNT_MON: + case AFE_IRQ26_CNT_MON: + case AFE_CM0_MON: + case AFE_CM0_IP_VERSION: + case AFE_CM1_MON: + case AFE_CM1_IP_VERSION: + case AFE_ADDA_UL0_SRC_DEBUG_MON0: + case AFE_ADDA_UL0_SRC_MON0: + case AFE_ADDA_UL0_SRC_MON1: + case AFE_ADDA_UL0_IP_VERSION: + case AFE_ADDA_DMIC0_SRC_DEBUG_MON0: + case AFE_ADDA_DMIC0_SRC_MON0: + case AFE_ADDA_DMIC0_SRC_MON1: + case AFE_ADDA_DMIC0_IP_VERSION: + case AFE_ADDA_DMIC1_SRC_DEBUG_MON0: + case AFE_ADDA_DMIC1_SRC_MON0: + case AFE_ADDA_DMIC1_SRC_MON1: + case AFE_ADDA_DMIC1_IP_VERSION: + case AFE_MTKAIF_IPM_VER_MON: + case AFE_MTKAIF_MON: + case AFE_AUD_PAD_TOP_MON: + case AFE_ADDA_MTKAIFV4_MON0: + case AFE_ADDA_MTKAIFV4_MON1: + case AFE_ADDA6_MTKAIFV4_MON0: + case ETDM_IN0_MON: + case ETDM_IN1_MON: + case ETDM_OUT0_MON: + case ETDM_OUT1_MON: + case ETDM_OUT4_MON: + case AFE_CONN_MON0: + case AFE_CONN_MON1: + case AFE_CONN_MON2: + case AFE_CONN_MON3: + case AFE_CONN_MON4: + case AFE_CONN_MON5: + case AFE_CBIP_SLV_DECODER_MON0: + case AFE_CBIP_SLV_DECODER_MON1: + case AFE_CBIP_SLV_MUX_MON0: + case AFE_CBIP_SLV_MUX_MON1: + case AFE_DL0_CUR_MSB: + case AFE_DL0_CUR: + case AFE_DL0_RCH_MON: + case AFE_DL0_LCH_MON: + case AFE_DL1_CUR_MSB: + case AFE_DL1_CUR: + case AFE_DL1_RCH_MON: + case AFE_DL1_LCH_MON: + case AFE_DL2_CUR_MSB: + case AFE_DL2_CUR: + case AFE_DL2_RCH_MON: + case AFE_DL2_LCH_MON: + case AFE_DL3_CUR_MSB: + case AFE_DL3_CUR: + case AFE_DL3_RCH_MON: + case AFE_DL3_LCH_MON: + case AFE_DL4_CUR_MSB: + case AFE_DL4_CUR: + case AFE_DL4_RCH_MON: + case AFE_DL4_LCH_MON: + case AFE_DL5_CUR_MSB: + case AFE_DL5_CUR: + case AFE_DL5_RCH_MON: + case AFE_DL5_LCH_MON: + case AFE_DL6_CUR_MSB: + case AFE_DL6_CUR: + case AFE_DL6_RCH_MON: + case AFE_DL6_LCH_MON: + case AFE_DL7_CUR_MSB: + case AFE_DL7_CUR: + case AFE_DL7_RCH_MON: + case AFE_DL7_LCH_MON: + case AFE_DL8_CUR_MSB: + case AFE_DL8_CUR: + case AFE_DL8_RCH_MON: + case AFE_DL8_LCH_MON: + case AFE_DL_24CH_CUR_MSB: + case AFE_DL_24CH_CUR: + case AFE_DL23_CUR_MSB: + case AFE_DL23_CUR: + case AFE_DL23_RCH_MON: + case AFE_DL23_LCH_MON: + case AFE_DL24_CUR_MSB: + case AFE_DL24_CUR: + case AFE_DL24_RCH_MON: + case AFE_DL24_LCH_MON: + case AFE_DL25_CUR_MSB: + case AFE_DL25_CUR: + case AFE_DL25_RCH_MON: + case AFE_DL25_LCH_MON: + case AFE_VUL0_CUR_MSB: + case AFE_VUL0_CUR: + case AFE_VUL1_CUR_MSB: + case AFE_VUL1_CUR: + case AFE_VUL2_CUR_MSB: + case AFE_VUL2_CUR: + case AFE_VUL3_CUR_MSB: + case AFE_VUL3_CUR: + case AFE_VUL4_CUR_MSB: + case AFE_VUL4_CUR: + case AFE_VUL5_CUR_MSB: + case AFE_VUL5_CUR: + case AFE_VUL6_CUR_MSB: + case AFE_VUL6_CUR: + case AFE_VUL7_CUR_MSB: + case AFE_VUL7_CUR: + case AFE_VUL8_CUR_MSB: + case AFE_VUL8_CUR: + case AFE_VUL9_CUR_MSB: + case AFE_VUL9_CUR: + case AFE_VUL10_CUR_MSB: + case AFE_VUL10_CUR: + case AFE_VUL24_CUR_MSB: + case AFE_VUL24_CUR: + case AFE_VUL25_CUR_MSB: + case AFE_VUL25_CUR: + case AFE_VUL_CM0_CUR_MSB: + case AFE_VUL_CM0_CUR: + case AFE_VUL_CM1_CUR_MSB: + case AFE_VUL_CM1_CUR: + case AFE_ETDM_IN0_CUR_MSB: + case AFE_ETDM_IN0_CUR: + case AFE_ETDM_IN1_CUR_MSB: + case AFE_ETDM_IN1_CUR: + case AFE_HDMI_OUT_CUR_MSB: + case AFE_HDMI_OUT_CUR: + case AFE_HDMI_OUT_END: + case AFE_HDMI_OUT_MON0: + case AFE_PROT_SIDEBAND0_MON: + case AFE_PROT_SIDEBAND1_MON: + case AFE_PROT_SIDEBAND2_MON: + case AFE_PROT_SIDEBAND3_MON: + case AFE_DOMAIN_SIDEBAND0_MON: + case AFE_DOMAIN_SIDEBAND1_MON: + case AFE_DOMAIN_SIDEBAND2_MON: + case AFE_DOMAIN_SIDEBAND3_MON: + case AFE_DOMAIN_SIDEBAND4_MON: + case AFE_DOMAIN_SIDEBAND5_MON: + case AFE_DOMAIN_SIDEBAND6_MON: + case AFE_DOMAIN_SIDEBAND7_MON: + case AFE_DOMAIN_SIDEBAND8_MON: + case AFE_DOMAIN_SIDEBAND9_MON: + case AFE_PCM0_INTF_CON1_MASK_MON: + case AFE_CONNSYS_I2S_CON_MASK_MON: + case AFE_MTKAIF0_CFG0_MASK_MON: + case AFE_MTKAIF1_CFG0_MASK_MON: + case AFE_ADDA_UL0_SRC_CON0_MASK_MON: + case AFE_ASRC_NEW_CON0: + case AFE_ASRC_NEW_CON6: + case AFE_ASRC_NEW_CON8: + case AFE_ASRC_NEW_CON9: + case AFE_ASRC_NEW_CON12: + case AFE_ASRC_NEW_IP_VERSION: + case AFE_GASRC0_NEW_CON0: + case AFE_GASRC0_NEW_CON6: + case AFE_GASRC0_NEW_CON8: + case AFE_GASRC0_NEW_CON9: + case AFE_GASRC0_NEW_CON10: + case AFE_GASRC0_NEW_CON11: + case AFE_GASRC0_NEW_CON12: + case AFE_GASRC0_NEW_IP_VERSION: + case AFE_GASRC1_NEW_CON0: + case AFE_GASRC1_NEW_CON6: + case AFE_GASRC1_NEW_CON8: + case AFE_GASRC1_NEW_CON9: + case AFE_GASRC1_NEW_CON12: + case AFE_GASRC1_NEW_IP_VERSION: + case AFE_GASRC2_NEW_CON0: + case AFE_GASRC2_NEW_CON6: + case AFE_GASRC2_NEW_CON8: + case AFE_GASRC2_NEW_CON9: + case AFE_GASRC2_NEW_CON12: + case AFE_GASRC2_NEW_IP_VERSION: + case AFE_GAIN0_CUR_L: + case AFE_GAIN0_CUR_R: + case AFE_GAIN1_CUR_L: + case AFE_GAIN1_CUR_R: + case AFE_GAIN2_CUR_L: + case AFE_GAIN2_CUR_R: + case AFE_GAIN3_CUR_L: + case AFE_GAIN3_CUR_R: + case AFE_IRQ_MCU_EN: + case AFE_CUSTOM_IRQ_MCU_EN: + case AFE_IRQ_MCU_DSP_EN: + case AFE_IRQ_MCU_DSP2_EN: + case AFE_DL5_CON0: + case AFE_DL6_CON0: + case AFE_DL23_CON0: + case AFE_DL_24CH_CON0: + case AFE_VUL1_CON0: + case AFE_VUL3_CON0: + case AFE_VUL4_CON0: + case AFE_VUL5_CON0: + case AFE_VUL9_CON0: + case AFE_VUL25_CON0: + case AFE_IRQ0_MCU_CFG0: + case AFE_IRQ1_MCU_CFG0: + case AFE_IRQ2_MCU_CFG0: + case AFE_IRQ3_MCU_CFG0: + case AFE_IRQ4_MCU_CFG0: + case AFE_IRQ5_MCU_CFG0: + case AFE_IRQ6_MCU_CFG0: + case AFE_IRQ7_MCU_CFG0: + case AFE_IRQ8_MCU_CFG0: + case AFE_IRQ9_MCU_CFG0: + case AFE_IRQ10_MCU_CFG0: + case AFE_IRQ11_MCU_CFG0: + case AFE_IRQ12_MCU_CFG0: + case AFE_IRQ13_MCU_CFG0: + case AFE_IRQ14_MCU_CFG0: + case AFE_IRQ15_MCU_CFG0: + case AFE_IRQ16_MCU_CFG0: + case AFE_IRQ17_MCU_CFG0: + case AFE_IRQ18_MCU_CFG0: + case AFE_IRQ19_MCU_CFG0: + case AFE_IRQ20_MCU_CFG0: + case AFE_IRQ21_MCU_CFG0: + case AFE_IRQ22_MCU_CFG0: + case AFE_IRQ23_MCU_CFG0: + case AFE_IRQ24_MCU_CFG0: + case AFE_IRQ25_MCU_CFG0: + case AFE_IRQ26_MCU_CFG0: + case AFE_CUSTOM_IRQ0_MCU_CFG0: + case AFE_IRQ0_MCU_CFG1: + case AFE_IRQ1_MCU_CFG1: + case AFE_IRQ2_MCU_CFG1: + case AFE_IRQ3_MCU_CFG1: + case AFE_IRQ4_MCU_CFG1: + case AFE_IRQ5_MCU_CFG1: + case AFE_IRQ6_MCU_CFG1: + case AFE_IRQ7_MCU_CFG1: + case AFE_IRQ8_MCU_CFG1: + case AFE_IRQ9_MCU_CFG1: + case AFE_IRQ10_MCU_CFG1: + case AFE_IRQ11_MCU_CFG1: + case AFE_IRQ12_MCU_CFG1: + case AFE_IRQ13_MCU_CFG1: + case AFE_IRQ14_MCU_CFG1: + case AFE_IRQ15_MCU_CFG1: + case AFE_IRQ16_MCU_CFG1: + case AFE_IRQ17_MCU_CFG1: + case AFE_IRQ18_MCU_CFG1: + case AFE_IRQ19_MCU_CFG1: + case AFE_IRQ20_MCU_CFG1: + case AFE_IRQ21_MCU_CFG1: + case AFE_IRQ22_MCU_CFG1: + case AFE_IRQ23_MCU_CFG1: + case AFE_IRQ24_MCU_CFG1: + case AFE_IRQ25_MCU_CFG1: + case AFE_IRQ26_MCU_CFG1: + case AFE_CUSTOM_IRQ0_MCU_CFG1: + /* for vow using */ + case AFE_IRQ_MCU_SCP_EN: + case AFE_VUL_CM0_BASE_MSB: + case AFE_VUL_CM0_BASE: + case AFE_VUL_CM0_END_MSB: + case AFE_VUL_CM0_END: + case AFE_VUL_CM0_CON0: + return true; + default: + return false; + }; +} + +static const struct regmap_config mt8189_afe_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + + .volatile_reg = mt8189_is_volatile_reg, + + .max_register = AFE_MAX_REGISTER, + .num_reg_defaults_raw = AFE_MAX_REGISTER, + + .cache_type = REGCACHE_FLAT, +}; + +static irqreturn_t mt8189_afe_irq_handler(int irq_id, void *dev) +{ + struct mtk_base_afe *afe = dev; + struct mtk_base_afe_irq *irq; + u32 status; + u32 status_mcu; + u32 mcu_en; + u32 cus_status; + u32 cus_status_mcu; + u32 cus_mcu_en; + u32 tmp_reg; + int ret, cus_ret; + int i; + struct timespec64 ts64; + u64 t1, t2; + /* one interrupt period = 5ms */ + const u64 timeout_limit = 5000000; + + /* get irq that is sent to MCU */ + regmap_read(afe->regmap, AFE_IRQ_MCU_EN, &mcu_en); + regmap_read(afe->regmap, AFE_CUSTOM_IRQ_MCU_EN, &cus_mcu_en); + + ret = regmap_read(afe->regmap, AFE_IRQ_MCU_STATUS, &status); + cus_ret = regmap_read(afe->regmap, AFE_CUSTOM_IRQ_MCU_STATUS, &cus_status); + /* only care IRQ which is sent to MCU */ + status_mcu = status & mcu_en & AFE_IRQ_STATUS_BITS; + cus_status_mcu = cus_status & cus_mcu_en & AFE_IRQ_STATUS_BITS; + if ((ret || status_mcu == 0) && (cus_ret || cus_status_mcu == 0)) { + dev_err(afe->dev, "%s(), irq status err, ret %d, 0x%x:0x%x:0x%x:0x%x\n", + __func__, ret, status, mcu_en, cus_status_mcu, cus_mcu_en); + return IRQ_NONE; + } + + ktime_get_ts64(&ts64); + t1 = ktime_get_ns(); + + for (i = 0; i < MT8189_MEMIF_NUM; i++) { + struct mtk_base_afe_memif *memif = &afe->memif[i]; + + if (!memif->substream) + continue; + + if (memif->irq_usage < 0) + continue; + irq = &afe->irqs[memif->irq_usage]; + + if (i == MT8189_MEMIF_HDMI) { + if (cus_status_mcu & BIT(irq->irq_data->id)) + snd_pcm_period_elapsed(memif->substream); + } else if (status_mcu & BIT(irq->irq_data->id)) { + snd_pcm_period_elapsed(memif->substream); + } + } + + ktime_get_ts64(&ts64); + t2 = ktime_get_ns(); + t2 = t2 - t1; /* in ns (10^9) */ + + if (t2 > timeout_limit) + dev_warn(afe->dev, "IRQ handler exceeded time limit by %llu ns\n", + t2 - timeout_limit); + + /* clear irq */ + for (i = 0; i < MT8189_IRQ_NUM; ++i) { + if (((cus_status_mcu & BIT(irq_data[i].id)) && i == MT8189_IRQ_31) || + ((status_mcu & BIT(irq_data[i].id)) && i != MT8189_IRQ_31)) { + regmap_read(afe->regmap, irq_data[i].irq_clr_reg, &tmp_reg); + regmap_update_bits(afe->regmap, irq_data[i].irq_clr_reg, + AFE_IRQ_CLR_CFG_MASK_SFT | + AFE_IRQ_MISS_FLAG_CLR_CFG_MASK_SFT, + tmp_reg ^ (AFE_IRQ_CLR_CFG_MASK_SFT | + AFE_IRQ_MISS_FLAG_CLR_CFG_MASK_SFT)); + } + } + + return IRQ_HANDLED; +} + +static int mt8189_afe_runtime_suspend(struct device *dev) +{ + struct mtk_base_afe *afe = dev_get_drvdata(dev); + unsigned int value; + unsigned int tmp_reg; + int ret, i; + + if (!afe->regmap) { + dev_warn(afe->dev, "%s() skip regmap\n", __func__); + goto skip_regmap; + } + + /* disable AFE */ + mt8189_afe_disable_main_clock(afe); + + ret = regmap_read_poll_timeout(afe->regmap, + AUDIO_ENGEN_CON0_MON, + value, + (value & AUDIO_ENGEN_MON_SFT) == 0, + 20, + 1 * 1000 * 1000); + dev_dbg(afe->dev, "%s() read_poll ret %d\n", __func__, ret); + if (ret) + dev_warn(afe->dev, "%s(), ret %d\n", __func__, ret); + + /* make sure all irq status are cleared */ + for (i = 0; i < MT8189_IRQ_NUM; i++) { + regmap_read(afe->regmap, irq_data[i].irq_clr_reg, &tmp_reg); + regmap_update_bits(afe->regmap, irq_data[i].irq_clr_reg, + AFE_IRQ_CLR_CFG_MASK_SFT | + AFE_IRQ_MISS_FLAG_CLR_CFG_MASK_SFT, + tmp_reg ^ (AFE_IRQ_CLR_CFG_MASK_SFT | + AFE_IRQ_MISS_FLAG_CLR_CFG_MASK_SFT)); + } + + /* reset audio 26M request */ + regmap_update_bits(afe->regmap, + AFE_SPM_CONTROL_REQ, 0x1, 0x0); + + /* cache only */ + regcache_cache_only(afe->regmap, true); + regcache_mark_dirty(afe->regmap); + +skip_regmap: + mt8189_afe_disable_reg_rw_clk(afe); + return 0; +} + +static int mt8189_afe_runtime_resume(struct device *dev) +{ + struct mtk_base_afe *afe = dev_get_drvdata(dev); + int ret; + + ret = mt8189_afe_enable_reg_rw_clk(afe); + if (ret) + return ret; + + if (!afe->regmap) { + dev_warn(afe->dev, "skip regmap\n"); + return 0; + } + + regcache_cache_only(afe->regmap, false); + regcache_sync(afe->regmap); + + /* set audio 26M request */ + regmap_update_bits(afe->regmap, AFE_SPM_CONTROL_REQ, 0x1, 0x1); + regmap_update_bits(afe->regmap, AFE_CBIP_CFG0, 0x1, 0x1); + + /* force cpu use 8_24 format when writing 32bit data */ + regmap_update_bits(afe->regmap, AFE_MEMIF_CON0, + CPU_HD_ALIGN_MASK_SFT, 0 << CPU_HD_ALIGN_SFT); + + /* enable AFE */ + mt8189_afe_enable_main_clock(afe); + + return 0; +} + +static int mt8189_afe_component_probe(struct snd_soc_component *component) +{ + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component); + + /* enable clock for regcache get default value from hw */ + pm_runtime_get_sync(afe->dev); + mtk_afe_add_sub_dai_control(component); + pm_runtime_put_sync(afe->dev); + + return 0; +} + +static int mt8189_afe_pcm_open(struct snd_soc_component *component, + struct snd_pcm_substream *substream) +{ + /* set the wait_for_avail to 2 sec*/ + substream->wait_time = msecs_to_jiffies(2 * 1000); + + return 0; +} + +static void mt8189_afe_pcm_free(struct snd_soc_component *component, + struct snd_pcm *pcm) +{ + snd_pcm_lib_preallocate_free_for_all(pcm); +} + +static const struct snd_soc_component_driver mt8189_afe_component = { + .name = AFE_PCM_NAME, + .probe = mt8189_afe_component_probe, + .pcm_construct = mtk_afe_pcm_new, + .pcm_destruct = mt8189_afe_pcm_free, + .open = mt8189_afe_pcm_open, + .pointer = mtk_afe_pcm_pointer, +}; + +static int mt8189_dai_memif_register(struct mtk_base_afe *afe) +{ + struct mtk_base_afe_dai *dai; + + dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL); + if (!dai) + return -ENOMEM; + + list_add(&dai->list, &afe->sub_dais); + + dai->dai_drivers = mt8189_memif_dai_driver; + dai->num_dai_drivers = ARRAY_SIZE(mt8189_memif_dai_driver); + dai->dapm_widgets = mt8189_memif_widgets; + dai->num_dapm_widgets = ARRAY_SIZE(mt8189_memif_widgets); + dai->dapm_routes = mt8189_memif_routes; + dai->num_dapm_routes = ARRAY_SIZE(mt8189_memif_routes); + + return 0; +} + +typedef int (*dai_register_cb)(struct mtk_base_afe *); +static const dai_register_cb dai_register_cbs[] = { + mt8189_dai_adda_register, + mt8189_dai_i2s_register, + mt8189_dai_pcm_register, + mt8189_dai_tdm_register, + mt8189_dai_memif_register, +}; + +static const struct reg_sequence mt8189_cg_patch[] = { + { AUDIO_TOP_CON4, 0x361c }, +}; + +static int mt8189_afe_pcm_dev_probe(struct platform_device *pdev) +{ + int ret, i; + unsigned int tmp_reg; + int irq_id; + struct mtk_base_afe *afe; + struct mt8189_afe_private *afe_priv; + struct device *dev = &pdev->dev; + + ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(34)); + if (ret) + return ret; + + ret = of_reserved_mem_device_init(dev); + if (ret) + dev_warn(dev, "failed to assign memory region: %d\n", ret); + + afe = devm_kzalloc(dev, sizeof(*afe), GFP_KERNEL); + if (!afe) + return -ENOMEM; + + platform_set_drvdata(pdev, afe); + + afe->platform_priv = devm_kzalloc(dev, sizeof(*afe_priv), + GFP_KERNEL); + if (!afe->platform_priv) + return -ENOMEM; + + afe_priv = afe->platform_priv; + afe->dev = dev; + + afe->base_addr = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(afe->base_addr)) + return dev_err_probe(dev, PTR_ERR(afe->base_addr), + "AFE base_addr not found\n"); + + /* init audio related clock */ + ret = mt8189_init_clock(afe); + if (ret) + return dev_err_probe(dev, ret, "init clock error.\n"); + + /* init memif */ + /* IPM2.0 no need banding */ + afe->memif_32bit_supported = 1; + afe->memif_size = MT8189_MEMIF_NUM; + afe->memif = devm_kcalloc(dev, afe->memif_size, sizeof(*afe->memif), + GFP_KERNEL); + + if (!afe->memif) + return -ENOMEM; + + for (i = 0; i < afe->memif_size; i++) { + afe->memif[i].data = &memif_data[i]; + afe->memif[i].irq_usage = memif_irq_usage[i]; + afe->memif[i].const_irq = 1; + } + + mutex_init(&afe->irq_alloc_lock); + + /* init irq */ + afe->irqs_size = MT8189_IRQ_NUM; + afe->irqs = devm_kcalloc(dev, afe->irqs_size, sizeof(*afe->irqs), + GFP_KERNEL); + + if (!afe->irqs) + return -ENOMEM; + + for (i = 0; i < afe->irqs_size; i++) + afe->irqs[i].irq_data = &irq_data[i]; + + /* request irq */ + irq_id = platform_get_irq(pdev, 0); + if (irq_id < 0) + return dev_err_probe(dev, irq_id, "no irq found"); + + ret = devm_request_irq(dev, irq_id, mt8189_afe_irq_handler, + IRQF_TRIGGER_NONE, + "Afe_ISR_Handle", afe); + if (ret) + return dev_err_probe(dev, ret, "could not request_irq for Afe_ISR_Handle\n"); + + /* init sub_dais */ + INIT_LIST_HEAD(&afe->sub_dais); + + for (i = 0; i < ARRAY_SIZE(dai_register_cbs); i++) { + ret = dai_register_cbs[i](afe); + if (ret) + return dev_err_probe(dev, ret, "dai register i %d fail\n", i); + } + + /* init dai_driver and component_driver */ + ret = mtk_afe_combine_sub_dai(afe); + if (ret) + return dev_err_probe(dev, ret, "mtk_afe_combine_sub_dai fail\n"); + + /* others */ + afe->mtk_afe_hardware = &mt8189_afe_hardware; + afe->memif_fs = mt8189_memif_fs; + afe->irq_fs = mt8189_irq_fs; + afe->get_dai_fs = mt8189_get_dai_fs; + afe->get_memif_pbuf_size = mt8189_get_memif_pbuf_size; + + afe->runtime_resume = mt8189_afe_runtime_resume; + afe->runtime_suspend = mt8189_afe_runtime_suspend; + + ret = devm_pm_runtime_enable(dev); + if (ret) + return ret; + + /* + * Audio device is part of genpd. Registering it as a syscore device + * ensure the proper power-on sequence of the AFE device. + */ + dev_pm_syscore_device(dev, true); + + /* enable clock for regcache get default value from hw */ + pm_runtime_get_sync(dev); + + afe->regmap = devm_regmap_init_mmio(dev, afe->base_addr, + &mt8189_afe_regmap_config); + if (IS_ERR(afe->regmap)) + return PTR_ERR(afe->regmap); + + ret = regmap_register_patch(afe->regmap, mt8189_cg_patch, + ARRAY_SIZE(mt8189_cg_patch)); + if (ret < 0) { + dev_err(dev, "Failed to apply cg patch\n"); + goto err_pm_disable; + } + + regmap_read(afe->regmap, AFE_IRQ_MCU_EN, &tmp_reg); + regmap_write(afe->regmap, AFE_IRQ_MCU_EN, 0xffffffff); + regmap_read(afe->regmap, AFE_IRQ_MCU_EN, &tmp_reg); + + pm_runtime_put_sync(dev); + + regcache_cache_only(afe->regmap, true); + regcache_mark_dirty(afe->regmap); + + /* register component */ + ret = devm_snd_soc_register_component(dev, + &mt8189_afe_component, + afe->dai_drivers, + afe->num_dai_drivers); + if (ret) { + dev_err(dev, "afe component err: %d\n", ret); + goto err_pm_disable; + } + + return 0; + +err_pm_disable: + pm_runtime_put_sync(dev); + return ret; +} + +static void mt8189_afe_pcm_dev_remove(struct platform_device *pdev) +{ + struct mtk_base_afe *afe = platform_get_drvdata(pdev); + struct device *dev = &pdev->dev; + + pm_runtime_put_sync(dev); + if (!pm_runtime_status_suspended(dev)) + mt8189_afe_runtime_suspend(dev); + + mt8189_afe_disable_main_clock(afe); + /* disable afe clock */ + mt8189_afe_disable_reg_rw_clk(afe); + of_reserved_mem_device_release(dev); +} + +static const struct of_device_id mt8189_afe_pcm_dt_match[] = { + { .compatible = "mediatek,mt8189-afe-pcm", }, + {}, +}; +MODULE_DEVICE_TABLE(of, mt8189_afe_pcm_dt_match); + +static const struct dev_pm_ops mt8189_afe_pm_ops = { + SET_RUNTIME_PM_OPS(mt8189_afe_runtime_suspend, + mt8189_afe_runtime_resume, NULL) +}; + +static struct platform_driver mt8189_afe_pcm_driver = { + .driver = { + .name = "mt8189-afe-pcm", + .of_match_table = mt8189_afe_pcm_dt_match, + .pm = &mt8189_afe_pm_ops, + }, + .probe = mt8189_afe_pcm_dev_probe, + .remove = mt8189_afe_pcm_dev_remove, +}; +module_platform_driver(mt8189_afe_pcm_driver); + +MODULE_DESCRIPTION("Mediatek ALSA SoC AFE platform driver for 8189"); +MODULE_AUTHOR("Darren Ye "); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/mediatek/mt8189/mt8189-dai-adda.c b/sound/soc/mediatek/mt8189/mt8189-dai-adda.c new file mode 100644 index 00000000000000..ad5b9546ff63ca --- /dev/null +++ b/sound/soc/mediatek/mt8189/mt8189-dai-adda.c @@ -0,0 +1,1228 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * MediaTek ALSA SoC Audio DAI ADDA Control + * + * Copyright (c) 2025 MediaTek Inc. + * Author: Darren Ye + */ + +#include +#include + +#include "mt8189-afe-clk.h" +#include "mt8189-afe-common.h" +#include "mt8189-interconnection.h" + +/* mt6363 vs1 voter */ +#define VS1_MT6338_MASK_SFT 0x1 +#define RG_BUCK_VS1_VOTER_EN_LO 0x189a +#define RG_BUCK_VS1_VOTER_EN_LO_SET 0x189b +#define RG_BUCK_VS1_VOTER_EN_LO_CLR 0x189c + +#define AUDIO_SDM_LEVEL_NORMAL 0x1d +#define MTK_AFE_ADDA_DL_GAIN_NORMAL 0xf74f +#define SDM_AUTO_RESET_THRESHOLD 0x190000 + +enum { + SUPPLY_SEQ_ADDA_AFE_ON, + SUPPLY_SEQ_ADDA_DL_ON, + SUPPLY_SEQ_ADDA_AUD_PAD_TOP, + SUPPLY_SEQ_ADDA_MTKAIF_CFG, + SUPPLY_SEQ_ADDA6_MTKAIF_CFG, + SUPPLY_SEQ_ADDA_FIFO, + SUPPLY_SEQ_ADDA_AP_DMIC, + SUPPLY_SEQ_ADDA_UL_ON, +}; + +enum { + UL_IIR_SW, + UL_IIR_5HZ, + UL_IIR_10HZ, + UL_IIR_25HZ, + UL_IIR_50HZ, + UL_IIR_75HZ, +}; + +enum { + AUDIO_SDM_2ND, + AUDIO_SDM_3RD, +}; + +enum { + DELAY_DATA_MISO1, + DELAY_DATA_MISO2, +}; + +enum { + MTK_AFE_ADDA_DL_RATE_8K, + MTK_AFE_ADDA_DL_RATE_11K, + MTK_AFE_ADDA_DL_RATE_12K, + MTK_AFE_ADDA_DL_RATE_16K = 4, + MTK_AFE_ADDA_DL_RATE_22K, + MTK_AFE_ADDA_DL_RATE_24K, + MTK_AFE_ADDA_DL_RATE_32K = 8, + MTK_AFE_ADDA_DL_RATE_44K, + MTK_AFE_ADDA_DL_RATE_48K, + MTK_AFE_ADDA_DL_RATE_88K = 13, + MTK_AFE_ADDA_DL_RATE_96K, + MTK_AFE_ADDA_DL_RATE_176K = 17, + MTK_AFE_ADDA_DL_RATE_192K, + MTK_AFE_ADDA_DL_RATE_352K = 21, + MTK_AFE_ADDA_DL_RATE_384K, +}; + +enum { + MTK_AFE_ADDA_UL_RATE_8K, + MTK_AFE_ADDA_UL_RATE_16K, + MTK_AFE_ADDA_UL_RATE_32K, + MTK_AFE_ADDA_UL_RATE_48K, + MTK_AFE_ADDA_UL_RATE_96K, + MTK_AFE_ADDA_UL_RATE_192K, + MTK_AFE_ADDA_UL_RATE_48K_HD, +}; + +struct mtk_afe_adda_priv { + int dl_rate; + int ul_rate; +}; + +static unsigned int adda_dl_rate_transform(struct mtk_base_afe *afe, + unsigned int rate) +{ + switch (rate) { + case 8000: + return MTK_AFE_ADDA_DL_RATE_8K; + case 11025: + return MTK_AFE_ADDA_DL_RATE_11K; + case 12000: + return MTK_AFE_ADDA_DL_RATE_12K; + case 16000: + return MTK_AFE_ADDA_DL_RATE_16K; + case 22050: + return MTK_AFE_ADDA_DL_RATE_22K; + case 24000: + return MTK_AFE_ADDA_DL_RATE_24K; + case 32000: + return MTK_AFE_ADDA_DL_RATE_32K; + case 44100: + return MTK_AFE_ADDA_DL_RATE_44K; + case 48000: + return MTK_AFE_ADDA_DL_RATE_48K; + case 96000: + return MTK_AFE_ADDA_DL_RATE_96K; + case 192000: + return MTK_AFE_ADDA_DL_RATE_192K; + default: + dev_warn(afe->dev, "%s(), rate %d invalid, use 48kHz!!!\n", + __func__, rate); + return MTK_AFE_ADDA_DL_RATE_48K; + } +} + +static unsigned int adda_ul_rate_transform(struct mtk_base_afe *afe, + unsigned int rate) +{ + switch (rate) { + case 8000: + return MTK_AFE_ADDA_UL_RATE_8K; + case 16000: + return MTK_AFE_ADDA_UL_RATE_16K; + case 32000: + return MTK_AFE_ADDA_UL_RATE_32K; + case 48000: + return MTK_AFE_ADDA_UL_RATE_48K; + case 96000: + return MTK_AFE_ADDA_UL_RATE_96K; + case 192000: + return MTK_AFE_ADDA_UL_RATE_192K; + default: + dev_warn(afe->dev, "%s(), rate %d invalid, use 48kHz!!!\n", + __func__, rate); + return MTK_AFE_ADDA_UL_RATE_48K; + } +} + +/* dai component */ +static const struct snd_kcontrol_new mtk_adda_dl_ch1_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("DL0_CH1", AFE_CONN014_1, I_DL0_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1", AFE_CONN014_1, I_DL1_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1", AFE_CONN014_1, I_DL2_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1", AFE_CONN014_1, I_DL3_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH1", AFE_CONN014_1, I_DL4_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH1", AFE_CONN014_1, I_DL5_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH1", AFE_CONN014_1, I_DL6_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL7_CH1", AFE_CONN014_1, I_DL7_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL8_CH1", AFE_CONN014_1, I_DL8_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH1", AFE_CONN014_1, I_DL_24CH_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL24_CH1", AFE_CONN014_2, I_DL24_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN014_0, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN014_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN014_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_GAIN0_OUT_CH1", AFE_CONN014_0, + I_GAIN0_OUT_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH1", AFE_CONN014_4, + I_PCM_0_CAP_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_0_OUT_CH1", AFE_CONN014_6, + I_SRC_0_OUT_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_1_OUT_CH1", AFE_CONN014_6, + I_SRC_1_OUT_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_2_OUT_CH1", AFE_CONN014_6, + I_SRC_2_OUT_CH1, 1, 0), +}; + +static const struct snd_kcontrol_new mtk_adda_dl_ch2_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("DL0_CH2", AFE_CONN015_1, I_DL0_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL0_CH1", AFE_CONN015_1, I_DL0_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2", AFE_CONN015_1, I_DL1_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2", AFE_CONN015_1, I_DL2_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2", AFE_CONN015_1, I_DL3_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH2", AFE_CONN015_1, I_DL4_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH2", AFE_CONN015_1, I_DL5_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH2", AFE_CONN015_1, I_DL6_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL7_CH2", AFE_CONN015_1, I_DL7_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL8_CH2", AFE_CONN015_1, I_DL8_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH2", AFE_CONN015_1, I_DL_24CH_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL24_CH2", AFE_CONN015_2, I_DL24_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN015_0, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN015_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN015_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_GAIN0_OUT_CH2", AFE_CONN015_0, + I_GAIN0_OUT_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH1", AFE_CONN015_4, + I_PCM_0_CAP_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH2", AFE_CONN015_4, + I_PCM_0_CAP_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_0_OUT_CH2", AFE_CONN015_6, + I_SRC_0_OUT_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_1_OUT_CH2", AFE_CONN015_6, + I_SRC_1_OUT_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_2_OUT_CH2", AFE_CONN015_6, + I_SRC_2_OUT_CH2, 1, 0), +}; + +static const struct snd_kcontrol_new mtk_adda_dl_ch3_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("DL0_CH1", AFE_CONN016_1, I_DL0_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1", AFE_CONN016_1, I_DL1_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1", AFE_CONN016_1, I_DL2_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1", AFE_CONN016_1, I_DL3_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH1", AFE_CONN016_1, I_DL4_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH1", AFE_CONN016_1, I_DL5_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH1", AFE_CONN016_1, I_DL6_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL7_CH1", AFE_CONN016_1, I_DL7_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL8_CH1", AFE_CONN016_1, I_DL8_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH1", AFE_CONN016_1, I_DL_24CH_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH3", AFE_CONN016_1, I_DL_24CH_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL24_CH1", AFE_CONN016_2, I_DL24_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN016_0, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN016_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN016_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_GAIN0_OUT_CH1", AFE_CONN016_0, + I_GAIN0_OUT_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH1", AFE_CONN016_4, + I_PCM_0_CAP_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_0_OUT_CH1", AFE_CONN016_6, + I_SRC_0_OUT_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_1_OUT_CH1", AFE_CONN016_6, + I_SRC_1_OUT_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_2_OUT_CH1", AFE_CONN016_6, + I_SRC_2_OUT_CH1, 1, 0), +}; + +static const struct snd_kcontrol_new mtk_adda_dl_ch4_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("DL0_CH2", AFE_CONN017_1, I_DL0_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2", AFE_CONN017_1, I_DL1_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2", AFE_CONN017_1, I_DL2_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2", AFE_CONN017_1, I_DL3_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH2", AFE_CONN017_1, I_DL4_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH2", AFE_CONN017_1, I_DL5_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH2", AFE_CONN017_1, I_DL6_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL7_CH2", AFE_CONN017_1, I_DL7_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL8_CH2", AFE_CONN017_1, I_DL8_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH2", AFE_CONN017_1, I_DL_24CH_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH4", AFE_CONN017_1, I_DL_24CH_CH4, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL24_CH2", AFE_CONN017_2, I_DL24_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN017_0, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN017_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN017_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_GAIN0_OUT_CH2", AFE_CONN017_0, + I_GAIN0_OUT_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH1", AFE_CONN017_4, + I_PCM_0_CAP_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH2", AFE_CONN017_4, + I_PCM_0_CAP_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_0_OUT_CH2", AFE_CONN017_6, + I_SRC_0_OUT_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_1_OUT_CH2", AFE_CONN017_6, + I_SRC_1_OUT_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_2_OUT_CH2", AFE_CONN017_6, + I_SRC_2_OUT_CH2, 1, 0), +}; + +static int mtk_adda_ul_src_enable_dmic(struct mtk_base_afe *afe, int id) +{ + unsigned int reg, reg1; + + switch (id) { + case MT8189_DAI_ADDA: + reg = AFE_ADDA_UL0_SRC_CON0; + reg1 = AFE_ADDA_UL0_SRC_CON1; + break; + case MT8189_DAI_AP_DMIC: + reg = AFE_ADDA_DMIC0_SRC_CON0; + reg1 = AFE_ADDA_DMIC0_SRC_CON1; + break; + case MT8189_DAI_AP_DMIC_CH34: + reg = AFE_ADDA_DMIC1_SRC_CON0; + reg1 = AFE_ADDA_DMIC1_SRC_CON1; + break; + default: + return -EINVAL; + } + /* choose Phase */ + regmap_update_bits(afe->regmap, reg, + UL_DMIC_PHASE_SEL_CH1_MASK_SFT, + 0x0 << UL_DMIC_PHASE_SEL_CH1_SFT); + regmap_update_bits(afe->regmap, reg, + UL_DMIC_PHASE_SEL_CH2_MASK_SFT, + 0x4 << UL_DMIC_PHASE_SEL_CH2_SFT); + + /* dmic mode, 3.25M*/ + regmap_update_bits(afe->regmap, reg, + DIGMIC_3P25M_1P625M_SEL_CTL_MASK_SFT, + 0x0); + regmap_update_bits(afe->regmap, reg, + DMIC_LOW_POWER_MODE_CTL_MASK_SFT, + 0x0); + + /* turn on dmic, ch1, ch2 */ + regmap_update_bits(afe->regmap, reg, + UL_SDM_3_LEVEL_CTL_MASK_SFT, + 0x1 << UL_SDM_3_LEVEL_CTL_SFT); + regmap_update_bits(afe->regmap, reg, + UL_MODE_3P25M_CH1_CTL_MASK_SFT, + 0x1 << UL_MODE_3P25M_CH1_CTL_SFT); + regmap_update_bits(afe->regmap, reg, + UL_MODE_3P25M_CH2_CTL_MASK_SFT, + 0x1 << UL_MODE_3P25M_CH2_CTL_SFT); + + /* ul gain: gain = 0x7fff/positive_gain = 0x0/gain_mode = 0x10 */ + regmap_update_bits(afe->regmap, reg1, + ADDA_UL_GAIN_VALUE_MASK_SFT, + 0x7fff << ADDA_UL_GAIN_VALUE_SFT); + regmap_update_bits(afe->regmap, reg1, + ADDA_UL_POSTIVEGAIN_MASK_SFT, + 0x0 << ADDA_UL_POSTIVEGAIN_SFT); + /* gain_mode = 0x02: Add 0.5 gain at CIC output */ + regmap_update_bits(afe->regmap, reg1, + GAIN_MODE_MASK_SFT, + 0x02 << GAIN_MODE_SFT); + + return 0; +} + +static int mtk_adda_ul_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8189_afe_private *afe_priv = afe->platform_priv; + int mtkaif_dmic = afe_priv->mtkaif_dmic; + + dev_dbg(afe->dev, "%s(), name %s, event 0x%x, mtkaif_dmic %d\n", + __func__, w->name, event, mtkaif_dmic); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + /* update setting to dmic */ + if (mtkaif_dmic) { + /* mtkaif_rxif_data_mode = 1, dmic */ + regmap_update_bits(afe->regmap, AFE_MTKAIF0_RX_CFG0, + RG_MTKAIF0_RXIF_DATA_MODE_MASK_SFT, + 0x1); + + /* dmic mode, 3.25M*/ + regmap_update_bits(afe->regmap, AFE_MTKAIF0_RX_CFG0, + RG_MTKAIF0_RXIF_VOICE_MODE_MASK_SFT, + 0x0); + mtk_adda_ul_src_enable_dmic(afe, MT8189_DAI_ADDA); + } + break; + case SND_SOC_DAPM_POST_PMD: + /* should delayed 1/fs(smallest is 8k) = 125us before afe off */ + usleep_range(120, 130); + + /* reset dmic */ + afe_priv->mtkaif_dmic = 0; + break; + default: + break; + } + + return 0; +} + +static int mtk_adda_pad_top_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8189_afe_private *afe_priv = afe->platform_priv; + + if (event == SND_SOC_DAPM_PRE_PMU) { + if (afe_priv->mtkaif_protocol == MTKAIF_PROTOCOL_2_CLK_P2) + regmap_write(afe->regmap, AFE_AUD_PAD_TOP_CFG0, 0xB8); + else if (afe_priv->mtkaif_protocol == MTKAIF_PROTOCOL_2) + regmap_write(afe->regmap, AFE_AUD_PAD_TOP_CFG0, 0xB0); + else + regmap_write(afe->regmap, AFE_AUD_PAD_TOP_CFG0, 0xB0); + } + + return 0; +} + +static bool is_adda_mtkaif_need_phase_delay(struct mt8189_afe_private *afe_priv) +{ + return afe_priv->mtkaif_chosen_phase[0] >= 0 && + afe_priv->mtkaif_chosen_phase[1] >= 0; +} + +static int mtk_adda_mtkaif_cfg_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8189_afe_private *afe_priv = afe->platform_priv; + int delay_data; + int delay_cycle; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if (afe_priv->mtkaif_protocol == MTKAIF_PROTOCOL_2_CLK_P2) { + /* set protocol 2 */ + regmap_write(afe->regmap, AFE_MTKAIF0_CFG0, + 0x00010000); + regmap_write(afe->regmap, AFE_MTKAIF1_CFG0, + 0x00010000); + + /* mtkaif_rxif_clkinv_adc inverse for calibration */ + regmap_update_bits(afe->regmap, AFE_MTKAIF0_CFG0, + RG_MTKAIF0_RXIF_CLKINV_MASK_SFT, + 0x1 << RG_MTKAIF0_RXIF_CLKINV_SFT); + regmap_update_bits(afe->regmap, AFE_MTKAIF1_CFG0, + RG_MTKAIF1_RXIF_CLKINV_ADC_MASK_SFT, + 0x1 << RG_MTKAIF1_RXIF_CLKINV_ADC_SFT); + + /* This event align the phase of every miso pin */ + /* If only 1 miso is used, there is no need to do phase delay. */ + if (strcmp(w->name, "ADDA_MTKAIF_CFG") == 0 && + !is_adda_mtkaif_need_phase_delay(afe_priv)) { + dev_dbg(afe->dev, + "%s(), check adda mtkaif_chosen_phase[0/1]:%d/%d\n", + __func__, + afe_priv->mtkaif_chosen_phase[0], + afe_priv->mtkaif_chosen_phase[1]); + break; + } else if (strcmp(w->name, "ADDA6_MTKAIF_CFG") == 0 && + afe_priv->mtkaif_chosen_phase[2] < 0) { + dev_dbg(afe->dev, + "%s(), check adda6 mtkaif_chosen_phase[2]:%d\n", + __func__, + afe_priv->mtkaif_chosen_phase[2]); + break; + } + + /* set delay for ch12 to align phase of miso0 and miso1 */ + if (afe_priv->mtkaif_phase_cycle[0] >= + afe_priv->mtkaif_phase_cycle[1]) { + delay_data = DELAY_DATA_MISO1; + delay_cycle = afe_priv->mtkaif_phase_cycle[0] - + afe_priv->mtkaif_phase_cycle[1]; + } else { + delay_data = DELAY_DATA_MISO2; + delay_cycle = afe_priv->mtkaif_phase_cycle[1] - + afe_priv->mtkaif_phase_cycle[0]; + } + + regmap_update_bits(afe->regmap, + AFE_MTKAIF0_RX_CFG2, + RG_MTKAIF0_RXIF_DELAY_DATA_MASK_SFT, + delay_data << + RG_MTKAIF0_RXIF_DELAY_DATA_SFT); + + regmap_update_bits(afe->regmap, + AFE_MTKAIF0_RX_CFG2, + RG_MTKAIF0_RXIF_DELAY_CYCLE_MASK_SFT, + delay_cycle << + RG_MTKAIF0_RXIF_DELAY_CYCLE_SFT); + + /* set delay between ch3 and ch2 */ + if (afe_priv->mtkaif_phase_cycle[2] >= + afe_priv->mtkaif_phase_cycle[1]) { + delay_data = DELAY_DATA_MISO1; /* ch3 */ + delay_cycle = afe_priv->mtkaif_phase_cycle[2] - + afe_priv->mtkaif_phase_cycle[1]; + } else { + delay_data = DELAY_DATA_MISO2; /* ch2 */ + delay_cycle = afe_priv->mtkaif_phase_cycle[1] - + afe_priv->mtkaif_phase_cycle[2]; + } + + regmap_update_bits(afe->regmap, + AFE_MTKAIF1_RX_CFG2, + RG_MTKAIF1_RXIF_DELAY_DATA_MASK_SFT, + delay_data << + RG_MTKAIF1_RXIF_DELAY_DATA_SFT); + regmap_update_bits(afe->regmap, + AFE_MTKAIF1_RX_CFG2, + RG_MTKAIF1_RXIF_DELAY_CYCLE_MASK_SFT, + delay_cycle << + RG_MTKAIF1_RXIF_DELAY_CYCLE_SFT); + } else if (afe_priv->mtkaif_protocol == MTKAIF_PROTOCOL_2) { + regmap_write(afe->regmap, AFE_MTKAIF0_CFG0, + 0x00010000); + regmap_write(afe->regmap, AFE_MTKAIF1_CFG0, + 0x00010000); + } else { + regmap_write(afe->regmap, AFE_MTKAIF0_CFG0, 0x0); + regmap_write(afe->regmap, AFE_MTKAIF1_CFG0, 0x0); + } + break; + default: + break; + } + + return 0; +} + +static int mtk_adda_dl_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + + dev_dbg(afe->dev, "%s(), name %s, event 0x%x\n", + __func__, w->name, event); + + /* should delayed 1/fs(smallest is 8k) = 125us before afe off */ + if (event == SND_SOC_DAPM_POST_PMD) + usleep_range(120, 130); + + return 0; +} + +static void mt6363_vs1_vote(struct mtk_base_afe *afe) +{ + struct mt8189_afe_private *afe_priv = afe->platform_priv; + bool pre_enable = afe_priv->is_mt6363_vote; + bool enable; + + if (!afe_priv->pmic_regmap) + return; + + enable = (afe_priv->is_adda_dl_on && afe_priv->is_adda_dl_max_vol) || + (afe_priv->is_adda_ul_on); + if (enable == pre_enable) { + dev_dbg(afe->dev, "%s() enable == pre_enable = %d\n", + __func__, enable); + return; + } + + afe_priv->is_mt6363_vote = enable; + dev_dbg(afe->dev, "%s() enable = %d\n", __func__, enable); + + if (enable) + regmap_update_bits(afe_priv->pmic_regmap, RG_BUCK_VS1_VOTER_EN_LO_SET, + VS1_MT6338_MASK_SFT, 0x1); + else + regmap_update_bits(afe_priv->pmic_regmap, RG_BUCK_VS1_VOTER_EN_LO_CLR, + VS1_MT6338_MASK_SFT, 0x1); +} + +static int mt_vs1_voter_dl_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8189_afe_private *afe_priv = afe->platform_priv; + + dev_dbg(afe->dev, "%s(), event = 0x%x\n", __func__, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + afe_priv->is_adda_dl_on = true; + mt6363_vs1_vote(afe); + break; + case SND_SOC_DAPM_POST_PMD: + afe_priv->is_adda_dl_on = false; + mt6363_vs1_vote(afe); + break; + default: + break; + } + + return 0; +} + +static int mt_vs1_voter_ul_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8189_afe_private *afe_priv = afe->platform_priv; + + dev_dbg(afe->dev, "%s(), event = 0x%x\n", __func__, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + afe_priv->is_adda_ul_on = true; + mt6363_vs1_vote(afe); + break; + case SND_SOC_DAPM_POST_PMD: + afe_priv->is_adda_ul_on = false; + mt6363_vs1_vote(afe); + break; + default: + break; + } + + return 0; +} + +static int mt8189_adda_dmic_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *cmpnt = snd_kcontrol_chip(kcontrol); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8189_afe_private *afe_priv = afe->platform_priv; + + ucontrol->value.integer.value[0] = afe_priv->mtkaif_dmic; + + return 0; +} + +static int mt8189_adda_dmic_set(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *cmpnt = snd_kcontrol_chip(kcontrol); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8189_afe_private *afe_priv = afe->platform_priv; + int dmic_on; + + dmic_on = !!ucontrol->value.integer.value[0]; + + dev_dbg(afe->dev, "%s(), kcontrol name %s, dmic_on %d\n", + __func__, kcontrol->id.name, dmic_on); + + afe_priv->mtkaif_dmic = dmic_on; + afe_priv->mtkaif_dmic_ch34 = dmic_on; + + return 0; +} + +static int mt8189_adda_dl_max_vol_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *cmpnt = snd_kcontrol_chip(kcontrol); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8189_afe_private *afe_priv = afe->platform_priv; + + ucontrol->value.integer.value[0] = afe_priv->is_adda_dl_max_vol; + + return 0; +} + +static int mt8189_adda_dl_max_vol_set(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *cmpnt = snd_kcontrol_chip(kcontrol); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8189_afe_private *afe_priv = afe->platform_priv; + bool is_adda_dl_max_vol = ucontrol->value.integer.value[0]; + + afe_priv->is_adda_dl_max_vol = is_adda_dl_max_vol; + mt6363_vs1_vote(afe); + + return 0; +} + +static const struct snd_kcontrol_new mtk_adda_controls[] = { + SOC_SINGLE("ADDA_DL_GAIN", AFE_ADDA_DL_SRC_CON1, + AFE_DL_GAIN1_CTL_PRE_SFT, AFE_DL_GAIN1_CTL_PRE_MASK, 0), + SOC_SINGLE_BOOL_EXT("MTKAIF_DMIC Switch", 0, + mt8189_adda_dmic_get, mt8189_adda_dmic_set), + SOC_SINGLE_BOOL_EXT("ADDA_DL_MAX_VOL Switch", 0, + mt8189_adda_dl_max_vol_get, + mt8189_adda_dl_max_vol_set), +}; + +static const char *const adda_ul_mux_texts[] = { + "MTKAIF", "AP_DMIC", "AP_DMIC_MULTI_CH", +}; + +static SOC_ENUM_SINGLE_DECL(adda_ul_mux_map_enum, + SND_SOC_NOPM, + 0, + adda_ul_mux_texts); + +static const struct snd_kcontrol_new adda_ul_mux_control = + SOC_DAPM_ENUM("ADDA_UL_MUX Select", adda_ul_mux_map_enum); + +static const struct snd_kcontrol_new adda_ch34_ul_mux_control = + SOC_DAPM_ENUM("ADDA_CH34_UL_MUX Select", adda_ul_mux_map_enum); + +static const struct snd_soc_dapm_widget mtk_dai_adda_widgets[] = { + /* inter-connections */ + SND_SOC_DAPM_MIXER("ADDA_DL_CH1", SND_SOC_NOPM, 0, 0, + mtk_adda_dl_ch1_mix, + ARRAY_SIZE(mtk_adda_dl_ch1_mix)), + SND_SOC_DAPM_MIXER("ADDA_DL_CH2", SND_SOC_NOPM, 0, 0, + mtk_adda_dl_ch2_mix, + ARRAY_SIZE(mtk_adda_dl_ch2_mix)), + + SND_SOC_DAPM_MIXER("ADDA_DL_CH3", SND_SOC_NOPM, 0, 0, + mtk_adda_dl_ch3_mix, + ARRAY_SIZE(mtk_adda_dl_ch3_mix)), + SND_SOC_DAPM_MIXER("ADDA_DL_CH4", SND_SOC_NOPM, 0, 0, + mtk_adda_dl_ch4_mix, + ARRAY_SIZE(mtk_adda_dl_ch4_mix)), + + SND_SOC_DAPM_SUPPLY_S("ADDA Enable", SUPPLY_SEQ_ADDA_AFE_ON, + AUDIO_ENGEN_CON0, AUDIO_F3P25M_EN_ON_SFT, 0, + NULL, 0), + SND_SOC_DAPM_SUPPLY_S("ADDA_DL0_CG", SUPPLY_SEQ_ADDA_DL_ON, + AUDIO_TOP_CON0, + PDN_DL0_DAC_SFT, 1, + NULL, 0), + SND_SOC_DAPM_SUPPLY_S("ADDA_UL0_CG", SUPPLY_SEQ_ADDA_UL_ON, + AUDIO_TOP_CON1, + PDN_UL0_ADC_SFT, 1, + NULL, 0), + + SND_SOC_DAPM_SUPPLY_S("ADDA Playback Enable", SUPPLY_SEQ_ADDA_DL_ON, + AFE_ADDA_DL_SRC_CON0, + AFE_DL_SRC_ON_TMP_CTL_PRE_SFT, 0, + mtk_adda_dl_event, + SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_SUPPLY_S("ADDA Capture Enable", SUPPLY_SEQ_ADDA_UL_ON, + AFE_ADDA_UL0_SRC_CON0, + UL_SRC_ON_TMP_CTL_SFT, 0, + mtk_adda_ul_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_SUPPLY_S("AP DMIC Capture Enable", SUPPLY_SEQ_ADDA_UL_ON, + AFE_ADDA_DMIC0_SRC_CON0, + UL_SRC_ON_TMP_CTL_SFT, 0, + NULL, 0), + + SND_SOC_DAPM_SUPPLY_S("AP DMIC CH34 Capture Enable", SUPPLY_SEQ_ADDA_UL_ON, + AFE_ADDA_DMIC1_SRC_CON0, + UL_SRC_ON_TMP_CTL_SFT, 0, + NULL, 0), + + SND_SOC_DAPM_SUPPLY_S("AUD_PAD_TOP", SUPPLY_SEQ_ADDA_AUD_PAD_TOP, + AFE_AUD_PAD_TOP_CFG0, + RG_RX_FIFO_ON_SFT, 0, + mtk_adda_pad_top_event, + SND_SOC_DAPM_PRE_PMU), + SND_SOC_DAPM_SUPPLY_S("ADDA_MTKAIF_CFG", SUPPLY_SEQ_ADDA_MTKAIF_CFG, + SND_SOC_NOPM, 0, 0, + mtk_adda_mtkaif_cfg_event, + SND_SOC_DAPM_PRE_PMU), + SND_SOC_DAPM_SUPPLY_S("ADDA6_MTKAIF_CFG", SUPPLY_SEQ_ADDA6_MTKAIF_CFG, + SND_SOC_NOPM, 0, 0, + mtk_adda_mtkaif_cfg_event, + SND_SOC_DAPM_PRE_PMU), + SND_SOC_DAPM_SUPPLY_S("AP_DMIC_EN", SUPPLY_SEQ_ADDA_AP_DMIC, + AFE_ADDA_DMIC0_SRC_CON0, + UL_AP_DMIC_ON_SFT, 0, + NULL, 0), + SND_SOC_DAPM_SUPPLY_S("AP_DMIC0_CG", SUPPLY_SEQ_ADDA_AP_DMIC, + AUDIO_TOP_CON1, + PDN_DMIC0_ADC_SFT, 1, + NULL, 0), + SND_SOC_DAPM_SUPPLY_S("AP_DMIC_CH34_EN", SUPPLY_SEQ_ADDA_AP_DMIC, + AFE_ADDA_DMIC1_SRC_CON0, + UL_AP_DMIC_ON_SFT, 0, + NULL, 0), + SND_SOC_DAPM_SUPPLY_S("AP_DMIC1_CG", SUPPLY_SEQ_ADDA_AP_DMIC, + AUDIO_TOP_CON1, + PDN_DMIC1_ADC_SFT, 1, + NULL, 0), + SND_SOC_DAPM_SUPPLY_S("ADDA_FIFO", SUPPLY_SEQ_ADDA_FIFO, + AFE_ADDA_UL0_SRC_CON1, + FIFO_SOFT_RST_SFT, 1, + NULL, 0), + SND_SOC_DAPM_SUPPLY_S("AP_DMIC_FIFO", SUPPLY_SEQ_ADDA_FIFO, + AFE_ADDA_DMIC0_SRC_CON1, + FIFO_SOFT_RST_SFT, 1, + NULL, 0), + SND_SOC_DAPM_SUPPLY_S("AP_DMIC_CH34_FIFO", SUPPLY_SEQ_ADDA_FIFO, + AFE_ADDA_DMIC1_SRC_CON1, + FIFO_SOFT_RST_SFT, 1, + NULL, 0), + SND_SOC_DAPM_SUPPLY_S("VS1_VOTER_DL", SUPPLY_SEQ_ADDA_AFE_ON, + SND_SOC_NOPM, 0, 0, + mt_vs1_voter_dl_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_SUPPLY_S("VS1_VOTER_UL", SUPPLY_SEQ_ADDA_AFE_ON, + SND_SOC_NOPM, 0, 0, + mt_vs1_voter_ul_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX("ADDA_UL_Mux", SND_SOC_NOPM, 0, 0, + &adda_ul_mux_control), + SND_SOC_DAPM_MUX("ADDA_CH34_UL_Mux", SND_SOC_NOPM, 0, 0, + &adda_ch34_ul_mux_control), + + SND_SOC_DAPM_INPUT("AP_DMIC_INPUT"), +}; + +static const struct snd_soc_dapm_route mtk_dai_adda_routes[] = { + /* playback */ + {"ADDA_DL_CH1", "DL0_CH1", "DL0"}, + {"ADDA_DL_CH2", "DL0_CH1", "DL0"}, + {"ADDA_DL_CH2", "DL0_CH2", "DL0"}, + + {"ADDA_DL_CH1", "DL1_CH1", "DL1"}, + {"ADDA_DL_CH2", "DL1_CH2", "DL1"}, + + {"ADDA_DL_CH1", "DL2_CH1", "DL2"}, + {"ADDA_DL_CH2", "DL2_CH2", "DL2"}, + + {"ADDA_DL_CH1", "DL3_CH1", "DL3"}, + {"ADDA_DL_CH2", "DL3_CH2", "DL3"}, + + {"ADDA_DL_CH1", "DL4_CH1", "DL4"}, + {"ADDA_DL_CH2", "DL4_CH2", "DL4"}, + + {"ADDA_DL_CH1", "DL5_CH1", "DL5"}, + {"ADDA_DL_CH2", "DL5_CH2", "DL5"}, + + {"ADDA_DL_CH1", "DL6_CH1", "DL6"}, + {"ADDA_DL_CH2", "DL6_CH2", "DL6"}, + + {"ADDA_DL_CH1", "DL7_CH1", "DL7"}, + {"ADDA_DL_CH2", "DL7_CH2", "DL7"}, + + {"ADDA_DL_CH1", "DL8_CH1", "DL8"}, + {"ADDA_DL_CH2", "DL8_CH2", "DL8"}, + + {"ADDA_DL_CH1", "DL_24CH_CH1", "DL_24CH"}, + {"ADDA_DL_CH2", "DL_24CH_CH2", "DL_24CH"}, + + {"ADDA_DL_CH1", "DL24_CH1", "DL24"}, + {"ADDA_DL_CH2", "DL24_CH2", "DL24"}, + + {"ADDA Playback", NULL, "ADDA_DL_CH1"}, + {"ADDA Playback", NULL, "ADDA_DL_CH2"}, + + {"ADDA Playback", NULL, "ADDA Enable"}, + {"ADDA Playback", NULL, "ADDA Playback Enable"}, + {"ADDA Playback", NULL, "AUD_PAD_TOP"}, + {"ADDA Playback", NULL, "VS1_VOTER_DL"}, + {"ADDA Playback", NULL, "ADDA_DL0_CG"}, + + {"ADDA_DL_CH3", "DL0_CH1", "DL0"}, + {"ADDA_DL_CH4", "DL0_CH2", "DL0"}, + + {"ADDA_DL_CH3", "DL1_CH1", "DL1"}, + {"ADDA_DL_CH4", "DL1_CH2", "DL1"}, + + {"ADDA_DL_CH3", "DL2_CH1", "DL2"}, + {"ADDA_DL_CH4", "DL2_CH2", "DL2"}, + + {"ADDA_DL_CH3", "DL3_CH1", "DL3"}, + {"ADDA_DL_CH4", "DL3_CH2", "DL3"}, + + {"ADDA_DL_CH3", "DL4_CH1", "DL4"}, + {"ADDA_DL_CH4", "DL4_CH2", "DL4"}, + + {"ADDA_DL_CH3", "DL5_CH1", "DL5"}, + {"ADDA_DL_CH4", "DL5_CH2", "DL5"}, + + {"ADDA_DL_CH3", "DL6_CH1", "DL6"}, + {"ADDA_DL_CH4", "DL6_CH2", "DL6"}, + + {"ADDA_DL_CH3", "DL7_CH1", "DL7"}, + {"ADDA_DL_CH4", "DL7_CH2", "DL7"}, + + {"ADDA_DL_CH3", "DL8_CH1", "DL8"}, + {"ADDA_DL_CH4", "DL8_CH2", "DL8"}, + + {"ADDA_DL_CH3", "DL_24CH_CH1", "DL_24CH"}, + {"ADDA_DL_CH4", "DL_24CH_CH2", "DL_24CH"}, + {"ADDA_DL_CH3", "DL_24CH_CH3", "DL_24CH"}, + {"ADDA_DL_CH4", "DL_24CH_CH4", "DL_24CH"}, + + {"ADDA_DL_CH3", "DL24_CH1", "DL24"}, + {"ADDA_DL_CH4", "DL24_CH2", "DL24"}, + + {"ADDA Capture", NULL, "ADDA Enable"}, + {"ADDA Capture", NULL, "ADDA Capture Enable"}, + {"ADDA Capture", NULL, "AUD_PAD_TOP"}, + {"ADDA Capture", NULL, "ADDA_MTKAIF_CFG"}, + {"ADDA Capture", NULL, "VS1_VOTER_UL"}, + {"ADDA Capture", NULL, "ADDA_UL0_CG"}, + + /* capture */ + {"ADDA_UL_Mux", "MTKAIF", "ADDA Capture"}, + {"ADDA_UL_Mux", "AP_DMIC", "AP DMIC Capture"}, + {"ADDA_CH34_UL_Mux", "AP_DMIC", "AP DMIC CH34 Capture"}, + + {"AP DMIC Capture", NULL, "ADDA Enable"}, + {"AP DMIC Capture", NULL, "AP DMIC Capture Enable"}, + {"AP DMIC Capture", NULL, "AP_DMIC_FIFO"}, + {"AP DMIC Capture", NULL, "AP_DMIC_EN"}, + {"AP DMIC Capture", NULL, "AP_DMIC0_CG"}, + + {"AP DMIC CH34 Capture", NULL, "ADDA Enable"}, + {"AP DMIC CH34 Capture", NULL, "AP DMIC CH34 Capture Enable"}, + {"AP DMIC CH34 Capture", NULL, "AP_DMIC_CH34_FIFO"}, + {"AP DMIC CH34 Capture", NULL, "AP_DMIC_CH34_EN"}, + {"AP DMIC CH34 Capture", NULL, "AP_DMIC1_CG"}, + + {"AP DMIC Capture", NULL, "AP_DMIC_INPUT"}, + {"AP DMIC CH34 Capture", NULL, "AP_DMIC_INPUT"}, +}; + +/* dai ops */ +static int set_playback_hw_params(struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); + struct mt8189_afe_private *afe_priv = afe->platform_priv; + unsigned int rate = params_rate(params); + struct mtk_afe_adda_priv *adda_priv; + unsigned int dl_src_con0; + unsigned int dl_src_con1; + int id = dai->id; + + adda_priv = afe_priv->dai_priv[id]; + if (!adda_priv) + return -EINVAL; + + adda_priv->dl_rate = rate; + + /* set sampling rate */ + dl_src_con0 = adda_dl_rate_transform(afe, rate) << + AFE_DL_INPUT_MODE_CTL_SFT; + + /* set output mode, UP_SAMPLING_RATE_X8 */ + dl_src_con0 |= (0x3 << AFE_DL_OUTPUT_SEL_CTL_SFT); + + /* turn off mute function */ + dl_src_con0 |= (0x01 << AFE_DL_MUTE_CH2_OFF_CTL_PRE_SFT); + dl_src_con0 |= (0x01 << AFE_DL_MUTE_CH1_OFF_CTL_PRE_SFT); + + /* set voice input data if input sample rate is 8k or 16k */ + if (rate == 8000 || rate == 16000) + dl_src_con0 |= 0x01 << AFE_DL_VOICE_MODE_CTL_PRE_SFT; + + /* SA suggest apply -0.3db to audio/speech path */ + dl_src_con1 = MTK_AFE_ADDA_DL_GAIN_NORMAL << + AFE_DL_GAIN1_CTL_PRE_SFT; + dl_src_con1 |= MTK_AFE_ADDA_DL_GAIN_NORMAL << + AFE_DL_GAIN2_CTL_PRE_SFT; + + /* turn on down-link gain */ + dl_src_con0 |= (0x01 << AFE_DL_GAIN_ON_CTL_PRE_SFT); + + if (id == MT8189_DAI_ADDA) { + /* clean predistortion */ + regmap_write(afe->regmap, AFE_ADDA_DL_PREDIS_CON0, 0); + regmap_write(afe->regmap, AFE_ADDA_DL_PREDIS_CON1, 0); + + regmap_write(afe->regmap, + AFE_ADDA_DL_SRC_CON0, dl_src_con0); + regmap_write(afe->regmap, + AFE_ADDA_DL_SRC_CON1, dl_src_con1); + + /* set sdm gain */ + regmap_update_bits(afe->regmap, + AFE_ADDA_DL_SDM_DCCOMP_CON, + AFE_DL_ATTGAIN_CTL_MASK_SFT, + AUDIO_SDM_LEVEL_NORMAL << + AFE_DL_ATTGAIN_CTL_SFT); + + /* 2nd sdm */ + regmap_update_bits(afe->regmap, + AFE_ADDA_DL_SDM_DCCOMP_CON, + AFE_DL_USE_3RD_SDM_MASK_SFT, + AUDIO_SDM_2ND << AFE_DL_USE_3RD_SDM_SFT); + + /* sdm auto reset */ + regmap_write(afe->regmap, + AFE_ADDA_DL_SDM_AUTO_RESET_CON, + SDM_AUTO_RESET_THRESHOLD); + regmap_update_bits(afe->regmap, + AFE_ADDA_DL_SDM_AUTO_RESET_CON, + AFE_DL_SDM_AUTO_RESET_TEST_ON_SFT, + 0x1 << AFE_DL_SDM_AUTO_RESET_TEST_ON_SFT); + } + + return 0; +} + +static int set_capture_hw_params(struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); + struct mt8189_afe_private *afe_priv = afe->platform_priv; + unsigned int rate = params_rate(params); + struct mtk_afe_adda_priv *adda_priv; + unsigned int voice_mode; + unsigned int ul_src_con0; + int id = dai->id; + + adda_priv = afe_priv->dai_priv[id]; + if (!adda_priv) + return -EINVAL; + + adda_priv->ul_rate = rate; + + voice_mode = adda_ul_rate_transform(afe, rate); + + ul_src_con0 = (voice_mode << UL_VOICE_MODE_CH1_CH2_CTL_SFT) & + UL_VOICE_MODE_CH1_CH2_CTL_MASK_SFT; + + /* enable iir */ + ul_src_con0 |= (1 << UL_IIR_ON_TMP_CTL_SFT) & + UL_IIR_ON_TMP_CTL_MASK_SFT; + ul_src_con0 |= (UL_IIR_SW << UL_IIRMODE_CTL_SFT) & + UL_IIRMODE_CTL_MASK_SFT; + + switch (id) { + case MT8189_DAI_ADDA: + /* 35Hz @ 48k */ + regmap_write(afe->regmap, + AFE_ADDA_UL0_IIR_COEF_02_01, 0x00000000); + regmap_write(afe->regmap, + AFE_ADDA_UL0_IIR_COEF_04_03, 0x00003FB8); + regmap_write(afe->regmap, + AFE_ADDA_UL0_IIR_COEF_06_05, 0x3FB80000); + regmap_write(afe->regmap, + AFE_ADDA_UL0_IIR_COEF_08_07, 0x3FB80000); + regmap_write(afe->regmap, + AFE_ADDA_UL0_IIR_COEF_10_09, 0x0000C048); + + regmap_write(afe->regmap, + AFE_ADDA_UL0_SRC_CON0, ul_src_con0); + + /* mtkaif_rxif_data_mode = 0, amic */ + regmap_update_bits(afe->regmap, + AFE_MTKAIF0_RX_CFG0, + RG_MTKAIF0_RXIF_DATA_MODE_MASK_SFT, + 0x0 << RG_MTKAIF0_RXIF_DATA_MODE_SFT); + break; + case MT8189_DAI_AP_DMIC: + /* 35Hz @ 48k */ + regmap_write(afe->regmap, + AFE_ADDA_DMIC0_IIR_COEF_02_01, 0x00000000); + regmap_write(afe->regmap, + AFE_ADDA_DMIC0_IIR_COEF_04_03, 0x00003FB8); + regmap_write(afe->regmap, + AFE_ADDA_DMIC0_IIR_COEF_06_05, 0x3FB80000); + regmap_write(afe->regmap, + AFE_ADDA_DMIC0_IIR_COEF_08_07, 0x3FB80000); + regmap_write(afe->regmap, + AFE_ADDA_DMIC0_IIR_COEF_10_09, 0x0000C048); + + regmap_write(afe->regmap, + AFE_ADDA_DMIC0_SRC_CON0, ul_src_con0); + break; + case MT8189_DAI_AP_DMIC_CH34: + /* 35Hz @ 48k */ + regmap_write(afe->regmap, + AFE_ADDA_DMIC1_IIR_COEF_02_01, 0x00000000); + regmap_write(afe->regmap, + AFE_ADDA_DMIC1_IIR_COEF_04_03, 0x00003FB8); + regmap_write(afe->regmap, + AFE_ADDA_DMIC1_IIR_COEF_06_05, 0x3FB80000); + regmap_write(afe->regmap, + AFE_ADDA_DMIC1_IIR_COEF_08_07, 0x3FB80000); + regmap_write(afe->regmap, + AFE_ADDA_DMIC1_IIR_COEF_10_09, 0x0000C048); + + regmap_write(afe->regmap, + AFE_ADDA_DMIC1_SRC_CON0, ul_src_con0); + break; + default: + break; + } + + /* ap dmic */ + if (id == MT8189_DAI_AP_DMIC || id == MT8189_DAI_AP_DMIC_CH34) + mtk_adda_ul_src_enable_dmic(afe, id); + + return 0; +} + +static int mtk_dai_adda_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); + int id = dai->id; + + if (id >= MT8189_DAI_NUM || id < 0) + return -EINVAL; + + dev_dbg(afe->dev, "%s(), id %d, stream %d, rate %d\n", + __func__, id, substream->stream, params_rate(params)); + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + return set_playback_hw_params(params, dai); + else + return set_capture_hw_params(params, dai); + + return 0; +} + +static const struct snd_soc_dai_ops mtk_dai_adda_ops = { + .hw_params = mtk_dai_adda_hw_params, +}; + +/* dai driver */ +#define MTK_ADDA_PLAYBACK_RATES (SNDRV_PCM_RATE_8000_48000) + +#define MTK_ADDA_CAPTURE_RATES (SNDRV_PCM_RATE_8000 |\ + SNDRV_PCM_RATE_16000 |\ + SNDRV_PCM_RATE_32000 |\ + SNDRV_PCM_RATE_48000) + +#define MTK_ADDA_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ + SNDRV_PCM_FMTBIT_S24_LE |\ + SNDRV_PCM_FMTBIT_S32_LE) + +static struct snd_soc_dai_driver mtk_dai_adda_driver[] = { + { + .name = "ADDA", + .id = MT8189_DAI_ADDA, + .playback = { + .stream_name = "ADDA Playback", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_ADDA_PLAYBACK_RATES, + .formats = MTK_ADDA_FORMATS, + }, + .capture = { + .stream_name = "ADDA Capture", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_ADDA_CAPTURE_RATES, + .formats = MTK_ADDA_FORMATS, + }, + .ops = &mtk_dai_adda_ops, + }, + { + .name = "ADDA_CH34", + .id = MT8189_DAI_ADDA_CH34, + .playback = { + .stream_name = "ADDA CH34 Playback", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_ADDA_PLAYBACK_RATES, + .formats = MTK_ADDA_FORMATS, + }, + .ops = &mtk_dai_adda_ops, + }, + { + .name = "AP_DMIC", + .id = MT8189_DAI_AP_DMIC, + .capture = { + .stream_name = "AP DMIC Capture", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_ADDA_CAPTURE_RATES, + .formats = MTK_ADDA_FORMATS, + }, + .ops = &mtk_dai_adda_ops, + }, + { + .name = "AP_DMIC_CH34", + .id = MT8189_DAI_AP_DMIC_CH34, + .capture = { + .stream_name = "AP DMIC CH34 Capture", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_ADDA_CAPTURE_RATES, + .formats = MTK_ADDA_FORMATS, + }, + .ops = &mtk_dai_adda_ops, + }, +}; + +static int init_adda_priv_data(struct mtk_base_afe *afe) +{ + struct mt8189_afe_private *afe_priv = afe->platform_priv; + struct mtk_afe_adda_priv *adda_priv; + static const int adda_dai_list[] = { + MT8189_DAI_ADDA, + MT8189_DAI_ADDA_CH34, + }; + + for (int i = 0; i < ARRAY_SIZE(adda_dai_list); i++) { + adda_priv = devm_kzalloc(afe->dev, + sizeof(struct mtk_afe_adda_priv), + GFP_KERNEL); + if (!adda_priv) + return -ENOMEM; + + afe_priv->dai_priv[adda_dai_list[i]] = adda_priv; + } + + /* ap dmic priv share with adda */ + afe_priv->dai_priv[MT8189_DAI_AP_DMIC] = + afe_priv->dai_priv[MT8189_DAI_ADDA]; + afe_priv->dai_priv[MT8189_DAI_AP_DMIC_CH34] = + afe_priv->dai_priv[MT8189_DAI_ADDA_CH34]; + + return 0; +} + +int mt8189_dai_adda_register(struct mtk_base_afe *afe) +{ + struct mtk_base_afe_dai *dai; + int ret; + + dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL); + if (!dai) + return -ENOMEM; + + dai->dai_drivers = mtk_dai_adda_driver; + dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_adda_driver); + dai->controls = mtk_adda_controls; + dai->num_controls = ARRAY_SIZE(mtk_adda_controls); + dai->dapm_widgets = mtk_dai_adda_widgets; + dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_adda_widgets); + dai->dapm_routes = mtk_dai_adda_routes; + dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_adda_routes); + + ret = init_adda_priv_data(afe); + if (ret) + return ret; + + list_add(&dai->list, &afe->sub_dais); + + return 0; +} diff --git a/sound/soc/mediatek/mt8189/mt8189-dai-i2s.c b/sound/soc/mediatek/mt8189/mt8189-dai-i2s.c new file mode 100644 index 00000000000000..94c49a662e2d53 --- /dev/null +++ b/sound/soc/mediatek/mt8189/mt8189-dai-i2s.c @@ -0,0 +1,1463 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * MediaTek ALSA SoC Audio DAI I2S Control + * + * Copyright (c) 2025 MediaTek Inc. + * Author: Darren Ye + */ + +#include +#include + +#include + +#include "mt8189-afe-clk.h" +#include "mt8189-afe-common.h" +#include "mt8189-interconnection.h" + +#include "../common/mtk-afe-fe-dai.h" + +#define I2SIN0_MCLK_EN_W_NAME "I2SIN0_MCLK_EN" +#define I2SIN1_MCLK_EN_W_NAME "I2SIN1_MCLK_EN" +#define I2SOUT0_MCLK_EN_W_NAME "I2SOUT0_MCLK_EN" +#define I2SOUT1_MCLK_EN_W_NAME "I2SOUT1_MCLK_EN" +#define I2SOUT4_MCLK_EN_W_NAME "I2SOUT4_MCLK_EN" + +enum { + SUPPLY_SEQ_APLL, + SUPPLY_SEQ_I2S_MCLK_EN, + SUPPLY_SEQ_I2S_CG_EN, + SUPPLY_SEQ_I2S_EN, +}; + +/* this enum is merely for mtk_afe_i2s_priv declare */ +enum { + DAI_I2SIN0, + DAI_I2SIN1, + DAI_I2SOUT0, + DAI_I2SOUT1, + DAI_I2SOUT4, + DAI_I2S_NUM, +}; + +enum { + ETDM_CLK_SOURCE_H26M, + ETDM_CLK_SOURCE_APLL, + ETDM_CLK_SOURCE_SPDIF, + ETDM_CLK_SOURCE_HDMI, + ETDM_CLK_SOURCE_EARC, + ETDM_CLK_SOURCE_LINEIN, +}; + +enum { + ETDM_RELATCH_SEL_H26M, + ETDM_RELATCH_SEL_APLL, +}; + +enum { + ETDM_RATE_8K, + ETDM_RATE_12K, + ETDM_RATE_16K, + ETDM_RATE_24K, + ETDM_RATE_32K, + ETDM_RATE_48K, + ETDM_RATE_64K, + ETDM_RATE_96K, + ETDM_RATE_128K, + ETDM_RATE_192K, + ETDM_RATE_256K, + ETDM_RATE_384K, + ETDM_RATE_11025 = 16, + ETDM_RATE_22050, + ETDM_RATE_44100, + ETDM_RATE_88200, + ETDM_RATE_176400, + ETDM_RATE_352800, +}; + +enum { + ETDM_CONN_8K, + ETDM_CONN_11K, + ETDM_CONN_12K, + ETDM_CONN_16K = 4, + ETDM_CONN_22K, + ETDM_CONN_24K, + ETDM_CONN_32K = 8, + ETDM_CONN_44K, + ETDM_CONN_48K, + ETDM_CONN_88K = 13, + ETDM_CONN_96K, + ETDM_CONN_176K = 17, + ETDM_CONN_192K, + ETDM_CONN_352K = 21, + ETDM_CONN_384K, +}; + +enum { + ETDM_WLEN_8_BIT = 0x7, + ETDM_WLEN_16_BIT = 0xf, + ETDM_WLEN_32_BIT = 0x1f, +}; + +enum { + ETDM_SLAVE_SEL_ETDMIN0_MASTER, + ETDM_SLAVE_SEL_ETDMIN0_SLAVE, + ETDM_SLAVE_SEL_ETDMIN1_MASTER, + ETDM_SLAVE_SEL_ETDMIN1_SLAVE, + ETDM_SLAVE_SEL_ETDMIN2_MASTER, + ETDM_SLAVE_SEL_ETDMIN2_SLAVE, + ETDM_SLAVE_SEL_ETDMIN3_MASTER, + ETDM_SLAVE_SEL_ETDMIN3_SLAVE, + ETDM_SLAVE_SEL_ETDMOUT0_MASTER, + ETDM_SLAVE_SEL_ETDMOUT0_SLAVE, + ETDM_SLAVE_SEL_ETDMOUT1_MASTER, + ETDM_SLAVE_SEL_ETDMOUT1_SLAVE, + ETDM_SLAVE_SEL_ETDMOUT2_MASTER, + ETDM_SLAVE_SEL_ETDMOUT2_SLAVE, + ETDM_SLAVE_SEL_ETDMOUT3_MASTER, + ETDM_SLAVE_SEL_ETDMOUT3_SLAVE, +}; + +struct mtk_afe_i2s_priv { + int id; + int rate; /* for determine which apll to use */ + int low_jitter_en; + unsigned int i2s_low_power_mask; + const char *share_property_name; + int share_i2s_id; + + int mclk_id; + int mclk_rate; + int mclk_apll; + + int ch_num; + int sync; + int ip_mode; + int slave_mode; + int lpbk_mode; +}; + +static unsigned int get_etdm_wlen(snd_pcm_format_t format) +{ + return snd_pcm_format_physical_width(format) <= 16 ? + ETDM_WLEN_16_BIT : ETDM_WLEN_32_BIT; +} + +static unsigned int get_etdm_lrck_width(snd_pcm_format_t format) +{ + if (snd_pcm_format_physical_width(format) <= 1) + return 0; + + /* The valid data bit number should be larger than 7 due to hardware limitation. */ + return snd_pcm_format_physical_width(format) - 1; +} + +static unsigned int get_etdm_rate(unsigned int rate) +{ + switch (rate) { + case 8000: + return ETDM_RATE_8K; + case 12000: + return ETDM_RATE_12K; + case 16000: + return ETDM_RATE_16K; + case 24000: + return ETDM_RATE_24K; + case 32000: + return ETDM_RATE_32K; + case 48000: + return ETDM_RATE_48K; + case 64000: + return ETDM_RATE_64K; + case 96000: + return ETDM_RATE_96K; + case 128000: + return ETDM_RATE_128K; + case 192000: + return ETDM_RATE_192K; + case 256000: + return ETDM_RATE_256K; + case 384000: + return ETDM_RATE_384K; + case 11025: + return ETDM_RATE_11025; + case 22050: + return ETDM_RATE_22050; + case 44100: + return ETDM_RATE_44100; + case 88200: + return ETDM_RATE_88200; + case 176400: + return ETDM_RATE_176400; + case 352800: + return ETDM_RATE_352800; + default: + return 0; + } +} + +static unsigned int get_etdm_inconn_rate(unsigned int rate) +{ + switch (rate) { + case 8000: + return ETDM_CONN_8K; + case 12000: + return ETDM_CONN_12K; + case 16000: + return ETDM_CONN_16K; + case 24000: + return ETDM_CONN_24K; + case 32000: + return ETDM_CONN_32K; + case 48000: + return ETDM_CONN_48K; + case 96000: + return ETDM_CONN_96K; + case 192000: + return ETDM_CONN_192K; + case 384000: + return ETDM_CONN_384K; + case 11025: + return ETDM_CONN_11K; + case 22050: + return ETDM_CONN_22K; + case 44100: + return ETDM_CONN_44K; + case 88200: + return ETDM_CONN_88K; + case 176400: + return ETDM_CONN_176K; + case 352800: + return ETDM_CONN_352K; + default: + return 0; + } +} + +static int get_i2s_id_by_name(struct mtk_base_afe *afe, + const char *name) +{ + if (strncmp(name, "I2SIN0", 6) == 0) + return MT8189_DAI_I2S_IN0; + else if (strncmp(name, "I2SIN1", 6) == 0) + return MT8189_DAI_I2S_IN1; + else if (strncmp(name, "I2SOUT0", 7) == 0) + return MT8189_DAI_I2S_OUT0; + else if (strncmp(name, "I2SOUT1", 7) == 0) + return MT8189_DAI_I2S_OUT1; + else if (strncmp(name, "I2SOUT4", 7) == 0) + return MT8189_DAI_I2S_OUT4; + else + return -EINVAL; +} + +static struct mtk_afe_i2s_priv *get_i2s_priv_by_name(struct mtk_base_afe *afe, + const char *name) +{ + struct mt8189_afe_private *afe_priv = afe->platform_priv; + int dai_id = get_i2s_id_by_name(afe, name); + + if (dai_id < 0) + return NULL; + + return afe_priv->dai_priv[dai_id]; +} + +static const char * const etdm_0_3_loopback_texts[] = { + "etdmin0", "etdmin1", "etdmout0", "etdmout1" +}; + +static const u32 etdm_loopback_values[] = { + 0, 2, 8, 10 +}; + +static SOC_VALUE_ENUM_SINGLE_DECL(i2sin0_loopback_enum, + ETDM_0_3_COWORK_CON1, + ETDM_IN0_SDATA0_SEL_SFT, + ETDM_IN0_SDATA0_SEL_MASK, + etdm_0_3_loopback_texts, + etdm_loopback_values); + +static SOC_VALUE_ENUM_SINGLE_DECL(i2sin1_loopback_enum, + ETDM_0_3_COWORK_CON1, + ETDM_IN1_SDATA0_SEL_SFT, + ETDM_IN1_SDATA0_SEL_MASK, + etdm_0_3_loopback_texts, + etdm_loopback_values); + +static const struct snd_kcontrol_new mtk_dai_i2s_controls[] = { + SOC_ENUM("I2SIN0 Loopback", i2sin0_loopback_enum), + SOC_ENUM("I2SIN1 Loopback", i2sin1_loopback_enum), +}; + +/* + * I2S virtual mux to output widget + * If the I2S interface is required but not connected to an actual codec dai, + * a Dummy_Widget must be used to establish the connection. + */ +static const char *const i2s_mux_map[] = { + "Normal", "Dummy_Widget", +}; + +static int i2s_mux_map_value[] = { + 0, 1, +}; + +static SOC_VALUE_ENUM_SINGLE_AUTODISABLE_DECL(i2s_mux_map_enum, + SND_SOC_NOPM, + 0, + 1, + i2s_mux_map, + i2s_mux_map_value); + +static const struct snd_kcontrol_new i2s_in0_mux_control = + SOC_DAPM_ENUM("I2S IN0 Select", i2s_mux_map_enum); +static const struct snd_kcontrol_new i2s_in1_mux_control = + SOC_DAPM_ENUM("I2S IN1 Select", i2s_mux_map_enum); +static const struct snd_kcontrol_new i2s_out0_mux_control = + SOC_DAPM_ENUM("I2S OUT0 Select", i2s_mux_map_enum); +static const struct snd_kcontrol_new i2s_out1_mux_control = + SOC_DAPM_ENUM("I2S OUT1 Select", i2s_mux_map_enum); +static const struct snd_kcontrol_new i2s_out4_mux_control = + SOC_DAPM_ENUM("I2S OUT4 Select", i2s_mux_map_enum); + +static const struct snd_kcontrol_new mtk_i2sout0_ch1_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("DL0_CH1", AFE_CONN108_1, I_DL0_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1", AFE_CONN108_1, I_DL1_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1", AFE_CONN108_1, I_DL2_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1", AFE_CONN108_1, I_DL3_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH1", AFE_CONN108_1, I_DL4_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH1", AFE_CONN108_1, I_DL5_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH1", AFE_CONN108_1, I_DL6_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL7_CH1", AFE_CONN108_1, I_DL7_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL8_CH1", AFE_CONN108_1, I_DL8_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH1", AFE_CONN108_1, I_DL_24CH_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_GAIN0_OUT_CH1", AFE_CONN108_0, + I_GAIN0_OUT_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN108_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH1", AFE_CONN108_4, + I_PCM_0_CAP_CH1, 1, 0), +}; + +static const struct snd_kcontrol_new mtk_i2sout0_ch2_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("DL0_CH2", AFE_CONN109_1, I_DL0_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2", AFE_CONN109_1, I_DL1_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2", AFE_CONN109_1, I_DL2_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2", AFE_CONN109_1, I_DL3_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH2", AFE_CONN109_1, I_DL4_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH2", AFE_CONN109_1, I_DL5_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH2", AFE_CONN109_1, I_DL6_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL7_CH2", AFE_CONN109_1, I_DL7_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL8_CH2", AFE_CONN109_1, I_DL8_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH2", AFE_CONN109_1, I_DL_24CH_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_GAIN0_OUT_CH2", AFE_CONN109_0, + I_GAIN0_OUT_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN109_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH1", AFE_CONN109_4, + I_PCM_0_CAP_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH2", AFE_CONN109_4, + I_PCM_0_CAP_CH2, 1, 0), +}; + +static const struct snd_kcontrol_new mtk_i2sout1_ch1_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("DL0_CH1", AFE_CONN110_1, I_DL0_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1", AFE_CONN110_1, I_DL1_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1", AFE_CONN110_1, I_DL2_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1", AFE_CONN110_1, I_DL3_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH1", AFE_CONN110_1, I_DL4_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH1", AFE_CONN110_1, I_DL5_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH1", AFE_CONN110_1, I_DL6_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL7_CH1", AFE_CONN110_1, I_DL7_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL8_CH1", AFE_CONN110_1, I_DL8_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH1", AFE_CONN110_1, I_DL_24CH_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_GAIN0_OUT_CH1", AFE_CONN110_0, + I_GAIN0_OUT_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN110_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH1", AFE_CONN110_4, + I_PCM_0_CAP_CH1, 1, 0), +}; + +static const struct snd_kcontrol_new mtk_i2sout1_ch2_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("DL0_CH2", AFE_CONN111_1, I_DL0_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2", AFE_CONN111_1, I_DL1_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2", AFE_CONN111_1, I_DL2_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2", AFE_CONN111_1, I_DL3_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH2", AFE_CONN111_1, I_DL4_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH2", AFE_CONN111_1, I_DL5_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH2", AFE_CONN111_1, I_DL6_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL7_CH2", AFE_CONN111_1, I_DL7_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL8_CH2", AFE_CONN111_1, I_DL8_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH2", AFE_CONN111_1, I_DL_24CH_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_GAIN0_OUT_CH2", AFE_CONN111_0, + I_GAIN0_OUT_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN111_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH1", AFE_CONN111_4, + I_PCM_0_CAP_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH2", AFE_CONN111_4, + I_PCM_0_CAP_CH2, 1, 0), +}; + +static const struct snd_kcontrol_new mtk_i2sout4_ch1_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("DL0_CH1", AFE_CONN116_1, I_DL0_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1", AFE_CONN116_1, I_DL1_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1", AFE_CONN116_1, I_DL2_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1", AFE_CONN116_1, I_DL3_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH1", AFE_CONN116_1, I_DL4_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH1", AFE_CONN116_1, I_DL5_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH1", AFE_CONN116_1, I_DL6_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL7_CH1", AFE_CONN116_1, I_DL7_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL8_CH1", AFE_CONN116_1, I_DL8_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH1", AFE_CONN116_1, I_DL_24CH_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL24_CH1", AFE_CONN116_2, I_DL24_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_GAIN0_OUT_CH1", AFE_CONN116_0, + I_GAIN0_OUT_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN116_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN116_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH1", AFE_CONN116_4, + I_PCM_0_CAP_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_2_OUT_CH1", AFE_CONN116_6, + I_SRC_2_OUT_CH1, 1, 0), +}; + +static const struct snd_kcontrol_new mtk_i2sout4_ch2_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("DL0_CH2", AFE_CONN117_1, I_DL0_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2", AFE_CONN117_1, I_DL1_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2", AFE_CONN117_1, I_DL2_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2", AFE_CONN117_1, I_DL3_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH2", AFE_CONN117_1, I_DL4_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH2", AFE_CONN117_1, I_DL5_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH2", AFE_CONN117_1, I_DL6_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL7_CH2", AFE_CONN117_1, I_DL7_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL8_CH2", AFE_CONN117_1, I_DL8_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH2", AFE_CONN117_1, I_DL_24CH_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL24_CH2", AFE_CONN117_2, I_DL24_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_GAIN0_OUT_CH2", AFE_CONN117_0, + I_GAIN0_OUT_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN117_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN117_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH1", AFE_CONN117_4, + I_PCM_0_CAP_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH2", AFE_CONN117_4, + I_PCM_0_CAP_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_2_OUT_CH2", AFE_CONN117_6, + I_SRC_2_OUT_CH2, 1, 0), +}; + +static const struct snd_kcontrol_new mtk_i2sout4_ch3_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH3", AFE_CONN118_1, I_DL_24CH_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH1", AFE_CONN118_4, + I_PCM_0_CAP_CH1, 1, 0), +}; + +static const struct snd_kcontrol_new mtk_i2sout4_ch4_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH4", AFE_CONN119_1, I_DL_24CH_CH4, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH1", AFE_CONN118_4, + I_PCM_0_CAP_CH1, 1, 0), +}; + +static const struct snd_kcontrol_new mtk_i2sout4_ch5_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH5", AFE_CONN120_1, I_DL_24CH_CH5, 1, 0), +}; + +static const struct snd_kcontrol_new mtk_i2sout4_ch6_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH6", AFE_CONN121_1, I_DL_24CH_CH6, 1, 0), +}; + +static const struct snd_kcontrol_new mtk_i2sout4_ch7_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH7", AFE_CONN122_1, I_DL_24CH_CH7, 1, 0), +}; + +static const struct snd_kcontrol_new mtk_i2sout4_ch8_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH8", AFE_CONN123_1, I_DL_24CH_CH8, 1, 0), +}; + +static int mtk_apll_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + + dev_dbg(cmpnt->dev, "%s(), name %s, event 0x%x\n", + __func__, w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if (strcmp(w->name, APLL1_W_NAME) == 0) + mt8189_apll1_enable(afe); + else + mt8189_apll2_enable(afe); + break; + case SND_SOC_DAPM_POST_PMD: + if (strcmp(w->name, APLL1_W_NAME) == 0) + mt8189_apll1_disable(afe); + else + mt8189_apll2_disable(afe); + break; + default: + break; + } + + return 0; +} + +static int mtk_mclk_en_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mtk_afe_i2s_priv *i2s_priv; + + dev_dbg(cmpnt->dev, "%s(), name %s, event 0x%x\n", + __func__, w->name, event); + + i2s_priv = get_i2s_priv_by_name(afe, w->name); + if (!i2s_priv) + return -EINVAL; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + mt8189_mck_enable(afe, i2s_priv->mclk_id, i2s_priv->mclk_rate); + break; + case SND_SOC_DAPM_POST_PMD: + i2s_priv->mclk_rate = 0; + mt8189_mck_disable(afe, i2s_priv->mclk_id); + break; + default: + break; + } + + return 0; +} + +static const struct snd_soc_dapm_widget mtk_dai_i2s_widgets[] = { + SND_SOC_DAPM_MIXER("I2SOUT0_CH1", SND_SOC_NOPM, 0, 0, + mtk_i2sout0_ch1_mix, + ARRAY_SIZE(mtk_i2sout0_ch1_mix)), + SND_SOC_DAPM_MIXER("I2SOUT0_CH2", SND_SOC_NOPM, 0, 0, + mtk_i2sout0_ch2_mix, + ARRAY_SIZE(mtk_i2sout0_ch2_mix)), + + SND_SOC_DAPM_MIXER("I2SOUT1_CH1", SND_SOC_NOPM, 0, 0, + mtk_i2sout1_ch1_mix, + ARRAY_SIZE(mtk_i2sout1_ch1_mix)), + SND_SOC_DAPM_MIXER("I2SOUT1_CH2", SND_SOC_NOPM, 0, 0, + mtk_i2sout1_ch2_mix, + ARRAY_SIZE(mtk_i2sout1_ch2_mix)), + + SND_SOC_DAPM_MIXER("I2SOUT4_CH1", SND_SOC_NOPM, 0, 0, + mtk_i2sout4_ch1_mix, + ARRAY_SIZE(mtk_i2sout4_ch1_mix)), + SND_SOC_DAPM_MIXER("I2SOUT4_CH2", SND_SOC_NOPM, 0, 0, + mtk_i2sout4_ch2_mix, + ARRAY_SIZE(mtk_i2sout4_ch2_mix)), + SND_SOC_DAPM_MIXER("I2SOUT4_CH3", SND_SOC_NOPM, 0, 0, + mtk_i2sout4_ch3_mix, + ARRAY_SIZE(mtk_i2sout4_ch3_mix)), + SND_SOC_DAPM_MIXER("I2SOUT4_CH4", SND_SOC_NOPM, 0, 0, + mtk_i2sout4_ch4_mix, + ARRAY_SIZE(mtk_i2sout4_ch4_mix)), + SND_SOC_DAPM_MIXER("I2SOUT4_CH5", SND_SOC_NOPM, 0, 0, + mtk_i2sout4_ch5_mix, + ARRAY_SIZE(mtk_i2sout4_ch5_mix)), + SND_SOC_DAPM_MIXER("I2SOUT4_CH6", SND_SOC_NOPM, 0, 0, + mtk_i2sout4_ch6_mix, + ARRAY_SIZE(mtk_i2sout4_ch6_mix)), + SND_SOC_DAPM_MIXER("I2SOUT4_CH7", SND_SOC_NOPM, 0, 0, + mtk_i2sout4_ch7_mix, + ARRAY_SIZE(mtk_i2sout4_ch7_mix)), + SND_SOC_DAPM_MIXER("I2SOUT4_CH8", SND_SOC_NOPM, 0, 0, + mtk_i2sout4_ch8_mix, + ARRAY_SIZE(mtk_i2sout4_ch8_mix)), + + /* i2s en*/ + SND_SOC_DAPM_SUPPLY_S("I2SIN0_EN", SUPPLY_SEQ_I2S_EN, + ETDM_IN0_CON0, REG_ETDM_IN_EN_SFT, 0, + NULL, 0), + SND_SOC_DAPM_SUPPLY_S("I2SIN1_EN", SUPPLY_SEQ_I2S_EN, + ETDM_IN1_CON0, REG_ETDM_IN_EN_SFT, 0, + NULL, 0), + SND_SOC_DAPM_SUPPLY_S("I2SOUT0_EN", SUPPLY_SEQ_I2S_EN, + ETDM_OUT0_CON0, OUT_REG_ETDM_OUT_EN_SFT, 0, + NULL, 0), + SND_SOC_DAPM_SUPPLY_S("I2SOUT1_EN", SUPPLY_SEQ_I2S_EN, + ETDM_OUT1_CON0, OUT_REG_ETDM_OUT_EN_SFT, 0, + NULL, 0), + SND_SOC_DAPM_SUPPLY_S("I2SOUT4_EN", SUPPLY_SEQ_I2S_EN, + ETDM_OUT4_CON0, OUT_REG_ETDM_OUT_EN_SFT, 0, + NULL, 0), + + /* i2s mclk en */ + SND_SOC_DAPM_SUPPLY_S(I2SIN0_MCLK_EN_W_NAME, SUPPLY_SEQ_I2S_MCLK_EN, + SND_SOC_NOPM, 0, 0, + mtk_mclk_en_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY_S(I2SIN1_MCLK_EN_W_NAME, SUPPLY_SEQ_I2S_MCLK_EN, + SND_SOC_NOPM, 0, 0, + mtk_mclk_en_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY_S(I2SOUT0_MCLK_EN_W_NAME, SUPPLY_SEQ_I2S_MCLK_EN, + SND_SOC_NOPM, 0, 0, + mtk_mclk_en_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY_S(I2SOUT1_MCLK_EN_W_NAME, SUPPLY_SEQ_I2S_MCLK_EN, + SND_SOC_NOPM, 0, 0, + mtk_mclk_en_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY_S(I2SOUT4_MCLK_EN_W_NAME, SUPPLY_SEQ_I2S_MCLK_EN, + SND_SOC_NOPM, 0, 0, + mtk_mclk_en_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + /* cg */ + SND_SOC_DAPM_SUPPLY_S("I2SOUT0_CG", SUPPLY_SEQ_I2S_CG_EN, + AUDIO_TOP_CON2, PDN_ETDM_OUT0_SFT, 1, + NULL, 0), + SND_SOC_DAPM_SUPPLY_S("I2SOUT1_CG", SUPPLY_SEQ_I2S_CG_EN, + AUDIO_TOP_CON2, PDN_ETDM_OUT1_SFT, 1, + NULL, 0), + SND_SOC_DAPM_SUPPLY_S("I2SOUT4_CG", SUPPLY_SEQ_I2S_CG_EN, + AUDIO_TOP_CON2, PDN_ETDM_OUT4_SFT, 1, + NULL, 0), + SND_SOC_DAPM_SUPPLY_S("I2SIN0_CG", SUPPLY_SEQ_I2S_CG_EN, + AUDIO_TOP_CON2, PDN_ETDM_IN0_SFT, 1, + NULL, 0), + SND_SOC_DAPM_SUPPLY_S("I2SIN1_CG", SUPPLY_SEQ_I2S_CG_EN, + AUDIO_TOP_CON2, PDN_ETDM_IN1_SFT, 1, + NULL, 0), + + /* apll */ + SND_SOC_DAPM_SUPPLY_S(APLL1_W_NAME, SUPPLY_SEQ_APLL, + SND_SOC_NOPM, 0, 0, + mtk_apll_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY_S(APLL2_W_NAME, SUPPLY_SEQ_APLL, + SND_SOC_NOPM, 0, 0, + mtk_apll_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + /* allow i2s on without codec on */ + SND_SOC_DAPM_OUTPUT("I2S_DUMMY_OUT"), + SND_SOC_DAPM_MUX("I2S_OUT0_Mux", + SND_SOC_NOPM, 0, 0, &i2s_out0_mux_control), + SND_SOC_DAPM_MUX("I2S_OUT1_Mux", + SND_SOC_NOPM, 0, 0, &i2s_out1_mux_control), + SND_SOC_DAPM_MUX("I2S_OUT4_Mux", + SND_SOC_NOPM, 0, 0, &i2s_out4_mux_control), + + SND_SOC_DAPM_INPUT("I2S_DUMMY_IN"), + SND_SOC_DAPM_MUX("I2S_IN0_Mux", + SND_SOC_NOPM, 0, 0, &i2s_in0_mux_control), + SND_SOC_DAPM_MUX("I2S_IN1_Mux", + SND_SOC_NOPM, 0, 0, &i2s_in1_mux_control), +}; + +static int mtk_afe_i2s_share_connect(struct snd_soc_dapm_widget *source, + struct snd_soc_dapm_widget *sink) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(sink->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mtk_afe_i2s_priv *i2s_priv; + + i2s_priv = get_i2s_priv_by_name(afe, sink->name); + if (!i2s_priv) + return 0; + + if (i2s_priv->share_i2s_id < 0) + return 0; + + return i2s_priv->share_i2s_id == get_i2s_id_by_name(afe, source->name); +} + +static int mtk_afe_i2s_apll_connect(struct snd_soc_dapm_widget *source, + struct snd_soc_dapm_widget *sink) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(sink->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mtk_afe_i2s_priv *i2s_priv; + int cur_apll; + int needed_apll; + + i2s_priv = get_i2s_priv_by_name(afe, sink->name); + if (!i2s_priv) + return 0; + + /* which apll */ + cur_apll = mt8189_get_apll_by_name(afe, source->name); + + /* choose APLL from i2s rate */ + needed_apll = mt8189_get_apll_by_rate(afe, i2s_priv->rate); + + return needed_apll == cur_apll; +} + +static int mtk_afe_i2s_mclk_connect(struct snd_soc_dapm_widget *source, + struct snd_soc_dapm_widget *sink) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(sink->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mtk_afe_i2s_priv *i2s_priv; + int i2s_num; + + i2s_priv = get_i2s_priv_by_name(afe, sink->name); + if (!i2s_priv) + return 0; + + i2s_num = get_i2s_id_by_name(afe, source->name); + if (get_i2s_id_by_name(afe, sink->name) == i2s_num) + return i2s_priv->mclk_rate > 0; + + /* check if share i2s need mclk */ + if (i2s_priv->share_i2s_id < 0) + return 0; + + if (i2s_priv->share_i2s_id == i2s_num) + return i2s_priv->mclk_rate > 0; + + return 0; +} + +static int mtk_afe_mclk_apll_connect(struct snd_soc_dapm_widget *source, + struct snd_soc_dapm_widget *sink) +{ + struct snd_soc_dapm_widget *w = sink; + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mtk_afe_i2s_priv *i2s_priv; + int cur_apll; + + i2s_priv = get_i2s_priv_by_name(afe, w->name); + if (!i2s_priv) + return 0; + + /* which apll */ + cur_apll = mt8189_get_apll_by_name(afe, source->name); + + return i2s_priv->mclk_apll == cur_apll; +} + +static const struct snd_soc_dapm_route mtk_dai_i2s_routes[] = { + /* I2SIN0 */ + {"I2SIN0", NULL, "I2SIN0_EN"}, + {"I2SIN0", NULL, "I2SIN1_EN", mtk_afe_i2s_share_connect}, + {"I2SIN0", NULL, "I2SOUT0_EN", mtk_afe_i2s_share_connect}, + {"I2SIN0", NULL, "I2SOUT1_EN", mtk_afe_i2s_share_connect}, + {"I2SIN0", NULL, "I2SOUT4_EN", mtk_afe_i2s_share_connect}, + + {"I2SIN0", NULL, I2SIN0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SIN0", NULL, I2SIN1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SIN0", NULL, I2SOUT0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SIN0", NULL, I2SOUT1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SIN0", NULL, I2SOUT4_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {I2SIN0_MCLK_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect}, + {I2SIN0_MCLK_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect}, + {"I2SIN0", NULL, APLL1_W_NAME, mtk_afe_i2s_apll_connect}, + {"I2SIN0", NULL, APLL2_W_NAME, mtk_afe_i2s_apll_connect}, + {"I2SIN0", NULL, "I2SOUT0_CG"}, + {"I2SIN0", NULL, "I2SIN0_CG"}, + + /* i2sin1 */ + {"I2SIN1", NULL, "I2SIN0_EN", mtk_afe_i2s_share_connect}, + {"I2SIN1", NULL, "I2SIN1_EN"}, + {"I2SIN1", NULL, "I2SOUT0_EN", mtk_afe_i2s_share_connect}, + {"I2SIN1", NULL, "I2SOUT1_EN", mtk_afe_i2s_share_connect}, + {"I2SIN1", NULL, "I2SOUT4_EN", mtk_afe_i2s_share_connect}, + + {"I2SIN1", NULL, I2SIN0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SIN1", NULL, I2SIN1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SIN1", NULL, I2SOUT0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SIN1", NULL, I2SOUT1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SIN1", NULL, I2SOUT4_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {I2SIN1_MCLK_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect}, + {I2SIN1_MCLK_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect}, + {"I2SIN1", NULL, APLL1_W_NAME, mtk_afe_i2s_apll_connect}, + {"I2SIN1", NULL, APLL2_W_NAME, mtk_afe_i2s_apll_connect}, + {"I2SIN1", NULL, "I2SIN1_CG"}, + {"I2SIN1", NULL, "I2SOUT1_CG"}, + + /* i2sout0 */ + {"I2SOUT0_CH1", "DL0_CH1", "DL0"}, + {"I2SOUT0_CH2", "DL0_CH2", "DL0"}, + {"I2SOUT0_CH1", "DL1_CH1", "DL1"}, + {"I2SOUT0_CH2", "DL1_CH2", "DL1"}, + {"I2SOUT0_CH1", "DL2_CH1", "DL2"}, + {"I2SOUT0_CH2", "DL2_CH2", "DL2"}, + {"I2SOUT0_CH1", "DL3_CH1", "DL3"}, + {"I2SOUT0_CH2", "DL3_CH2", "DL3"}, + {"I2SOUT0_CH1", "DL4_CH1", "DL4"}, + {"I2SOUT0_CH2", "DL4_CH2", "DL4"}, + {"I2SOUT0_CH1", "DL5_CH1", "DL5"}, + {"I2SOUT0_CH2", "DL5_CH2", "DL5"}, + {"I2SOUT0_CH1", "DL6_CH1", "DL6"}, + {"I2SOUT0_CH2", "DL6_CH2", "DL6"}, + {"I2SOUT0_CH1", "DL7_CH1", "DL7"}, + {"I2SOUT0_CH2", "DL7_CH2", "DL7"}, + {"I2SOUT0_CH1", "DL8_CH1", "DL8"}, + {"I2SOUT0_CH2", "DL8_CH2", "DL8"}, + {"I2SOUT0_CH1", "DL_24CH_CH1", "DL_24CH"}, + {"I2SOUT0_CH2", "DL_24CH_CH2", "DL_24CH"}, + + {"I2SOUT0", NULL, "I2SOUT0_CH1"}, + {"I2SOUT0", NULL, "I2SOUT0_CH2"}, + + {"I2SOUT0", NULL, "I2SIN0_EN", mtk_afe_i2s_share_connect}, + {"I2SOUT0", NULL, "I2SIN1_EN", mtk_afe_i2s_share_connect}, + {"I2SOUT0", NULL, "I2SOUT0_EN"}, + {"I2SOUT0", NULL, "I2SOUT1_EN", mtk_afe_i2s_share_connect}, + {"I2SOUT0", NULL, "I2SOUT4_EN", mtk_afe_i2s_share_connect}, + + {"I2SOUT0", NULL, I2SIN0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT0", NULL, I2SIN1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT0", NULL, I2SOUT0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT0", NULL, I2SOUT1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT0", NULL, I2SOUT4_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {I2SOUT0_MCLK_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect}, + {I2SOUT0_MCLK_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect}, + {"I2SOUT0", NULL, APLL1_W_NAME, mtk_afe_i2s_apll_connect}, + {"I2SOUT0", NULL, APLL2_W_NAME, mtk_afe_i2s_apll_connect}, + {"I2SOUT0", NULL, "I2SOUT0_CG"}, + {"I2SOUT0", NULL, "I2SIN0_CG"}, + + /* i2sout1 */ + {"I2SOUT1_CH1", "DL0_CH1", "DL0"}, + {"I2SOUT1_CH2", "DL0_CH2", "DL0"}, + {"I2SOUT1_CH1", "DL1_CH1", "DL1"}, + {"I2SOUT1_CH2", "DL1_CH2", "DL1"}, + {"I2SOUT1_CH1", "DL2_CH1", "DL2"}, + {"I2SOUT1_CH2", "DL2_CH2", "DL2"}, + {"I2SOUT1_CH1", "DL3_CH1", "DL3"}, + {"I2SOUT1_CH2", "DL3_CH2", "DL3"}, + {"I2SOUT1_CH1", "DL4_CH1", "DL4"}, + {"I2SOUT1_CH2", "DL4_CH2", "DL4"}, + {"I2SOUT1_CH1", "DL5_CH1", "DL5"}, + {"I2SOUT1_CH2", "DL5_CH2", "DL5"}, + {"I2SOUT1_CH1", "DL6_CH1", "DL6"}, + {"I2SOUT1_CH2", "DL6_CH2", "DL6"}, + {"I2SOUT1_CH1", "DL7_CH1", "DL7"}, + {"I2SOUT1_CH2", "DL7_CH2", "DL7"}, + {"I2SOUT1_CH1", "DL8_CH1", "DL8"}, + {"I2SOUT1_CH2", "DL8_CH2", "DL8"}, + {"I2SOUT1_CH1", "DL_24CH_CH1", "DL_24CH"}, + {"I2SOUT1_CH2", "DL_24CH_CH2", "DL_24CH"}, + + {"I2SOUT1", NULL, "I2SOUT1_CH1"}, + {"I2SOUT1", NULL, "I2SOUT1_CH2"}, + + {"I2SOUT1", NULL, "I2SIN0_EN", mtk_afe_i2s_share_connect}, + {"I2SOUT1", NULL, "I2SIN1_EN", mtk_afe_i2s_share_connect}, + {"I2SOUT1", NULL, "I2SOUT0_EN", mtk_afe_i2s_share_connect}, + {"I2SOUT1", NULL, "I2SOUT1_EN"}, + {"I2SOUT1", NULL, "I2SOUT4_EN", mtk_afe_i2s_share_connect}, + + {"I2SOUT1", NULL, I2SIN0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT1", NULL, I2SIN1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT1", NULL, I2SOUT0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT1", NULL, I2SOUT1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT1", NULL, I2SOUT4_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {I2SOUT1_MCLK_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect}, + {I2SOUT1_MCLK_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect}, + {"I2SOUT1", NULL, APLL1_W_NAME, mtk_afe_i2s_apll_connect}, + {"I2SOUT1", NULL, APLL2_W_NAME, mtk_afe_i2s_apll_connect}, + {"I2SOUT1", NULL, "I2SOUT1_CG"}, + {"I2SOUT1", NULL, "I2SIN1_CG"}, + + /* i2sout4 */ + {"I2SOUT4_CH1", "DL0_CH1", "DL0"}, + {"I2SOUT4_CH2", "DL0_CH2", "DL0"}, + {"I2SOUT4_CH1", "DL1_CH1", "DL1"}, + {"I2SOUT4_CH2", "DL1_CH2", "DL1"}, + {"I2SOUT4_CH1", "DL2_CH1", "DL2"}, + {"I2SOUT4_CH2", "DL2_CH2", "DL2"}, + {"I2SOUT4_CH1", "DL3_CH1", "DL3"}, + {"I2SOUT4_CH2", "DL3_CH2", "DL3"}, + {"I2SOUT4_CH1", "DL4_CH1", "DL4"}, + {"I2SOUT4_CH2", "DL4_CH2", "DL4"}, + {"I2SOUT4_CH1", "DL5_CH1", "DL5"}, + {"I2SOUT4_CH2", "DL5_CH2", "DL5"}, + {"I2SOUT4_CH1", "DL6_CH1", "DL6"}, + {"I2SOUT4_CH2", "DL6_CH2", "DL6"}, + {"I2SOUT4_CH1", "DL7_CH1", "DL7"}, + {"I2SOUT4_CH2", "DL7_CH2", "DL7"}, + {"I2SOUT4_CH1", "DL8_CH1", "DL8"}, + {"I2SOUT4_CH2", "DL8_CH2", "DL8"}, + {"I2SOUT4_CH1", "DL_24CH_CH1", "DL_24CH"}, + {"I2SOUT4_CH2", "DL_24CH_CH2", "DL_24CH"}, + {"I2SOUT4_CH3", "DL_24CH_CH3", "DL_24CH"}, + {"I2SOUT4_CH4", "DL_24CH_CH4", "DL_24CH"}, + {"I2SOUT4_CH5", "DL_24CH_CH5", "DL_24CH"}, + {"I2SOUT4_CH6", "DL_24CH_CH6", "DL_24CH"}, + {"I2SOUT4_CH7", "DL_24CH_CH7", "DL_24CH"}, + {"I2SOUT4_CH8", "DL_24CH_CH8", "DL_24CH"}, + {"I2SOUT4_CH1", "DL24_CH1", "DL24"}, + {"I2SOUT4_CH2", "DL24_CH2", "DL24"}, + + {"I2SOUT4", NULL, "I2SOUT4_CH1"}, + {"I2SOUT4", NULL, "I2SOUT4_CH2"}, + {"I2SOUT4", NULL, "I2SOUT4_CH3"}, + {"I2SOUT4", NULL, "I2SOUT4_CH4"}, + {"I2SOUT4", NULL, "I2SOUT4_CH5"}, + {"I2SOUT4", NULL, "I2SOUT4_CH6"}, + {"I2SOUT4", NULL, "I2SOUT4_CH7"}, + {"I2SOUT4", NULL, "I2SOUT4_CH8"}, + + {"I2SOUT4", NULL, "I2SIN0_EN", mtk_afe_i2s_share_connect}, + {"I2SOUT4", NULL, "I2SIN1_EN", mtk_afe_i2s_share_connect}, + {"I2SOUT4", NULL, "I2SOUT0_EN", mtk_afe_i2s_share_connect}, + {"I2SOUT4", NULL, "I2SOUT1_EN", mtk_afe_i2s_share_connect}, + {"I2SOUT4", NULL, "I2SOUT4_EN"}, + + {"I2SOUT4", NULL, I2SIN0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT4", NULL, I2SIN1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT4", NULL, I2SOUT0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT4", NULL, I2SOUT1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2SOUT4", NULL, I2SOUT4_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {I2SOUT4_MCLK_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect}, + {I2SOUT4_MCLK_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect}, + {"I2SOUT4", NULL, APLL1_W_NAME, mtk_afe_i2s_apll_connect}, + {"I2SOUT4", NULL, APLL2_W_NAME, mtk_afe_i2s_apll_connect}, + /* CG */ + {"I2SOUT4", NULL, "I2SOUT4_CG"}, + + /* allow i2s on without codec on */ + {"I2SIN0", NULL, "I2S_IN0_Mux"}, + {"I2S_IN0_Mux", "Dummy_Widget", "I2S_DUMMY_IN"}, + + {"I2SIN1", NULL, "I2S_IN1_Mux"}, + {"I2S_IN1_Mux", "Dummy_Widget", "I2S_DUMMY_IN"}, + + {"I2S_OUT0_Mux", "Dummy_Widget", "I2SOUT0"}, + {"I2S_DUMMY_OUT", NULL, "I2S_OUT0_Mux"}, + + {"I2S_OUT1_Mux", "Dummy_Widget", "I2SOUT1"}, + {"I2S_DUMMY_OUT", NULL, "I2S_OUT1_Mux"}, + + {"I2S_OUT4_Mux", "Dummy_Widget", "I2SOUT4"}, + {"I2S_DUMMY_OUT", NULL, "I2S_OUT4_Mux"}, +}; + +/* i2s dai ops*/ +static int mtk_dai_i2s_config(struct mtk_base_afe *afe, + struct snd_pcm_hw_params *params, + int i2s_id) +{ + struct mt8189_afe_private *afe_priv = afe->platform_priv; + struct mtk_afe_i2s_priv *i2s_priv; + unsigned int rate = params_rate(params); + snd_pcm_format_t format = params_format(params); + int ret; + + if (i2s_id >= MT8189_DAI_NUM || i2s_id < 0) + return -EINVAL; + + i2s_priv = afe_priv->dai_priv[i2s_id]; + if (!i2s_priv) + return -EINVAL; + + i2s_priv->rate = rate; + + dev_dbg(afe->dev, "%s(), id %d, rate %d, format %d\n", + __func__, i2s_id, rate, format); + + switch (i2s_id) { + case MT8189_DAI_I2S_IN0: + /* ---etdm in --- */ + regmap_update_bits(afe->regmap, ETDM_IN0_CON1, + REG_INITIAL_COUNT_MASK_SFT, + 0x5 << REG_INITIAL_COUNT_SFT); + /* 3: pad top 5: no pad top */ + regmap_update_bits(afe->regmap, ETDM_IN0_CON1, + REG_INITIAL_POINT_MASK_SFT, + 0x5 << REG_INITIAL_POINT_SFT); + regmap_update_bits(afe->regmap, ETDM_IN0_CON1, + REG_LRCK_RESET_MASK_SFT, + 0x1 << REG_LRCK_RESET_SFT); + regmap_update_bits(afe->regmap, ETDM_IN0_CON2, + REG_CLOCK_SOURCE_SEL_MASK_SFT, + ETDM_CLK_SOURCE_APLL << + REG_CLOCK_SOURCE_SEL_SFT); + /* 0: manual 1: auto */ + regmap_update_bits(afe->regmap, ETDM_IN0_CON2, + REG_CK_EN_SEL_AUTO_MASK_SFT, + 0x1 << REG_CK_EN_SEL_AUTO_SFT); + regmap_update_bits(afe->regmap, ETDM_IN0_CON3, + REG_FS_TIMING_SEL_MASK_SFT, + get_etdm_rate(rate) << + REG_FS_TIMING_SEL_SFT); + regmap_update_bits(afe->regmap, ETDM_IN0_CON4, + REG_RELATCH_1X_EN_SEL_MASK_SFT, + get_etdm_inconn_rate(rate) << + REG_RELATCH_1X_EN_SEL_SFT); + + regmap_update_bits(afe->regmap, ETDM_IN0_CON8, + REG_ETDM_USE_AFIFO_MASK_SFT, + 0x0 << REG_ETDM_USE_AFIFO_SFT); + regmap_update_bits(afe->regmap, ETDM_IN0_CON8, + REG_AFIFO_MODE_MASK_SFT, + 0x0 << REG_AFIFO_MODE_SFT); + regmap_update_bits(afe->regmap, ETDM_IN0_CON9, + REG_ALMOST_END_CH_COUNT_MASK_SFT, + 0x0 << REG_ALMOST_END_CH_COUNT_SFT); + regmap_update_bits(afe->regmap, ETDM_IN0_CON9, + REG_ALMOST_END_BIT_COUNT_MASK_SFT, + 0x0 << REG_ALMOST_END_BIT_COUNT_SFT); + regmap_update_bits(afe->regmap, ETDM_IN0_CON9, + REG_OUT2LATCH_TIME_MASK_SFT, + 0x6 << REG_OUT2LATCH_TIME_SFT); + + /* 5: TDM Mode */ + regmap_update_bits(afe->regmap, ETDM_IN0_CON0, + REG_FMT_MASK_SFT, 0x0 << REG_FMT_SFT); + + /* APLL */ + regmap_update_bits(afe->regmap, ETDM_IN0_CON0, + REG_RELATCH_1X_EN_DOMAIN_SEL_MASK_SFT, + ETDM_RELATCH_SEL_APLL + << REG_RELATCH_1X_EN_DOMAIN_SEL_SFT); + regmap_update_bits(afe->regmap, ETDM_IN0_CON0, + REG_BIT_LENGTH_MASK_SFT, + get_etdm_lrck_width(format) << + REG_BIT_LENGTH_SFT); + regmap_update_bits(afe->regmap, ETDM_IN0_CON0, + REG_WORD_LENGTH_MASK_SFT, + get_etdm_wlen(format) << + REG_WORD_LENGTH_SFT); + + /* ---etdm cowork --- */ + regmap_update_bits(afe->regmap, ETDM_0_3_COWORK_CON0, + ETDM_IN0_SLAVE_SEL_MASK_SFT, + ETDM_SLAVE_SEL_ETDMOUT0_MASTER + << ETDM_IN0_SLAVE_SEL_SFT); + break; + case MT8189_DAI_I2S_IN1: + /* ---etdm in --- */ + regmap_update_bits(afe->regmap, ETDM_IN1_CON1, + REG_INITIAL_COUNT_MASK_SFT, + 0x5 << REG_INITIAL_COUNT_SFT); + /* 3: pad top 5: no pad top */ + regmap_update_bits(afe->regmap, ETDM_IN1_CON1, + REG_INITIAL_POINT_MASK_SFT, + 0x5 << REG_INITIAL_POINT_SFT); + regmap_update_bits(afe->regmap, ETDM_IN1_CON1, + REG_LRCK_RESET_MASK_SFT, + 0x1 << REG_LRCK_RESET_SFT); + regmap_update_bits(afe->regmap, ETDM_IN1_CON2, + REG_CLOCK_SOURCE_SEL_MASK_SFT, + ETDM_CLK_SOURCE_APLL << + REG_CLOCK_SOURCE_SEL_SFT); + /* 0: manual 1: auto */ + regmap_update_bits(afe->regmap, ETDM_IN1_CON2, + REG_CK_EN_SEL_AUTO_MASK_SFT, + 0x1 << REG_CK_EN_SEL_AUTO_SFT); + regmap_update_bits(afe->regmap, ETDM_IN1_CON3, + REG_FS_TIMING_SEL_MASK_SFT, + get_etdm_rate(rate) << + REG_FS_TIMING_SEL_SFT); + regmap_update_bits(afe->regmap, ETDM_IN1_CON4, + REG_RELATCH_1X_EN_SEL_MASK_SFT, + get_etdm_inconn_rate(rate) << + REG_RELATCH_1X_EN_SEL_SFT); + + regmap_update_bits(afe->regmap, ETDM_IN1_CON8, + REG_ETDM_USE_AFIFO_MASK_SFT, + 0x0 << REG_ETDM_USE_AFIFO_SFT); + regmap_update_bits(afe->regmap, ETDM_IN1_CON8, + REG_AFIFO_MODE_MASK_SFT, + 0x0 << REG_AFIFO_MODE_SFT); + regmap_update_bits(afe->regmap, ETDM_IN1_CON9, + REG_ALMOST_END_CH_COUNT_MASK_SFT, + 0x0 << REG_ALMOST_END_CH_COUNT_SFT); + regmap_update_bits(afe->regmap, ETDM_IN1_CON9, + REG_ALMOST_END_BIT_COUNT_MASK_SFT, + 0x0 << REG_ALMOST_END_BIT_COUNT_SFT); + regmap_update_bits(afe->regmap, ETDM_IN1_CON9, + REG_OUT2LATCH_TIME_MASK_SFT, + 0x6 << REG_OUT2LATCH_TIME_SFT); + + /* 5: TDM Mode */ + regmap_update_bits(afe->regmap, ETDM_IN1_CON0, + REG_FMT_MASK_SFT, 0x0 << REG_FMT_SFT); + + /* APLL */ + regmap_update_bits(afe->regmap, ETDM_IN1_CON0, + REG_RELATCH_1X_EN_DOMAIN_SEL_MASK_SFT, + ETDM_RELATCH_SEL_APLL + << REG_RELATCH_1X_EN_DOMAIN_SEL_SFT); + regmap_update_bits(afe->regmap, ETDM_IN1_CON0, + REG_BIT_LENGTH_MASK_SFT, + get_etdm_lrck_width(format) << + REG_BIT_LENGTH_SFT); + regmap_update_bits(afe->regmap, ETDM_IN1_CON0, + REG_WORD_LENGTH_MASK_SFT, + get_etdm_wlen(format) << + REG_WORD_LENGTH_SFT); + + /* ---etdm cowork --- */ + regmap_update_bits(afe->regmap, ETDM_0_3_COWORK_CON1, + ETDM_IN1_SLAVE_SEL_MASK_SFT, + ETDM_SLAVE_SEL_ETDMOUT1_MASTER + << ETDM_IN1_SLAVE_SEL_SFT); + break; + case MT8189_DAI_I2S_OUT0: + /* ---etdm out --- */ + regmap_update_bits(afe->regmap, ETDM_OUT0_CON1, + OUT_REG_INITIAL_COUNT_MASK_SFT, + 0x5 << OUT_REG_INITIAL_COUNT_SFT); + regmap_update_bits(afe->regmap, ETDM_OUT0_CON1, + OUT_REG_INITIAL_POINT_MASK_SFT, + 0x6 << OUT_REG_INITIAL_POINT_SFT); + regmap_update_bits(afe->regmap, ETDM_OUT0_CON1, + OUT_REG_LRCK_RESET_MASK_SFT, + 0x1 << OUT_REG_LRCK_RESET_SFT); + regmap_update_bits(afe->regmap, ETDM_OUT0_CON4, + OUT_REG_FS_TIMING_SEL_MASK_SFT, + get_etdm_rate(rate) << + OUT_REG_FS_TIMING_SEL_SFT); + regmap_update_bits(afe->regmap, ETDM_OUT0_CON4, + OUT_REG_CLOCK_SOURCE_SEL_MASK_SFT, + ETDM_CLK_SOURCE_APLL << + OUT_REG_CLOCK_SOURCE_SEL_SFT); + regmap_update_bits(afe->regmap, ETDM_OUT0_CON4, + OUT_REG_RELATCH_EN_SEL_MASK_SFT, + get_etdm_inconn_rate(rate) << + OUT_REG_RELATCH_EN_SEL_SFT); + /* 5: TDM Mode */ + regmap_update_bits(afe->regmap, ETDM_OUT0_CON0, + OUT_REG_FMT_MASK_SFT, + 0x0 << OUT_REG_FMT_SFT); + + /* APLL */ + regmap_update_bits(afe->regmap, ETDM_OUT0_CON0, + OUT_REG_RELATCH_DOMAIN_SEL_MASK_SFT, + ETDM_RELATCH_SEL_APLL + << OUT_REG_RELATCH_DOMAIN_SEL_SFT); + regmap_update_bits(afe->regmap, ETDM_OUT0_CON0, + OUT_REG_BIT_LENGTH_MASK_SFT, + get_etdm_lrck_width(format) << + OUT_REG_BIT_LENGTH_SFT); + regmap_update_bits(afe->regmap, ETDM_OUT0_CON0, + OUT_REG_WORD_LENGTH_MASK_SFT, + get_etdm_wlen(format) << + OUT_REG_WORD_LENGTH_SFT); + + /* ---etdm cowork --- */ + regmap_update_bits(afe->regmap, ETDM_0_3_COWORK_CON0, + ETDM_OUT0_SLAVE_SEL_MASK_SFT, + ETDM_SLAVE_SEL_ETDMIN0_MASTER + << ETDM_OUT0_SLAVE_SEL_SFT); + break; + case MT8189_DAI_I2S_OUT1: + /* ---etdm out --- */ + regmap_update_bits(afe->regmap, ETDM_OUT1_CON1, + OUT_REG_INITIAL_COUNT_MASK_SFT, + 0x5 << OUT_REG_INITIAL_COUNT_SFT); + regmap_update_bits(afe->regmap, ETDM_OUT1_CON1, + OUT_REG_INITIAL_POINT_MASK_SFT, + 0x6 << OUT_REG_INITIAL_POINT_SFT); + regmap_update_bits(afe->regmap, ETDM_OUT1_CON1, + OUT_REG_LRCK_RESET_MASK_SFT, + 0x1 << OUT_REG_LRCK_RESET_SFT); + regmap_update_bits(afe->regmap, ETDM_OUT1_CON4, + OUT_REG_FS_TIMING_SEL_MASK_SFT, + get_etdm_rate(rate) << + OUT_REG_FS_TIMING_SEL_SFT); + regmap_update_bits(afe->regmap, ETDM_OUT1_CON4, + OUT_REG_CLOCK_SOURCE_SEL_MASK_SFT, + ETDM_CLK_SOURCE_APLL << + OUT_REG_CLOCK_SOURCE_SEL_SFT); + regmap_update_bits(afe->regmap, ETDM_OUT1_CON4, + OUT_REG_RELATCH_EN_SEL_MASK_SFT, + get_etdm_inconn_rate(rate) << + OUT_REG_RELATCH_EN_SEL_SFT); + /* 5: TDM Mode */ + regmap_update_bits(afe->regmap, ETDM_OUT1_CON0, + OUT_REG_FMT_MASK_SFT, + 0x0 << OUT_REG_FMT_SFT); + + /* APLL */ + regmap_update_bits(afe->regmap, ETDM_OUT1_CON0, + OUT_REG_RELATCH_DOMAIN_SEL_MASK_SFT, + ETDM_RELATCH_SEL_APLL + << OUT_REG_RELATCH_DOMAIN_SEL_SFT); + regmap_update_bits(afe->regmap, ETDM_OUT1_CON0, + OUT_REG_BIT_LENGTH_MASK_SFT, + get_etdm_lrck_width(format) << + OUT_REG_BIT_LENGTH_SFT); + regmap_update_bits(afe->regmap, ETDM_OUT1_CON0, + OUT_REG_WORD_LENGTH_MASK_SFT, + get_etdm_wlen(format) << + OUT_REG_WORD_LENGTH_SFT); + + /* ---etdm cowork --- */ + regmap_update_bits(afe->regmap, ETDM_0_3_COWORK_CON0, + ETDM_OUT1_SLAVE_SEL_MASK_SFT, + ETDM_SLAVE_SEL_ETDMIN1_MASTER + << ETDM_OUT1_SLAVE_SEL_SFT); + break; + case MT8189_DAI_I2S_OUT4: + /* ---etdm out --- */ + regmap_update_bits(afe->regmap, ETDM_OUT4_CON1, + OUT_REG_INITIAL_COUNT_MASK_SFT, + 0x5 << OUT_REG_INITIAL_COUNT_SFT); + regmap_update_bits(afe->regmap, ETDM_OUT4_CON1, + OUT_REG_INITIAL_POINT_MASK_SFT, + 0x6 << OUT_REG_INITIAL_POINT_SFT); + regmap_update_bits(afe->regmap, ETDM_OUT4_CON1, + OUT_REG_LRCK_RESET_MASK_SFT, + 0x1 << OUT_REG_LRCK_RESET_SFT); + regmap_update_bits(afe->regmap, ETDM_OUT4_CON4, + OUT_REG_FS_TIMING_SEL_MASK_SFT, + get_etdm_rate(rate) << + OUT_REG_FS_TIMING_SEL_SFT); + regmap_update_bits(afe->regmap, ETDM_OUT4_CON4, + OUT_REG_CLOCK_SOURCE_SEL_MASK_SFT, + ETDM_CLK_SOURCE_APLL << + OUT_REG_CLOCK_SOURCE_SEL_SFT); + regmap_update_bits(afe->regmap, ETDM_OUT4_CON4, + OUT_REG_RELATCH_EN_SEL_MASK_SFT, + get_etdm_inconn_rate(rate) << + OUT_REG_RELATCH_EN_SEL_SFT); + /* 5: TDM Mode */ + regmap_update_bits(afe->regmap, ETDM_OUT4_CON0, + OUT_REG_FMT_MASK_SFT, + 0x0 << OUT_REG_FMT_SFT); + + /* APLL */ + regmap_update_bits(afe->regmap, ETDM_OUT4_CON0, + OUT_REG_RELATCH_DOMAIN_SEL_MASK_SFT, + ETDM_RELATCH_SEL_APLL + << OUT_REG_RELATCH_DOMAIN_SEL_SFT); + regmap_update_bits(afe->regmap, ETDM_OUT4_CON0, + OUT_REG_BIT_LENGTH_MASK_SFT, + get_etdm_lrck_width(format) << + OUT_REG_BIT_LENGTH_SFT); + regmap_update_bits(afe->regmap, ETDM_OUT4_CON0, + OUT_REG_WORD_LENGTH_MASK_SFT, + get_etdm_wlen(format) << + OUT_REG_WORD_LENGTH_SFT); + break; + default: + dev_err(afe->dev, "%s(), id %d not support\n", + __func__, i2s_id); + return -EINVAL; + } + + /* set share i2s */ + if (i2s_priv->share_i2s_id >= 0) { + ret = mtk_dai_i2s_config(afe, params, i2s_priv->share_i2s_id); + if (ret) + return ret; + } + + return 0; +} + +static int mtk_dai_i2s_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); + + return mtk_dai_i2s_config(afe, params, dai->id); +} + +static int mtk_dai_i2s_set_sysclk(struct snd_soc_dai *dai, + int clk_id, unsigned int freq, int dir) +{ + struct mtk_base_afe *afe = dev_get_drvdata(dai->dev); + struct mt8189_afe_private *afe_priv = afe->platform_priv; + struct mtk_afe_i2s_priv *i2s_priv; + int apll; + int apll_rate; + + if (dai->id >= MT8189_DAI_NUM || dai->id < 0 || + dir != SND_SOC_CLOCK_OUT) + return -EINVAL; + + i2s_priv = afe_priv->dai_priv[dai->id]; + if (!i2s_priv) + return -EINVAL; + + dev_dbg(afe->dev, "%s(), freq %d\n", __func__, freq); + + apll = mt8189_get_apll_by_rate(afe, freq); + apll_rate = mt8189_get_apll_rate(afe, apll); + + if (freq > apll_rate || apll_rate % freq) { + dev_err(afe->dev, "%s(), freq %d, apll_rate %d\n", + __func__, freq, apll_rate); + return -EINVAL; + } + + i2s_priv->mclk_rate = freq; + i2s_priv->mclk_apll = apll; + + if (i2s_priv->share_i2s_id > 0) { + struct mtk_afe_i2s_priv *share_i2s_priv; + + share_i2s_priv = afe_priv->dai_priv[i2s_priv->share_i2s_id]; + if (!share_i2s_priv) + return -EINVAL; + + share_i2s_priv->mclk_rate = i2s_priv->mclk_rate; + share_i2s_priv->mclk_apll = i2s_priv->mclk_apll; + } + + return 0; +} + +static const struct snd_soc_dai_ops mtk_dai_i2s_ops = { + .hw_params = mtk_dai_i2s_hw_params, + .set_sysclk = mtk_dai_i2s_set_sysclk, +}; + +/* dai driver */ +#define MTK_ETDM_RATES (SNDRV_PCM_RATE_8000_192000) +#define MTK_ETDM_FORMATS (SNDRV_PCM_FMTBIT_S8 |\ + SNDRV_PCM_FMTBIT_S16_LE |\ + SNDRV_PCM_FMTBIT_S24_LE |\ + SNDRV_PCM_FMTBIT_S32_LE) + +#define MT8189_I2S_DAI(_name, _id, max_ch, dir) \ +{ \ + .name = #_name, \ + .id = _id, \ + .dir = { \ + .stream_name = #_name, \ + .channels_min = 1, \ + .channels_max = max_ch, \ + .rates = MTK_ETDM_RATES, \ + .formats = MTK_ETDM_FORMATS, \ + }, \ + .ops = &mtk_dai_i2s_ops, \ +} + +static struct snd_soc_dai_driver mtk_dai_i2s_driver[] = { + /* capture */ + MT8189_I2S_DAI(I2SIN0, MT8189_DAI_I2S_IN0, 2, capture), + MT8189_I2S_DAI(I2SIN1, MT8189_DAI_I2S_IN1, 2, capture), + /* playback */ + MT8189_I2S_DAI(I2SOUT0, MT8189_DAI_I2S_OUT0, 2, playback), + MT8189_I2S_DAI(I2SOUT1, MT8189_DAI_I2S_OUT1, 2, playback), + MT8189_I2S_DAI(I2SOUT4, MT8189_DAI_I2S_OUT4, 8, playback), +}; + +static const struct mtk_afe_i2s_priv mt8189_i2s_priv[DAI_I2S_NUM] = { + [DAI_I2SIN0] = { + .id = MT8189_DAI_I2S_IN0, + .mclk_id = MT8189_I2SIN0_MCK, + .share_property_name = "i2sin0-share", + .share_i2s_id = MT8189_DAI_I2S_OUT0, + }, + [DAI_I2SIN1] = { + .id = MT8189_DAI_I2S_IN1, + .mclk_id = MT8189_I2SIN1_MCK, + .share_property_name = "i2sin1-share", + .share_i2s_id = MT8189_DAI_I2S_OUT1, + }, + [DAI_I2SOUT0] = { + .id = MT8189_DAI_I2S_OUT0, + .mclk_id = MT8189_I2SOUT0_MCK, + .share_property_name = "i2sout0-share", + .share_i2s_id = -1, + }, + [DAI_I2SOUT1] = { + .id = MT8189_DAI_I2S_OUT1, + .mclk_id = MT8189_I2SOUT1_MCK, + .share_property_name = "i2sout1-share", + .share_i2s_id = -1, + }, + [DAI_I2SOUT4] = { + .id = MT8189_DAI_I2S_OUT4, + .mclk_id = MT8189_I2SIN1_MCK, + .share_property_name = "i2sout4-share", + .share_i2s_id = -1, + }, +}; + +static int mt8189_dai_i2s_get_share(struct mtk_base_afe *afe) +{ + struct mt8189_afe_private *afe_priv = afe->platform_priv; + const struct device_node *of_node = afe->dev->of_node; + + for (int i = 0; i < DAI_I2S_NUM; i++) { + const char *of_str; + struct mtk_afe_i2s_priv *i2s_priv = + afe_priv->dai_priv[mt8189_i2s_priv[i].id]; + const char *property_name = + mt8189_i2s_priv[i].share_property_name; + + if (of_property_read_string(of_node, property_name, &of_str)) + continue; + + i2s_priv->share_i2s_id = get_i2s_id_by_name(afe, of_str); + } + + return 0; +} + +static int init_i2s_priv_data(struct mtk_base_afe *afe) +{ + struct mt8189_afe_private *afe_priv = afe->platform_priv; + struct mtk_afe_i2s_priv *i2s_priv; + + for (int i = 0; i < DAI_I2S_NUM; i++) { + int id = mt8189_i2s_priv[i].id; + size_t size = sizeof(struct mtk_afe_i2s_priv); + + if (id >= MT8189_DAI_NUM || id < 0) + return -EINVAL; + + i2s_priv = devm_kzalloc(afe->dev, size, GFP_KERNEL); + if (!i2s_priv) + return -ENOMEM; + + memcpy(i2s_priv, &mt8189_i2s_priv[i], size); + + afe_priv->dai_priv[id] = i2s_priv; + } + + return 0; +} + +int mt8189_dai_i2s_register(struct mtk_base_afe *afe) +{ + struct mtk_base_afe_dai *dai; + int ret; + + dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL); + if (!dai) + return -ENOMEM; + + dai->dai_drivers = mtk_dai_i2s_driver; + dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_i2s_driver); + + dai->controls = mtk_dai_i2s_controls; + dai->num_controls = ARRAY_SIZE(mtk_dai_i2s_controls); + dai->dapm_widgets = mtk_dai_i2s_widgets; + dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_i2s_widgets); + dai->dapm_routes = mtk_dai_i2s_routes; + dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_i2s_routes); + + /* set all dai i2s private data */ + ret = init_i2s_priv_data(afe); + if (ret) + return ret; + + /* parse share i2s */ + ret = mt8189_dai_i2s_get_share(afe); + if (ret) + return ret; + + list_add(&dai->list, &afe->sub_dais); + + return 0; +} diff --git a/sound/soc/mediatek/mt8189/mt8189-dai-pcm.c b/sound/soc/mediatek/mt8189/mt8189-dai-pcm.c new file mode 100644 index 00000000000000..21317c0413e5c7 --- /dev/null +++ b/sound/soc/mediatek/mt8189/mt8189-dai-pcm.c @@ -0,0 +1,332 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * MediaTek ALSA SoC Audio DAI I2S Control + * + * Copyright (c) 2025 MediaTek Inc. + * Author: Darren Ye + */ + +#include + +#include + +#include "mt8189-afe-common.h" +#include "mt8189-interconnection.h" +#include "mt8189-afe-clk.h" + +enum AUD_TX_LCH_RPT { + AUD_TX_LCH_RPT_NO_REPEAT, + AUD_TX_LCH_RPT_REPEAT +}; + +enum AUD_VBT_16K_MODE { + AUD_VBT_16K_MODE_DISABLE, + AUD_VBT_16K_MODE_ENABLE +}; + +enum AUD_EXT_MODEM { + AUD_EXT_MODEM_SELECT_INTERNAL, + AUD_EXT_MODEM_SELECT_EXTERNAL +}; + +enum AUD_PCM_SYNC_TYPE { + /* bck sync length = 1 */ + AUD_PCM_ONE_BCK_CYCLE_SYNC, + /* bck sync length = PCM_INTF_CON1[9:13] */ + AUD_PCM_EXTENDED_BCK_CYCLE_SYNC +}; + +enum AUD_BT_MODE { + AUD_BT_MODE_DUAL_MIC_ON_TX, + AUD_BT_MODE_SINGLE_MIC_ON_TX +}; + +enum AUD_PCM_AFIFO_SRC { + /* slave mode & external modem uses different crystal */ + AUD_PCM_AFIFO_ASRC, + /* slave mode & external modem uses the same crystal */ + AUD_PCM_AFIFO_AFIFO +}; + +enum AUD_PCM_CLOCK_SOURCE { + AUD_PCM_CLOCK_MASTER_MODE, + AUD_PCM_CLOCK_SLAVE_MODE +}; + +enum AUD_PCM_WLEN { + AUD_PCM_WLEN_PCM_32_BCK_CYCLES, + AUD_PCM_WLEN_PCM_64_BCK_CYCLES +}; + +enum AUD_PCM_MODE { + AUD_PCM_MODE_PCM_MODE_8K, + AUD_PCM_MODE_PCM_MODE_16K, + AUD_PCM_MODE_PCM_MODE_32K, + AUD_PCM_MODE_PCM_MODE_48K +}; + +enum AUD_PCM_FMT { + AUD_PCM_FMT_I2S, + AUD_PCM_FMT_EIAJ, + AUD_PCM_FMT_PCM_MODE_A, + AUD_PCM_FMT_PCM_MODE_B +}; + +enum AUD_BCLK_OUT_INV { + AUD_BCLK_OUT_INV_NO_INVERSE, + AUD_BCLK_OUT_INV_INVERSE +}; + +enum AUD_PCM_EN { + AUD_PCM_EN_DISABLE, + AUD_PCM_EN_ENABLE +}; + +enum AUD_PCM1_1X_EN_DOMAIN { + HOPPING_26M, + APLL, + SLAVE = 6 +}; + +enum AUD_PCM1_1X_EN_SLAVE_MODE { + PCM0_SLAVE_1X_EN, + PCM1_SLAVE_1X_EN +}; + +enum { + PCM_8K, + PCM_16K = 4, + PCM_32K = 8, + PCM_48K = 10 +}; + +static unsigned int pcm_1x_rate_transform(struct device *dev, + unsigned int rate) +{ + switch (rate) { + case 8000: + return PCM_8K; + case 16000: + return PCM_16K; + case 32000: + return PCM_32K; + case 48000: + return PCM_48K; + default: + dev_warn(dev, "rate %u invalid, use %d!!!\n", + rate, PCM_48K); + return PCM_48K; + } +} + +static unsigned int pcm_rate_transform(struct device *dev, + unsigned int rate) +{ + switch (rate) { + case 8000: + return MTK_AFE_PCM_RATE_8K; + case 16000: + return MTK_AFE_PCM_RATE_16K; + case 32000: + return MTK_AFE_PCM_RATE_32K; + case 48000: + return MTK_AFE_PCM_RATE_48K; + default: + dev_warn(dev, "rate %u invalid, use %d\n", + rate, MTK_AFE_PCM_RATE_48K); + return MTK_AFE_PCM_RATE_48K; + } +} + +/* dai component */ +static const struct snd_kcontrol_new mtk_pcm_0_playback_ch1_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN096_0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1", AFE_CONN096_1, + I_DL2_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH1", AFE_CONN096_1, + I_DL_24CH_CH1, 1, 0), +}; + +static const struct snd_kcontrol_new mtk_pcm_0_playback_ch2_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN097_0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2", AFE_CONN097_1, + I_DL2_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH2", AFE_CONN097_1, + I_DL_24CH_CH2, 1, 0), +}; + +static const struct snd_kcontrol_new mtk_pcm_0_playback_ch4_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("I2SIN1_CH1", AFE_CONN099_4, + I_I2SIN1_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I2SIN1_CH2", AFE_CONN099_4, + I_I2SIN1_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL0_CH1", AFE_CONN099_1, + I_DL0_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH1", AFE_CONN099_1, + I_DL_24CH_CH1, 1, 0), +}; + +static const struct snd_soc_dapm_widget mtk_dai_pcm_widgets[] = { + /* inter-connections */ + SND_SOC_DAPM_MIXER("PCM_0_PB_CH1", SND_SOC_NOPM, 0, 0, + mtk_pcm_0_playback_ch1_mix, + ARRAY_SIZE(mtk_pcm_0_playback_ch1_mix)), + SND_SOC_DAPM_MIXER("PCM_0_PB_CH2", SND_SOC_NOPM, 0, 0, + mtk_pcm_0_playback_ch2_mix, + ARRAY_SIZE(mtk_pcm_0_playback_ch2_mix)), + SND_SOC_DAPM_MIXER("PCM_0_PB_CH4", SND_SOC_NOPM, 0, 0, + mtk_pcm_0_playback_ch4_mix, + ARRAY_SIZE(mtk_pcm_0_playback_ch4_mix)), + + SND_SOC_DAPM_SUPPLY("PCM_0_EN", + AFE_PCM0_INTF_CON0, PCM0_EN_SFT, 0, + NULL, 0), + + SND_SOC_DAPM_SUPPLY("PCM0_CG", AUDIO_TOP_CON0, PDN_PCM0_SFT, 1, + NULL, 0), + + SND_SOC_DAPM_INPUT("AFE_PCM_INPUT"), + SND_SOC_DAPM_OUTPUT("AFE_PCM_OUTPUT"), +}; + +static const struct snd_soc_dapm_route mtk_dai_pcm_routes[] = { + {"PCM 0 Playback", NULL, "PCM_0_PB_CH1"}, + {"PCM 0 Playback", NULL, "PCM_0_PB_CH2"}, + {"PCM 0 Playback", NULL, "PCM_0_PB_CH4"}, + + {"PCM 0 Playback", NULL, "PCM_0_EN"}, + {"PCM 0 Capture", NULL, "PCM_0_EN"}, + {"PCM 0 Playback", NULL, "PCM0_CG"}, + {"PCM 0 Capture", NULL, "PCM0_CG"}, + + {"AFE_PCM_OUTPUT", NULL, "PCM 0 Playback"}, + {"PCM 0 Capture", NULL, "AFE_PCM_INPUT"}, + + {"PCM_0_PB_CH1", "DL2_CH1", "DL2"}, + {"PCM_0_PB_CH2", "DL2_CH2", "DL2"}, + {"PCM_0_PB_CH4", "DL0_CH1", "DL0"}, + + {"PCM_0_PB_CH1", "DL_24CH_CH1", "DL_24CH"}, + {"PCM_0_PB_CH2", "DL_24CH_CH2", "DL_24CH"}, + {"PCM_0_PB_CH4", "DL_24CH_CH1", "DL_24CH"}, +}; + +/* dai ops */ +static int mtk_dai_pcm_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); + unsigned int rate = params_rate(params); + unsigned int rate_reg = pcm_rate_transform(afe->dev, rate); + unsigned int x_rate_reg = pcm_1x_rate_transform(afe->dev, rate); + unsigned int pcm_con0; + unsigned int pcm_con1; + unsigned int playback_active = 0; + unsigned int capture_active = 0; + struct snd_soc_dapm_widget *playback_widget = + snd_soc_dai_get_widget(dai, SNDRV_PCM_STREAM_PLAYBACK); + struct snd_soc_dapm_widget *capture_widget = + snd_soc_dai_get_widget(dai, SNDRV_PCM_STREAM_CAPTURE); + + if (playback_widget) + playback_active = playback_widget->active; + if (capture_widget) + capture_active = capture_widget->active; + dev_dbg(afe->dev, + "id %d, stream %d, rate %d, rate_reg %d, active p %d, c %d\n", + dai->id, substream->stream, rate, rate_reg, + playback_active, capture_active); + + if (playback_active || capture_active) + return 0; + switch (dai->id) { + case MT8189_DAI_PCM_0: + pcm_con0 = AUD_BCLK_OUT_INV_NO_INVERSE << PCM0_BCLK_OUT_INV_SFT; + pcm_con0 |= AUD_TX_LCH_RPT_NO_REPEAT << PCM0_TX_LCH_RPT_SFT; + pcm_con0 |= AUD_VBT_16K_MODE_DISABLE << PCM0_VBT_16K_MODE_SFT; + pcm_con0 |= 0 << PCM0_SYNC_LENGTH_SFT; + pcm_con0 |= AUD_PCM_ONE_BCK_CYCLE_SYNC << PCM0_SYNC_TYPE_SFT; + pcm_con0 |= AUD_PCM_AFIFO_AFIFO << PCM0_BYP_ASRC_SFT; + pcm_con0 |= AUD_PCM_CLOCK_MASTER_MODE << PCM0_SLAVE_SFT; + pcm_con0 |= rate_reg << PCM0_MODE_SFT; + pcm_con0 |= AUD_PCM_FMT_I2S << PCM0_FMT_SFT; + + pcm_con1 = AUD_EXT_MODEM_SELECT_INTERNAL << PCM0_EXT_MODEM_SFT; + pcm_con1 |= AUD_BT_MODE_DUAL_MIC_ON_TX << PCM0_BT_MODE_SFT; + pcm_con1 |= HOPPING_26M << PCM0_1X_EN_DOMAIN_SFT; + pcm_con1 |= x_rate_reg << PCM0_1X_EN_MODE_SFT; + + regmap_update_bits(afe->regmap, AFE_PCM0_INTF_CON0, + ~(unsigned int)PCM0_EN_MASK_SFT, pcm_con0); + regmap_update_bits(afe->regmap, AFE_PCM0_INTF_CON1, + AFE_PCM0_INTF_CON1_MASK_MON_MASK_SFT, + pcm_con1); + break; + default: + dev_err(afe->dev, "%s(), id %d not support\n", + __func__, dai->id); + return -EINVAL; + } + return 0; +} + +static const struct snd_soc_dai_ops mtk_dai_pcm_ops = { + .hw_params = mtk_dai_pcm_hw_params, +}; + +/* dai driver */ +#define MTK_PCM_RATES (SNDRV_PCM_RATE_8000 |\ + SNDRV_PCM_RATE_16000 |\ + SNDRV_PCM_RATE_32000 |\ + SNDRV_PCM_RATE_48000) + +#define MTK_PCM_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ + SNDRV_PCM_FMTBIT_S24_LE |\ + SNDRV_PCM_FMTBIT_S32_LE) + +static struct snd_soc_dai_driver mtk_dai_pcm_driver[] = { + { + .name = "PCM 0", + .id = MT8189_DAI_PCM_0, + .playback = { + .stream_name = "PCM 0 Playback", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_PCM_RATES, + .formats = MTK_PCM_FORMATS, + }, + .capture = { + .stream_name = "PCM 0 Capture", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_PCM_RATES, + .formats = MTK_PCM_FORMATS, + }, + .ops = &mtk_dai_pcm_ops, + .symmetric_rate = 1, + .symmetric_sample_bits = 1, + }, +}; + +int mt8189_dai_pcm_register(struct mtk_base_afe *afe) +{ + struct mtk_base_afe_dai *dai; + + dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL); + if (!dai) + return -ENOMEM; + + dai->dai_drivers = mtk_dai_pcm_driver; + dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_pcm_driver); + dai->dapm_widgets = mtk_dai_pcm_widgets; + dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_pcm_widgets); + dai->dapm_routes = mtk_dai_pcm_routes; + dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_pcm_routes); + + list_add(&dai->list, &afe->sub_dais); + + return 0; +} diff --git a/sound/soc/mediatek/mt8189/mt8189-dai-tdm.c b/sound/soc/mediatek/mt8189/mt8189-dai-tdm.c new file mode 100644 index 00000000000000..5d68a55ccc45cd --- /dev/null +++ b/sound/soc/mediatek/mt8189/mt8189-dai-tdm.c @@ -0,0 +1,672 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * MediaTek ALSA SoC Audio DAI TDM Control + * + * Copyright (c) 2025 MediaTek Inc. + * Author: Darren Ye + */ + +#include + +#include + +#include "mt8189-afe-clk.h" +#include "mt8189-afe-common.h" +#include "mt8189-interconnection.h" + +#define DPTX_CH_EN_MASK_2CH (0x3) +#define DPTX_CH_EN_MASK_4CH (0xf) +#define DPTX_CH_EN_MASK_6CH (0x3f) +#define DPTX_CH_EN_MASK_8CH (0xff) + +enum { + SUPPLY_SEQ_APLL, + SUPPLY_SEQ_TDM_MCK_EN, + SUPPLY_SEQ_TDM_BCK_EN, + SUPPLY_SEQ_TDM_DPTX_MCK_EN, + SUPPLY_SEQ_TDM_DPTX_BCK_EN, + SUPPLY_SEQ_TDM_CG_EN, +}; + +enum { + TDM_WLEN_8_BIT, + TDM_WLEN_16_BIT, + TDM_WLEN_24_BIT, + TDM_WLEN_32_BIT, +}; + +enum { + TDM_CHANNEL_BCK_16, + TDM_CHANNEL_BCK_24, + TDM_CHANNEL_BCK_32 +}; + +enum { + TDM_CHANNEL_NUM_2, + TDM_CHANNEL_NUM_4, + TDM_CHANNEL_NUM_8 +}; + +enum { + TDM_CH_START_O30_O31, + TDM_CH_START_O32_O33, + TDM_CH_START_O34_O35, + TDM_CH_START_O36_O37, + TDM_CH_ZERO, +}; + +enum { + DPTX_CHANNEL_2, + DPTX_CHANNEL_8, +}; + +enum { + DPTX_WLEN_24_BIT, + DPTX_WLEN_16_BIT, +}; + +struct mtk_afe_tdm_priv { + int bck_id; + int bck_rate; + + int mclk_id; + int mclk_multiple; /* according to sample rate */ + int mclk_rate; + int mclk_apll; +}; + +static unsigned int get_tdm_wlen(snd_pcm_format_t format) +{ + return snd_pcm_format_physical_width(format) <= 16 ? + TDM_WLEN_16_BIT : TDM_WLEN_32_BIT; +} + +static unsigned int get_tdm_channel_bck(snd_pcm_format_t format) +{ + return snd_pcm_format_physical_width(format) <= 16 ? + TDM_CHANNEL_BCK_16 : TDM_CHANNEL_BCK_32; +} + +static unsigned int get_tdm_lrck_width(snd_pcm_format_t format) +{ + return snd_pcm_format_physical_width(format) - 1; +} + +static unsigned int get_tdm_ch(unsigned int ch) +{ + switch (ch) { + case 1: + case 2: + return TDM_CHANNEL_NUM_2; + case 3: + case 4: + return TDM_CHANNEL_NUM_4; + case 5: + case 6: + case 7: + case 8: + default: + return TDM_CHANNEL_NUM_8; + } +} + +static unsigned int get_dptx_ch_enable_mask(unsigned int ch) +{ + switch (ch) { + case 1: + case 2: + return DPTX_CH_EN_MASK_2CH; + case 3: + case 4: + return DPTX_CH_EN_MASK_4CH; + case 5: + case 6: + return DPTX_CH_EN_MASK_6CH; + case 7: + case 8: + return DPTX_CH_EN_MASK_8CH; + default: + return DPTX_CH_EN_MASK_2CH; + } +} + +static unsigned int get_dptx_ch(unsigned int ch) +{ + if (ch == 2) + return DPTX_CHANNEL_2; + + return DPTX_CHANNEL_8; +} + +static unsigned int get_dptx_wlen(snd_pcm_format_t format) +{ + return snd_pcm_format_physical_width(format) <= 16 ? + DPTX_WLEN_16_BIT : DPTX_WLEN_24_BIT; +} + +/* interconnection */ +enum { + HDMI_CONN_CH0, + HDMI_CONN_CH1, + HDMI_CONN_CH2, + HDMI_CONN_CH3, + HDMI_CONN_CH4, + HDMI_CONN_CH5, + HDMI_CONN_CH6, + HDMI_CONN_CH7, +}; + +static const char *const hdmi_conn_mux_map[] = { + "CH0", "CH1", "CH2", "CH3", "CH4", "CH5", "CH6", "CH7", +}; + +static int hdmi_conn_mux_map_value[] = { + HDMI_CONN_CH0, HDMI_CONN_CH1, HDMI_CONN_CH2, HDMI_CONN_CH3, + HDMI_CONN_CH4, HDMI_CONN_CH5, HDMI_CONN_CH6, HDMI_CONN_CH7, +}; + +static SOC_VALUE_ENUM_SINGLE_DECL(hdmi_ch0_mux_map_enum, + AFE_HDMI_CONN0, + HDMI_O_0_SFT, + HDMI_O_0_MASK, + hdmi_conn_mux_map, + hdmi_conn_mux_map_value); + +static SOC_VALUE_ENUM_SINGLE_DECL(hdmi_ch1_mux_map_enum, + AFE_HDMI_CONN0, + HDMI_O_1_SFT, + HDMI_O_1_MASK, + hdmi_conn_mux_map, + hdmi_conn_mux_map_value); + +static SOC_VALUE_ENUM_SINGLE_DECL(hdmi_ch2_mux_map_enum, + AFE_HDMI_CONN0, + HDMI_O_2_SFT, + HDMI_O_2_MASK, + hdmi_conn_mux_map, + hdmi_conn_mux_map_value); + +static SOC_VALUE_ENUM_SINGLE_DECL(hdmi_ch3_mux_map_enum, + AFE_HDMI_CONN0, + HDMI_O_3_SFT, + HDMI_O_3_MASK, + hdmi_conn_mux_map, + hdmi_conn_mux_map_value); + +static SOC_VALUE_ENUM_SINGLE_DECL(hdmi_ch4_mux_map_enum, + AFE_HDMI_CONN0, + HDMI_O_4_SFT, + HDMI_O_4_MASK, + hdmi_conn_mux_map, + hdmi_conn_mux_map_value); + +static SOC_VALUE_ENUM_SINGLE_DECL(hdmi_ch5_mux_map_enum, + AFE_HDMI_CONN0, + HDMI_O_5_SFT, + HDMI_O_5_MASK, + hdmi_conn_mux_map, + hdmi_conn_mux_map_value); + +static SOC_VALUE_ENUM_SINGLE_DECL(hdmi_ch6_mux_map_enum, + AFE_HDMI_CONN0, + HDMI_O_6_SFT, + HDMI_O_6_MASK, + hdmi_conn_mux_map, + hdmi_conn_mux_map_value); + +static SOC_VALUE_ENUM_SINGLE_DECL(hdmi_ch7_mux_map_enum, + AFE_HDMI_CONN0, + HDMI_O_7_SFT, + HDMI_O_7_MASK, + hdmi_conn_mux_map, + hdmi_conn_mux_map_value); + +static const struct snd_kcontrol_new mtk_dai_tdm_controls[] = { + SOC_ENUM("HDMI_CH0_MUX", hdmi_ch0_mux_map_enum), + SOC_ENUM("HDMI_CH1_MUX", hdmi_ch1_mux_map_enum), + SOC_ENUM("HDMI_CH2_MUX", hdmi_ch2_mux_map_enum), + SOC_ENUM("HDMI_CH3_MUX", hdmi_ch3_mux_map_enum), + SOC_ENUM("HDMI_CH4_MUX", hdmi_ch4_mux_map_enum), + SOC_ENUM("HDMI_CH5_MUX", hdmi_ch5_mux_map_enum), + SOC_ENUM("HDMI_CH6_MUX", hdmi_ch6_mux_map_enum), + SOC_ENUM("HDMI_CH7_MUX", hdmi_ch7_mux_map_enum), +}; + +static const char *const tdm_out_demux_texts[] = { + "NONE", "TDMOUT", "DPTXOUT", +}; + +static SOC_ENUM_SINGLE_DECL(tdm_out_demux_enum, + SND_SOC_NOPM, + 0, + tdm_out_demux_texts); + +static const struct snd_kcontrol_new tdm_out_demux_control = + SOC_DAPM_ENUM("TDM Playback Route", tdm_out_demux_enum); + +static int get_tdm_id_by_name(const char *name) +{ + if (strstr(name, "DPTX")) + return MT8189_DAI_TDM_DPTX; + + return MT8189_DAI_TDM; +} + +static int mtk_tdm_bck_en_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8189_afe_private *afe_priv = afe->platform_priv; + int dai_id = get_tdm_id_by_name(w->name); + struct mtk_afe_tdm_priv *tdm_priv = afe_priv->dai_priv[dai_id]; + + dev_dbg(cmpnt->dev, "name %s, event 0x%x, dai_id %d, bck: %d\n", + w->name, event, dai_id, tdm_priv->bck_rate); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + mt8189_mck_enable(afe, tdm_priv->bck_id, tdm_priv->bck_rate); + break; + case SND_SOC_DAPM_POST_PMD: + mt8189_mck_disable(afe, tdm_priv->bck_id); + break; + default: + break; + } + + return 0; +} + +static int mtk_tdm_mck_en_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8189_afe_private *afe_priv = afe->platform_priv; + int dai_id = get_tdm_id_by_name(w->name); + struct mtk_afe_tdm_priv *tdm_priv = afe_priv->dai_priv[dai_id]; + + dev_dbg(cmpnt->dev, "name %s, event 0x%x, dai_id %d, mclk %d\n", + w->name, event, dai_id, tdm_priv->mclk_rate); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + mt8189_mck_enable(afe, tdm_priv->mclk_id, tdm_priv->mclk_rate); + break; + case SND_SOC_DAPM_POST_PMD: + tdm_priv->mclk_rate = 0; + mt8189_mck_disable(afe, tdm_priv->mclk_id); + break; + default: + break; + } + + return 0; +} + +static const struct snd_soc_dapm_widget mtk_dai_tdm_widgets[] = { + SND_SOC_DAPM_DEMUX("TDM Playback Route", SND_SOC_NOPM, 0, 0, + &tdm_out_demux_control), + + SND_SOC_DAPM_SUPPLY_S("TDM_BCK", SUPPLY_SEQ_TDM_BCK_EN, + SND_SOC_NOPM, 0, 0, + mtk_tdm_bck_en_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_SUPPLY_S("TDM_MCK", SUPPLY_SEQ_TDM_MCK_EN, + SND_SOC_NOPM, 0, 0, + mtk_tdm_mck_en_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_SUPPLY_S("TDM_DPTX_BCK", SUPPLY_SEQ_TDM_DPTX_BCK_EN, + SND_SOC_NOPM, 0, 0, + mtk_tdm_bck_en_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_SUPPLY_S("TDM_DPTX_MCK", SUPPLY_SEQ_TDM_DPTX_MCK_EN, + SND_SOC_NOPM, 0, 0, + mtk_tdm_mck_en_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_SUPPLY_S("TDM_CG", SUPPLY_SEQ_TDM_CG_EN, + AUDIO_TOP_CON2, PDN_TDM_OUT_SFT, 1, + NULL, 0), +}; + +static int mtk_afe_tdm_apll_connect(struct snd_soc_dapm_widget *source, + struct snd_soc_dapm_widget *sink) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(sink->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8189_afe_private *afe_priv = afe->platform_priv; + int dai_id = get_tdm_id_by_name(sink->name); + struct mtk_afe_tdm_priv *tdm_priv = afe_priv->dai_priv[dai_id]; + int cur_apll; + + /* which apll */ + cur_apll = mt8189_get_apll_by_name(afe, source->name); + + return (tdm_priv->mclk_apll == cur_apll) ? 1 : 0; +} + +static const struct snd_soc_dapm_route mtk_dai_tdm_routes[] = { + {"TDM Playback Route", NULL, "HDMI"}, + + {"TDM", "TDMOUT", "TDM Playback Route"}, + {"TDM", NULL, "TDM_BCK"}, + {"TDM", NULL, "TDM_CG"}, + + {"TDM_DPTX", "DPTXOUT", "TDM Playback Route"}, + {"TDM_DPTX", NULL, "TDM_DPTX_BCK"}, + {"TDM_DPTX", NULL, "TDM_CG"}, + + {"TDM_BCK", NULL, "TDM_MCK"}, + {"TDM_DPTX_BCK", NULL, "TDM_DPTX_MCK"}, + {"TDM_MCK", NULL, APLL1_W_NAME, mtk_afe_tdm_apll_connect}, + {"TDM_MCK", NULL, APLL2_W_NAME, mtk_afe_tdm_apll_connect}, + {"TDM_DPTX_MCK", NULL, APLL1_W_NAME, mtk_afe_tdm_apll_connect}, + {"TDM_DPTX_MCK", NULL, APLL2_W_NAME, mtk_afe_tdm_apll_connect}, +}; + +/* dai ops */ +static int mtk_dai_tdm_cal_mclk(struct mtk_base_afe *afe, + struct mtk_afe_tdm_priv *tdm_priv, + int freq) +{ + int apll; + int apll_rate; + + apll = mt8189_get_apll_by_rate(afe, freq); + apll_rate = mt8189_get_apll_rate(afe, apll); + + if (freq > apll_rate) + return -EINVAL; + + if (apll_rate % freq != 0) + return -EINVAL; + + tdm_priv->mclk_rate = freq; + tdm_priv->mclk_apll = apll; + + return 0; +} + +static int mtk_dai_tdm_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); + struct mt8189_afe_private *afe_priv = afe->platform_priv; + int tdm_id = dai->id; + struct mtk_afe_tdm_priv *tdm_priv; + unsigned int rate = params_rate(params); + unsigned int channels = params_channels(params); + snd_pcm_format_t format = params_format(params); + unsigned int tdm_con; + + if (tdm_id >= MT8189_DAI_NUM || tdm_id < 0) + return -EINVAL; + + tdm_priv = afe_priv->dai_priv[tdm_id]; + + /* calculate mclk_rate, if not set explicitly */ + if (!tdm_priv->mclk_rate) { + tdm_priv->mclk_rate = rate * tdm_priv->mclk_multiple; + mtk_dai_tdm_cal_mclk(afe, + tdm_priv, + tdm_priv->mclk_rate); + } + + /* calculate bck */ + tdm_priv->bck_rate = rate * + channels * + snd_pcm_format_physical_width(format); + + if (tdm_priv->bck_rate > tdm_priv->mclk_rate) + return -EINVAL; + + if (tdm_priv->mclk_rate % tdm_priv->bck_rate != 0) + return -EINVAL; + + dev_dbg(afe->dev, "id %d, rate %d, ch %d, fmt %d, mclk %d, bck %d\n", + tdm_id, rate, channels, format, + tdm_priv->mclk_rate, tdm_priv->bck_rate); + + /* set tdm */ + tdm_con = 1 << LEFT_ALIGN_SFT; + tdm_con |= get_tdm_wlen(format) << WLEN_SFT; + tdm_con |= get_tdm_ch(channels) << CHANNEL_NUM_SFT; + tdm_con |= get_tdm_channel_bck(format) << CHANNEL_BCK_CYCLES_SFT; + tdm_con |= get_tdm_lrck_width(format) << LRCK_TDM_WIDTH_SFT; + regmap_write(afe->regmap, AFE_TDM_CON1, tdm_con); + + /* set dptx */ + if (tdm_id == MT8189_DAI_TDM_DPTX) { + regmap_update_bits(afe->regmap, AFE_DPTX_CON, + DPTX_CHANNEL_ENABLE_MASK_SFT, + get_dptx_ch_enable_mask(channels) << + DPTX_CHANNEL_ENABLE_SFT); + regmap_update_bits(afe->regmap, AFE_DPTX_CON, + DPTX_CHANNEL_NUMBER_MASK_SFT, + get_dptx_ch(channels) << + DPTX_CHANNEL_NUMBER_SFT); + regmap_update_bits(afe->regmap, AFE_DPTX_CON, + DPTX_16BIT_MASK_SFT, + get_dptx_wlen(format) << DPTX_16BIT_SFT); + } + switch (channels) { + case 1: + case 2: + tdm_con = TDM_CH_START_O30_O31 << ST_CH_PAIR_SOUT0_SFT; + tdm_con |= TDM_CH_ZERO << ST_CH_PAIR_SOUT1_SFT; + tdm_con |= TDM_CH_ZERO << ST_CH_PAIR_SOUT2_SFT; + tdm_con |= TDM_CH_ZERO << ST_CH_PAIR_SOUT3_SFT; + break; + case 3: + case 4: + tdm_con = TDM_CH_START_O30_O31 << ST_CH_PAIR_SOUT0_SFT; + tdm_con |= TDM_CH_START_O32_O33 << ST_CH_PAIR_SOUT1_SFT; + tdm_con |= TDM_CH_ZERO << ST_CH_PAIR_SOUT2_SFT; + tdm_con |= TDM_CH_ZERO << ST_CH_PAIR_SOUT3_SFT; + break; + case 5: + case 6: + tdm_con = TDM_CH_START_O30_O31 << ST_CH_PAIR_SOUT0_SFT; + tdm_con |= TDM_CH_START_O32_O33 << ST_CH_PAIR_SOUT1_SFT; + tdm_con |= TDM_CH_START_O34_O35 << ST_CH_PAIR_SOUT2_SFT; + tdm_con |= TDM_CH_ZERO << ST_CH_PAIR_SOUT3_SFT; + break; + case 7: + case 8: + tdm_con = TDM_CH_START_O30_O31 << ST_CH_PAIR_SOUT0_SFT; + tdm_con |= TDM_CH_START_O32_O33 << ST_CH_PAIR_SOUT1_SFT; + tdm_con |= TDM_CH_START_O34_O35 << ST_CH_PAIR_SOUT2_SFT; + tdm_con |= TDM_CH_START_O36_O37 << ST_CH_PAIR_SOUT3_SFT; + break; + default: + tdm_con = 0; + } + regmap_write(afe->regmap, AFE_TDM_CON2, tdm_con); + regmap_update_bits(afe->regmap, AFE_HDMI_OUT_CON0, + HDMI_CH_NUM_MASK_SFT, + channels << HDMI_CH_NUM_SFT); + + return 0; +} + +static int mtk_dai_tdm_trigger(struct snd_pcm_substream *substream, + int cmd, + struct snd_soc_dai *dai) +{ + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); + int tdm_id = dai->id; + + dev_dbg(afe->dev, "%s(), cmd %d, tdm_id %d\n", __func__, cmd, tdm_id); + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + /* enable Out control */ + regmap_update_bits(afe->regmap, AFE_HDMI_OUT_CON0, + HDMI_OUT_ON_MASK_SFT, + 0x1 << HDMI_OUT_ON_SFT); + + /* enable dptx */ + if (tdm_id == MT8189_DAI_TDM_DPTX) { + regmap_update_bits(afe->regmap, AFE_DPTX_CON, + DPTX_ON_MASK_SFT, 0x1 << + DPTX_ON_SFT); + } + + /* enable tdm */ + regmap_update_bits(afe->regmap, AFE_TDM_CON1, + TDM_EN_MASK_SFT, 0x1 << TDM_EN_SFT); + break; + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + /* disable tdm */ + regmap_update_bits(afe->regmap, AFE_TDM_CON1, + TDM_EN_MASK_SFT, 0); + + /* disable dptx */ + if (tdm_id == MT8189_DAI_TDM_DPTX) { + regmap_update_bits(afe->regmap, AFE_DPTX_CON, + DPTX_ON_MASK_SFT, 0); + } + + /* disable Out control */ + regmap_update_bits(afe->regmap, AFE_HDMI_OUT_CON0, + HDMI_OUT_ON_MASK_SFT, 0); + break; + default: + return -EINVAL; + } + + return 0; +} + +static int mtk_dai_tdm_set_sysclk(struct snd_soc_dai *dai, + int clk_id, unsigned int freq, int dir) +{ + struct mtk_base_afe *afe = dev_get_drvdata(dai->dev); + struct mt8189_afe_private *afe_priv = afe->platform_priv; + struct mtk_afe_tdm_priv *tdm_priv; + + if (dai->id >= MT8189_DAI_NUM || dai->id < 0) + return -EINVAL; + + tdm_priv = afe_priv->dai_priv[dai->id]; + + if (!tdm_priv) + return -EINVAL; + + if (dir != SND_SOC_CLOCK_OUT) + return -EINVAL; + + dev_dbg(afe->dev, "%s(), freq %d\n", __func__, freq); + + return mtk_dai_tdm_cal_mclk(afe, tdm_priv, freq); +} + +static const struct snd_soc_dai_ops mtk_dai_tdm_ops = { + .hw_params = mtk_dai_tdm_hw_params, + .trigger = mtk_dai_tdm_trigger, + .set_sysclk = mtk_dai_tdm_set_sysclk, +}; + +/* dai driver */ +#define MTK_TDM_RATES (SNDRV_PCM_RATE_8000_48000 |\ + SNDRV_PCM_RATE_88200 |\ + SNDRV_PCM_RATE_96000 |\ + SNDRV_PCM_RATE_176400 |\ + SNDRV_PCM_RATE_192000) + +#define MTK_TDM_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ + SNDRV_PCM_FMTBIT_S24_LE |\ + SNDRV_PCM_FMTBIT_S32_LE) + +static struct snd_soc_dai_driver mtk_dai_tdm_driver[] = { + { + .name = "TDM", + .id = MT8189_DAI_TDM, + .playback = { + .stream_name = "TDM", + .channels_min = 2, + .channels_max = 8, + .rates = MTK_TDM_RATES, + .formats = MTK_TDM_FORMATS, + }, + .ops = &mtk_dai_tdm_ops, + }, + { + .name = "TDM_DPTX", + .id = MT8189_DAI_TDM_DPTX, + .playback = { + .stream_name = "TDM_DPTX", + .channels_min = 2, + .channels_max = 8, + .rates = MTK_TDM_RATES, + .formats = MTK_TDM_FORMATS, + }, + .ops = &mtk_dai_tdm_ops, + }, +}; + +static struct mtk_afe_tdm_priv *init_tdm_priv_data(struct mtk_base_afe *afe, + int id) +{ + struct mtk_afe_tdm_priv *tdm_priv; + + tdm_priv = devm_kzalloc(afe->dev, sizeof(struct mtk_afe_tdm_priv), + GFP_KERNEL); + if (!tdm_priv) + return NULL; + + if (id == MT8189_DAI_TDM_DPTX) + tdm_priv->mclk_multiple = 256; + else + tdm_priv->mclk_multiple = 128; + + tdm_priv->bck_id = MT8189_TDMOUT_BCK; + tdm_priv->mclk_id = MT8189_TDMOUT_MCK; + + return tdm_priv; +} + +int mt8189_dai_tdm_register(struct mtk_base_afe *afe) +{ + struct mt8189_afe_private *afe_priv = afe->platform_priv; + struct mtk_afe_tdm_priv *tdm_priv, *tdm_dptx_priv; + struct mtk_base_afe_dai *dai; + + dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL); + if (!dai) + return -ENOMEM; + + dai->dai_drivers = mtk_dai_tdm_driver; + dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_tdm_driver); + dai->controls = mtk_dai_tdm_controls; + dai->num_controls = ARRAY_SIZE(mtk_dai_tdm_controls); + dai->dapm_widgets = mtk_dai_tdm_widgets; + dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_tdm_widgets); + dai->dapm_routes = mtk_dai_tdm_routes; + dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_tdm_routes); + + tdm_priv = init_tdm_priv_data(afe, MT8189_DAI_TDM); + if (!tdm_priv) + return -ENOMEM; + + tdm_dptx_priv = init_tdm_priv_data(afe, MT8189_DAI_TDM_DPTX); + if (!tdm_dptx_priv) + return -ENOMEM; + + list_add(&dai->list, &afe->sub_dais); + + afe_priv->dai_priv[MT8189_DAI_TDM] = tdm_priv; + afe_priv->dai_priv[MT8189_DAI_TDM_DPTX] = tdm_dptx_priv; + + return 0; +} diff --git a/sound/soc/mediatek/mt8189/mt8189-interconnection.h b/sound/soc/mediatek/mt8189/mt8189-interconnection.h new file mode 100644 index 00000000000000..a244a2599fa283 --- /dev/null +++ b/sound/soc/mediatek/mt8189/mt8189-interconnection.h @@ -0,0 +1,97 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Mediatek MT8189 audio driver interconnection definition + * + * Copyright (c) 2025 MediaTek Inc. + * Author: Darren Ye + */ + +#ifndef _MT8189_INTERCONNECTION_H_ +#define _MT8189_INTERCONNECTION_H_ + +/* in port define */ +#define I_CONNSYS_I2S_CH1 0 +#define I_CONNSYS_I2S_CH2 1 +#define I_GAIN0_OUT_CH1 6 +#define I_GAIN0_OUT_CH2 7 +#define I_GAIN1_OUT_CH1 8 +#define I_GAIN1_OUT_CH2 9 +#define I_GAIN2_OUT_CH1 10 +#define I_GAIN2_OUT_CH2 11 +#define I_GAIN3_OUT_CH1 12 +#define I_GAIN3_OUT_CH2 13 +#define I_STF_CH1 14 +#define I_ADDA_UL_CH1 16 +#define I_ADDA_UL_CH2 17 +#define I_ADDA_UL_CH3 18 +#define I_ADDA_UL_CH4 19 +#define I_UL_PROX_CH1 20 +#define I_UL_PROX_CH2 21 +#define I_ADDA_UL_CH5 24 +#define I_ADDA_UL_CH6 25 +#define I_DMIC0_CH1 28 +#define I_DMIC0_CH2 29 +#define I_DMIC1_CH1 30 +#define I_DMIC1_CH2 31 + +/* in port define >= 32 */ +#define I_32_OFFSET 32 +#define I_DL0_CH1 (32 - I_32_OFFSET) +#define I_DL0_CH2 (33 - I_32_OFFSET) +#define I_DL1_CH1 (34 - I_32_OFFSET) +#define I_DL1_CH2 (35 - I_32_OFFSET) +#define I_DL2_CH1 (36 - I_32_OFFSET) +#define I_DL2_CH2 (37 - I_32_OFFSET) +#define I_DL3_CH1 (38 - I_32_OFFSET) +#define I_DL3_CH2 (39 - I_32_OFFSET) +#define I_DL4_CH1 (40 - I_32_OFFSET) +#define I_DL4_CH2 (41 - I_32_OFFSET) +#define I_DL5_CH1 (42 - I_32_OFFSET) +#define I_DL5_CH2 (43 - I_32_OFFSET) +#define I_DL6_CH1 (44 - I_32_OFFSET) +#define I_DL6_CH2 (45 - I_32_OFFSET) +#define I_DL7_CH1 (46 - I_32_OFFSET) +#define I_DL7_CH2 (47 - I_32_OFFSET) +#define I_DL8_CH1 (48 - I_32_OFFSET) +#define I_DL8_CH2 (49 - I_32_OFFSET) +#define I_DL_24CH_CH1 (54 - I_32_OFFSET) +#define I_DL_24CH_CH2 (55 - I_32_OFFSET) +#define I_DL_24CH_CH3 (56 - I_32_OFFSET) +#define I_DL_24CH_CH4 (57 - I_32_OFFSET) +#define I_DL_24CH_CH5 (58 - I_32_OFFSET) +#define I_DL_24CH_CH6 (59 - I_32_OFFSET) +#define I_DL_24CH_CH7 (60 - I_32_OFFSET) +#define I_DL_24CH_CH8 (61 - I_32_OFFSET) + +/* in port define >= 64 */ +#define I_64_OFFSET 64 +#define I_DL23_CH1 (78 - I_64_OFFSET) +#define I_DL23_CH2 (79 - I_64_OFFSET) +#define I_DL24_CH1 (80 - I_64_OFFSET) +#define I_DL24_CH2 (81 - I_64_OFFSET) +#define I_DL25_CH1 (82 - I_64_OFFSET) +#define I_DL25_CH2 (83 - I_64_OFFSET) + +/* in port define >= 128 */ +#define I_128_OFFSET 128 +#define I_PCM_0_CAP_CH1 (130 - I_128_OFFSET) +#define I_PCM_0_CAP_CH2 (131 - I_128_OFFSET) +#define I_I2SIN0_CH1 (134 - I_128_OFFSET) +#define I_I2SIN0_CH2 (135 - I_128_OFFSET) +#define I_I2SIN1_CH1 (136 - I_128_OFFSET) +#define I_I2SIN1_CH2 (137 - I_128_OFFSET) + +/* in port define >= 192 */ +#define I_192_OFFSET 192 +#define I_SRC_0_OUT_CH1 (198 - I_192_OFFSET) +#define I_SRC_0_OUT_CH2 (199 - I_192_OFFSET) +#define I_SRC_1_OUT_CH1 (200 - I_192_OFFSET) +#define I_SRC_1_OUT_CH2 (201 - I_192_OFFSET) +#define I_SRC_2_OUT_CH1 (202 - I_192_OFFSET) +#define I_SRC_2_OUT_CH2 (203 - I_192_OFFSET) +#define I_SRC_3_OUT_CH1 (204 - I_192_OFFSET) +#define I_SRC_3_OUT_CH2 (205 - I_192_OFFSET) +#define I_SRC_4_OUT_CH1 (206 - I_192_OFFSET) +#define I_SRC_4_OUT_CH2 (207 - I_192_OFFSET) + +#endif diff --git a/sound/soc/mediatek/mt8189/mt8189-nau8825.c b/sound/soc/mediatek/mt8189/mt8189-nau8825.c new file mode 100644 index 00000000000000..5ef15ec988be79 --- /dev/null +++ b/sound/soc/mediatek/mt8189/mt8189-nau8825.c @@ -0,0 +1,1178 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * mt8189-nau8825.c -- mt8189 nau8825 ALSA SoC machine driver + * + * Copyright (c) 2025 MediaTek Inc. + * Author: Darren Ye + */ + +#include +#include +#include +#include + +#include +#include +#include + +#include "mt8189-afe-common.h" + +#include "../common/mtk-soc-card.h" +#include "../common/mtk-soundcard-driver.h" +#include "../common/mtk-afe-platform-driver.h" + +#include "../../codecs/cs35l41.h" +#include "../../codecs/nau8825.h" +#include "../../codecs/rt5682s.h" +#include "../../codecs/rt5682.h" + +#define NAU8825_HS_PRESENT BIT(0) +#define RT5682S_HS_PRESENT BIT(1) +#define RT5650_HS_PRESENT BIT(2) +#define RT5682I_HS_PRESENT BIT(3) +#define ES8326_HS_PRESENT BIT(4) + +/* + * Nau88l25 + */ +#define NAU8825_CODEC_DAI "nau8825-hifi" + +/* + * Rt5682s + */ +#define RT5682S_CODEC_DAI "rt5682s-aif1" + +/* + * Rt5650 + */ +#define RT5650_CODEC_DAI "rt5645-aif1" + +/* + * Rt5682i + */ +#define RT5682I_CODEC_DAI "rt5682-aif1" + +/* + * Cs35l41 + */ +#define CS35L41_CODEC_DAI "cs35l41-pcm" +#define CS35L41_DEV0_NAME "cs35l41.7-0040" +#define CS35L41_DEV1_NAME "cs35l41.7-0042" + +/* + * ES8326 + */ +#define ES8326_CODEC_DAI "ES8326 HiFi" + +enum mt8189_jacks { + MT8189_JACK_HEADSET, + MT8189_JACK_DP, + MT8189_JACK_HDMI, + MT8189_JACK_MAX, +}; + +static struct snd_soc_jack_pin mt8189_dp_jack_pins[] = { + { + .pin = "DP", + .mask = SND_JACK_LINEOUT, + }, +}; + +static struct snd_soc_jack_pin mt8189_hdmi_jack_pins[] = { + { + .pin = "HDMI", + .mask = SND_JACK_LINEOUT, + }, +}; + +static struct snd_soc_jack_pin mt8189_headset_jack_pins[] = { + { + .pin = "Headphone Jack", + .mask = SND_JACK_HEADPHONE, + }, + { + .pin = "Headset Mic", + .mask = SND_JACK_MICROPHONE, + }, +}; + +static const struct snd_kcontrol_new mt8189_dumb_spk_controls[] = { + SOC_DAPM_PIN_SWITCH("Ext Spk"), +}; + +static const struct snd_soc_dapm_widget mt8189_dumb_spk_widgets[] = { + SND_SOC_DAPM_SPK("Ext Spk", NULL), +}; + +static const struct snd_soc_dapm_widget mt8189_headset_widgets[] = { + SND_SOC_DAPM_HP("Headphone Jack", NULL), + SND_SOC_DAPM_MIC("Headset Mic", NULL), +}; + +static const struct snd_kcontrol_new mt8189_headset_controls[] = { + SOC_DAPM_PIN_SWITCH("Headphone Jack"), + SOC_DAPM_PIN_SWITCH("Headset Mic"), +}; + +static const struct snd_soc_dapm_widget mt8189_nau8825_card_widgets[] = { + SND_SOC_DAPM_SINK("DP"), +}; + +static int mt8189_common_i2s_startup(struct snd_pcm_substream *substream) +{ + static const unsigned int rates[] = { + 48000, + }; + static const struct snd_pcm_hw_constraint_list constraints_rates = { + .count = ARRAY_SIZE(rates), + .list = rates, + }; + + return snd_pcm_hw_constraint_list(substream->runtime, 0, + SNDRV_PCM_HW_PARAM_RATE, + &constraints_rates); +} + +static int mt8189_common_i2s_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + unsigned int rate = params_rate(params); + unsigned int mclk_fs_ratio = 128; + unsigned int mclk_fs = rate * mclk_fs_ratio; + struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); + + return snd_soc_dai_set_sysclk(cpu_dai, + 0, mclk_fs, SND_SOC_CLOCK_OUT); +} + +static const struct snd_soc_ops mt8189_common_i2s_ops = { + .startup = mt8189_common_i2s_startup, + .hw_params = mt8189_common_i2s_hw_params, +}; + +static int mt8189_dptx_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + unsigned int rate = params_rate(params); + unsigned int mclk_fs_ratio = 256; + unsigned int mclk_fs = rate * mclk_fs_ratio; + struct snd_soc_dai *dai = snd_soc_rtd_to_cpu(rtd, 0); + + return snd_soc_dai_set_sysclk(dai, 0, mclk_fs, SND_SOC_CLOCK_OUT); +} + +static const struct snd_soc_ops mt8189_dptx_ops = { + .hw_params = mt8189_dptx_hw_params, +}; + +static int mt8189_dptx_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params) +{ + dev_dbg(rtd->dev, "%s(), fix format to 32bit\n", __func__); + + /* fix BE i2s format to 32bit, clean param mask first */ + snd_mask_reset_range(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT), + 0, (__force unsigned int)SNDRV_PCM_FORMAT_LAST); + + params_set_format(params, SNDRV_PCM_FORMAT_S32_LE); + + return 0; +} + +static const struct snd_soc_ops mt8189_pcm_ops = { + .startup = mt8189_common_i2s_startup, +}; + +static int mt8189_nau8825_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); + unsigned int rate = params_rate(params); + unsigned int bit_width = params_width(params); + int clk_freq, ret; + + clk_freq = rate * 2 * bit_width; + dev_dbg(codec_dai->dev, "clk_freq %d, rate: %d, bit_width: %d\n", + clk_freq, rate, bit_width); + + /* Configure clock for codec */ + ret = snd_soc_dai_set_sysclk(codec_dai, NAU8825_CLK_FLL_BLK, 0, + SND_SOC_CLOCK_IN); + if (ret < 0) { + dev_err(codec_dai->dev, "can't set BCLK clock %d\n", ret); + return ret; + } + + /* Configure pll for codec */ + ret = snd_soc_dai_set_pll(codec_dai, 0, 0, clk_freq, + rate * 256); + if (ret < 0) { + dev_err(codec_dai->dev, "can't set BCLK: %d\n", ret); + return ret; + } + + return 0; +} + +static const struct snd_soc_ops mt8189_nau8825_ops = { + .startup = mt8189_common_i2s_startup, + .hw_params = mt8189_nau8825_hw_params, +}; + +static int mt8189_rtxxxx_i2s_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_soc_card *card = rtd->card; + struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); + unsigned int rate = params_rate(params); + int bitwidth; + int ret; + + bitwidth = snd_pcm_format_width(params_format(params)); + if (bitwidth < 0) { + dev_err(card->dev, "invalid bit width: %d\n", bitwidth); + return bitwidth; + } + + ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x00, 0x0, 0x2, bitwidth); + if (ret) { + dev_err(card->dev, "failed to set tdm slot\n"); + return ret; + } + + ret = snd_soc_dai_set_pll(codec_dai, 0, 1, rate * 32, rate * 512); + if (ret) { + dev_err(card->dev, "failed to set pll\n"); + return ret; + } + + ret = snd_soc_dai_set_sysclk(codec_dai, 1, rate * 512, SND_SOC_CLOCK_IN); + if (ret) { + dev_err(card->dev, "failed to set sysclk\n"); + return ret; + } + + return snd_soc_dai_set_sysclk(cpu_dai, 0, rate * 512, + SND_SOC_CLOCK_OUT); +} + +static const struct snd_soc_ops mt8189_rtxxxx_i2s_ops = { + .startup = mt8189_common_i2s_startup, + .hw_params = mt8189_rtxxxx_i2s_hw_params, +}; + +static int mt8189_cs35l41_i2s_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + unsigned int rate = params_rate(params); + unsigned int mclk_fs = rate * 128; + struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); + struct snd_soc_dai *codec_dai; + int clk_freq = rate * 32; + int rx_slot[] = {0, 1}; + int i, ret; + + for_each_rtd_codec_dais(rtd, i, codec_dai) { + ret = snd_soc_component_set_sysclk(codec_dai->component, + CS35L41_CLKID_SCLK, 0, + clk_freq, SND_SOC_CLOCK_IN); + if (ret < 0) { + dev_err(codec_dai->dev, "set component sysclk fail: %d\n", + ret); + return ret; + } + + ret = snd_soc_dai_set_sysclk(codec_dai, CS35L41_CLKID_SCLK, + clk_freq, SND_SOC_CLOCK_IN); + if (ret < 0) { + dev_err(codec_dai->dev, "set sysclk fail: %d\n", + ret); + return ret; + } + + ret = snd_soc_dai_set_channel_map(codec_dai, 0, NULL, + 1, &rx_slot[i]); + if (ret < 0) { + dev_err(codec_dai->dev, "set channel map fail: %d\n", + ret); + return ret; + } + } + + return snd_soc_dai_set_sysclk(cpu_dai, + 0, mclk_fs, SND_SOC_CLOCK_OUT); +} + +static const struct snd_soc_ops mt8189_cs35l41_i2s_ops = { + .startup = mt8189_common_i2s_startup, + .hw_params = mt8189_cs35l41_i2s_hw_params, +}; + +static int mt8189_es8326_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); + unsigned int rate = params_rate(params); + int ret; + + /* Configure MCLK for codec */ + ret = snd_soc_dai_set_sysclk(codec_dai, 0, rate * 256, SND_SOC_CLOCK_IN); + if (ret < 0) { + dev_err(codec_dai->dev, "can't set MCLK %d\n", ret); + return ret; + } + + /* Configure MCLK for cpu */ + return snd_soc_dai_set_sysclk(cpu_dai, 0, rate * 256, SND_SOC_CLOCK_OUT); +} + +static const struct snd_soc_ops mt8189_es8326_ops = { + .startup = mt8189_common_i2s_startup, + .hw_params = mt8189_es8326_hw_params, +}; + +static int mt8189_dumb_amp_init(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_card *card = rtd->card; + int ret; + + ret = snd_soc_dapm_new_controls(&card->dapm, mt8189_dumb_spk_widgets, + ARRAY_SIZE(mt8189_dumb_spk_widgets)); + if (ret) { + dev_err(rtd->dev, "unable to add Dumb Speaker dapm, ret %d\n", ret); + return ret; + } + + ret = snd_soc_add_card_controls(card, mt8189_dumb_spk_controls, + ARRAY_SIZE(mt8189_dumb_spk_controls)); + if (ret) { + dev_err(rtd->dev, "unable to add Dumb card controls, ret %d\n", ret); + return ret; + } + + return 0; +} + +static int mt8189_dptx_codec_init(struct snd_soc_pcm_runtime *rtd) +{ + struct mtk_soc_card_data *soc_card_data = snd_soc_card_get_drvdata(rtd->card); + struct snd_soc_jack *jack = &soc_card_data->card_data->jacks[MT8189_JACK_DP]; + struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component; + int ret; + + ret = snd_soc_card_jack_new_pins(rtd->card, "DP Jack", SND_JACK_LINEOUT, + jack, mt8189_dp_jack_pins, + ARRAY_SIZE(mt8189_dp_jack_pins)); + if (ret) { + dev_err(rtd->dev, "%s, new jack failed: %d\n", __func__, ret); + return ret; + } + + ret = snd_soc_component_set_jack(component, jack, NULL); + if (ret) { + dev_err(rtd->dev, "%s, set jack failed on %s (ret=%d)\n", + __func__, component->name, ret); + return ret; + } + + return 0; +} + +static int mt8189_hdmi_codec_init(struct snd_soc_pcm_runtime *rtd) +{ + struct mtk_soc_card_data *soc_card_data = snd_soc_card_get_drvdata(rtd->card); + struct snd_soc_jack *jack = &soc_card_data->card_data->jacks[MT8189_JACK_HDMI]; + struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component; + int ret; + + ret = snd_soc_card_jack_new_pins(rtd->card, "HDMI Jack", SND_JACK_LINEOUT, + jack, mt8189_hdmi_jack_pins, + ARRAY_SIZE(mt8189_hdmi_jack_pins)); + if (ret) { + dev_err(rtd->dev, "%s, new jack failed: %d\n", __func__, ret); + return ret; + } + + ret = snd_soc_component_set_jack(component, jack, NULL); + if (ret) { + dev_err(rtd->dev, "%s, set jack failed on %s (ret=%d)\n", + __func__, component->name, ret); + return ret; + } + + return 0; +} + +static int mt8189_headset_codec_init(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_card *card = rtd->card; + struct mtk_soc_card_data *soc_card_data = snd_soc_card_get_drvdata(card); + struct snd_soc_jack *jack = &soc_card_data->card_data->jacks[MT8189_JACK_HEADSET]; + struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component; + struct mtk_platform_card_data *card_data = soc_card_data->card_data; + int ret; + int type; + + ret = snd_soc_dapm_new_controls(&card->dapm, mt8189_headset_widgets, + ARRAY_SIZE(mt8189_headset_widgets)); + if (ret) { + dev_err(rtd->dev, "unable to add nau8825 card widget, ret %d\n", ret); + return ret; + } + + ret = snd_soc_add_card_controls(card, mt8189_headset_controls, + ARRAY_SIZE(mt8189_headset_controls)); + if (ret) { + dev_err(rtd->dev, "unable to add nau8825 card controls, ret %d\n", ret); + return ret; + } + + ret = snd_soc_card_jack_new_pins(rtd->card, "Headset Jack", + SND_JACK_HEADSET | SND_JACK_BTN_0 | + SND_JACK_BTN_1 | SND_JACK_BTN_2 | + SND_JACK_BTN_3, + jack, + mt8189_headset_jack_pins, + ARRAY_SIZE(mt8189_headset_jack_pins)); + if (ret) { + dev_err(rtd->dev, "Headset Jack creation failed: %d\n", ret); + return ret; + } + + if (card_data->flags & ES8326_HS_PRESENT) { + snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE); + snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOLUMEUP); + snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN); + snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOICECOMMAND); + } else { + snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE); + snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOICECOMMAND); + snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP); + snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN); + } + + type = SND_JACK_HEADSET | SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2 | SND_JACK_BTN_3; + ret = snd_soc_component_set_jack(component, jack, (void *)&type); + if (ret) { + dev_err(rtd->dev, "Headset Jack call-back failed: %d\n", ret); + return ret; + } + + return 0; +}; + +static void mt8189_headset_codec_exit(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component; + + snd_soc_component_set_jack(component, NULL, NULL); +} + +/* FE */ +SND_SOC_DAILINK_DEFS(playback0, + DAILINK_COMP_ARRAY(COMP_CPU("DL0")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); +SND_SOC_DAILINK_DEFS(playback1, + DAILINK_COMP_ARRAY(COMP_CPU("DL1")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); +SND_SOC_DAILINK_DEFS(playback2, + DAILINK_COMP_ARRAY(COMP_CPU("DL2")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); +SND_SOC_DAILINK_DEFS(playback3, + DAILINK_COMP_ARRAY(COMP_CPU("DL3")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); +SND_SOC_DAILINK_DEFS(playback4, + DAILINK_COMP_ARRAY(COMP_CPU("DL4")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); +SND_SOC_DAILINK_DEFS(playback5, + DAILINK_COMP_ARRAY(COMP_CPU("DL5")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); +SND_SOC_DAILINK_DEFS(playback6, + DAILINK_COMP_ARRAY(COMP_CPU("DL6")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); +SND_SOC_DAILINK_DEFS(playback7, + DAILINK_COMP_ARRAY(COMP_CPU("DL7")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); +SND_SOC_DAILINK_DEFS(playback8, + DAILINK_COMP_ARRAY(COMP_CPU("DL8")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); +SND_SOC_DAILINK_DEFS(playback23, + DAILINK_COMP_ARRAY(COMP_CPU("DL23")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); +SND_SOC_DAILINK_DEFS(playback24, + DAILINK_COMP_ARRAY(COMP_CPU("DL24")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); +SND_SOC_DAILINK_DEFS(playback25, + DAILINK_COMP_ARRAY(COMP_CPU("DL25")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); +SND_SOC_DAILINK_DEFS(playback_24ch, + DAILINK_COMP_ARRAY(COMP_CPU("DL_24CH")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); +SND_SOC_DAILINK_DEFS(capture0, + DAILINK_COMP_ARRAY(COMP_CPU("UL0")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); +SND_SOC_DAILINK_DEFS(capture1, + DAILINK_COMP_ARRAY(COMP_CPU("UL1")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); +SND_SOC_DAILINK_DEFS(capture2, + DAILINK_COMP_ARRAY(COMP_CPU("UL2")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); +SND_SOC_DAILINK_DEFS(capture3, + DAILINK_COMP_ARRAY(COMP_CPU("UL3")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); +SND_SOC_DAILINK_DEFS(capture4, + DAILINK_COMP_ARRAY(COMP_CPU("UL4")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); +SND_SOC_DAILINK_DEFS(capture5, + DAILINK_COMP_ARRAY(COMP_CPU("UL5")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); +SND_SOC_DAILINK_DEFS(capture6, + DAILINK_COMP_ARRAY(COMP_CPU("UL6")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); +SND_SOC_DAILINK_DEFS(capture7, + DAILINK_COMP_ARRAY(COMP_CPU("UL7")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); +SND_SOC_DAILINK_DEFS(capture8, + DAILINK_COMP_ARRAY(COMP_CPU("UL8")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); +SND_SOC_DAILINK_DEFS(capture9, + DAILINK_COMP_ARRAY(COMP_CPU("UL9")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); +SND_SOC_DAILINK_DEFS(capture10, + DAILINK_COMP_ARRAY(COMP_CPU("UL10")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); +SND_SOC_DAILINK_DEFS(capture24, + DAILINK_COMP_ARRAY(COMP_CPU("UL24")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); +SND_SOC_DAILINK_DEFS(capture25, + DAILINK_COMP_ARRAY(COMP_CPU("UL25")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); +SND_SOC_DAILINK_DEFS(capture_cm0, + DAILINK_COMP_ARRAY(COMP_CPU("UL_CM0")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); +SND_SOC_DAILINK_DEFS(capture_cm1, + DAILINK_COMP_ARRAY(COMP_CPU("UL_CM1")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); +SND_SOC_DAILINK_DEFS(capture_etdm_in0, + DAILINK_COMP_ARRAY(COMP_CPU("UL_ETDM_IN0")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); +SND_SOC_DAILINK_DEFS(capture_etdm_in1, + DAILINK_COMP_ARRAY(COMP_CPU("UL_ETDM_IN1")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); +SND_SOC_DAILINK_DEFS(playback_hdmi, + DAILINK_COMP_ARRAY(COMP_CPU("HDMI")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); +/* BE */ +SND_SOC_DAILINK_DEFS(ap_dmic, + DAILINK_COMP_ARRAY(COMP_CPU("AP_DMIC")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); +SND_SOC_DAILINK_DEFS(ap_dmic_ch34, + DAILINK_COMP_ARRAY(COMP_CPU("AP_DMIC_CH34")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); +SND_SOC_DAILINK_DEFS(i2sin0, + DAILINK_COMP_ARRAY(COMP_CPU("I2SIN0")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); +SND_SOC_DAILINK_DEFS(i2sin1, + DAILINK_COMP_ARRAY(COMP_CPU("I2SIN1")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); +SND_SOC_DAILINK_DEFS(i2sout0, + DAILINK_COMP_ARRAY(COMP_CPU("I2SOUT0")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); +SND_SOC_DAILINK_DEFS(i2sout1, + DAILINK_COMP_ARRAY(COMP_CPU("I2SOUT1")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); +SND_SOC_DAILINK_DEFS(pcm0, + DAILINK_COMP_ARRAY(COMP_CPU("PCM 0")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); +SND_SOC_DAILINK_DEFS(tdm_dptx, + DAILINK_COMP_ARRAY(COMP_CPU("TDM_DPTX")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); + +static struct snd_soc_dai_link mt8189_nau8825_dai_links[] = { + /* Front End DAI links */ + { + .name = "DL0_FE", + .stream_name = "DL0 Playback", + .trigger = {SND_SOC_DPCM_TRIGGER_PRE, + SND_SOC_DPCM_TRIGGER_PRE}, + .dynamic = 1, + .playback_only = 1, + .dpcm_merged_format = 1, + SND_SOC_DAILINK_REG(playback0), + }, + { + .name = "DL1_FE", + .stream_name = "DL1 Playback", + .trigger = {SND_SOC_DPCM_TRIGGER_PRE, + SND_SOC_DPCM_TRIGGER_PRE}, + .dynamic = 1, + .playback_only = 1, + .dpcm_merged_format = 1, + SND_SOC_DAILINK_REG(playback1), + }, + { + .name = "UL0_FE", + .stream_name = "UL0 Capture", + .trigger = {SND_SOC_DPCM_TRIGGER_PRE, + SND_SOC_DPCM_TRIGGER_PRE}, + .dynamic = 1, + .capture_only = 1, + .dpcm_merged_format = 1, + SND_SOC_DAILINK_REG(capture0), + }, + { + .name = "UL1_FE", + .stream_name = "UL1 Capture", + .trigger = {SND_SOC_DPCM_TRIGGER_PRE, + SND_SOC_DPCM_TRIGGER_PRE}, + .dynamic = 1, + .capture_only = 1, + .dpcm_merged_format = 1, + SND_SOC_DAILINK_REG(capture1), + }, + { + .name = "UL2_FE", + .stream_name = "UL2 Capture", + .trigger = {SND_SOC_DPCM_TRIGGER_PRE, + SND_SOC_DPCM_TRIGGER_PRE}, + .dynamic = 1, + .capture_only = 1, + .dpcm_merged_format = 1, + SND_SOC_DAILINK_REG(capture2), + }, + { + .name = "HDMI_FE", + .stream_name = "HDMI Playback", + .trigger = {SND_SOC_DPCM_TRIGGER_PRE, + SND_SOC_DPCM_TRIGGER_PRE}, + .dynamic = 1, + .playback_only = 1, + SND_SOC_DAILINK_REG(playback_hdmi), + }, + { + .name = "DL2_FE", + .stream_name = "DL2 Playback", + .trigger = {SND_SOC_DPCM_TRIGGER_PRE, + SND_SOC_DPCM_TRIGGER_PRE}, + .dynamic = 1, + .playback_only = 1, + SND_SOC_DAILINK_REG(playback2), + }, + { + .name = "DL3_FE", + .stream_name = "DL3 Playback", + .trigger = {SND_SOC_DPCM_TRIGGER_PRE, + SND_SOC_DPCM_TRIGGER_PRE}, + .dynamic = 1, + .playback_only = 1, + SND_SOC_DAILINK_REG(playback3), + }, + { + .name = "DL4_FE", + .stream_name = "DL4 Playback", + .trigger = {SND_SOC_DPCM_TRIGGER_PRE, + SND_SOC_DPCM_TRIGGER_PRE}, + .dynamic = 1, + .playback_only = 1, + SND_SOC_DAILINK_REG(playback4), + }, + { + .name = "DL5_FE", + .stream_name = "DL5 Playback", + .trigger = {SND_SOC_DPCM_TRIGGER_PRE, + SND_SOC_DPCM_TRIGGER_PRE}, + .dynamic = 1, + .playback_only = 1, + SND_SOC_DAILINK_REG(playback5), + }, + { + .name = "DL6_FE", + .stream_name = "DL6 Playback", + .trigger = {SND_SOC_DPCM_TRIGGER_PRE, + SND_SOC_DPCM_TRIGGER_PRE}, + .dynamic = 1, + .playback_only = 1, + SND_SOC_DAILINK_REG(playback6), + }, + { + .name = "DL7_FE", + .stream_name = "DL7 Playback", + .trigger = {SND_SOC_DPCM_TRIGGER_PRE, + SND_SOC_DPCM_TRIGGER_PRE}, + .dynamic = 1, + .playback_only = 1, + SND_SOC_DAILINK_REG(playback7), + }, + { + .name = "DL8 FE", + .stream_name = "DL8 Playback", + .trigger = {SND_SOC_DPCM_TRIGGER_PRE, + SND_SOC_DPCM_TRIGGER_PRE}, + .dynamic = 1, + .playback_only = 1, + SND_SOC_DAILINK_REG(playback8), + }, + { + .name = "DL23 FE", + .stream_name = "DL23 Playback", + .trigger = {SND_SOC_DPCM_TRIGGER_PRE, + SND_SOC_DPCM_TRIGGER_PRE}, + .dynamic = 1, + .playback_only = 1, + SND_SOC_DAILINK_REG(playback23), + }, + { + .name = "DL24 FE", + .stream_name = "DL24 Playback", + .trigger = {SND_SOC_DPCM_TRIGGER_PRE, + SND_SOC_DPCM_TRIGGER_PRE}, + .dynamic = 1, + .playback_only = 1, + SND_SOC_DAILINK_REG(playback24), + }, + { + .name = "DL25 FE", + .stream_name = "DL25 Playback", + .trigger = {SND_SOC_DPCM_TRIGGER_PRE, + SND_SOC_DPCM_TRIGGER_PRE}, + .dynamic = 1, + .playback_only = 1, + SND_SOC_DAILINK_REG(playback25), + }, + { + .name = "DL_24CH_FE", + .stream_name = "DL_24CH Playback", + .trigger = {SND_SOC_DPCM_TRIGGER_PRE, + SND_SOC_DPCM_TRIGGER_PRE}, + .dynamic = 1, + .playback_only = 1, + SND_SOC_DAILINK_REG(playback_24ch), + }, + { + .name = "UL9_FE", + .stream_name = "UL9 Capture", + .trigger = {SND_SOC_DPCM_TRIGGER_PRE, + SND_SOC_DPCM_TRIGGER_PRE}, + .dynamic = 1, + .capture_only = 1, + SND_SOC_DAILINK_REG(capture9), + }, + { + .name = "UL3_FE", + .stream_name = "UL3 Capture", + .trigger = {SND_SOC_DPCM_TRIGGER_PRE, + SND_SOC_DPCM_TRIGGER_PRE}, + .dynamic = 1, + .capture_only = 1, + SND_SOC_DAILINK_REG(capture3), + }, + { + .name = "UL7_FE", + .stream_name = "UL7 Capture", + .trigger = {SND_SOC_DPCM_TRIGGER_PRE, + SND_SOC_DPCM_TRIGGER_PRE}, + .dynamic = 1, + .capture_only = 1, + SND_SOC_DAILINK_REG(capture7), + }, + { + .name = "UL4_FE", + .stream_name = "UL4 Capture", + .trigger = {SND_SOC_DPCM_TRIGGER_PRE, + SND_SOC_DPCM_TRIGGER_PRE}, + .dynamic = 1, + .capture_only = 1, + SND_SOC_DAILINK_REG(capture4), + }, + { + .name = "UL5_FE", + .stream_name = "UL5 Capture", + .trigger = {SND_SOC_DPCM_TRIGGER_PRE, + SND_SOC_DPCM_TRIGGER_PRE}, + .dynamic = 1, + .capture_only = 1, + SND_SOC_DAILINK_REG(capture5), + }, + { + .name = "UL_CM0_FE", + .stream_name = "UL_CM0 Capture", + .trigger = {SND_SOC_DPCM_TRIGGER_PRE, + SND_SOC_DPCM_TRIGGER_PRE}, + .dynamic = 1, + .capture_only = 1, + SND_SOC_DAILINK_REG(capture_cm0), + }, + { + .name = "UL_CM1_FE", + .stream_name = "UL_CM1 Capture", + .trigger = {SND_SOC_DPCM_TRIGGER_PRE, + SND_SOC_DPCM_TRIGGER_PRE}, + .dynamic = 1, + .capture_only = 1, + SND_SOC_DAILINK_REG(capture_cm1), + }, + { + .name = "UL10_FE", + .stream_name = "UL10 Capture", + .trigger = {SND_SOC_DPCM_TRIGGER_PRE, + SND_SOC_DPCM_TRIGGER_PRE}, + .dynamic = 1, + .capture_only = 1, + SND_SOC_DAILINK_REG(capture10), + }, + { + .name = "UL6_FE", + .stream_name = "UL6 Capture", + .trigger = {SND_SOC_DPCM_TRIGGER_PRE, + SND_SOC_DPCM_TRIGGER_PRE}, + .dynamic = 1, + .capture_only = 1, + SND_SOC_DAILINK_REG(capture6), + }, + { + .name = "UL25_FE", + .stream_name = "UL25 Capture", + .trigger = {SND_SOC_DPCM_TRIGGER_PRE, + SND_SOC_DPCM_TRIGGER_PRE}, + .dynamic = 1, + .capture_only = 1, + SND_SOC_DAILINK_REG(capture25), + }, + { + .name = "UL8_FE", + .stream_name = "UL8 Capture_Mono_1", + .trigger = {SND_SOC_DPCM_TRIGGER_PRE, + SND_SOC_DPCM_TRIGGER_PRE}, + .dynamic = 1, + .capture_only = 1, + SND_SOC_DAILINK_REG(capture8), + }, + { + .name = "UL24_FE", + .stream_name = "UL24 Capture_Mono_2", + .trigger = {SND_SOC_DPCM_TRIGGER_PRE, + SND_SOC_DPCM_TRIGGER_PRE}, + .dynamic = 1, + .capture_only = 1, + SND_SOC_DAILINK_REG(capture24), + }, + { + .name = "UL_ETDM_In0_FE", + .stream_name = "UL_ETDM_In0 Capture", + .trigger = {SND_SOC_DPCM_TRIGGER_PRE, + SND_SOC_DPCM_TRIGGER_PRE}, + .dynamic = 1, + .capture_only = 1, + SND_SOC_DAILINK_REG(capture_etdm_in0), + }, + { + .name = "UL_ETDM_In1_FE", + .stream_name = "UL_ETDM_In1 Capture", + .trigger = {SND_SOC_DPCM_TRIGGER_PRE, + SND_SOC_DPCM_TRIGGER_PRE}, + .dynamic = 1, + .capture_only = 1, + SND_SOC_DAILINK_REG(capture_etdm_in1), + }, + /* Back End DAI links */ + { + .name = "I2SIN0_BE", + .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBC_CFC + | SND_SOC_DAIFMT_GATED, + .ops = &mt8189_common_i2s_ops, + .no_pcm = 1, + .capture_only = 1, + .ignore_suspend = 1, + SND_SOC_DAILINK_REG(i2sin0), + }, + { + .name = "I2SIN1_BE", + .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBC_CFC + | SND_SOC_DAIFMT_GATED, + .ops = &mt8189_common_i2s_ops, + .no_pcm = 1, + .capture_only = 1, + .ignore_suspend = 1, + SND_SOC_DAILINK_REG(i2sin1), + }, + { + .name = "I2SOUT0_BE", + .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBC_CFC + | SND_SOC_DAIFMT_GATED, + .ops = &mt8189_common_i2s_ops, + .no_pcm = 1, + .playback_only = 1, + .ignore_suspend = 1, + SND_SOC_DAILINK_REG(i2sout0), + }, + { + .name = "I2SOUT1_BE", + .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBC_CFC + | SND_SOC_DAIFMT_GATED, + .ops = &mt8189_common_i2s_ops, + .no_pcm = 1, + .playback_only = 1, + .ignore_suspend = 1, + SND_SOC_DAILINK_REG(i2sout1), + }, + { + .name = "AP_DMIC_BE", + .no_pcm = 1, + .capture_only = 1, + .ignore_suspend = 1, + SND_SOC_DAILINK_REG(ap_dmic), + }, + { + .name = "AP_DMIC_CH34_BE", + .no_pcm = 1, + .capture_only = 1, + .ignore_suspend = 1, + SND_SOC_DAILINK_REG(ap_dmic_ch34), + }, + { + .name = "TDM_DPTX_BE", + .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBC_CFC + | SND_SOC_DAIFMT_GATED, + .ops = &mt8189_dptx_ops, + .be_hw_params_fixup = mt8189_dptx_hw_params_fixup, + .no_pcm = 1, + .playback_only = 1, + .ignore_suspend = 1, + SND_SOC_DAILINK_REG(tdm_dptx), + }, + { + .name = "PCM_0_BE", + .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBC_CFC + | SND_SOC_DAIFMT_GATED, + .no_pcm = 1, + .ops = &mt8189_pcm_ops, + .playback_only = 1, + .ignore_suspend = 1, + SND_SOC_DAILINK_REG(pcm0), + }, +}; + +static struct snd_soc_codec_conf mt8189_cs35l41_codec_conf[] = { + { + .dlc = COMP_CODEC_CONF(CS35L41_DEV0_NAME), + .name_prefix = "Right", + }, + { + .dlc = COMP_CODEC_CONF(CS35L41_DEV1_NAME), + .name_prefix = "Left", + }, +}; + +static int mt8189_nau8825_soc_card_probe(struct mtk_soc_card_data *soc_card_data, bool legacy) +{ + struct snd_soc_card *card = soc_card_data->card_data->card; + struct snd_soc_dai_link *dai_link; + bool init_nau8825 = false; + bool init_rt5682s = false; + bool init_rt5650 = false; + bool init_rt5682i = false; + bool init_es8326 = false; + bool init_dumb = false; + int i; + + for_each_card_prelinks(card, i, dai_link) { + if (strcmp(dai_link->name, "TDM_DPTX_BE") == 0) { + if (dai_link->num_codecs && + strcmp(dai_link->codecs->dai_name, "snd-soc-dummy-dai")) + dai_link->init = mt8189_dptx_codec_init; + } else if (strcmp(dai_link->name, "PCM_0_BE") == 0) { + if (dai_link->num_codecs && + strcmp(dai_link->codecs->dai_name, "snd-soc-dummy-dai")) + dai_link->init = mt8189_hdmi_codec_init; + } else if (strcmp(dai_link->name, "I2SOUT0_BE") == 0 || + strcmp(dai_link->name, "I2SIN0_BE") == 0) { + if (!strcmp(dai_link->codecs->dai_name, NAU8825_CODEC_DAI)) { + dai_link->ops = &mt8189_nau8825_ops; + if (!init_nau8825) { + dai_link->init = mt8189_headset_codec_init; + dai_link->exit = mt8189_headset_codec_exit; + init_nau8825 = true; + } + } else if (!strcmp(dai_link->codecs->dai_name, RT5682S_CODEC_DAI)) { + dai_link->ops = &mt8189_rtxxxx_i2s_ops; + if (!init_rt5682s) { + dai_link->init = mt8189_headset_codec_init; + dai_link->exit = mt8189_headset_codec_exit; + init_rt5682s = true; + } + } else if (!strcmp(dai_link->codecs->dai_name, RT5650_CODEC_DAI)) { + dai_link->ops = &mt8189_rtxxxx_i2s_ops; + if (!init_rt5650) { + dai_link->init = mt8189_headset_codec_init; + dai_link->exit = mt8189_headset_codec_exit; + init_rt5650 = true; + } + } else if (!strcmp(dai_link->codecs->dai_name, RT5682I_CODEC_DAI)) { + dai_link->ops = &mt8189_rtxxxx_i2s_ops; + if (!init_rt5682i) { + dai_link->init = mt8189_headset_codec_init; + dai_link->exit = mt8189_headset_codec_exit; + init_rt5682i = true; + } + } else if (!strcmp(dai_link->codecs->dai_name, ES8326_CODEC_DAI)) { + dai_link->ops = &mt8189_es8326_ops; + if (!init_es8326) { + dai_link->init = mt8189_headset_codec_init; + dai_link->exit = mt8189_headset_codec_exit; + init_es8326 = true; + } + } else { + if (strcmp(dai_link->codecs->dai_name, "snd-soc-dummy-dai")) { + if (!init_dumb) { + dai_link->init = mt8189_dumb_amp_init; + init_dumb = true; + } + } + } + } else if (strcmp(dai_link->name, "I2SOUT1_BE") == 0) { + if (!strcmp(dai_link->codecs->dai_name, CS35L41_CODEC_DAI)) { + dai_link->ops = &mt8189_cs35l41_i2s_ops; + card->num_configs = ARRAY_SIZE(mt8189_cs35l41_codec_conf); + card->codec_conf = mt8189_cs35l41_codec_conf; + } + } + } + + return 0; +} + +static struct snd_soc_card mt8189_nau8825_soc_card = { + .owner = THIS_MODULE, + .dai_link = mt8189_nau8825_dai_links, + .num_links = ARRAY_SIZE(mt8189_nau8825_dai_links), + .dapm_widgets = mt8189_nau8825_card_widgets, + .num_dapm_widgets = ARRAY_SIZE(mt8189_nau8825_card_widgets), +}; + +static const struct mtk_soundcard_pdata mt8189_nau8825_card = { + .card_name = "mt8189_nau8825", + .card_data = &(struct mtk_platform_card_data) { + .card = &mt8189_nau8825_soc_card, + .num_jacks = MT8189_JACK_MAX, + .flags = NAU8825_HS_PRESENT + }, + .sof_priv = NULL, + .soc_probe = mt8189_nau8825_soc_card_probe, +}; + +static const struct mtk_soundcard_pdata mt8189_rt5650_card = { + .card_name = "mt8189_rt5650", + .card_data = &(struct mtk_platform_card_data) { + .card = &mt8189_nau8825_soc_card, + .num_jacks = MT8189_JACK_MAX, + .flags = RT5650_HS_PRESENT + }, + .sof_priv = NULL, + .soc_probe = mt8189_nau8825_soc_card_probe, +}; + +static const struct mtk_soundcard_pdata mt8189_rt5682s_card = { + .card_name = "mt8189_rt5682s", + .card_data = &(struct mtk_platform_card_data) { + .card = &mt8189_nau8825_soc_card, + .num_jacks = MT8189_JACK_MAX, + .flags = RT5682S_HS_PRESENT + }, + .sof_priv = NULL, + .soc_probe = mt8189_nau8825_soc_card_probe, +}; + +static const struct mtk_soundcard_pdata mt8189_rt5682i_card = { + .card_name = "mt8189_rt5682i", + .card_data = &(struct mtk_platform_card_data) { + .card = &mt8189_nau8825_soc_card, + .num_jacks = MT8189_JACK_MAX, + .flags = RT5682I_HS_PRESENT + }, + .sof_priv = NULL, + .soc_probe = mt8189_nau8825_soc_card_probe, +}; + +static const struct mtk_soundcard_pdata mt8188_es8326_card = { + .card_name = "mt8188_es8326", + .card_data = &(struct mtk_platform_card_data) { + .card = &mt8189_nau8825_soc_card, + .num_jacks = MT8189_JACK_MAX, + .flags = ES8326_HS_PRESENT + }, + .sof_priv = NULL, + .soc_probe = mt8189_nau8825_soc_card_probe, +}; + +static const struct of_device_id mt8189_nau8825_dt_match[] = { + {.compatible = "mediatek,mt8189-nau8825", .data = &mt8189_nau8825_card,}, + {.compatible = "mediatek,mt8189-rt5650", .data = &mt8189_rt5650_card,}, + {.compatible = "mediatek,mt8189-rt5682s", .data = &mt8189_rt5682s_card,}, + {.compatible = "mediatek,mt8189-rt5682i", .data = &mt8189_rt5682i_card,}, + {.compatible = "mediatek,mt8189-es8326", .data = &mt8188_es8326_card,}, + {} +}; +MODULE_DEVICE_TABLE(of, mt8189_nau8825_dt_match); + +static struct platform_driver mt8189_nau8825_driver = { + .driver = { + .name = "mt8189-nau8825", + .of_match_table = mt8189_nau8825_dt_match, + .pm = &snd_soc_pm_ops, + }, + .probe = mtk_soundcard_common_probe, +}; +module_platform_driver(mt8189_nau8825_driver); + +/* Module information */ +MODULE_DESCRIPTION("MT8189 NAU8825 ALSA SoC machine driver"); +MODULE_AUTHOR("Darren Ye "); +MODULE_AUTHOR("Cyril Chao "); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/mediatek/mt8189/mt8189-reg.h b/sound/soc/mediatek/mt8189/mt8189-reg.h new file mode 100644 index 00000000000000..25f9658b6eaeef --- /dev/null +++ b/sound/soc/mediatek/mt8189/mt8189-reg.h @@ -0,0 +1,10773 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * mt8189-reg.h -- Mediatek 8189 audio driver reg definition + * + * Copyright (c) 2025 MediaTek Inc. + * Author: Darren Ye + */ + +#ifndef _MT8189_REG_H_ +#define _MT8189_REG_H_ + + /* reg bit enum */ +enum { + MT8189_MEMIF_PBUF_SIZE_32_BYTES, + MT8189_MEMIF_PBUF_SIZE_64_BYTES, + MT8189_MEMIF_PBUF_SIZE_128_BYTES, + MT8189_MEMIF_PBUF_SIZE_256_BYTES, + MT8189_MEMIF_PBUF_SIZE_NUM, +}; + +/***************************************************************************** + * R E G I S T E R D E F I N I T I O N + *****************************************************************************/ +/* AUDIO_TOP_CON0 */ +#define PDN_MTKAIFV4_SFT 25 +#define PDN_MTKAIFV4_MASK 0x1 +#define PDN_MTKAIFV4_MASK_SFT (0x1 << 25) +#define PDN_FM_I2S_SFT 24 +#define PDN_FM_I2S_MASK 0x1 +#define PDN_FM_I2S_MASK_SFT (0x1 << 24) +#define PDN_HW_GAIN01_SFT 21 +#define PDN_HW_GAIN01_MASK 0x1 +#define PDN_HW_GAIN01_MASK_SFT (0x1 << 21) +#define PDN_HW_GAIN23_SFT 20 +#define PDN_HW_GAIN23_MASK 0x1 +#define PDN_HW_GAIN23_MASK_SFT (0x1 << 20) +#define PDN_STF_SFT 19 +#define PDN_STF_MASK 0x1 +#define PDN_STF_MASK_SFT (0x1 << 19) +#define PDN_CM0_SFT 18 +#define PDN_CM0_MASK 0x1 +#define PDN_CM0_MASK_SFT (0x1 << 18) +#define PDN_CM1_SFT 17 +#define PDN_CM1_MASK 0x1 +#define PDN_CM1_MASK_SFT (0x1 << 17) +#define PDN_PCM0_SFT 14 +#define PDN_PCM0_MASK 0x1 +#define PDN_PCM0_MASK_SFT (0x1 << 14) +#define PDN_DL0_NLE_SFT 11 +#define PDN_DL0_NLE_MASK 0x1 +#define PDN_DL0_NLE_MASK_SFT (0x1 << 11) +#define PDN_DL0_PREDIS_SFT 10 +#define PDN_DL0_PREDIS_MASK 0x1 +#define PDN_DL0_PREDIS_MASK_SFT (0x1 << 10) +#define PDN_DL0_DAC_SFT 9 +#define PDN_DL0_DAC_MASK 0x1 +#define PDN_DL0_DAC_MASK_SFT (0x1 << 9) +#define PDN_DL0_DAC_HIRES_SFT 8 +#define PDN_DL0_DAC_HIRES_MASK 0x1 +#define PDN_DL0_DAC_HIRES_MASK_SFT (0x1 << 8) +#define PDN_DL0_DAC_TML_SFT 7 +#define PDN_DL0_DAC_TML_MASK 0x1 +#define PDN_DL0_DAC_TML_MASK_SFT (0x1 << 7) + +/* AUDIO_TOP_CON1 */ +#define PDN_UL0_ADC_SFT 23 +#define PDN_UL0_ADC_MASK 0x1 +#define PDN_UL0_ADC_MASK_SFT (0x1 << 23) +#define PDN_UL0_TML_SFT 22 +#define PDN_UL0_TML_MASK 0x1 +#define PDN_UL0_TML_MASK_SFT (0x1 << 22) +#define PDN_UL0_ADC_HIRES_SFT 21 +#define PDN_UL0_ADC_HIRES_MASK 0x1 +#define PDN_UL0_ADC_HIRES_MASK_SFT (0x1 << 21) +#define PDN_UL0_ADC_HIRES_TML_SFT 20 +#define PDN_UL0_ADC_HIRES_TML_MASK 0x1 +#define PDN_UL0_ADC_HIRES_TML_MASK_SFT (0x1 << 20) +#define PDN_UL1_ADC_SFT 19 +#define PDN_UL1_ADC_MASK 0x1 +#define PDN_UL1_ADC_MASK_SFT (0x1 << 19) +#define PDN_UL1_TML_SFT 18 +#define PDN_UL1_TML_MASK 0x1 +#define PDN_UL1_TML_MASK_SFT (0x1 << 18) +#define PDN_UL1_ADC_HIRES_SFT 17 +#define PDN_UL1_ADC_HIRES_MASK 0x1 +#define PDN_UL1_ADC_HIRES_MASK_SFT (0x1 << 17) +#define PDN_UL1_ADC_HIRES_TML_SFT 16 +#define PDN_UL1_ADC_HIRES_TML_MASK 0x1 +#define PDN_UL1_ADC_HIRES_TML_MASK_SFT (0x1 << 16) +#define PDN_DMIC0_ADC_SFT 7 +#define PDN_DMIC0_ADC_MASK 0x1 +#define PDN_DMIC0_ADC_MASK_SFT (0x1 << 7) +#define PDN_DMIC1_ADC_SFT 3 +#define PDN_DMIC1_ADC_MASK 0x1 +#define PDN_DMIC1_ADC_MASK_SFT (0x1 << 3) + +/* AUDIO_TOP_CON2 */ +#define PDN_TDM_OUT_SFT 24 +#define PDN_TDM_OUT_MASK 0x1 +#define PDN_TDM_OUT_MASK_SFT (0x1 << 24) +#define PDN_ETDM_OUT0_SFT 21 +#define PDN_ETDM_OUT0_MASK 0x1 +#define PDN_ETDM_OUT0_MASK_SFT (0x1 << 21) +#define PDN_ETDM_OUT1_SFT 20 +#define PDN_ETDM_OUT1_MASK 0x1 +#define PDN_ETDM_OUT1_MASK_SFT (0x1 << 20) +#define PDN_ETDM_OUT4_SFT 17 +#define PDN_ETDM_OUT4_MASK 0x1 +#define PDN_ETDM_OUT4_MASK_SFT (0x1 << 17) +#define PDN_ETDM_IN0_SFT 13 +#define PDN_ETDM_IN0_MASK 0x1 +#define PDN_ETDM_IN0_MASK_SFT (0x1 << 13) +#define PDN_ETDM_IN1_SFT 12 +#define PDN_ETDM_IN1_MASK 0x1 +#define PDN_ETDM_IN1_MASK_SFT (0x1 << 12) + +/* AUDIO_TOP_CON3 */ +#define PDN_CONNSYS_I2S_ASRC_SFT 25 +#define PDN_CONNSYS_I2S_ASRC_MASK 0x1 +#define PDN_CONNSYS_I2S_ASRC_MASK_SFT (0x1 << 25) +#define PDN_GENERAL0_ASRC_SFT 24 +#define PDN_GENERAL0_ASRC_MASK 0x1 +#define PDN_GENERAL0_ASRC_MASK_SFT (0x1 << 24) +#define PDN_GENERAL1_ASRC_SFT 23 +#define PDN_GENERAL1_ASRC_MASK 0x1 +#define PDN_GENERAL1_ASRC_MASK_SFT (0x1 << 23) +#define PDN_GENERAL2_ASRC_SFT 22 +#define PDN_GENERAL2_ASRC_MASK 0x1 +#define PDN_GENERAL2_ASRC_MASK_SFT (0x1 << 22) +#define PDN_GENERAL3_ASRC_SFT 21 +#define PDN_GENERAL3_ASRC_MASK 0x1 +#define PDN_GENERAL3_ASRC_MASK_SFT (0x1 << 21) +#define PDN_GENERAL4_ASRC_SFT 20 +#define PDN_GENERAL4_ASRC_MASK 0x1 +#define PDN_GENERAL4_ASRC_MASK_SFT (0x1 << 20) + +/* AUDIO_TOP_CON4 */ +#define PDN_APLL_TUNER1_SFT 13 +#define PDN_APLL_TUNER1_MASK 0x1 +#define PDN_APLL_TUNER1_MASK_SFT (0x1 << 13) +#define PDN_APLL_TUNER2_SFT 12 +#define PDN_APLL_TUNER2_MASK 0x1 +#define PDN_APLL_TUNER2_MASK_SFT (0x1 << 12) +#define CG_H208M_CK_SFT 4 +#define CG_H208M_CK_MASK 0x1 +#define CG_H208M_CK_MASK_SFT (0x1 << 4) +#define CG_APLL2_CK_SFT 3 +#define CG_APLL2_CK_MASK 0x1 +#define CG_APLL2_CK_MASK_SFT (0x1 << 3) +#define CG_APLL1_CK_SFT 2 +#define CG_APLL1_CK_MASK 0x1 +#define CG_APLL1_CK_MASK_SFT (0x1 << 2) +#define CG_AUDIO_F26M_CK_SFT 1 +#define CG_AUDIO_F26M_CK_MASK 0x1 +#define CG_AUDIO_F26M_CK_MASK_SFT (0x1 << 1) +#define CG_AUDIO_HOPPING_CK_SFT 0 +#define CG_AUDIO_HOPPING_CK_MASK 0x1 +#define CG_AUDIO_HOPPING_CK_MASK_SFT (0x1 << 0) + +/* AUDIO_ENGEN_CON0 */ +/* AUDIO_ENGEN_CON0_USER1 */ +/* AUDIO_ENGEN_CON0_USER2 */ +#define MULTI_USER_BYPASS_SFT 17 +#define MULTI_USER_BYPASS_MASK 0x1 +#define MULTI_USER_BYPASS_MASK_SFT (0x1 << 17) +#define MULTI_USER_RST_SFT 16 +#define MULTI_USER_RST_MASK 0x1 +#define MULTI_USER_RST_MASK_SFT (0x1 << 16) +#define AUDIO_F26M_EN_RST_SFT 8 +#define AUDIO_F26M_EN_RST_MASK 0x1 +#define AUDIO_F26M_EN_RST_MASK_SFT (0x1 << 8) +#define AUDIO_APLL2_EN_ON_SFT 3 +#define AUDIO_APLL2_EN_ON_MASK 0x1 +#define AUDIO_APLL2_EN_ON_MASK_SFT (0x1 << 3) +#define AUDIO_APLL1_EN_ON_SFT 2 +#define AUDIO_APLL1_EN_ON_MASK 0x1 +#define AUDIO_APLL1_EN_ON_MASK_SFT (0x1 << 2) +#define AUDIO_F3P25M_EN_ON_SFT 1 +#define AUDIO_F3P25M_EN_ON_MASK 0x1 +#define AUDIO_F3P25M_EN_ON_MASK_SFT (0x1 << 1) +#define AUDIO_26M_EN_ON_SFT 0 +#define AUDIO_26M_EN_ON_MASK 0x1 +#define AUDIO_26M_EN_ON_MASK_SFT (0x1 << 0) + +/* AFE_SINEGEN_CON0 */ +#define DAC_EN_SFT 26 +#define DAC_EN_MASK 0x1 +#define DAC_EN_MASK_SFT (0x1 << 26) +#define TIE_SW_CH2_SFT 25 +#define TIE_SW_CH2_MASK 0x1 +#define TIE_SW_CH2_MASK_SFT (0x1 << 25) +#define TIE_SW_CH1_SFT 24 +#define TIE_SW_CH1_MASK 0x1 +#define TIE_SW_CH1_MASK_SFT (0x1 << 24) +#define AMP_DIV_CH2_SFT 20 +#define AMP_DIV_CH2_MASK 0xf +#define AMP_DIV_CH2_MASK_SFT (0xf << 20) +#define FREQ_DIV_CH2_SFT 12 +#define FREQ_DIV_CH2_MASK 0x1f +#define FREQ_DIV_CH2_MASK_SFT (0x1f << 12) +#define AMP_DIV_CH1_SFT 8 +#define AMP_DIV_CH1_MASK 0xf +#define AMP_DIV_CH1_MASK_SFT (0xf << 8) +#define FREQ_DIV_CH1_SFT 0 +#define FREQ_DIV_CH1_MASK 0x1f +#define FREQ_DIV_CH1_MASK_SFT (0x1f << 0) + +/* AFE_SINEGEN_CON1 */ +#define SINE_DOMAIN_SFT 20 +#define SINE_DOMAIN_MASK 0x7 +#define SINE_DOMAIN_MASK_SFT (0x7 << 20) +#define SINE_MODE_SFT 12 +#define SINE_MODE_MASK 0x1f +#define SINE_MODE_MASK_SFT (0x1f << 12) +#define INNER_LOOP_BACKI_SEL_SFT 8 +#define INNER_LOOP_BACKI_SEL_MASK 0x1 +#define INNER_LOOP_BACKI_SEL_MASK_SFT (0x1 << 8) +#define INNER_LOOP_BACK_MODE_SFT 0 +#define INNER_LOOP_BACK_MODE_MASK 0xff +#define INNER_LOOP_BACK_MODE_MASK_SFT (0xff << 0) + +/* AFE_SINEGEN_CON2 */ +#define TIE_CH1_CONSTANT_SFT 0 +#define TIE_CH1_CONSTANT_MASK 0xffffffff +#define TIE_CH1_CONSTANT_MASK_SFT (0xffffffff << 0) + +/* AFE_SINEGEN_CON3 */ +#define TIE_CH2_CONSTANT_SFT 0 +#define TIE_CH2_CONSTANT_MASK 0xffffffff +#define TIE_CH2_CONSTANT_MASK_SFT (0xffffffff << 0) + +/* AFE_APLL1_TUNER_CFG */ +#define UPPER_BOUND_SFT 8 +#define UPPER_BOUND_MASK 0xff +#define UPPER_BOUND_MASK_SFT (0xff << 8) +#define APLL_DIV_SFT 4 +#define APLL_DIV_MASK 0xf +#define APLL_DIV_MASK_SFT (0xf << 4) +#define XTAL_EN_128FS_SEL_SFT 1 +#define XTAL_EN_128FS_SEL_MASK 0x3 +#define XTAL_EN_128FS_SEL_MASK_SFT (0x3 << 1) +#define FREQ_TUNER_EN_SFT 0 +#define FREQ_TUNER_EN_MASK 0x1 +#define FREQ_TUNER_EN_MASK_SFT (0x1 << 0) + +/* AFE_APLL1_TUNER_MON0 */ +#define TUNER_MON_SFT 0 +#define TUNER_MON_MASK 0xffffffff +#define TUNER_MON_MASK_SFT (0xffffffff << 0) + +/* AFE_APLL2_TUNER_CFG */ +#define UPPER_BOUND_SFT 8 +#define UPPER_BOUND_MASK 0xff +#define UPPER_BOUND_MASK_SFT (0xff << 8) +#define APLL_DIV_SFT 4 +#define APLL_DIV_MASK 0xf +#define APLL_DIV_MASK_SFT (0xf << 4) +#define XTAL_EN_128FS_SEL_SFT 1 +#define XTAL_EN_128FS_SEL_MASK 0x3 +#define XTAL_EN_128FS_SEL_MASK_SFT (0x3 << 1) +#define FREQ_TUNER_EN_SFT 0 +#define FREQ_TUNER_EN_MASK 0x1 +#define FREQ_TUNER_EN_MASK_SFT (0x1 << 0) + +/* AFE_APLL2_TUNER_MON0 */ +#define TUNER_MON_SFT 0 +#define TUNER_MON_MASK 0xffffffff +#define TUNER_MON_MASK_SFT (0xffffffff << 0) + +/* AUDIO_TOP_RG0 */ +#define RESERVE_RG_SFT 0 +#define RESERVE_RG_MASK 0xffffffff +#define RESERVE_RG_MASK_SFT (0xffffffff << 0) + +/* AUDIO_TOP_RG1 */ +#define RESERVE_RG_SFT 0 +#define RESERVE_RG_MASK 0xffffffff +#define RESERVE_RG_MASK_SFT (0xffffffff << 0) + +/* AUDIO_TOP_RG2 */ +#define RESERVE_RG_SFT 0 +#define RESERVE_RG_MASK 0xffffffff +#define RESERVE_RG_MASK_SFT (0xffffffff << 0) + +/* AUDIO_TOP_RG3 */ +#define RESERVE_RG_SFT 0 +#define RESERVE_RG_MASK 0xffffffff +#define RESERVE_RG_MASK_SFT (0xffffffff << 0) + +/* AUDIO_TOP_RG4 */ +#define RESERVE_RG_SFT 0 +#define RESERVE_RG_MASK 0xffffffff +#define RESERVE_RG_MASK_SFT (0xffffffff << 0) + +/* AFE_SPM_CONTROL_REQ */ +#define AFE_DDREN_REQ_SFT 4 +#define AFE_DDREN_REQ_MASK 0x1 +#define AFE_DDREN_REQ_MASK_SFT (0x1 << 4) +#define AFE_INFRA_REQ_SFT 3 +#define AFE_INFRA_REQ_MASK 0x1 +#define AFE_INFRA_REQ_MASK_SFT (0x1 << 3) +#define AFE_VRF18_REQ_SFT 2 +#define AFE_VRF18_REQ_MASK 0x1 +#define AFE_VRF18_REQ_MASK_SFT (0x1 << 2) +#define AFE_APSRC_REQ_SFT 1 +#define AFE_APSRC_REQ_MASK 0x1 +#define AFE_APSRC_REQ_MASK_SFT (0x1 << 1) +#define AFE_SRCCLKENA_REQ_SFT 0 +#define AFE_SRCCLKENA_REQ_MASK 0x1 +#define AFE_SRCCLKENA_REQ_MASK_SFT (0x1 << 0) + +/* AFE_SPM_CONTROL_ACK */ +#define SPM_RESOURCE_CONTROL_ACK_SFT 0 +#define SPM_RESOURCE_CONTROL_ACK_MASK 0xffffffff +#define SPM_RESOURCE_CONTROL_ACK_MASK_SFT (0xffffffff << 0) + +/* AUD_TOP_CFG_VCORE_RG */ +#define AUD_TOP_CFG_SFT 0 +#define AUD_TOP_CFG_MASK 0xffffffff +#define AUD_TOP_CFG_MASK_SFT (0xffffffff << 0) + +/* AUDIO_TOP_IP_VERSION */ +#define AUDIO_TOP_IP_VERSION_SFT 0 +#define AUDIO_TOP_IP_VERSION_MASK 0xffffffff +#define AUDIO_TOP_IP_VERSION_MASK_SFT (0xffffffff << 0) + +/* AUDIO_ENGEN_CON0_MON */ +#define AUDIO_ENGEN_MON_SFT 0 +#define AUDIO_ENGEN_MON_MASK 0xffffffff +#define AUDIO_ENGEN_MON_MASK_SFT (0xffffffff << 0) + +/* AUD_TOP_CFG_VLP_RG */ +#define AUD_TOP_CFG_SFT 0 +#define AUD_TOP_CFG_MASK 0xffffffff +#define AUD_TOP_CFG_MASK_SFT (0xffffffff << 0) + +/* AUD_TOP_MON_RG */ +#define AUD_TOP_MON_SFT 0 +#define AUD_TOP_MON_MASK 0xffffffff +#define AUD_TOP_MON_MASK_SFT (0xffffffff << 0) + +/* AUDIO_USE_DEFAULT_DELSEL0 */ +#define USE_DEFAULT_DELSEL_RG_SFT 0 +#define USE_DEFAULT_DELSEL_RG_MASK 0xffffffff +#define USE_DEFAULT_DELSEL_RG_MASK_SFT (0xffffffff << 0) + +/* AUDIO_USE_DEFAULT_DELSEL1 */ +#define USE_DEFAULT_DELSEL_RG_SFT 0 +#define USE_DEFAULT_DELSEL_RG_MASK 0xffffffff +#define USE_DEFAULT_DELSEL_RG_MASK_SFT (0xffffffff << 0) + +/* AUDIO_USE_DEFAULT_DELSEL2 */ +#define USE_DEFAULT_DELSEL_RG_SFT 0 +#define USE_DEFAULT_DELSEL_RG_MASK 0xffffffff +#define USE_DEFAULT_DELSEL_RG_MASK_SFT (0xffffffff << 0) + +/* AFE_CONNSYS_I2S_IPM_VER_MON */ +#define RG_CONNSYS_I2S_IPM_VER_MON_SFT 0 +#define RG_CONNSYS_I2S_IPM_VER_MON_MASK 0xffffffff +#define RG_CONNSYS_I2S_IPM_VER_MON_MASK_SFT (0xffffffff << 0) + +/* AFE_CONNSYS_I2S_MON_SEL */ +#define RG_CONNSYS_I2S_MON_SEL_SFT 0 +#define RG_CONNSYS_I2S_MON_SEL_MASK 0xff +#define RG_CONNSYS_I2S_MON_SEL_MASK_SFT (0xff << 0) + +/* AFE_CONNSYS_I2S_MON */ +#define RG_CONNSYS_I2S_MON_SFT 0 +#define RG_CONNSYS_I2S_MON_MASK 0xffffffff +#define RG_CONNSYS_I2S_MON_MASK_SFT (0xffffffff << 0) + +/* AFE_CONNSYS_I2S_CON */ +#define I2S_SOFT_RST_SFT 31 +#define I2S_SOFT_RST_MASK 0x1 +#define I2S_SOFT_RST_MASK_SFT (0x1 << 31) +#define BCK_NEG_EG_LATCH_SFT 30 +#define BCK_NEG_EG_LATCH_MASK 0x1 +#define BCK_NEG_EG_LATCH_MASK_SFT (0x1 << 30) +#define BCK_INV_SFT 29 +#define BCK_INV_MASK 0x1 +#define BCK_INV_MASK_SFT (0x1 << 29) +#define I2SIN_PAD_SEL_SFT 28 +#define I2SIN_PAD_SEL_MASK 0x1 +#define I2SIN_PAD_SEL_MASK_SFT (0x1 << 28) +#define I2S_LOOPBACK_SFT 20 +#define I2S_LOOPBACK_MASK 0x1 +#define I2S_LOOPBACK_MASK_SFT (0x1 << 20) +#define I2S_HDEN_SFT 12 +#define I2S_HDEN_MASK 0x1 +#define I2S_HDEN_MASK_SFT (0x1 << 12) +#define I2S_MODE_SFT 8 +#define I2S_MODE_MASK 0xf +#define I2S_MODE_MASK_SFT (0xf << 8) +#define I2S_BYPSRC_SFT 6 +#define I2S_BYPSRC_MASK 0x1 +#define I2S_BYPSRC_MASK_SFT (0x1 << 6) +#define INV_LRCK_SFT 5 +#define INV_LRCK_MASK 0x1 +#define INV_LRCK_MASK_SFT (0x1 << 5) +#define I2S_FMT_SFT 3 +#define I2S_FMT_MASK 0x1 +#define I2S_FMT_MASK_SFT (0x1 << 3) +#define I2S_SRC_SFT 2 +#define I2S_SRC_MASK 0x1 +#define I2S_SRC_MASK_SFT (0x1 << 2) +#define I2S_WLEN_SFT 1 +#define I2S_WLEN_MASK 0x1 +#define I2S_WLEN_MASK_SFT (0x1 << 1) +#define I2S_EN_SFT 0 +#define I2S_EN_MASK 0x1 +#define I2S_EN_MASK_SFT (0x1 << 0) + +/* AFE_PCM0_INTF_CON0 */ +#define PCM0_HDEN_SFT 26 +#define PCM0_HDEN_MASK 0x1 +#define PCM0_HDEN_MASK_SFT (0x1 << 26) +#define PCM0_SYNC_DELSEL_SFT 25 +#define PCM0_SYNC_DELSEL_MASK 0x1 +#define PCM0_SYNC_DELSEL_MASK_SFT (0x1 << 25) +#define PCM0_TX_LR_SWAP_SFT 24 +#define PCM0_TX_LR_SWAP_MASK 0x1 +#define PCM0_TX_LR_SWAP_MASK_SFT (0x1 << 24) +#define PCM0_SYNC_OUT_INV_SFT 23 +#define PCM0_SYNC_OUT_INV_MASK 0x1 +#define PCM0_SYNC_OUT_INV_MASK_SFT (0x1 << 23) +#define PCM0_BCLK_OUT_INV_SFT 22 +#define PCM0_BCLK_OUT_INV_MASK 0x1 +#define PCM0_BCLK_OUT_INV_MASK_SFT (0x1 << 22) +#define PCM0_SYNC_IN_INV_SFT 21 +#define PCM0_SYNC_IN_INV_MASK 0x1 +#define PCM0_SYNC_IN_INV_MASK_SFT (0x1 << 21) +#define PCM0_BCLK_IN_INV_SFT 20 +#define PCM0_BCLK_IN_INV_MASK 0x1 +#define PCM0_BCLK_IN_INV_MASK_SFT (0x1 << 20) +#define PCM0_TX_LCH_RPT_SFT 19 +#define PCM0_TX_LCH_RPT_MASK 0x1 +#define PCM0_TX_LCH_RPT_MASK_SFT (0x1 << 19) +#define PCM0_VBT_16K_MODE_SFT 18 +#define PCM0_VBT_16K_MODE_MASK 0x1 +#define PCM0_VBT_16K_MODE_MASK_SFT (0x1 << 18) +#define PCM0_BIT_LENGTH_SFT 16 +#define PCM0_BIT_LENGTH_MASK 0x3 +#define PCM0_BIT_LENGTH_MASK_SFT (0x3 << 16) +#define PCM0_WLEN_SFT 14 +#define PCM0_WLEN_MASK 0x3 +#define PCM0_WLEN_MASK_SFT (0x3 << 14) +#define PCM0_SYNC_LENGTH_SFT 9 +#define PCM0_SYNC_LENGTH_MASK 0x1f +#define PCM0_SYNC_LENGTH_MASK_SFT (0x1f << 9) +#define PCM0_SYNC_TYPE_SFT 8 +#define PCM0_SYNC_TYPE_MASK 0x1 +#define PCM0_SYNC_TYPE_MASK_SFT (0x1 << 8) +#define PCM0_BYP_ASRC_SFT 7 +#define PCM0_BYP_ASRC_MASK 0x1 +#define PCM0_BYP_ASRC_MASK_SFT (0x1 << 7) +#define PCM0_SLAVE_SFT 6 +#define PCM0_SLAVE_MASK 0x1 +#define PCM0_SLAVE_MASK_SFT (0x1 << 6) +#define PCM0_MODE_SFT 3 +#define PCM0_MODE_MASK 0x7 +#define PCM0_MODE_MASK_SFT (0x7 << 3) +#define PCM0_FMT_SFT 1 +#define PCM0_FMT_MASK 0x3 +#define PCM0_FMT_MASK_SFT (0x3 << 1) +#define PCM0_EN_SFT 0 +#define PCM0_EN_MASK 0x1 +#define PCM0_EN_MASK_SFT (0x1 << 0) + +/* AFE_PCM0_INTF_CON1 */ +#define PCM0_TX_RX_LOOPBACK_SFT 31 +#define PCM0_TX_RX_LOOPBACK_MASK 0x1 +#define PCM0_TX_RX_LOOPBACK_MASK_SFT (0x1 << 31) +#define PCM0_BUFFER_LOOPBACK_SFT 30 +#define PCM0_BUFFER_LOOPBACK_MASK 0x1 +#define PCM0_BUFFER_LOOPBACK_MASK_SFT (0x1 << 30) +#define PCM0_PARALLEL_LOOPBACK_SFT 29 +#define PCM0_PARALLEL_LOOPBACK_MASK 0x1 +#define PCM0_PARALLEL_LOOPBACK_MASK_SFT (0x1 << 29) +#define PCM0_SERIAL_LOOPBACK_SFT 28 +#define PCM0_SERIAL_LOOPBACK_MASK 0x1 +#define PCM0_SERIAL_LOOPBACK_MASK_SFT (0x1 << 28) +#define PCM0_DAI_LOOPBACK_SFT 27 +#define PCM0_DAI_LOOPBACK_MASK 0x1 +#define PCM0_DAI_LOOPBACK_MASK_SFT (0x1 << 27) +#define PCM0_I2S_LOOPBACK_SFT 26 +#define PCM0_I2S_LOOPBACK_MASK 0x1 +#define PCM0_I2S_LOOPBACK_MASK_SFT (0x1 << 26) +#define PCM0_1X_EN_DOMAIN_SFT 23 +#define PCM0_1X_EN_DOMAIN_MASK 0x7 +#define PCM0_1X_EN_DOMAIN_MASK_SFT (0x7 << 23) +#define PCM0_1X_EN_MODE_SFT 18 +#define PCM0_1X_EN_MODE_MASK 0x1f +#define PCM0_1X_EN_MODE_MASK_SFT (0x1f << 18) +#define PCM0_TX3_RCH_DBG_MODE_SFT 17 +#define PCM0_TX3_RCH_DBG_MODE_MASK 0x1 +#define PCM0_TX3_RCH_DBG_MODE_MASK_SFT (0x1 << 17) +#define PCM0_PCM1_LOOPBACK_SFT 16 +#define PCM0_PCM1_LOOPBACK_MASK 0x1 +#define PCM0_PCM1_LOOPBACK_MASK_SFT (0x1 << 16) +#define PCM0_LOOPBACK_CH_SEL_SFT 12 +#define PCM0_LOOPBACK_CH_SEL_MASK 0x3 +#define PCM0_LOOPBACK_CH_SEL_MASK_SFT (0x3 << 12) +#define PCM0_BT_MODE_SFT 11 +#define PCM0_BT_MODE_MASK 0x1 +#define PCM0_BT_MODE_MASK_SFT (0x1 << 11) +#define PCM0_EXT_MODEM_SFT 10 +#define PCM0_EXT_MODEM_MASK 0x1 +#define PCM0_EXT_MODEM_MASK_SFT (0x1 << 10) +#define PCM0_USE_MD3_SFT 9 +#define PCM0_USE_MD3_MASK 0x1 +#define PCM0_USE_MD3_MASK_SFT (0x1 << 9) +#define PCM0_FIX_VALUE_SEL_SFT 8 +#define PCM0_FIX_VALUE_SEL_MASK 0x1 +#define PCM0_FIX_VALUE_SEL_MASK_SFT (0x1 << 8) +#define PCM0_TX_FIX_VALUE_SFT 0 +#define PCM0_TX_FIX_VALUE_MASK 0xff +#define PCM0_TX_FIX_VALUE_MASK_SFT (0xff << 0) + +/* AFE_PCM_INTF_MON */ +#define PCM0_TX_FIFO_OV_SFT 5 +#define PCM0_TX_FIFO_OV_MASK 0x1 +#define PCM0_TX_FIFO_OV_MASK_SFT (0x1 << 5) +#define PCM0_RX_FIFO_OV_SFT 4 +#define PCM0_RX_FIFO_OV_MASK 0x1 +#define PCM0_RX_FIFO_OV_MASK_SFT (0x1 << 4) +#define PCM1_TX_FIFO_OV_SFT 3 +#define PCM1_TX_FIFO_OV_MASK 0x1 +#define PCM1_TX_FIFO_OV_MASK_SFT (0x1 << 3) +#define PCM1_RX_FIFO_OV_SFT 2 +#define PCM1_RX_FIFO_OV_MASK 0x1 +#define PCM1_RX_FIFO_OV_MASK_SFT (0x1 << 2) +#define PCM0_SYNC_GLITCH_SFT 1 +#define PCM0_SYNC_GLITCH_MASK 0x1 +#define PCM0_SYNC_GLITCH_MASK_SFT (0x1 << 1) +#define PCM1_SYNC_GLITCH_SFT 0 +#define PCM1_SYNC_GLITCH_MASK 0x1 +#define PCM1_SYNC_GLITCH_MASK_SFT (0x1 << 0) + +/* AFE_PCM_TOP_IP_VERSION */ +#define AFE_PCM_TOP_IP_VERSION_SFT 0 +#define AFE_PCM_TOP_IP_VERSION_MASK 0xffffffff +#define AFE_PCM_TOP_IP_VERSION_MASK_SFT (0xffffffff << 0) + +/* AFE_IRQ_MCU_EN */ +#define AFE_IRQ_MCU_EN_SFT 0 +#define AFE_IRQ_MCU_EN_MASK 0xffffffff +#define AFE_IRQ_MCU_EN_MASK_SFT (0xffffffff << 0) + +/* AFE_IRQ_MCU_DSP_EN */ +#define AFE_IRQ_DSP_EN_SFT 0 +#define AFE_IRQ_DSP_EN_MASK 0xffffffff +#define AFE_IRQ_DSP_EN_MASK_SFT (0xffffffff << 0) + +/* AFE_IRQ_MCU_DSP2_EN */ +#define AFE_IRQ_DSP2_EN_SFT 0 +#define AFE_IRQ_DSP2_EN_MASK 0xffffffff +#define AFE_IRQ_DSP2_EN_MASK_SFT (0xffffffff << 0) + +/* AFE_IRQ_MCU_SCP_EN */ +#define IRQ31_MCU_SCP_EN_SFT 31 +#define IRQ30_MCU_SCP_EN_SFT 30 +#define IRQ29_MCU_SCP_EN_SFT 29 +#define IRQ28_MCU_SCP_EN_SFT 28 +#define IRQ27_MCU_SCP_EN_SFT 27 +#define IRQ26_MCU_SCP_EN_SFT 26 +#define IRQ25_MCU_SCP_EN_SFT 25 +#define IRQ24_MCU_SCP_EN_SFT 24 +#define IRQ23_MCU_SCP_EN_SFT 23 +#define IRQ22_MCU_SCP_EN_SFT 22 +#define IRQ21_MCU_SCP_EN_SFT 21 +#define IRQ20_MCU_SCP_EN_SFT 20 +#define IRQ19_MCU_SCP_EN_SFT 19 +#define IRQ18_MCU_SCP_EN_SFT 18 +#define IRQ17_MCU_SCP_EN_SFT 17 +#define IRQ16_MCU_SCP_EN_SFT 16 +#define IRQ15_MCU_SCP_EN_SFT 15 +#define IRQ14_MCU_SCP_EN_SFT 14 +#define IRQ13_MCU_SCP_EN_SFT 13 +#define IRQ12_MCU_SCP_EN_SFT 12 +#define IRQ11_MCU_SCP_EN_SFT 11 +#define IRQ10_MCU_SCP_EN_SFT 10 +#define IRQ9_MCU_SCP_EN_SFT 9 +#define IRQ8_MCU_SCP_EN_SFT 8 +#define IRQ7_MCU_SCP_EN_SFT 7 +#define IRQ6_MCU_SCP_EN_SFT 6 +#define IRQ5_MCU_SCP_EN_SFT 5 +#define IRQ4_MCU_SCP_EN_SFT 4 +#define IRQ3_MCU_SCP_EN_SFT 3 +#define IRQ2_MCU_SCP_EN_SFT 2 +#define IRQ1_MCU_SCP_EN_SFT 1 +#define IRQ0_MCU_SCP_EN_SFT 0 + +/* AFE_CUSTOM_IRQ_MCU_EN */ +#define AFE_CUSTOM_IRQ_MCU_EN_SFT 0 +#define AFE_CUSTOM_IRQ_MCU_EN_MASK 0xffffffff +#define AFE_CUSTOM_IRQ_MCU_EN_MASK_SFT (0xffffffff << 0) + +/* AFE_CUSTOM_IRQ_MCU_DSP_EN */ +#define AFE_CUSTOM_IRQ_DSP_EN_SFT 0 +#define AFE_CUSTOM_IRQ_DSP_EN_MASK 0xffffffff +#define AFE_CUSTOM_IRQ_DSP_EN_MASK_SFT (0xffffffff << 0) + +/* AFE_CUSTOM_IRQ_MCU_DSP2_EN */ +#define AFE_CUSTOM_IRQ_DSP2_EN_SFT 0 +#define AFE_CUSTOM_IRQ_DSP2_EN_MASK 0xffffffff +#define AFE_CUSTOM_IRQ_DSP2_EN_MASK_SFT (0xffffffff << 0) + +/* AFE_CUSTOM_IRQ_MCU_SCP_EN */ +#define AFE_CUSTOM_IRQ_SCP_EN_SFT 0 +#define AFE_CUSTOM_IRQ_SCP_EN_MASK 0xffffffff +#define AFE_CUSTOM_IRQ_SCP_EN_MASK_SFT (0xffffffff << 0) + +/* AFE_IRQ_MCU_STATUS */ +#define IRQ26_MCU_SFT 26 +#define IRQ26_MCU_MASK 0x1 +#define IRQ26_MCU_MASK_SFT (0x1 << 26) +#define IRQ25_MCU_SFT 25 +#define IRQ25_MCU_MASK 0x1 +#define IRQ25_MCU_MASK_SFT (0x1 << 25) +#define IRQ24_MCU_SFT 24 +#define IRQ24_MCU_MASK 0x1 +#define IRQ24_MCU_MASK_SFT (0x1 << 24) +#define IRQ23_MCU_SFT 23 +#define IRQ23_MCU_MASK 0x1 +#define IRQ23_MCU_MASK_SFT (0x1 << 23) +#define IRQ22_MCU_SFT 22 +#define IRQ22_MCU_MASK 0x1 +#define IRQ22_MCU_MASK_SFT (0x1 << 22) +#define IRQ21_MCU_SFT 21 +#define IRQ21_MCU_MASK 0x1 +#define IRQ21_MCU_MASK_SFT (0x1 << 21) +#define IRQ20_MCU_SFT 20 +#define IRQ20_MCU_MASK 0x1 +#define IRQ20_MCU_MASK_SFT (0x1 << 20) +#define IRQ19_MCU_SFT 19 +#define IRQ19_MCU_MASK 0x1 +#define IRQ19_MCU_MASK_SFT (0x1 << 19) +#define IRQ18_MCU_SFT 18 +#define IRQ18_MCU_MASK 0x1 +#define IRQ18_MCU_MASK_SFT (0x1 << 18) +#define IRQ17_MCU_SFT 17 +#define IRQ17_MCU_MASK 0x1 +#define IRQ17_MCU_MASK_SFT (0x1 << 17) +#define IRQ16_MCU_SFT 16 +#define IRQ16_MCU_MASK 0x1 +#define IRQ16_MCU_MASK_SFT (0x1 << 16) +#define IRQ15_MCU_SFT 15 +#define IRQ15_MCU_MASK 0x1 +#define IRQ15_MCU_MASK_SFT (0x1 << 15) +#define IRQ14_MCU_SFT 14 +#define IRQ14_MCU_MASK 0x1 +#define IRQ14_MCU_MASK_SFT (0x1 << 14) +#define IRQ13_MCU_SFT 13 +#define IRQ13_MCU_MASK 0x1 +#define IRQ13_MCU_MASK_SFT (0x1 << 13) +#define IRQ12_MCU_SFT 12 +#define IRQ12_MCU_MASK 0x1 +#define IRQ12_MCU_MASK_SFT (0x1 << 12) +#define IRQ11_MCU_SFT 11 +#define IRQ11_MCU_MASK 0x1 +#define IRQ11_MCU_MASK_SFT (0x1 << 11) +#define IRQ10_MCU_SFT 10 +#define IRQ10_MCU_MASK 0x1 +#define IRQ10_MCU_MASK_SFT (0x1 << 10) +#define IRQ9_MCU_SFT 9 +#define IRQ9_MCU_MASK 0x1 +#define IRQ9_MCU_MASK_SFT (0x1 << 9) +#define IRQ8_MCU_SFT 8 +#define IRQ8_MCU_MASK 0x1 +#define IRQ8_MCU_MASK_SFT (0x1 << 8) +#define IRQ7_MCU_SFT 7 +#define IRQ7_MCU_MASK 0x1 +#define IRQ7_MCU_MASK_SFT (0x1 << 7) +#define IRQ6_MCU_SFT 6 +#define IRQ6_MCU_MASK 0x1 +#define IRQ6_MCU_MASK_SFT (0x1 << 6) +#define IRQ5_MCU_SFT 5 +#define IRQ5_MCU_MASK 0x1 +#define IRQ5_MCU_MASK_SFT (0x1 << 5) +#define IRQ4_MCU_SFT 4 +#define IRQ4_MCU_MASK 0x1 +#define IRQ4_MCU_MASK_SFT (0x1 << 4) +#define IRQ3_MCU_SFT 3 +#define IRQ3_MCU_MASK 0x1 +#define IRQ3_MCU_MASK_SFT (0x1 << 3) +#define IRQ2_MCU_SFT 2 +#define IRQ2_MCU_MASK 0x1 +#define IRQ2_MCU_MASK_SFT (0x1 << 2) +#define IRQ1_MCU_SFT 1 +#define IRQ1_MCU_MASK 0x1 +#define IRQ1_MCU_MASK_SFT (0x1 << 1) +#define IRQ0_MCU_SFT 0 +#define IRQ0_MCU_MASK 0x1 +#define IRQ0_MCU_MASK_SFT (0x1 << 0) + +/* AFE_CUSTOM_IRQ_MCU_STATUS */ +#define CUSTOM_IRQ21_MCU_SFT 21 +#define CUSTOM_IRQ21_MCU_MASK 0x1 +#define CUSTOM_IRQ21_MCU_MASK_SFT (0x1 << 21) +#define CUSTOM_IRQ20_MCU_SFT 20 +#define CUSTOM_IRQ20_MCU_MASK 0x1 +#define CUSTOM_IRQ20_MCU_MASK_SFT (0x1 << 20) +#define CUSTOM_IRQ19_MCU_SFT 19 +#define CUSTOM_IRQ19_MCU_MASK 0x1 +#define CUSTOM_IRQ19_MCU_MASK_SFT (0x1 << 19) +#define CUSTOM_IRQ18_MCU_SFT 18 +#define CUSTOM_IRQ18_MCU_MASK 0x1 +#define CUSTOM_IRQ18_MCU_MASK_SFT (0x1 << 18) +#define CUSTOM_IRQ17_MCU_SFT 17 +#define CUSTOM_IRQ17_MCU_MASK 0x1 +#define CUSTOM_IRQ17_MCU_MASK_SFT (0x1 << 17) +#define CUSTOM_IRQ16_MCU_SFT 16 +#define CUSTOM_IRQ16_MCU_MASK 0x1 +#define CUSTOM_IRQ16_MCU_MASK_SFT (0x1 << 16) +#define CUSTOM_IRQ9_MCU_SFT 9 +#define CUSTOM_IRQ9_MCU_MASK 0x1 +#define CUSTOM_IRQ9_MCU_MASK_SFT (0x1 << 9) +#define CUSTOM_IRQ8_MCU_SFT 8 +#define CUSTOM_IRQ8_MCU_MASK 0x1 +#define CUSTOM_IRQ8_MCU_MASK_SFT (0x1 << 8) +#define CUSTOM_IRQ7_MCU_SFT 7 +#define CUSTOM_IRQ7_MCU_MASK 0x1 +#define CUSTOM_IRQ7_MCU_MASK_SFT (0x1 << 7) +#define CUSTOM_IRQ6_MCU_SFT 6 +#define CUSTOM_IRQ6_MCU_MASK 0x1 +#define CUSTOM_IRQ6_MCU_MASK_SFT (0x1 << 6) +#define CUSTOM_IRQ5_MCU_SFT 5 +#define CUSTOM_IRQ5_MCU_MASK 0x1 +#define CUSTOM_IRQ5_MCU_MASK_SFT (0x1 << 5) +#define CUSTOM_IRQ4_MCU_SFT 4 +#define CUSTOM_IRQ4_MCU_MASK 0x1 +#define CUSTOM_IRQ4_MCU_MASK_SFT (0x1 << 4) +#define CUSTOM_IRQ3_MCU_SFT 3 +#define CUSTOM_IRQ3_MCU_MASK 0x1 +#define CUSTOM_IRQ3_MCU_MASK_SFT (0x1 << 3) +#define CUSTOM_IRQ2_MCU_SFT 2 +#define CUSTOM_IRQ2_MCU_MASK 0x1 +#define CUSTOM_IRQ2_MCU_MASK_SFT (0x1 << 2) +#define CUSTOM_IRQ1_MCU_SFT 1 +#define CUSTOM_IRQ1_MCU_MASK 0x1 +#define CUSTOM_IRQ1_MCU_MASK_SFT (0x1 << 1) +#define CUSTOM_IRQ0_MCU_SFT 0 +#define CUSTOM_IRQ0_MCU_MASK 0x1 +#define CUSTOM_IRQ0_MCU_MASK_SFT (0x1 << 0) + +/* AFE_IRQ_MCU_CFG */ +#define AFE_IRQ_CLR_CFG_SFT 31 +#define AFE_IRQ_CLR_CFG_MASK 0x1 +#define AFE_IRQ_CLR_CFG_MASK_SFT (0x1 << 31) +#define AFE_IRQ_MISS_FLAG_CLR_CFG_SFT 30 +#define AFE_IRQ_MISS_FLAG_CLR_CFG_MASK 0x1 +#define AFE_IRQ_MISS_FLAG_CLR_CFG_MASK_SFT (0x1 << 30) +#define AFE_IRQ_MCU_CNT_SFT 0 +#define AFE_IRQ_MCU_CNT_MASK 0xffffff +#define AFE_IRQ_MCU_CNT_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ0_MCU_CFG0 */ +#define AFE_IRQ0_MCU_DOMAIN_SFT 9 +#define AFE_IRQ0_MCU_DOMAIN_MASK 0x7 +#define AFE_IRQ0_MCU_DOMAIN_MASK_SFT (0x7 << 9) +#define AFE_IRQ0_MCU_FS_SFT 4 +#define AFE_IRQ0_MCU_FS_MASK 0x1f +#define AFE_IRQ0_MCU_FS_MASK_SFT (0x1f << 4) +#define AFE_IRQ0_MCU_ON_SFT 0 +#define AFE_IRQ0_MCU_ON_MASK 0x1 +#define AFE_IRQ0_MCU_ON_MASK_SFT (0x1 << 0) + +/* AFE_IRQ0_MCU_CFG1 */ +#define AFE_IRQ0_CLR_CFG_SFT 31 +#define AFE_IRQ0_CLR_CFG_MASK 0x1 +#define AFE_IRQ0_CLR_CFG_MASK_SFT (0x1 << 31) +#define AFE_IRQ0_MISS_FLAG_CLR_CFG_SFT 30 +#define AFE_IRQ0_MISS_FLAG_CLR_CFG_MASK 0x1 +#define AFE_IRQ0_MISS_FLAG_CLR_CFG_MASK_SFT (0x1 << 30) +#define AFE_IRQ0_MCU_CNT_SFT 0 +#define AFE_IRQ0_MCU_CNT_MASK 0xffffff +#define AFE_IRQ0_MCU_CNT_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ1_MCU_CFG0 */ +#define AFE_IRQ1_MCU_DOMAIN_SFT 9 +#define AFE_IRQ1_MCU_DOMAIN_MASK 0x7 +#define AFE_IRQ1_MCU_DOMAIN_MASK_SFT (0x7 << 9) +#define AFE_IRQ1_MCU_FS_SFT 4 +#define AFE_IRQ1_MCU_FS_MASK 0x1f +#define AFE_IRQ1_MCU_FS_MASK_SFT (0x1f << 4) +#define AFE_IRQ1_MCU_ON_SFT 0 +#define AFE_IRQ1_MCU_ON_MASK 0x1 +#define AFE_IRQ1_MCU_ON_MASK_SFT (0x1 << 0) + +/* AFE_IRQ1_MCU_CFG1 */ +#define AFE_IRQ1_CLR_CFG_SFT 31 +#define AFE_IRQ1_CLR_CFG_MASK 0x1 +#define AFE_IRQ1_CLR_CFG_MASK_SFT (0x1 << 31) +#define AFE_IRQ1_MISS_FLAG_CLR_CFG_SFT 30 +#define AFE_IRQ1_MISS_FLAG_CLR_CFG_MASK 0x1 +#define AFE_IRQ1_MISS_FLAG_CLR_CFG_MASK_SFT (0x1 << 30) +#define AFE_IRQ1_MCU_CNT_SFT 0 +#define AFE_IRQ1_MCU_CNT_MASK 0xffffff +#define AFE_IRQ1_MCU_CNT_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ2_MCU_CFG0 */ +#define AFE_IRQ2_MCU_DOMAIN_SFT 9 +#define AFE_IRQ2_MCU_DOMAIN_MASK 0x7 +#define AFE_IRQ2_MCU_DOMAIN_MASK_SFT (0x7 << 9) +#define AFE_IRQ2_MCU_FS_SFT 4 +#define AFE_IRQ2_MCU_FS_MASK 0x1f +#define AFE_IRQ2_MCU_FS_MASK_SFT (0x1f << 4) +#define AFE_IRQ2_MCU_ON_SFT 0 +#define AFE_IRQ2_MCU_ON_MASK 0x1 +#define AFE_IRQ2_MCU_ON_MASK_SFT (0x1 << 0) + +/* AFE_IRQ2_MCU_CFG1 */ +#define AFE_IRQ2_CLR_CFG_SFT 31 +#define AFE_IRQ2_CLR_CFG_MASK 0x1 +#define AFE_IRQ2_CLR_CFG_MASK_SFT (0x1 << 31) +#define AFE_IRQ2_MISS_FLAG_CLR_CFG_SFT 30 +#define AFE_IRQ2_MISS_FLAG_CLR_CFG_MASK 0x1 +#define AFE_IRQ2_MISS_FLAG_CLR_CFG_MASK_SFT (0x1 << 30) +#define AFE_IRQ2_MCU_CNT_SFT 0 +#define AFE_IRQ2_MCU_CNT_MASK 0xffffff +#define AFE_IRQ2_MCU_CNT_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ3_MCU_CFG0 */ +#define AFE_IRQ3_MCU_DOMAIN_SFT 9 +#define AFE_IRQ3_MCU_DOMAIN_MASK 0x7 +#define AFE_IRQ3_MCU_DOMAIN_MASK_SFT (0x7 << 9) +#define AFE_IRQ3_MCU_FS_SFT 4 +#define AFE_IRQ3_MCU_FS_MASK 0x1f +#define AFE_IRQ3_MCU_FS_MASK_SFT (0x1f << 4) +#define AFE_IRQ3_MCU_ON_SFT 0 +#define AFE_IRQ3_MCU_ON_MASK 0x1 +#define AFE_IRQ3_MCU_ON_MASK_SFT (0x1 << 0) + +/* AFE_IRQ3_MCU_CFG1 */ +#define AFE_IRQ3_CLR_CFG_SFT 31 +#define AFE_IRQ3_CLR_CFG_MASK 0x1 +#define AFE_IRQ3_CLR_CFG_MASK_SFT (0x1 << 31) +#define AFE_IRQ3_MISS_FLAG_CLR_CFG_SFT 30 +#define AFE_IRQ3_MISS_FLAG_CLR_CFG_MASK 0x1 +#define AFE_IRQ3_MISS_FLAG_CLR_CFG_MASK_SFT (0x1 << 30) +#define AFE_IRQ3_MCU_CNT_SFT 0 +#define AFE_IRQ3_MCU_CNT_MASK 0xffffff +#define AFE_IRQ3_MCU_CNT_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ4_MCU_CFG0 */ +#define AFE_IRQ4_MCU_DOMAIN_SFT 9 +#define AFE_IRQ4_MCU_DOMAIN_MASK 0x7 +#define AFE_IRQ4_MCU_DOMAIN_MASK_SFT (0x7 << 9) +#define AFE_IRQ4_MCU_FS_SFT 4 +#define AFE_IRQ4_MCU_FS_MASK 0x1f +#define AFE_IRQ4_MCU_FS_MASK_SFT (0x1f << 4) +#define AFE_IRQ4_MCU_ON_SFT 0 +#define AFE_IRQ4_MCU_ON_MASK 0x1 +#define AFE_IRQ4_MCU_ON_MASK_SFT (0x1 << 0) + +/* AFE_IRQ4_MCU_CFG1 */ +#define AFE_IRQ4_CLR_CFG_SFT 31 +#define AFE_IRQ4_CLR_CFG_MASK 0x1 +#define AFE_IRQ4_CLR_CFG_MASK_SFT (0x1 << 31) +#define AFE_IRQ4_MISS_FLAG_CLR_CFG_SFT 30 +#define AFE_IRQ4_MISS_FLAG_CLR_CFG_MASK 0x1 +#define AFE_IRQ4_MISS_FLAG_CLR_CFG_MASK_SFT (0x1 << 30) +#define AFE_IRQ4_MCU_CNT_SFT 0 +#define AFE_IRQ4_MCU_CNT_MASK 0xffffff +#define AFE_IRQ4_MCU_CNT_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ5_MCU_CFG0 */ +#define AFE_IRQ5_MCU_DOMAIN_SFT 9 +#define AFE_IRQ5_MCU_DOMAIN_MASK 0x7 +#define AFE_IRQ5_MCU_DOMAIN_MASK_SFT (0x7 << 9) +#define AFE_IRQ5_MCU_FS_SFT 4 +#define AFE_IRQ5_MCU_FS_MASK 0x1f +#define AFE_IRQ5_MCU_FS_MASK_SFT (0x1f << 4) +#define AFE_IRQ5_MCU_ON_SFT 0 +#define AFE_IRQ5_MCU_ON_MASK 0x1 +#define AFE_IRQ5_MCU_ON_MASK_SFT (0x1 << 0) + +/* AFE_IRQ5_MCU_CFG1 */ +#define AFE_IRQ5_CLR_CFG_SFT 31 +#define AFE_IRQ5_CLR_CFG_MASK 0x1 +#define AFE_IRQ5_CLR_CFG_MASK_SFT (0x1 << 31) +#define AFE_IRQ5_MISS_FLAG_CLR_CFG_SFT 30 +#define AFE_IRQ5_MISS_FLAG_CLR_CFG_MASK 0x1 +#define AFE_IRQ5_MISS_FLAG_CLR_CFG_MASK_SFT (0x1 << 30) +#define AFE_IRQ5_MCU_CNT_SFT 0 +#define AFE_IRQ5_MCU_CNT_MASK 0xffffff +#define AFE_IRQ5_MCU_CNT_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ6_MCU_CFG0 */ +#define AFE_IRQ6_MCU_DOMAIN_SFT 9 +#define AFE_IRQ6_MCU_DOMAIN_MASK 0x7 +#define AFE_IRQ6_MCU_DOMAIN_MASK_SFT (0x7 << 9) +#define AFE_IRQ6_MCU_FS_SFT 4 +#define AFE_IRQ6_MCU_FS_MASK 0x1f +#define AFE_IRQ6_MCU_FS_MASK_SFT (0x1f << 4) +#define AFE_IRQ6_MCU_ON_SFT 0 +#define AFE_IRQ6_MCU_ON_MASK 0x1 +#define AFE_IRQ6_MCU_ON_MASK_SFT (0x1 << 0) + +/* AFE_IRQ6_MCU_CFG1 */ +#define AFE_IRQ6_CLR_CFG_SFT 31 +#define AFE_IRQ6_CLR_CFG_MASK 0x1 +#define AFE_IRQ6_CLR_CFG_MASK_SFT (0x1 << 31) +#define AFE_IRQ6_MISS_FLAG_CLR_CFG_SFT 30 +#define AFE_IRQ6_MISS_FLAG_CLR_CFG_MASK 0x1 +#define AFE_IRQ6_MISS_FLAG_CLR_CFG_MASK_SFT (0x1 << 30) +#define AFE_IRQ6_MCU_CNT_SFT 0 +#define AFE_IRQ6_MCU_CNT_MASK 0xffffff +#define AFE_IRQ6_MCU_CNT_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ7_MCU_CFG0 */ +#define AFE_IRQ7_MCU_DOMAIN_SFT 9 +#define AFE_IRQ7_MCU_DOMAIN_MASK 0x7 +#define AFE_IRQ7_MCU_DOMAIN_MASK_SFT (0x7 << 9) +#define AFE_IRQ7_MCU_FS_SFT 4 +#define AFE_IRQ7_MCU_FS_MASK 0x1f +#define AFE_IRQ7_MCU_FS_MASK_SFT (0x1f << 4) +#define AFE_IRQ7_MCU_ON_SFT 0 +#define AFE_IRQ7_MCU_ON_MASK 0x1 +#define AFE_IRQ7_MCU_ON_MASK_SFT (0x1 << 0) + +/* AFE_IRQ7_MCU_CFG1 */ +#define AFE_IRQ7_CLR_CFG_SFT 31 +#define AFE_IRQ7_CLR_CFG_MASK 0x1 +#define AFE_IRQ7_CLR_CFG_MASK_SFT (0x1 << 31) +#define AFE_IRQ7_MISS_FLAG_CLR_CFG_SFT 30 +#define AFE_IRQ7_MISS_FLAG_CLR_CFG_MASK 0x1 +#define AFE_IRQ7_MISS_FLAG_CLR_CFG_MASK_SFT (0x1 << 30) +#define AFE_IRQ7_MCU_CNT_SFT 0 +#define AFE_IRQ7_MCU_CNT_MASK 0xffffff +#define AFE_IRQ7_MCU_CNT_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ8_MCU_CFG0 */ +#define AFE_IRQ8_MCU_DOMAIN_SFT 9 +#define AFE_IRQ8_MCU_DOMAIN_MASK 0x7 +#define AFE_IRQ8_MCU_DOMAIN_MASK_SFT (0x7 << 9) +#define AFE_IRQ8_MCU_FS_SFT 4 +#define AFE_IRQ8_MCU_FS_MASK 0x1f +#define AFE_IRQ8_MCU_FS_MASK_SFT (0x1f << 4) +#define AFE_IRQ8_MCU_ON_SFT 0 +#define AFE_IRQ8_MCU_ON_MASK 0x1 +#define AFE_IRQ8_MCU_ON_MASK_SFT (0x1 << 0) + +/* AFE_IRQ8_MCU_CFG1 */ +#define AFE_IRQ8_CLR_CFG_SFT 31 +#define AFE_IRQ8_CLR_CFG_MASK 0x1 +#define AFE_IRQ8_CLR_CFG_MASK_SFT (0x1 << 31) +#define AFE_IRQ8_MISS_FLAG_CLR_CFG_SFT 30 +#define AFE_IRQ8_MISS_FLAG_CLR_CFG_MASK 0x1 +#define AFE_IRQ8_MISS_FLAG_CLR_CFG_MASK_SFT (0x1 << 30) +#define AFE_IRQ8_MCU_CNT_SFT 0 +#define AFE_IRQ8_MCU_CNT_MASK 0xffffff +#define AFE_IRQ8_MCU_CNT_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ9_MCU_CFG0 */ +#define AFE_IRQ9_MCU_DOMAIN_SFT 9 +#define AFE_IRQ9_MCU_DOMAIN_MASK 0x7 +#define AFE_IRQ9_MCU_DOMAIN_MASK_SFT (0x7 << 9) +#define AFE_IRQ9_MCU_FS_SFT 4 +#define AFE_IRQ9_MCU_FS_MASK 0x1f +#define AFE_IRQ9_MCU_FS_MASK_SFT (0x1f << 4) +#define AFE_IRQ9_MCU_ON_SFT 0 +#define AFE_IRQ9_MCU_ON_MASK 0x1 +#define AFE_IRQ9_MCU_ON_MASK_SFT (0x1 << 0) + +/* AFE_IRQ9_MCU_CFG1 */ +#define AFE_IRQ9_CLR_CFG_SFT 31 +#define AFE_IRQ9_CLR_CFG_MASK 0x1 +#define AFE_IRQ9_CLR_CFG_MASK_SFT (0x1 << 31) +#define AFE_IRQ9_MISS_FLAG_CLR_CFG_SFT 30 +#define AFE_IRQ9_MISS_FLAG_CLR_CFG_MASK 0x1 +#define AFE_IRQ9_MISS_FLAG_CLR_CFG_MASK_SFT (0x1 << 30) +#define AFE_IRQ9_MCU_CNT_SFT 0 +#define AFE_IRQ9_MCU_CNT_MASK 0xffffff +#define AFE_IRQ9_MCU_CNT_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ10_MCU_CFG0 */ +#define AFE_IRQ10_MCU_DOMAIN_SFT 9 +#define AFE_IRQ10_MCU_DOMAIN_MASK 0x7 +#define AFE_IRQ10_MCU_DOMAIN_MASK_SFT (0x7 << 9) +#define AFE_IRQ10_MCU_FS_SFT 4 +#define AFE_IRQ10_MCU_FS_MASK 0x1f +#define AFE_IRQ10_MCU_FS_MASK_SFT (0x1f << 4) +#define AFE_IRQ10_MCU_ON_SFT 0 +#define AFE_IRQ10_MCU_ON_MASK 0x1 +#define AFE_IRQ10_MCU_ON_MASK_SFT (0x1 << 0) + +/* AFE_IRQ10_MCU_CFG1 */ +#define AFE_IRQ10_CLR_CFG_SFT 31 +#define AFE_IRQ10_CLR_CFG_MASK 0x1 +#define AFE_IRQ10_CLR_CFG_MASK_SFT (0x1 << 31) +#define AFE_IRQ10_MISS_FLAG_CLR_CFG_SFT 30 +#define AFE_IRQ10_MISS_FLAG_CLR_CFG_MASK 0x1 +#define AFE_IRQ10_MISS_FLAG_CLR_CFG_MASK_SFT (0x1 << 30) +#define AFE_IRQ10_MCU_CNT_SFT 0 +#define AFE_IRQ10_MCU_CNT_MASK 0xffffff +#define AFE_IRQ10_MCU_CNT_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ11_MCU_CFG0 */ +#define AFE_IRQ11_MCU_DOMAIN_SFT 9 +#define AFE_IRQ11_MCU_DOMAIN_MASK 0x7 +#define AFE_IRQ11_MCU_DOMAIN_MASK_SFT (0x7 << 9) +#define AFE_IRQ11_MCU_FS_SFT 4 +#define AFE_IRQ11_MCU_FS_MASK 0x1f +#define AFE_IRQ11_MCU_FS_MASK_SFT (0x1f << 4) +#define AFE_IRQ11_MCU_ON_SFT 0 +#define AFE_IRQ11_MCU_ON_MASK 0x1 +#define AFE_IRQ11_MCU_ON_MASK_SFT (0x1 << 0) + +/* AFE_IRQ11_MCU_CFG1 */ +#define AFE_IRQ11_CLR_CFG_SFT 31 +#define AFE_IRQ11_CLR_CFG_MASK 0x1 +#define AFE_IRQ11_CLR_CFG_MASK_SFT (0x1 << 31) +#define AFE_IRQ11_MISS_FLAG_CLR_CFG_SFT 30 +#define AFE_IRQ11_MISS_FLAG_CLR_CFG_MASK 0x1 +#define AFE_IRQ11_MISS_FLAG_CLR_CFG_MASK_SFT (0x1 << 30) +#define AFE_IRQ11_MCU_CNT_SFT 0 +#define AFE_IRQ11_MCU_CNT_MASK 0xffffff +#define AFE_IRQ11_MCU_CNT_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ12_MCU_CFG0 */ +#define AFE_IRQ12_MCU_DOMAIN_SFT 9 +#define AFE_IRQ12_MCU_DOMAIN_MASK 0x7 +#define AFE_IRQ12_MCU_DOMAIN_MASK_SFT (0x7 << 9) +#define AFE_IRQ12_MCU_FS_SFT 4 +#define AFE_IRQ12_MCU_FS_MASK 0x1f +#define AFE_IRQ12_MCU_FS_MASK_SFT (0x1f << 4) +#define AFE_IRQ12_MCU_ON_SFT 0 +#define AFE_IRQ12_MCU_ON_MASK 0x1 +#define AFE_IRQ12_MCU_ON_MASK_SFT (0x1 << 0) + +/* AFE_IRQ12_MCU_CFG1 */ +#define AFE_IRQ12_CLR_CFG_SFT 31 +#define AFE_IRQ12_CLR_CFG_MASK 0x1 +#define AFE_IRQ12_CLR_CFG_MASK_SFT (0x1 << 31) +#define AFE_IRQ12_MISS_FLAG_CLR_CFG_SFT 30 +#define AFE_IRQ12_MISS_FLAG_CLR_CFG_MASK 0x1 +#define AFE_IRQ12_MISS_FLAG_CLR_CFG_MASK_SFT (0x1 << 30) +#define AFE_IRQ12_MCU_CNT_SFT 0 +#define AFE_IRQ12_MCU_CNT_MASK 0xffffff +#define AFE_IRQ12_MCU_CNT_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ13_MCU_CFG0 */ +#define AFE_IRQ13_MCU_DOMAIN_SFT 9 +#define AFE_IRQ13_MCU_DOMAIN_MASK 0x7 +#define AFE_IRQ13_MCU_DOMAIN_MASK_SFT (0x7 << 9) +#define AFE_IRQ13_MCU_FS_SFT 4 +#define AFE_IRQ13_MCU_FS_MASK 0x1f +#define AFE_IRQ13_MCU_FS_MASK_SFT (0x1f << 4) +#define AFE_IRQ13_MCU_ON_SFT 0 +#define AFE_IRQ13_MCU_ON_MASK 0x1 +#define AFE_IRQ13_MCU_ON_MASK_SFT (0x1 << 0) + +/* AFE_IRQ13_MCU_CFG1 */ +#define AFE_IRQ13_CLR_CFG_SFT 31 +#define AFE_IRQ13_CLR_CFG_MASK 0x1 +#define AFE_IRQ13_CLR_CFG_MASK_SFT (0x1 << 31) +#define AFE_IRQ13_MISS_FLAG_CLR_CFG_SFT 30 +#define AFE_IRQ13_MISS_FLAG_CLR_CFG_MASK 0x1 +#define AFE_IRQ13_MISS_FLAG_CLR_CFG_MASK_SFT (0x1 << 30) +#define AFE_IRQ13_MCU_CNT_SFT 0 +#define AFE_IRQ13_MCU_CNT_MASK 0xffffff +#define AFE_IRQ13_MCU_CNT_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ14_MCU_CFG0 */ +#define AFE_IRQ14_MCU_DOMAIN_SFT 9 +#define AFE_IRQ14_MCU_DOMAIN_MASK 0x7 +#define AFE_IRQ14_MCU_DOMAIN_MASK_SFT (0x7 << 9) +#define AFE_IRQ14_MCU_FS_SFT 4 +#define AFE_IRQ14_MCU_FS_MASK 0x1f +#define AFE_IRQ14_MCU_FS_MASK_SFT (0x1f << 4) +#define AFE_IRQ14_MCU_ON_SFT 0 +#define AFE_IRQ14_MCU_ON_MASK 0x1 +#define AFE_IRQ14_MCU_ON_MASK_SFT (0x1 << 0) + +/* AFE_IRQ14_MCU_CFG1 */ +#define AFE_IRQ14_CLR_CFG_SFT 31 +#define AFE_IRQ14_CLR_CFG_MASK 0x1 +#define AFE_IRQ14_CLR_CFG_MASK_SFT (0x1 << 31) +#define AFE_IRQ14_MISS_FLAG_CLR_CFG_SFT 30 +#define AFE_IRQ14_MISS_FLAG_CLR_CFG_MASK 0x1 +#define AFE_IRQ14_MISS_FLAG_CLR_CFG_MASK_SFT (0x1 << 30) +#define AFE_IRQ14_MCU_CNT_SFT 0 +#define AFE_IRQ14_MCU_CNT_MASK 0xffffff +#define AFE_IRQ14_MCU_CNT_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ15_MCU_CFG0 */ +#define AFE_IRQ15_MCU_DOMAIN_SFT 9 +#define AFE_IRQ15_MCU_DOMAIN_MASK 0x7 +#define AFE_IRQ15_MCU_DOMAIN_MASK_SFT (0x7 << 9) +#define AFE_IRQ15_MCU_FS_SFT 4 +#define AFE_IRQ15_MCU_FS_MASK 0x1f +#define AFE_IRQ15_MCU_FS_MASK_SFT (0x1f << 4) +#define AFE_IRQ15_MCU_ON_SFT 0 +#define AFE_IRQ15_MCU_ON_MASK 0x1 +#define AFE_IRQ15_MCU_ON_MASK_SFT (0x1 << 0) + +/* AFE_IRQ15_MCU_CFG1 */ +#define AFE_IRQ15_CLR_CFG_SFT 31 +#define AFE_IRQ15_CLR_CFG_MASK 0x1 +#define AFE_IRQ15_CLR_CFG_MASK_SFT (0x1 << 31) +#define AFE_IRQ15_MISS_FLAG_CLR_CFG_SFT 30 +#define AFE_IRQ15_MISS_FLAG_CLR_CFG_MASK 0x1 +#define AFE_IRQ15_MISS_FLAG_CLR_CFG_MASK_SFT (0x1 << 30) +#define AFE_IRQ15_MCU_CNT_SFT 0 +#define AFE_IRQ15_MCU_CNT_MASK 0xffffff +#define AFE_IRQ15_MCU_CNT_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ16_MCU_CFG0 */ +#define AFE_IRQ16_MCU_DOMAIN_SFT 9 +#define AFE_IRQ16_MCU_DOMAIN_MASK 0x7 +#define AFE_IRQ16_MCU_DOMAIN_MASK_SFT (0x7 << 9) +#define AFE_IRQ16_MCU_FS_SFT 4 +#define AFE_IRQ16_MCU_FS_MASK 0x1f +#define AFE_IRQ16_MCU_FS_MASK_SFT (0x1f << 4) +#define AFE_IRQ16_MCU_ON_SFT 0 +#define AFE_IRQ16_MCU_ON_MASK 0x1 +#define AFE_IRQ16_MCU_ON_MASK_SFT (0x1 << 0) + +/* AFE_IRQ16_MCU_CFG1 */ +#define AFE_IRQ16_CLR_CFG_SFT 31 +#define AFE_IRQ16_CLR_CFG_MASK 0x1 +#define AFE_IRQ16_CLR_CFG_MASK_SFT (0x1 << 31) +#define AFE_IRQ16_MISS_FLAG_CLR_CFG_SFT 30 +#define AFE_IRQ16_MISS_FLAG_CLR_CFG_MASK 0x1 +#define AFE_IRQ16_MISS_FLAG_CLR_CFG_MASK_SFT (0x1 << 30) +#define AFE_IRQ16_MCU_CNT_SFT 0 +#define AFE_IRQ16_MCU_CNT_MASK 0xffffff +#define AFE_IRQ16_MCU_CNT_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ17_MCU_CFG0 */ +#define AFE_IRQ17_MCU_DOMAIN_SFT 9 +#define AFE_IRQ17_MCU_DOMAIN_MASK 0x7 +#define AFE_IRQ17_MCU_DOMAIN_MASK_SFT (0x7 << 9) +#define AFE_IRQ17_MCU_FS_SFT 4 +#define AFE_IRQ17_MCU_FS_MASK 0x1f +#define AFE_IRQ17_MCU_FS_MASK_SFT (0x1f << 4) +#define AFE_IRQ17_MCU_ON_SFT 0 +#define AFE_IRQ17_MCU_ON_MASK 0x1 +#define AFE_IRQ17_MCU_ON_MASK_SFT (0x1 << 0) + +/* AFE_IRQ17_MCU_CFG1 */ +#define AFE_IRQ17_CLR_CFG_SFT 31 +#define AFE_IRQ17_CLR_CFG_MASK 0x1 +#define AFE_IRQ17_CLR_CFG_MASK_SFT (0x1 << 31) +#define AFE_IRQ17_MISS_FLAG_CLR_CFG_SFT 30 +#define AFE_IRQ17_MISS_FLAG_CLR_CFG_MASK 0x1 +#define AFE_IRQ17_MISS_FLAG_CLR_CFG_MASK_SFT (0x1 << 30) +#define AFE_IRQ17_MCU_CNT_SFT 0 +#define AFE_IRQ17_MCU_CNT_MASK 0xffffff +#define AFE_IRQ17_MCU_CNT_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ18_MCU_CFG0 */ +#define AFE_IRQ18_MCU_DOMAIN_SFT 9 +#define AFE_IRQ18_MCU_DOMAIN_MASK 0x7 +#define AFE_IRQ18_MCU_DOMAIN_MASK_SFT (0x7 << 9) +#define AFE_IRQ18_MCU_FS_SFT 4 +#define AFE_IRQ18_MCU_FS_MASK 0x1f +#define AFE_IRQ18_MCU_FS_MASK_SFT (0x1f << 4) +#define AFE_IRQ18_MCU_ON_SFT 0 +#define AFE_IRQ18_MCU_ON_MASK 0x1 +#define AFE_IRQ18_MCU_ON_MASK_SFT (0x1 << 0) + +/* AFE_IRQ18_MCU_CFG1 */ +#define AFE_IRQ18_CLR_CFG_SFT 31 +#define AFE_IRQ18_CLR_CFG_MASK 0x1 +#define AFE_IRQ18_CLR_CFG_MASK_SFT (0x1 << 31) +#define AFE_IRQ18_MISS_FLAG_CLR_CFG_SFT 30 +#define AFE_IRQ18_MISS_FLAG_CLR_CFG_MASK 0x1 +#define AFE_IRQ18_MISS_FLAG_CLR_CFG_MASK_SFT (0x1 << 30) +#define AFE_IRQ18_MCU_CNT_SFT 0 +#define AFE_IRQ18_MCU_CNT_MASK 0xffffff +#define AFE_IRQ18_MCU_CNT_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ19_MCU_CFG0 */ +#define AFE_IRQ19_MCU_DOMAIN_SFT 9 +#define AFE_IRQ19_MCU_DOMAIN_MASK 0x7 +#define AFE_IRQ19_MCU_DOMAIN_MASK_SFT (0x7 << 9) +#define AFE_IRQ19_MCU_FS_SFT 4 +#define AFE_IRQ19_MCU_FS_MASK 0x1f +#define AFE_IRQ19_MCU_FS_MASK_SFT (0x1f << 4) +#define AFE_IRQ19_MCU_ON_SFT 0 +#define AFE_IRQ19_MCU_ON_MASK 0x1 +#define AFE_IRQ19_MCU_ON_MASK_SFT (0x1 << 0) + +/* AFE_IRQ19_MCU_CFG1 */ +#define AFE_IRQ19_CLR_CFG_SFT 31 +#define AFE_IRQ19_CLR_CFG_MASK 0x1 +#define AFE_IRQ19_CLR_CFG_MASK_SFT (0x1 << 31) +#define AFE_IRQ19_MISS_FLAG_CLR_CFG_SFT 30 +#define AFE_IRQ19_MISS_FLAG_CLR_CFG_MASK 0x1 +#define AFE_IRQ19_MISS_FLAG_CLR_CFG_MASK_SFT (0x1 << 30) +#define AFE_IRQ19_MCU_CNT_SFT 0 +#define AFE_IRQ19_MCU_CNT_MASK 0xffffff +#define AFE_IRQ19_MCU_CNT_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ20_MCU_CFG0 */ +#define AFE_IRQ20_MCU_DOMAIN_SFT 9 +#define AFE_IRQ20_MCU_DOMAIN_MASK 0x7 +#define AFE_IRQ20_MCU_DOMAIN_MASK_SFT (0x7 << 9) +#define AFE_IRQ20_MCU_FS_SFT 4 +#define AFE_IRQ20_MCU_FS_MASK 0x1f +#define AFE_IRQ20_MCU_FS_MASK_SFT (0x1f << 4) +#define AFE_IRQ20_MCU_ON_SFT 0 +#define AFE_IRQ20_MCU_ON_MASK 0x1 +#define AFE_IRQ20_MCU_ON_MASK_SFT (0x1 << 0) + +/* AFE_IRQ20_MCU_CFG1 */ +#define AFE_IRQ20_CLR_CFG_SFT 31 +#define AFE_IRQ20_CLR_CFG_MASK 0x1 +#define AFE_IRQ20_CLR_CFG_MASK_SFT (0x1 << 31) +#define AFE_IRQ20_MISS_FLAG_CLR_CFG_SFT 30 +#define AFE_IRQ20_MISS_FLAG_CLR_CFG_MASK 0x1 +#define AFE_IRQ20_MISS_FLAG_CLR_CFG_MASK_SFT (0x1 << 30) +#define AFE_IRQ20_MCU_CNT_SFT 0 +#define AFE_IRQ20_MCU_CNT_MASK 0xffffff +#define AFE_IRQ20_MCU_CNT_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ21_MCU_CFG0 */ +#define AFE_IRQ21_MCU_DOMAIN_SFT 9 +#define AFE_IRQ21_MCU_DOMAIN_MASK 0x7 +#define AFE_IRQ21_MCU_DOMAIN_MASK_SFT (0x7 << 9) +#define AFE_IRQ21_MCU_FS_SFT 4 +#define AFE_IRQ21_MCU_FS_MASK 0x1f +#define AFE_IRQ21_MCU_FS_MASK_SFT (0x1f << 4) +#define AFE_IRQ21_MCU_ON_SFT 0 +#define AFE_IRQ21_MCU_ON_MASK 0x1 +#define AFE_IRQ21_MCU_ON_MASK_SFT (0x1 << 0) + +/* AFE_IRQ21_MCU_CFG1 */ +#define AFE_IRQ21_CLR_CFG_SFT 31 +#define AFE_IRQ21_CLR_CFG_MASK 0x1 +#define AFE_IRQ21_CLR_CFG_MASK_SFT (0x1 << 31) +#define AFE_IRQ21_MISS_FLAG_CLR_CFG_SFT 30 +#define AFE_IRQ21_MISS_FLAG_CLR_CFG_MASK 0x1 +#define AFE_IRQ21_MISS_FLAG_CLR_CFG_MASK_SFT (0x1 << 30) +#define AFE_IRQ21_MCU_CNT_SFT 0 +#define AFE_IRQ21_MCU_CNT_MASK 0xffffff +#define AFE_IRQ21_MCU_CNT_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ22_MCU_CFG0 */ +#define AFE_IRQ22_MCU_DOMAIN_SFT 9 +#define AFE_IRQ22_MCU_DOMAIN_MASK 0x7 +#define AFE_IRQ22_MCU_DOMAIN_MASK_SFT (0x7 << 9) +#define AFE_IRQ22_MCU_FS_SFT 4 +#define AFE_IRQ22_MCU_FS_MASK 0x1f +#define AFE_IRQ22_MCU_FS_MASK_SFT (0x1f << 4) +#define AFE_IRQ22_MCU_ON_SFT 0 +#define AFE_IRQ22_MCU_ON_MASK 0x1 +#define AFE_IRQ22_MCU_ON_MASK_SFT (0x1 << 0) + +/* AFE_IRQ22_MCU_CFG1 */ +#define AFE_IRQ22_CLR_CFG_SFT 31 +#define AFE_IRQ22_CLR_CFG_MASK 0x1 +#define AFE_IRQ22_CLR_CFG_MASK_SFT (0x1 << 31) +#define AFE_IRQ22_MISS_FLAG_CLR_CFG_SFT 30 +#define AFE_IRQ22_MISS_FLAG_CLR_CFG_MASK 0x1 +#define AFE_IRQ22_MISS_FLAG_CLR_CFG_MASK_SFT (0x1 << 30) +#define AFE_IRQ22_MCU_CNT_SFT 0 +#define AFE_IRQ22_MCU_CNT_MASK 0xffffff +#define AFE_IRQ22_MCU_CNT_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ23_MCU_CFG0 */ +#define AFE_IRQ23_MCU_DOMAIN_SFT 9 +#define AFE_IRQ23_MCU_DOMAIN_MASK 0x7 +#define AFE_IRQ23_MCU_DOMAIN_MASK_SFT (0x7 << 9) +#define AFE_IRQ23_MCU_FS_SFT 4 +#define AFE_IRQ23_MCU_FS_MASK 0x1f +#define AFE_IRQ23_MCU_FS_MASK_SFT (0x1f << 4) +#define AFE_IRQ23_MCU_ON_SFT 0 +#define AFE_IRQ23_MCU_ON_MASK 0x1 +#define AFE_IRQ23_MCU_ON_MASK_SFT (0x1 << 0) + +/* AFE_IRQ23_MCU_CFG1 */ +#define AFE_IRQ23_CLR_CFG_SFT 31 +#define AFE_IRQ23_CLR_CFG_MASK 0x1 +#define AFE_IRQ23_CLR_CFG_MASK_SFT (0x1 << 31) +#define AFE_IRQ23_MISS_FLAG_CLR_CFG_SFT 30 +#define AFE_IRQ23_MISS_FLAG_CLR_CFG_MASK 0x1 +#define AFE_IRQ23_MISS_FLAG_CLR_CFG_MASK_SFT (0x1 << 30) +#define AFE_IRQ23_MCU_CNT_SFT 0 +#define AFE_IRQ23_MCU_CNT_MASK 0xffffff +#define AFE_IRQ23_MCU_CNT_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ24_MCU_CFG0 */ +#define AFE_IRQ24_MCU_DOMAIN_SFT 9 +#define AFE_IRQ24_MCU_DOMAIN_MASK 0x7 +#define AFE_IRQ24_MCU_DOMAIN_MASK_SFT (0x7 << 9) +#define AFE_IRQ24_MCU_FS_SFT 4 +#define AFE_IRQ24_MCU_FS_MASK 0x1f +#define AFE_IRQ24_MCU_FS_MASK_SFT (0x1f << 4) +#define AFE_IRQ24_MCU_ON_SFT 0 +#define AFE_IRQ24_MCU_ON_MASK 0x1 +#define AFE_IRQ24_MCU_ON_MASK_SFT (0x1 << 0) + +/* AFE_IRQ24_MCU_CFG1 */ +#define AFE_IRQ24_CLR_CFG_SFT 31 +#define AFE_IRQ24_CLR_CFG_MASK 0x1 +#define AFE_IRQ24_CLR_CFG_MASK_SFT (0x1 << 31) +#define AFE_IRQ24_MISS_FLAG_CLR_CFG_SFT 30 +#define AFE_IRQ24_MISS_FLAG_CLR_CFG_MASK 0x1 +#define AFE_IRQ24_MISS_FLAG_CLR_CFG_MASK_SFT (0x1 << 30) +#define AFE_IRQ24_MCU_CNT_SFT 0 +#define AFE_IRQ24_MCU_CNT_MASK 0xffffff +#define AFE_IRQ24_MCU_CNT_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ25_MCU_CFG0 */ +#define AFE_IRQ25_MCU_DOMAIN_SFT 9 +#define AFE_IRQ25_MCU_DOMAIN_MASK 0x7 +#define AFE_IRQ25_MCU_DOMAIN_MASK_SFT (0x7 << 9) +#define AFE_IRQ25_MCU_FS_SFT 4 +#define AFE_IRQ25_MCU_FS_MASK 0x1f +#define AFE_IRQ25_MCU_FS_MASK_SFT (0x1f << 4) +#define AFE_IRQ25_MCU_ON_SFT 0 +#define AFE_IRQ25_MCU_ON_MASK 0x1 +#define AFE_IRQ25_MCU_ON_MASK_SFT (0x1 << 0) + +/* AFE_IRQ25_MCU_CFG1 */ +#define AFE_IRQ25_CLR_CFG_SFT 31 +#define AFE_IRQ25_CLR_CFG_MASK 0x1 +#define AFE_IRQ25_CLR_CFG_MASK_SFT (0x1 << 31) +#define AFE_IRQ25_MISS_FLAG_CLR_CFG_SFT 30 +#define AFE_IRQ25_MISS_FLAG_CLR_CFG_MASK 0x1 +#define AFE_IRQ25_MISS_FLAG_CLR_CFG_MASK_SFT (0x1 << 30) +#define AFE_IRQ25_MCU_CNT_SFT 0 +#define AFE_IRQ25_MCU_CNT_MASK 0xffffff +#define AFE_IRQ25_MCU_CNT_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ26_MCU_CFG0 */ +#define AFE_IRQ26_MCU_DOMAIN_SFT 9 +#define AFE_IRQ26_MCU_DOMAIN_MASK 0x7 +#define AFE_IRQ26_MCU_DOMAIN_MASK_SFT (0x7 << 9) +#define AFE_IRQ26_MCU_FS_SFT 4 +#define AFE_IRQ26_MCU_FS_MASK 0x1f +#define AFE_IRQ26_MCU_FS_MASK_SFT (0x1f << 4) +#define AFE_IRQ26_MCU_ON_SFT 0 +#define AFE_IRQ26_MCU_ON_MASK 0x1 +#define AFE_IRQ26_MCU_ON_MASK_SFT (0x1 << 0) + +/* AFE_IRQ26_MCU_CFG1 */ +#define AFE_IRQ26_CLR_CFG_SFT 31 +#define AFE_IRQ26_CLR_CFG_MASK 0x1 +#define AFE_IRQ26_CLR_CFG_MASK_SFT (0x1 << 31) +#define AFE_IRQ26_MISS_FLAG_CLR_CFG_SFT 30 +#define AFE_IRQ26_MISS_FLAG_CLR_CFG_MASK 0x1 +#define AFE_IRQ26_MISS_FLAG_CLR_CFG_MASK_SFT (0x1 << 30) +#define AFE_IRQ26_MCU_CNT_SFT 0 +#define AFE_IRQ26_MCU_CNT_MASK 0xffffff +#define AFE_IRQ26_MCU_CNT_MASK_SFT (0xffffff << 0) + +/* AFE_CUSTOM_IRQ0_MCU_CFG0 */ +#define AFE_CUSTOM_IRQ0_MCU_ON_SFT 0 +#define AFE_CUSTOM_IRQ0_MCU_ON_MASK 0x1 +#define AFE_CUSTOM_IRQ0_MCU_ON_MASK_SFT (0x1 << 0) + +/* AFE_CUSTOM_IRQ0_CNT_MON */ +#define AFE_CUSTOM_IRQ0_CNT_MON_SFT 0 +#define AFE_CUSTOM_IRQ0_CNT_MON_MASK 0xffffff +#define AFE_CUSTOM_IRQ0_CNT_MON_MASK_SFT (0xffffff << 0) + +/* AFE_CUSTOM_IRQ0_MCU_CFG1 */ +#define AFE_CUSTOM_IRQ0_CLR_CFG_SFT 31 +#define AFE_CUSTOM_IRQ0_CLR_CFG_MASK 0x1 +#define AFE_CUSTOM_IRQ0_CLR_CFG_MASK_SFT (0x1 << 31) +#define AFE_CUSTOM_IRQ0_MISS_FLAG_CLR_CFG_SFT 30 +#define AFE_CUSTOM_IRQ0_MISS_FLAG_CLR_CFG_MASK 0x1 +#define AFE_CUSTOM_IRQ0_MISS_FLAG_CLR_CFG_MASK_SFT (0x1 << 30) +#define AFE_CUSTOM_IRQ0_MCU_CNT_SFT 0 +#define AFE_CUSTOM_IRQ0_MCU_CNT_MASK 0xffffff +#define AFE_CUSTOM_IRQ0_MCU_CNT_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ_MCU_MON0 */ +#define AFE_IRQ26_MISS_FLAG_SFT 26 +#define AFE_IRQ26_MISS_FLAG_MASK 0x1 +#define AFE_IRQ26_MISS_FLAG_MASK_SFT (0x1 << 26) +#define AFE_IRQ25_MISS_FLAG_SFT 25 +#define AFE_IRQ25_MISS_FLAG_MASK 0x1 +#define AFE_IRQ25_MISS_FLAG_MASK_SFT (0x1 << 25) +#define AFE_IRQ24_MISS_FLAG_SFT 24 +#define AFE_IRQ24_MISS_FLAG_MASK 0x1 +#define AFE_IRQ24_MISS_FLAG_MASK_SFT (0x1 << 24) +#define AFE_IRQ23_MISS_FLAG_SFT 23 +#define AFE_IRQ23_MISS_FLAG_MASK 0x1 +#define AFE_IRQ23_MISS_FLAG_MASK_SFT (0x1 << 23) +#define AFE_IRQ22_MISS_FLAG_SFT 22 +#define AFE_IRQ22_MISS_FLAG_MASK 0x1 +#define AFE_IRQ22_MISS_FLAG_MASK_SFT (0x1 << 22) +#define AFE_IRQ21_MISS_FLAG_SFT 21 +#define AFE_IRQ21_MISS_FLAG_MASK 0x1 +#define AFE_IRQ21_MISS_FLAG_MASK_SFT (0x1 << 21) +#define AFE_IRQ20_MISS_FLAG_SFT 20 +#define AFE_IRQ20_MISS_FLAG_MASK 0x1 +#define AFE_IRQ20_MISS_FLAG_MASK_SFT (0x1 << 20) +#define AFE_IRQ19_MISS_FLAG_SFT 19 +#define AFE_IRQ19_MISS_FLAG_MASK 0x1 +#define AFE_IRQ19_MISS_FLAG_MASK_SFT (0x1 << 19) +#define AFE_IRQ18_MISS_FLAG_SFT 18 +#define AFE_IRQ18_MISS_FLAG_MASK 0x1 +#define AFE_IRQ18_MISS_FLAG_MASK_SFT (0x1 << 18) +#define AFE_IRQ17_MISS_FLAG_SFT 17 +#define AFE_IRQ17_MISS_FLAG_MASK 0x1 +#define AFE_IRQ17_MISS_FLAG_MASK_SFT (0x1 << 17) +#define AFE_IRQ16_MISS_FLAG_SFT 16 +#define AFE_IRQ16_MISS_FLAG_MASK 0x1 +#define AFE_IRQ16_MISS_FLAG_MASK_SFT (0x1 << 16) +#define AFE_IRQ15_MISS_FLAG_SFT 15 +#define AFE_IRQ15_MISS_FLAG_MASK 0x1 +#define AFE_IRQ15_MISS_FLAG_MASK_SFT (0x1 << 15) +#define AFE_IRQ14_MISS_FLAG_SFT 14 +#define AFE_IRQ14_MISS_FLAG_MASK 0x1 +#define AFE_IRQ14_MISS_FLAG_MASK_SFT (0x1 << 14) +#define AFE_IRQ13_MISS_FLAG_SFT 13 +#define AFE_IRQ13_MISS_FLAG_MASK 0x1 +#define AFE_IRQ13_MISS_FLAG_MASK_SFT (0x1 << 13) +#define AFE_IRQ12_MISS_FLAG_SFT 12 +#define AFE_IRQ12_MISS_FLAG_MASK 0x1 +#define AFE_IRQ12_MISS_FLAG_MASK_SFT (0x1 << 12) +#define AFE_IRQ11_MISS_FLAG_SFT 11 +#define AFE_IRQ11_MISS_FLAG_MASK 0x1 +#define AFE_IRQ11_MISS_FLAG_MASK_SFT (0x1 << 11) +#define AFE_IRQ10_MISS_FLAG_SFT 10 +#define AFE_IRQ10_MISS_FLAG_MASK 0x1 +#define AFE_IRQ10_MISS_FLAG_MASK_SFT (0x1 << 10) +#define AFE_IRQ9_MISS_FLAG_SFT 9 +#define AFE_IRQ9_MISS_FLAG_MASK 0x1 +#define AFE_IRQ9_MISS_FLAG_MASK_SFT (0x1 << 9) +#define AFE_IRQ8_MISS_FLAG_SFT 8 +#define AFE_IRQ8_MISS_FLAG_MASK 0x1 +#define AFE_IRQ8_MISS_FLAG_MASK_SFT (0x1 << 8) +#define AFE_IRQ7_MISS_FLAG_SFT 7 +#define AFE_IRQ7_MISS_FLAG_MASK 0x1 +#define AFE_IRQ7_MISS_FLAG_MASK_SFT (0x1 << 7) +#define AFE_IRQ6_MISS_FLAG_SFT 6 +#define AFE_IRQ6_MISS_FLAG_MASK 0x1 +#define AFE_IRQ6_MISS_FLAG_MASK_SFT (0x1 << 6) +#define AFE_IRQ5_MISS_FLAG_SFT 5 +#define AFE_IRQ5_MISS_FLAG_MASK 0x1 +#define AFE_IRQ5_MISS_FLAG_MASK_SFT (0x1 << 5) +#define AFE_IRQ4_MISS_FLAG_SFT 4 +#define AFE_IRQ4_MISS_FLAG_MASK 0x1 +#define AFE_IRQ4_MISS_FLAG_MASK_SFT (0x1 << 4) +#define AFE_IRQ3_MISS_FLAG_SFT 3 +#define AFE_IRQ3_MISS_FLAG_MASK 0x1 +#define AFE_IRQ3_MISS_FLAG_MASK_SFT (0x1 << 3) +#define AFE_IRQ2_MISS_FLAG_SFT 2 +#define AFE_IRQ2_MISS_FLAG_MASK 0x1 +#define AFE_IRQ2_MISS_FLAG_MASK_SFT (0x1 << 2) +#define AFE_IRQ1_MISS_FLAG_SFT 1 +#define AFE_IRQ1_MISS_FLAG_MASK 0x1 +#define AFE_IRQ1_MISS_FLAG_MASK_SFT (0x1 << 1) +#define AFE_IRQ0_MISS_FLAG_SFT 0 +#define AFE_IRQ0_MISS_FLAG_MASK 0x1 +#define AFE_IRQ0_MISS_FLAG_MASK_SFT (0x1 << 0) + +/* AFE_IRQ_MCU_MON1 */ +#define AFE_CUSTOM_IRQ21_MISS_FLAG_SFT 21 +#define AFE_CUSTOM_IRQ21_MISS_FLAG_MASK 0x1 +#define AFE_CUSTOM_IRQ21_MISS_FLAG_MASK_SFT (0x1 << 21) +#define AFE_CUSTOM_IRQ20_MISS_FLAG_SFT 20 +#define AFE_CUSTOM_IRQ20_MISS_FLAG_MASK 0x1 +#define AFE_CUSTOM_IRQ20_MISS_FLAG_MASK_SFT (0x1 << 20) +#define AFE_CUSTOM_IRQ19_MISS_FLAG_SFT 19 +#define AFE_CUSTOM_IRQ19_MISS_FLAG_MASK 0x1 +#define AFE_CUSTOM_IRQ19_MISS_FLAG_MASK_SFT (0x1 << 19) +#define AFE_CUSTOM_IRQ18_MISS_FLAG_SFT 18 +#define AFE_CUSTOM_IRQ18_MISS_FLAG_MASK 0x1 +#define AFE_CUSTOM_IRQ18_MISS_FLAG_MASK_SFT (0x1 << 18) +#define AFE_CUSTOM_IRQ17_MISS_FLAG_SFT 17 +#define AFE_CUSTOM_IRQ17_MISS_FLAG_MASK 0x1 +#define AFE_CUSTOM_IRQ17_MISS_FLAG_MASK_SFT (0x1 << 17) +#define AFE_CUSTOM_IRQ16_MISS_FLAG_SFT 16 +#define AFE_CUSTOM_IRQ16_MISS_FLAG_MASK 0x1 +#define AFE_CUSTOM_IRQ16_MISS_FLAG_MASK_SFT (0x1 << 16) +#define AFE_CUSTOM_IRQ9_MISS_FLAG_SFT 9 +#define AFE_CUSTOM_IRQ9_MISS_FLAG_MASK 0x1 +#define AFE_CUSTOM_IRQ9_MISS_FLAG_MASK_SFT (0x1 << 9) +#define AFE_CUSTOM_IRQ8_MISS_FLAG_SFT 8 +#define AFE_CUSTOM_IRQ8_MISS_FLAG_MASK 0x1 +#define AFE_CUSTOM_IRQ8_MISS_FLAG_MASK_SFT (0x1 << 8) +#define AFE_CUSTOM_IRQ7_MISS_FLAG_SFT 7 +#define AFE_CUSTOM_IRQ7_MISS_FLAG_MASK 0x1 +#define AFE_CUSTOM_IRQ7_MISS_FLAG_MASK_SFT (0x1 << 7) +#define AFE_CUSTOM_IRQ6_MISS_FLAG_SFT 6 +#define AFE_CUSTOM_IRQ6_MISS_FLAG_MASK 0x1 +#define AFE_CUSTOM_IRQ6_MISS_FLAG_MASK_SFT (0x1 << 6) +#define AFE_CUSTOM_IRQ5_MISS_FLAG_SFT 5 +#define AFE_CUSTOM_IRQ5_MISS_FLAG_MASK 0x1 +#define AFE_CUSTOM_IRQ5_MISS_FLAG_MASK_SFT (0x1 << 5) +#define AFE_CUSTOM_IRQ4_MISS_FLAG_SFT 4 +#define AFE_CUSTOM_IRQ4_MISS_FLAG_MASK 0x1 +#define AFE_CUSTOM_IRQ4_MISS_FLAG_MASK_SFT (0x1 << 4) +#define AFE_CUSTOM_IRQ3_MISS_FLAG_SFT 3 +#define AFE_CUSTOM_IRQ3_MISS_FLAG_MASK 0x1 +#define AFE_CUSTOM_IRQ3_MISS_FLAG_MASK_SFT (0x1 << 3) +#define AFE_CUSTOM_IRQ2_MISS_FLAG_SFT 2 +#define AFE_CUSTOM_IRQ2_MISS_FLAG_MASK 0x1 +#define AFE_CUSTOM_IRQ2_MISS_FLAG_MASK_SFT (0x1 << 2) +#define AFE_CUSTOM_IRQ1_MISS_FLAG_SFT 1 +#define AFE_CUSTOM_IRQ1_MISS_FLAG_MASK 0x1 +#define AFE_CUSTOM_IRQ1_MISS_FLAG_MASK_SFT (0x1 << 1) +#define AFE_CUSTOM_IRQ0_MISS_FLAG_SFT 0 +#define AFE_CUSTOM_IRQ0_MISS_FLAG_MASK 0x1 +#define AFE_CUSTOM_IRQ0_MISS_FLAG_MASK_SFT (0x1 << 0) + +/* AFE_IRQ_MCU_MON2 */ +#define AFE_IRQ_B_R_CNT_SFT 8 +#define AFE_IRQ_B_R_CNT_MASK 0xff +#define AFE_IRQ_B_R_CNT_MASK_SFT (0xff << 8) +#define AFE_IRQ_B_F_CNT_SFT 0 +#define AFE_IRQ_B_F_CNT_MASK 0xff +#define AFE_IRQ_B_F_CNT_MASK_SFT (0xff << 0) + +/* AFE_IRQ0_CNT_MON */ +#define AFE_IRQ0_CNT_MON_SFT 0 +#define AFE_IRQ0_CNT_MON_MASK 0xffffff +#define AFE_IRQ0_CNT_MON_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ1_CNT_MON */ +#define AFE_IRQ1_CNT_MON_SFT 0 +#define AFE_IRQ1_CNT_MON_MASK 0xffffff +#define AFE_IRQ1_CNT_MON_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ2_CNT_MON */ +#define AFE_IRQ2_CNT_MON_SFT 0 +#define AFE_IRQ2_CNT_MON_MASK 0xffffff +#define AFE_IRQ2_CNT_MON_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ3_CNT_MON */ +#define AFE_IRQ3_CNT_MON_SFT 0 +#define AFE_IRQ3_CNT_MON_MASK 0xffffff +#define AFE_IRQ3_CNT_MON_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ4_CNT_MON */ +#define AFE_IRQ4_CNT_MON_SFT 0 +#define AFE_IRQ4_CNT_MON_MASK 0xffffff +#define AFE_IRQ4_CNT_MON_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ5_CNT_MON */ +#define AFE_IRQ5_CNT_MON_SFT 0 +#define AFE_IRQ5_CNT_MON_MASK 0xffffff +#define AFE_IRQ5_CNT_MON_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ6_CNT_MON */ +#define AFE_IRQ6_CNT_MON_SFT 0 +#define AFE_IRQ6_CNT_MON_MASK 0xffffff +#define AFE_IRQ6_CNT_MON_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ7_CNT_MON */ +#define AFE_IRQ7_CNT_MON_SFT 0 +#define AFE_IRQ7_CNT_MON_MASK 0xffffff +#define AFE_IRQ7_CNT_MON_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ8_CNT_MON */ +#define AFE_IRQ8_CNT_MON_SFT 0 +#define AFE_IRQ8_CNT_MON_MASK 0xffffff +#define AFE_IRQ8_CNT_MON_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ9_CNT_MON */ +#define AFE_IRQ9_CNT_MON_SFT 0 +#define AFE_IRQ9_CNT_MON_MASK 0xffffff +#define AFE_IRQ9_CNT_MON_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ10_CNT_MON */ +#define AFE_IRQ10_CNT_MON_SFT 0 +#define AFE_IRQ10_CNT_MON_MASK 0xffffff +#define AFE_IRQ10_CNT_MON_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ11_CNT_MON */ +#define AFE_IRQ11_CNT_MON_SFT 0 +#define AFE_IRQ11_CNT_MON_MASK 0xffffff +#define AFE_IRQ11_CNT_MON_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ12_CNT_MON */ +#define AFE_IRQ12_CNT_MON_SFT 0 +#define AFE_IRQ12_CNT_MON_MASK 0xffffff +#define AFE_IRQ12_CNT_MON_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ13_CNT_MON */ +#define AFE_IRQ13_CNT_MON_SFT 0 +#define AFE_IRQ13_CNT_MON_MASK 0xffffff +#define AFE_IRQ13_CNT_MON_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ14_CNT_MON */ +#define AFE_IRQ14_CNT_MON_SFT 0 +#define AFE_IRQ14_CNT_MON_MASK 0xffffff +#define AFE_IRQ14_CNT_MON_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ15_CNT_MON */ +#define AFE_IRQ15_CNT_MON_SFT 0 +#define AFE_IRQ15_CNT_MON_MASK 0xffffff +#define AFE_IRQ15_CNT_MON_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ16_CNT_MON */ +#define AFE_IRQ16_CNT_MON_SFT 0 +#define AFE_IRQ16_CNT_MON_MASK 0xffffff +#define AFE_IRQ16_CNT_MON_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ17_CNT_MON */ +#define AFE_IRQ17_CNT_MON_SFT 0 +#define AFE_IRQ17_CNT_MON_MASK 0xffffff +#define AFE_IRQ17_CNT_MON_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ18_CNT_MON */ +#define AFE_IRQ18_CNT_MON_SFT 0 +#define AFE_IRQ18_CNT_MON_MASK 0xffffff +#define AFE_IRQ18_CNT_MON_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ19_CNT_MON */ +#define AFE_IRQ19_CNT_MON_SFT 0 +#define AFE_IRQ19_CNT_MON_MASK 0xffffff +#define AFE_IRQ19_CNT_MON_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ20_CNT_MON */ +#define AFE_IRQ20_CNT_MON_SFT 0 +#define AFE_IRQ20_CNT_MON_MASK 0xffffff +#define AFE_IRQ20_CNT_MON_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ21_CNT_MON */ +#define AFE_IRQ21_CNT_MON_SFT 0 +#define AFE_IRQ21_CNT_MON_MASK 0xffffff +#define AFE_IRQ21_CNT_MON_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ22_CNT_MON */ +#define AFE_IRQ22_CNT_MON_SFT 0 +#define AFE_IRQ22_CNT_MON_MASK 0xffffff +#define AFE_IRQ22_CNT_MON_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ23_CNT_MON */ +#define AFE_IRQ23_CNT_MON_SFT 0 +#define AFE_IRQ23_CNT_MON_MASK 0xffffff +#define AFE_IRQ23_CNT_MON_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ24_CNT_MON */ +#define AFE_IRQ24_CNT_MON_SFT 0 +#define AFE_IRQ24_CNT_MON_MASK 0xffffff +#define AFE_IRQ24_CNT_MON_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ25_CNT_MON */ +#define AFE_IRQ25_CNT_MON_SFT 0 +#define AFE_IRQ25_CNT_MON_MASK 0xffffff +#define AFE_IRQ25_CNT_MON_MASK_SFT (0xffffff << 0) + +/* AFE_IRQ26_CNT_MON */ +#define AFE_IRQ26_CNT_MON_SFT 0 +#define AFE_IRQ26_CNT_MON_MASK 0xffffff +#define AFE_IRQ26_CNT_MON_MASK_SFT (0xffffff << 0) + + /* AFE_GAIN0_CON0 */ + /* AFE_GAIN1_CON0 */ + /* AFE_GAIN2_CON0 */ + /* AFE_GAIN3_CON0 */ +#define GAIN_TARGET_SYNC_ON_SFT 24 +#define GAIN_TARGET_SYNC_ON_MASK 0x1 +#define GAIN_TARGET_SYNC_ON_MASK_SFT (0x1 << 24) +#define GAIN_TIMEOUT_SFT 18 +#define GAIN_TIMEOUT_MASK 0x3f +#define GAIN_TIMEOUT_MASK_SFT (0x3f << 18) +#define GAIN_TRIG_SFT 17 +#define GAIN_TRIG_MASK 0x1 +#define GAIN_TRIG_MASK_SFT (0x1 << 17) +#define GAIN_ON_SFT 16 +#define GAIN_ON_MASK 0x1 +#define GAIN_ON_MASK_SFT (0x1 << 16) +#define GAIN_SAMPLE_PER_STEP_SFT 8 +#define GAIN_SAMPLE_PER_STEP_MASK 0xff +#define GAIN_SAMPLE_PER_STEP_MASK_SFT (0xff << 8) +#define GAIN_SEL_DOMAIN_SFT 5 +#define GAIN_SEL_DOMAIN_MASK 0x7 +#define GAIN_SEL_DOMAIN_MASK_SFT (0x7 << 5) +#define GAIN_SEL_FS_SFT 0 +#define GAIN_SEL_FS_MASK 0x1f +#define GAIN_SEL_FS_MASK_SFT (0x1f << 0) + + /* AFE_GAIN0_CON1_R */ + /* AFE_GAIN1_CON1_R */ + /* AFE_GAIN2_CON1_R */ + /* AFE_GAIN3_CON1_R */ +#define GAIN_TARGET_R_SFT 0 +#define GAIN_TARGET_R_MASK 0xffffffff +#define GAIN_TARGET_R_MASK_SFT (0xffffffff << 0) + + /* AFE_GAIN0_CON1_L */ + /* AFE_GAIN1_CON1_L */ + /* AFE_GAIN2_CON1_L */ + /* AFE_GAIN3_CON1_L */ +#define GAIN_TARGET_L_SFT 0 +#define GAIN_TARGET_L_MASK 0xffffffff +#define GAIN_TARGET_L_MASK_SFT (0xffffffff << 0) + + /* AFE_GAIN0_CON2 */ + /* AFE_GAIN1_CON2 */ + /* AFE_GAIN2_CON2 */ + /* AFE_GAIN3_CON2 */ +#define GAIN_DOWN_STEP_SFT 0 +#define GAIN_DOWN_STEP_MASK 0x3fffff +#define GAIN_DOWN_STEP_MASK_SFT (0x3fffff << 0) + + /* AFE_GAIN0_CON3 */ + /* AFE_GAIN1_CON3 */ + /* AFE_GAIN2_CON3 */ + /* AFE_GAIN3_CON3 */ +#define GAIN_UP_STEP_SFT 0 +#define GAIN_UP_STEP_MASK 0x3fffff +#define GAIN_UP_STEP_MASK_SFT (0x3fffff << 0) + + /* AFE_GAIN0_CUR_R */ + /* AFE_GAIN1_CUR_R */ + /* AFE_GAIN2_CUR_R */ + /* AFE_GAIN3_CUR_R */ +#define AFE_GAIN_CUR_R_SFT 0 +#define AFE_GAIN_CUR_R_MASK 0xffffffff +#define AFE_GAIN_CUR_R_MASK_SFT (0xffffffff << 0) + + /* AFE_GAIN0_CUR_L */ + /* AFE_GAIN1_CUR_L */ + /* AFE_GAIN2_CUR_L */ + /* AFE_GAIN3_CUR_L */ +#define AFE_GAIN_CUR_L_SFT 0 +#define AFE_GAIN_CUR_L_MASK 0xffffffff +#define AFE_GAIN_CUR_L_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_DL_IPM_VER_MON */ +#define RG_DL_IPM_VER_MON_SFT 0 +#define RG_DL_IPM_VER_MON_MASK 0xffffffff +#define RG_DL_IPM_VER_MON_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_DL_SRC_CON0 */ +#define AFE_DL_INPUT_MODE_CTL_SFT 24 +#define AFE_DL_INPUT_MODE_CTL_MASK 0x1f +#define AFE_DL_INPUT_MODE_CTL_MASK_SFT (0x1f << 24) +#define AFE_DL_CH1_SATURATION_EN_CTL_SFT 21 +#define AFE_DL_CH1_SATURATION_EN_CTL_MASK 0x1 +#define AFE_DL_CH1_SATURATION_EN_CTL_MASK_SFT (0x1 << 21) +#define AFE_DL_CH2_SATURATION_EN_CTL_SFT 20 +#define AFE_DL_CH2_SATURATION_EN_CTL_MASK 0x1 +#define AFE_DL_CH2_SATURATION_EN_CTL_MASK_SFT (0x1 << 20) +#define AFE_DL_OUTPUT_SEL_CTL_SFT 18 +#define AFE_DL_OUTPUT_SEL_CTL_MASK 0x3 +#define AFE_DL_OUTPUT_SEL_CTL_MASK_SFT (0x3 << 18) +#define AFE_DL_FADEIN_0START_EN_SFT 16 +#define AFE_DL_FADEIN_0START_EN_MASK 0x3 +#define AFE_DL_FADEIN_0START_EN_MASK_SFT (0x3 << 16) +#define AFE_DL_DISABLE_HW_CG_CTL_SFT 15 +#define AFE_DL_DISABLE_HW_CG_CTL_MASK 0x1 +#define AFE_DL_DISABLE_HW_CG_CTL_MASK_SFT (0x1 << 15) +#define AFE_DL_MUTE_CH1_OFF_CTL_PRE_SFT 12 +#define AFE_DL_MUTE_CH1_OFF_CTL_PRE_MASK 0x1 +#define AFE_DL_MUTE_CH1_OFF_CTL_PRE_MASK_SFT (0x1 << 12) +#define AFE_DL_MUTE_CH2_OFF_CTL_PRE_SFT 11 +#define AFE_DL_MUTE_CH2_OFF_CTL_PRE_MASK 0x1 +#define AFE_DL_MUTE_CH2_OFF_CTL_PRE_MASK_SFT (0x1 << 11) +#define AFE_DL_ARAMPSP_CTL_PRE_SFT 9 +#define AFE_DL_ARAMPSP_CTL_PRE_MASK 0x3 +#define AFE_DL_ARAMPSP_CTL_PRE_MASK_SFT (0x3 << 9) +#define AFE_DL_VOICE_MODE_CTL_PRE_SFT 5 +#define AFE_DL_VOICE_MODE_CTL_PRE_MASK 0x1 +#define AFE_DL_VOICE_MODE_CTL_PRE_MASK_SFT (0x1 << 5) +#define AFE_DL_MUTE_CH1_ON_CTL_PRE_SFT 4 +#define AFE_DL_MUTE_CH1_ON_CTL_PRE_MASK 0x1 +#define AFE_DL_MUTE_CH1_ON_CTL_PRE_MASK_SFT (0x1 << 4) +#define AFE_DL_MUTE_CH2_ON_CTL_PRE_SFT 3 +#define AFE_DL_MUTE_CH2_ON_CTL_PRE_MASK 0x1 +#define AFE_DL_MUTE_CH2_ON_CTL_PRE_MASK_SFT (0x1 << 3) +#define AFE_DL_GAIN_ON_CTL_PRE_SFT 1 +#define AFE_DL_GAIN_ON_CTL_PRE_MASK 0x1 +#define AFE_DL_GAIN_ON_CTL_PRE_MASK_SFT (0x1 << 1) +#define AFE_DL_SRC_ON_TMP_CTL_PRE_SFT 0 +#define AFE_DL_SRC_ON_TMP_CTL_PRE_MASK 0x1 +#define AFE_DL_SRC_ON_TMP_CTL_PRE_MASK_SFT (0x1 << 0) + +/* AFE_ADDA_DL_SRC_CON1 */ +#define AFE_DL_GAIN1_CTL_PRE_SFT 16 +#define AFE_DL_GAIN1_CTL_PRE_MASK 0xffff +#define AFE_DL_GAIN1_CTL_PRE_MASK_SFT (0xffff << 16) +#define AFE_DL_GAIN2_CTL_PRE_SFT 0 +#define AFE_DL_GAIN2_CTL_PRE_MASK 0xffff +#define AFE_DL_GAIN2_CTL_PRE_MASK_SFT (0xffff << 0) + +/* AFE_ADDA_DL_SRC_DEBUG_MON0 */ +#define AFE_DL_SLT_CNT_FLAG_CTL_SFT 15 +#define AFE_DL_SLT_CNT_FLAG_CTL_MASK 0x1 +#define AFE_DL_SLT_CNT_FLAG_CTL_MASK_SFT (0x1 << 15) +#define AFE_DL_INI_SRAM_FINISH_CTL_SFT 12 +#define AFE_DL_INI_SRAM_FINISH_CTL_MASK 0x1 +#define AFE_DL_INI_SRAM_FINISH_CTL_MASK_SFT (0x1 << 12) +#define AFE_DL_SLT_COUNTER_CTL_SFT 0 +#define AFE_DL_SLT_COUNTER_CTL_MASK 0xfff +#define AFE_DL_SLT_COUNTER_CTL_MASK_SFT (0xfff << 0) + +/* AFE_ADDA_DL_PREDIS_CON0 */ +#define AFE_DL_PREDIS_ON_CH1_CTL_SFT 31 +#define AFE_DL_PREDIS_ON_CH1_CTL_MASK 0x1 +#define AFE_DL_PREDIS_ON_CH1_CTL_MASK_SFT (0x1 << 31) +#define AFE_DL_PREDIS_A2_CH1_CTL_SFT 16 +#define AFE_DL_PREDIS_A2_CH1_CTL_MASK 0xfff +#define AFE_DL_PREDIS_A2_CH1_CTL_MASK_SFT (0xfff << 16) +#define AFE_DL_PREDIS_A3_CH1_CTL_SFT 0 +#define AFE_DL_PREDIS_A3_CH1_CTL_MASK 0xfff +#define AFE_DL_PREDIS_A3_CH1_CTL_MASK_SFT (0xfff << 0) + +/* AFE_ADDA_DL_PREDIS_CON1 */ +#define AFE_DL_PREDIS_ON_CH2_CTL_SFT 31 +#define AFE_DL_PREDIS_ON_CH2_CTL_MASK 0x1 +#define AFE_DL_PREDIS_ON_CH2_CTL_MASK_SFT (0x1 << 31) +#define AFE_DL_PREDIS_A2_CH2_CTL_SFT 16 +#define AFE_DL_PREDIS_A2_CH2_CTL_MASK 0xfff +#define AFE_DL_PREDIS_A2_CH2_CTL_MASK_SFT (0xfff << 16) +#define AFE_DL_PREDIS_A3_CH2_CTL_SFT 0 +#define AFE_DL_PREDIS_A3_CH2_CTL_MASK 0xfff +#define AFE_DL_PREDIS_A3_CH2_CTL_MASK_SFT (0xfff << 0) + +/* AFE_ADDA_DL_PREDIS_CON2 */ +#define AFE_DL_PREDIS_A4_CH1_CTL_SFT 16 +#define AFE_DL_PREDIS_A4_CH1_CTL_MASK 0xfff +#define AFE_DL_PREDIS_A4_CH1_CTL_MASK_SFT (0xfff << 16) +#define AFE_DL_PREDIS_A5_CH1_CTL_SFT 0 +#define AFE_DL_PREDIS_A5_CH1_CTL_MASK 0xfff +#define AFE_DL_PREDIS_A5_CH1_CTL_MASK_SFT (0xfff << 0) + +/* AFE_ADDA_DL_PREDIS_CON3 */ +#define AFE_DL_PREDIS_A4_CH2_CTL_SFT 16 +#define AFE_DL_PREDIS_A4_CH2_CTL_MASK 0xfff +#define AFE_DL_PREDIS_A4_CH2_CTL_MASK_SFT (0xfff << 16) +#define AFE_DL_PREDIS_A5_CH2_CTL_SFT 0 +#define AFE_DL_PREDIS_A5_CH2_CTL_MASK 0xfff +#define AFE_DL_PREDIS_A5_CH2_CTL_MASK_SFT (0xfff << 0) + +/* AFE_ADDA_DL_SDM_DCCOMP_CON */ +#define AFE_DL_USE_NEW_2ND_12BIT_SDM_SFT 31 +#define AFE_DL_USE_NEW_2ND_12BIT_SDM_MASK 0x1 +#define AFE_DL_USE_NEW_2ND_12BIT_SDM_MASK_SFT (0x1 << 31) +#define AFE_DL_USE_NEW_2ND_SDM_SFT 30 +#define AFE_DL_USE_NEW_2ND_SDM_MASK 0x1 +#define AFE_DL_USE_NEW_2ND_SDM_MASK_SFT (0x1 << 30) +#define AFE_DL_USE_3RD_SDM_SFT 28 +#define AFE_DL_USE_3RD_SDM_MASK 0x1 +#define AFE_DL_USE_3RD_SDM_MASK_SFT (0x1 << 28) +#define AFE_DL_DCM_AUTO_IDLE_EN_SFT 14 +#define AFE_DL_DCM_AUTO_IDLE_EN_MASK 0x1 +#define AFE_DL_DCM_AUTO_IDLE_EN_MASK_SFT (0x1 << 14) +#define AFE_DL_SRC_DCM_EN_SFT 13 +#define AFE_DL_SRC_DCM_EN_MASK 0x1 +#define AFE_DL_SRC_DCM_EN_MASK_SFT (0x1 << 13) +#define AFE_DL_POST_SRC_DCM_EN_SFT 12 +#define AFE_DL_POST_SRC_DCM_EN_MASK 0x1 +#define AFE_DL_POST_SRC_DCM_EN_MASK_SFT (0x1 << 12) +#define AFE_DL_DCCOMP_SYNC_TOGGLE_SFT 11 +#define AFE_DL_DCCOMP_SYNC_TOGGLE_MASK 0x1 +#define AFE_DL_DCCOMP_SYNC_TOGGLE_MASK_SFT (0x1 << 11) +#define AFE_DL_AUD_SDM_MONO_SFT 9 +#define AFE_DL_AUD_SDM_MONO_MASK 0x1 +#define AFE_DL_AUD_SDM_MONO_MASK_SFT (0x1 << 9) +#define AFE_DL_AUD_DC_COMP_EN_SFT 8 +#define AFE_DL_AUD_DC_COMP_EN_MASK 0x1 +#define AFE_DL_AUD_DC_COMP_EN_MASK_SFT (0x1 << 8) +#define AFE_DL_ATTGAIN_CTL_SFT 0 +#define AFE_DL_ATTGAIN_CTL_MASK 0x3f +#define AFE_DL_ATTGAIN_CTL_MASK_SFT (0x3f << 0) + +/* AFE_ADDA_DL_SDM_TEST */ +#define AFE_DL_TRI_AMP_DIV_SFT 12 +#define AFE_DL_TRI_AMP_DIV_MASK 0x7 +#define AFE_DL_TRI_AMP_DIV_MASK_SFT (0x7 << 12) +#define AFE_DL_TRI_FREQ_DIV_SFT 4 +#define AFE_DL_TRI_FREQ_DIV_MASK 0x3f +#define AFE_DL_TRI_FREQ_DIV_MASK_SFT (0x3f << 4) +#define AFE_DL_RG_DL_LEFT_SAT_RSTN_SFT 3 +#define AFE_DL_RG_DL_LEFT_SAT_RSTN_MASK 0x1 +#define AFE_DL_RG_DL_LEFT_SAT_RSTN_MASK_SFT (0x1 << 3) +#define AFE_DL_RG_DL_RIGHT_SAT_RSTN_SFT 2 +#define AFE_DL_RG_DL_RIGHT_SAT_RSTN_MASK 0x1 +#define AFE_DL_RG_DL_RIGHT_SAT_RSTN_MASK_SFT (0x1 << 2) +#define AFE_DL_TRI_MUTE_SW_SFT 1 +#define AFE_DL_TRI_MUTE_SW_MASK 0x1 +#define AFE_DL_TRI_MUTE_SW_MASK_SFT (0x1 << 1) +#define AFE_DL_TRI_DAC_EN_SFT 0 +#define AFE_DL_TRI_DAC_EN_MASK 0x1 +#define AFE_DL_TRI_DAC_EN_MASK_SFT (0x1 << 0) + +/* AFE_ADDA_DL_DC_COMP_CFG0 */ +#define AFE_DL_AUD_DC_COMP_LCH_H_SFT 16 +#define AFE_DL_AUD_DC_COMP_LCH_H_MASK 0xffff +#define AFE_DL_AUD_DC_COMP_LCH_H_MASK_SFT (0xffff << 16) +#define AFE_DL_AUD_DC_COMP_LCH_L_SFT 0 +#define AFE_DL_AUD_DC_COMP_LCH_L_MASK 0xffff +#define AFE_DL_AUD_DC_COMP_LCH_L_MASK_SFT (0xffff << 0) + +/* AFE_ADDA_DL_DC_COMP_CFG1 */ +#define AFE_DL_AUD_DC_COMP_RCH_H_SFT 16 +#define AFE_DL_AUD_DC_COMP_RCH_H_MASK 0xffff +#define AFE_DL_AUD_DC_COMP_RCH_H_MASK_SFT (0xffff << 16) +#define AFE_DL_AUD_DC_COMP_RCH_L_SFT 0 +#define AFE_DL_AUD_DC_COMP_RCH_L_MASK 0xffff +#define AFE_DL_AUD_DC_COMP_RCH_L_MASK_SFT (0xffff << 0) + +/* AFE_ADDA_DL_SDM_OUT_MON */ +#define AFE_DL_SDM_DITHER_MON_SFT 28 +#define AFE_DL_SDM_DITHER_MON_MASK 0x3 +#define AFE_DL_SDM_DITHER_MON_MASK_SFT (0x3 << 28) +#define AFE_DL_BF_SDM_LEFT_SAT_SFT 21 +#define AFE_DL_BF_SDM_LEFT_SAT_MASK 0x1 +#define AFE_DL_BF_SDM_LEFT_SAT_MASK_SFT (0x1 << 21) +#define AFE_DL_BF_SDM_RIGHT_SAT_SFT 20 +#define AFE_DL_BF_SDM_RIGHT_SAT_MASK 0x1 +#define AFE_DL_BF_SDM_RIGHT_SAT_MASK_SFT (0x1 << 20) +#define AFE_DL_3RD_SDM_AUTO_RESET_R_SFT 19 +#define AFE_DL_3RD_SDM_AUTO_RESET_R_MASK 0x1 +#define AFE_DL_3RD_SDM_AUTO_RESET_R_MASK_SFT (0x1 << 19) +#define AFE_DL_3RD_SDM_AUTO_RESET_L_SFT 18 +#define AFE_DL_3RD_SDM_AUTO_RESET_L_MASK 0x1 +#define AFE_DL_3RD_SDM_AUTO_RESET_L_MASK_SFT (0x1 << 18) +#define AFE_DL_2ND_SDM_AUTO_RESET_R_SFT 17 +#define AFE_DL_2ND_SDM_AUTO_RESET_R_MASK 0x1 +#define AFE_DL_2ND_SDM_AUTO_RESET_R_MASK_SFT (0x1 << 17) +#define AFE_DL_2ND_SDM_AUTO_RESET_L_SFT 16 +#define AFE_DL_2ND_SDM_AUTO_RESET_L_MASK 0x1 +#define AFE_DL_2ND_SDM_AUTO_RESET_L_MASK_SFT (0x1 << 16) +#define AFE_DL_AUD_SDM_OUT_L_SFT 8 +#define AFE_DL_AUD_SDM_OUT_L_MASK 0xff +#define AFE_DL_AUD_SDM_OUT_L_MASK_SFT (0xff << 8) +#define AFE_DL_AUD_SDM_OUT_R_SFT 0 +#define AFE_DL_AUD_SDM_OUT_R_MASK 0xff +#define AFE_DL_AUD_SDM_OUT_R_MASK_SFT (0xff << 0) + +/* AFE_ADDA_DL_SRC_LCH_MON */ +#define AFE_DL_ASDM_LEFT_SFT 0 +#define AFE_DL_ASDM_LEFT_MASK 0xffffff +#define AFE_DL_ASDM_LEFT_MASK_SFT (0xffffff << 0) + +/* AFE_ADDA_DL_SRC_RCH_MON */ +#define AFE_DL_ASDM_RIGHT_SFT 0 +#define AFE_DL_ASDM_RIGHT_MASK 0xffffff +#define AFE_DL_ASDM_RIGHT_MASK_SFT (0xffffff << 0) + +/* AFE_ADDA_DL_SRC_DEBUG */ +#define AFE_DL_SLT_CNT_FLAG_RESET_CTL_SFT 12 +#define AFE_DL_SLT_CNT_FLAG_RESET_CTL_MASK 0x1 +#define AFE_DL_SLT_CNT_FLAG_RESET_CTL_MASK_SFT (0x1 << 12) +#define AFE_DL_SLT_CNT_THD_CTL_SFT 0 +#define AFE_DL_SLT_CNT_THD_CTL_MASK 0xfff +#define AFE_DL_SLT_CNT_THD_CTL_MASK_SFT (0xfff << 0) + +/* AFE_ADDA_DL_SDM_DITHER_CON */ +#define AFE_DL_SDM_DITHER_64TAP_EN_SFT 20 +#define AFE_DL_SDM_DITHER_64TAP_EN_MASK 0x1 +#define AFE_DL_SDM_DITHER_64TAP_EN_MASK_SFT (0x1 << 20) +#define AFE_DL_SDM_DITHER_EN_SFT 16 +#define AFE_DL_SDM_DITHER_EN_MASK 0x1 +#define AFE_DL_SDM_DITHER_EN_MASK_SFT (0x1 << 16) +#define AFE_DL_SDM_DITHER_GAIN_SFT 0 +#define AFE_DL_SDM_DITHER_GAIN_MASK 0xff +#define AFE_DL_SDM_DITHER_GAIN_MASK_SFT (0xff << 0) + +/* AFE_ADDA_DL_SDM_AUTO_RESET_CON */ +#define AFE_DL_SDM_AUTO_RESET_TEST_ON_SFT 31 +#define AFE_DL_SDM_AUTO_RESET_TEST_ON_MASK 0x1 +#define AFE_DL_SDM_AUTO_RESET_TEST_ON_MASK_SFT (0x1 << 31) +#define AFE_DL_SDM_AUTO_RESET_SOURCE_SEL_SFT 24 +#define AFE_DL_SDM_AUTO_RESET_SOURCE_SEL_MASK 0x1 +#define AFE_DL_SDM_AUTO_RESET_SOURCE_SEL_MASK_SFT (0x1 << 24) +#define AFE_DL_SDM_AUTO_RESET_COUNT_TH_SFT 0 +#define AFE_DL_SDM_AUTO_RESET_COUNT_TH_MASK 0xffffff +#define AFE_DL_SDM_AUTO_RESET_COUNT_TH_MASK_SFT (0xffffff << 0) + +/* AFE_ADDA_DL_HBF1_SCF1_CONFIG */ +#define AFE_DL_HBF1_SW_CONFIG_SFT 31 +#define AFE_DL_HBF1_SW_CONFIG_MASK 0x1 +#define AFE_DL_HBF1_SW_CONFIG_MASK_SFT (0x1 << 31) +#define AFE_DL_HBF1_TAPNUM_CONFIG_SFT 16 +#define AFE_DL_HBF1_TAPNUM_CONFIG_MASK 0x7f +#define AFE_DL_HBF1_TAPNUM_CONFIG_MASK_SFT (0x7f << 16) +#define AFE_DL_SCF1_SW_CONFIG_SFT 8 +#define AFE_DL_SCF1_SW_CONFIG_MASK 0x1 +#define AFE_DL_SCF1_SW_CONFIG_MASK_SFT (0x1 << 8) +#define AFE_DL_SCF1_TAPNUM_CONFIG_SFT 0 +#define AFE_DL_SCF1_TAPNUM_CONFIG_MASK 0xff +#define AFE_DL_SCF1_TAPNUM_CONFIG_MASK_SFT (0xff << 0) + +/* AFE_ADDA_DL_HBF1_SCF1_TAP1_TAP2_CONFIG */ +#define AFE_DL_HBF1_SCF1_TAP1_TAP2_CONFIG_SFT 0 +#define AFE_DL_HBF1_SCF1_TAP1_TAP2_CONFIG_MASK 0xffffffff +#define AFE_DL_HBF1_SCF1_TAP1_TAP2_CONFIG_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_DL_HBF1_SCF1_TAP3_TAP4_CONFIG */ +#define AFE_DL_HBF1_SCF1_TAP3_TAP4_CONFIG_SFT 0 +#define AFE_DL_HBF1_SCF1_TAP3_TAP4_CONFIG_MASK 0xffffffff +#define AFE_DL_HBF1_SCF1_TAP3_TAP4_CONFIG_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_DL_HBF1_SCF1_TAP5_TAP6_CONFIG */ +#define AFE_DL_HBF1_SCF1_TAP5_TAP6_CONFIG_SFT 0 +#define AFE_DL_HBF1_SCF1_TAP5_TAP6_CONFIG_MASK 0xffffffff +#define AFE_DL_HBF1_SCF1_TAP5_TAP6_CONFIG_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_DL_HBF1_SCF1_TAP7_TAP8_CONFIG */ +#define AFE_DL_HBF1_SCF1_TAP7_TAP8_CONFIG_SFT 0 +#define AFE_DL_HBF1_SCF1_TAP7_TAP8_CONFIG_MASK 0xffffffff +#define AFE_DL_HBF1_SCF1_TAP7_TAP8_CONFIG_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_DL_HBF1_SCF1_TAP9_TAP10_CONFIG */ +#define AFE_DL_HBF1_SCF1_TAP9_TAP10_CONFIG_SFT 0 +#define AFE_DL_HBF1_SCF1_TAP9_TAP10_CONFIG_MASK 0xffffffff +#define AFE_DL_HBF1_SCF1_TAP9_TAP10_CONFIG_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_DL_HBF1_SCF1_TAP11_TAP12_CONFIG */ +#define AFE_DL_HBF1_SCF1_TAP11_TAP12_CONFIG_SFT 0 +#define AFE_DL_HBF1_SCF1_TAP11_TAP12_CONFIG_MASK 0xffffffff +#define AFE_DL_HBF1_SCF1_TAP11_TAP12_CONFIG_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_DL_HBF1_SCF1_TAP13_TAP14_CONFIG */ +#define AFE_DL_HBF1_SCF1_TAP13_TAP14_CONFIG_SFT 0 +#define AFE_DL_HBF1_SCF1_TAP13_TAP14_CONFIG_MASK 0xffffffff +#define AFE_DL_HBF1_SCF1_TAP13_TAP14_CONFIG_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_DL_HBF1_SCF1_TAP15_TAP16_CONFIG */ +#define AFE_DL_HBF1_SCF1_TAP15_TAP16_CONFIG_SFT 0 +#define AFE_DL_HBF1_SCF1_TAP15_TAP16_CONFIG_MASK 0xffffffff +#define AFE_DL_HBF1_SCF1_TAP15_TAP16_CONFIG_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_DL_HBF1_SCF1_TAP17_TAP18_CONFIG */ +#define AFE_DL_HBF1_SCF1_TAP17_TAP18_CONFIG_SFT 0 +#define AFE_DL_HBF1_SCF1_TAP17_TAP18_CONFIG_MASK 0xffffffff +#define AFE_DL_HBF1_SCF1_TAP17_TAP18_CONFIG_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_DL_HBF1_SCF1_TAP19_TAP20_CONFIG */ +#define AFE_DL_HBF1_SCF1_TAP19_TAP20_CONFIG_SFT 0 +#define AFE_DL_HBF1_SCF1_TAP19_TAP20_CONFIG_MASK 0xffffffff +#define AFE_DL_HBF1_SCF1_TAP19_TAP20_CONFIG_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_DL_HBF1_SCF1_TAP21_TAP22_CONFIG */ +#define AFE_DL_HBF1_SCF1_TAP21_TAP22_CONFIG_SFT 0 +#define AFE_DL_HBF1_SCF1_TAP21_TAP22_CONFIG_MASK 0xffffffff +#define AFE_DL_HBF1_SCF1_TAP21_TAP22_CONFIG_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_DL_HBF1_SCF1_TAP23_TAP24_CONFIG */ +#define AFE_DL_HBF1_SCF1_TAP23_TAP24_CONFIG_SFT 0 +#define AFE_DL_HBF1_SCF1_TAP23_TAP24_CONFIG_MASK 0xffffffff +#define AFE_DL_HBF1_SCF1_TAP23_TAP24_CONFIG_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_DL_HBF1_SCF1_TAP25_TAP26_CONFIG */ +#define AFE_DL_HBF1_SCF1_TAP25_TAP26_CONFIG_SFT 0 +#define AFE_DL_HBF1_SCF1_TAP25_TAP26_CONFIG_MASK 0xffffffff +#define AFE_DL_HBF1_SCF1_TAP25_TAP26_CONFIG_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_DL_HBF1_SCF1_TAP27_TAP28_CONFIG */ +#define AFE_DL_HBF1_SCF1_TAP27_TAP28_CONFIG_SFT 0 +#define AFE_DL_HBF1_SCF1_TAP27_TAP28_CONFIG_MASK 0xffffffff +#define AFE_DL_HBF1_SCF1_TAP27_TAP28_CONFIG_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_DL_HBF1_SCF1_TAP29_TAP30_CONFIG */ +#define AFE_DL_HBF1_SCF1_TAP29_TAP30_CONFIG_SFT 0 +#define AFE_DL_HBF1_SCF1_TAP29_TAP30_CONFIG_MASK 0xffffffff +#define AFE_DL_HBF1_SCF1_TAP29_TAP30_CONFIG_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_DL_HBF1_SCF1_TAP31_TAP32_CONFIG */ +#define AFE_DL_HBF1_SCF1_TAP31_TAP32_CONFIG_SFT 0 +#define AFE_DL_HBF1_SCF1_TAP31_TAP32_CONFIG_MASK 0xffffffff +#define AFE_DL_HBF1_SCF1_TAP31_TAP32_CONFIG_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_DL_HBF1_SCF1_TAP33_TAP34_CONFIG */ +#define AFE_DL_HBF1_SCF1_TAP33_TAP34_CONFIG_SFT 0 +#define AFE_DL_HBF1_SCF1_TAP33_TAP34_CONFIG_MASK 0xffffffff +#define AFE_DL_HBF1_SCF1_TAP33_TAP34_CONFIG_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_DL_HBF1_SCF1_TAP35_TAP36_CONFIG */ +#define AFE_DL_HBF1_SCF1_TAP35_TAP36_CONFIG_SFT 0 +#define AFE_DL_HBF1_SCF1_TAP35_TAP36_CONFIG_MASK 0xffffffff +#define AFE_DL_HBF1_SCF1_TAP35_TAP36_CONFIG_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_DL_HBF1_SCF1_TAP37_TAP38_CONFIG */ +#define AFE_DL_HBF1_SCF1_TAP37_TAP38_CONFIG_SFT 0 +#define AFE_DL_HBF1_SCF1_TAP37_TAP38_CONFIG_MASK 0xffffffff +#define AFE_DL_HBF1_SCF1_TAP37_TAP38_CONFIG_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_DL_HBF1_SCF1_TAP39_TAP40_CONFIG */ +#define AFE_DL_HBF1_SCF1_TAP39_TAP40_CONFIG_SFT 0 +#define AFE_DL_HBF1_SCF1_TAP39_TAP40_CONFIG_MASK 0xffffffff +#define AFE_DL_HBF1_SCF1_TAP39_TAP40_CONFIG_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_DL_HBF1_SCF1_TAP41_TAP42_CONFIG */ +#define AFE_DL_HBF1_SCF1_TAP41_TAP42_CONFIG_SFT 0 +#define AFE_DL_HBF1_SCF1_TAP41_TAP42_CONFIG_MASK 0xffffffff +#define AFE_DL_HBF1_SCF1_TAP41_TAP42_CONFIG_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_DL_HBF1_SCF1_TAP43_TAP44_CONFIG */ +#define AFE_DL_HBF1_SCF1_TAP43_TAP44_CONFIG_SFT 0 +#define AFE_DL_HBF1_SCF1_TAP43_TAP44_CONFIG_MASK 0xffffffff +#define AFE_DL_HBF1_SCF1_TAP43_TAP44_CONFIG_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_DL_HBF1_SCF1_TAP45_TAP46_CONFIG */ +#define AFE_DL_HBF1_SCF1_TAP45_TAP46_CONFIG_SFT 0 +#define AFE_DL_HBF1_SCF1_TAP45_TAP46_CONFIG_MASK 0xffffffff +#define AFE_DL_HBF1_SCF1_TAP45_TAP46_CONFIG_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_DL_HBF1_SCF1_TAP47_TAP48_CONFIG */ +#define AFE_DL_HBF1_SCF1_TAP47_TAP48_CONFIG_SFT 0 +#define AFE_DL_HBF1_SCF1_TAP47_TAP48_CONFIG_MASK 0xffffffff +#define AFE_DL_HBF1_SCF1_TAP47_TAP48_CONFIG_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_DL_HBF1_SCF1_TAP49_TAP50_CONFIG */ +#define AFE_DL_HBF1_SCF1_TAP49_TAP50_CONFIG_SFT 0 +#define AFE_DL_HBF1_SCF1_TAP49_TAP50_CONFIG_MASK 0xffffffff +#define AFE_DL_HBF1_SCF1_TAP49_TAP50_CONFIG_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_DL_HBF1_SCF1_TAP51_TAP52_CONFIG */ +#define AFE_DL_HBF1_SCF1_TAP51_TAP52_CONFIG_SFT 0 +#define AFE_DL_HBF1_SCF1_TAP51_TAP52_CONFIG_MASK 0xffffffff +#define AFE_DL_HBF1_SCF1_TAP51_TAP52_CONFIG_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_DL_HBF1_SCF1_TAP53_TAP54_CONFIG */ +#define AFE_DL_HBF1_SCF1_TAP53_TAP54_CONFIG_SFT 0 +#define AFE_DL_HBF1_SCF1_TAP53_TAP54_CONFIG_MASK 0xffffffff +#define AFE_DL_HBF1_SCF1_TAP53_TAP54_CONFIG_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_DL_HBF1_SCF1_TAP55_TAP56_CONFIG */ +#define AFE_DL_HBF1_SCF1_TAP55_TAP56_CONFIG_SFT 0 +#define AFE_DL_HBF1_SCF1_TAP55_TAP56_CONFIG_MASK 0xffffffff +#define AFE_DL_HBF1_SCF1_TAP55_TAP56_CONFIG_MASK_SFT (0xffffffff << 0) + +/* AFE_DL_NLE_R_CFG0 */ +#define RG_NLE_R_GAIN_DIG_TAR_SFT 24 +#define RG_NLE_R_GAIN_DIG_TAR_MASK 0x3f +#define RG_NLE_R_GAIN_DIG_TAR_MASK_SFT (0x3f << 24) +#define RG_NLE_R_GAIN_ANA_TAR_SFT 16 +#define RG_NLE_R_GAIN_ANA_TAR_MASK 0x3f +#define RG_NLE_R_GAIN_ANA_TAR_MASK_SFT (0x3f << 16) +#define RG_NLE_R_NO_ZCE_SFT 15 +#define RG_NLE_R_NO_ZCE_MASK 0x1 +#define RG_NLE_R_NO_ZCE_MASK_SFT (0x1 << 15) +#define RG_NLE_R_HP_MODE_SFT 14 +#define RG_NLE_R_HP_MODE_MASK 0x1 +#define RG_NLE_R_HP_MODE_MASK_SFT (0x1 << 14) +#define RG_NLE_R_GAIN_STEP_SFT 8 +#define RG_NLE_R_GAIN_STEP_MASK 0x7 +#define RG_NLE_R_GAIN_STEP_MASK_SFT (0x7 << 8) +#define RG_NLE_R_TOGGLE_NUM_SFT 0 +#define RG_NLE_R_TOGGLE_NUM_MASK 0x3f +#define RG_NLE_R_TOGGLE_NUM_MASK_SFT (0x3f << 0) + +/* AFE_DL_NLE_R_CFG1 */ +#define RG_NLE_R_INITIATE_SFT 24 +#define RG_NLE_R_INITIATE_MASK 0x1 +#define RG_NLE_R_INITIATE_MASK_SFT (0x1 << 24) +#define RG_NLE_R_READY_SFT 16 +#define RG_NLE_R_READY_MASK 0x1 +#define RG_NLE_R_READY_MASK_SFT (0x1 << 16) +#define RG_NLE_R_TIMEOUT_SCALE_SFT 12 +#define RG_NLE_R_TIMEOUT_SCALE_MASK 0x7 +#define RG_NLE_R_TIMEOUT_SCALE_MASK_SFT (0x7 << 12) +#define RG_NLE_R_ANC_ON_SFT 11 +#define RG_NLE_R_ANC_ON_MASK 0x1 +#define RG_NLE_R_ANC_ON_MASK_SFT (0x1 << 11) +#define RG_NLE_R_GTIME_SFT 8 +#define RG_NLE_R_GTIME_MASK 0x7 +#define RG_NLE_R_GTIME_MASK_SFT (0x7 << 8) +#define RG_NLE_R_ON_SFT 7 +#define RG_NLE_R_ON_MASK 0x1 +#define RG_NLE_R_ON_MASK_SFT (0x1 << 7) +#define RG_PDN_NLE_CTL_SFT 6 +#define RG_PDN_NLE_CTL_MASK 0x1 +#define RG_PDN_NLE_CTL_MASK_SFT (0x1 << 6) +#define RG_NLE_R_DELAY_ANA_SFT 0 +#define RG_NLE_R_DELAY_ANA_MASK 0x3f +#define RG_NLE_R_DELAY_ANA_MASK_SFT (0x3f << 0) + +/* AFE_DL_NLE_L_CFG0 */ +#define RG_NLE_L_GAIN_DIG_TAR_SFT 24 +#define RG_NLE_L_GAIN_DIG_TAR_MASK 0x3f +#define RG_NLE_L_GAIN_DIG_TAR_MASK_SFT (0x3f << 24) +#define RG_NLE_L_GAIN_ANA_TAR_SFT 16 +#define RG_NLE_L_GAIN_ANA_TAR_MASK 0x3f +#define RG_NLE_L_GAIN_ANA_TAR_MASK_SFT (0x3f << 16) +#define RG_NLE_L_NO_ZCE_SFT 15 +#define RG_NLE_L_NO_ZCE_MASK 0x1 +#define RG_NLE_L_NO_ZCE_MASK_SFT (0x1 << 15) +#define RG_NLE_L_HP_MODE_SFT 14 +#define RG_NLE_L_HP_MODE_MASK 0x1 +#define RG_NLE_L_HP_MODE_MASK_SFT (0x1 << 14) +#define RG_NLE_L_GAIN_STEP_SFT 8 +#define RG_NLE_L_GAIN_STEP_MASK 0x7 +#define RG_NLE_L_GAIN_STEP_MASK_SFT (0x7 << 8) +#define RG_NLE_L_TOGGLE_NUM_SFT 0 +#define RG_NLE_L_TOGGLE_NUM_MASK 0x3f +#define RG_NLE_L_TOGGLE_NUM_MASK_SFT (0x3f << 0) + +/* AFE_DL_NLE_L_CFG1 */ +#define RG_NLE_L_INITIATE_SFT 24 +#define RG_NLE_L_INITIATE_MASK 0x1 +#define RG_NLE_L_INITIATE_MASK_SFT (0x1 << 24) +#define RG_NLE_L_READY_SFT 16 +#define RG_NLE_L_READY_MASK 0x1 +#define RG_NLE_L_READY_MASK_SFT (0x1 << 16) +#define RG_NLE_L_TIMEOUT_SCALE_SFT 12 +#define RG_NLE_L_TIMEOUT_SCALE_MASK 0x7 +#define RG_NLE_L_TIMEOUT_SCALE_MASK_SFT (0x7 << 12) +#define RG_NLE_L_ANC_ON_SFT 11 +#define RG_NLE_L_ANC_ON_MASK 0x1 +#define RG_NLE_L_ANC_ON_MASK_SFT (0x1 << 11) +#define RG_NLE_L_GTIME_SFT 8 +#define RG_NLE_L_GTIME_MASK 0x7 +#define RG_NLE_L_GTIME_MASK_SFT (0x7 << 8) +#define RG_NLE_L_ON_SFT 7 +#define RG_NLE_L_ON_MASK 0x1 +#define RG_NLE_L_ON_MASK_SFT (0x1 << 7) +#define RG_PDN_NLE_CTL_SFT 6 +#define RG_PDN_NLE_CTL_MASK 0x1 +#define RG_PDN_NLE_CTL_MASK_SFT (0x1 << 6) +#define RG_NLE_L_DELAY_ANA_SFT 0 +#define RG_NLE_L_DELAY_ANA_MASK 0x3f +#define RG_NLE_L_DELAY_ANA_MASK_SFT (0x3f << 0) + +/* AFE_DL_NLE_R_MON0 */ +#define NLE_R_GAIN_DIG_CUR_SFT 24 +#define NLE_R_GAIN_DIG_CUR_MASK 0x3f +#define NLE_R_GAIN_DIG_CUR_MASK_SFT (0x3f << 24) +#define NLE_R_ANC_MASK_SFT 23 +#define NLE_R_ANC_MASK_MASK 0x1 +#define NLE_R_ANC_MASK_MASK_SFT (0x1 << 23) +#define NLE_R_GAIN_ANA_CUR_SFT 16 +#define NLE_R_GAIN_ANA_CUR_MASK 0x3f +#define NLE_R_GAIN_ANA_CUR_MASK_SFT (0x3f << 16) +#define NLE_R_GAIN_DIG_TAR_CUR_SFT 8 +#define NLE_R_GAIN_DIG_TAR_CUR_MASK 0x3f +#define NLE_R_GAIN_DIG_TAR_CUR_MASK_SFT (0x3f << 8) +#define NLE_R_GAIN_ANA_TAR_CUR_SFT 0 +#define NLE_R_GAIN_ANA_TAR_CUR_MASK 0x3f +#define NLE_R_GAIN_ANA_TAR_CUR_MASK_SFT (0x3f << 0) + +/* AFE_DL_NLE_R_MON1 */ +#define NLE_R_STATE_CUR_SFT 28 +#define NLE_R_STATE_CUR_MASK 0x7 +#define NLE_R_STATE_CUR_MASK_SFT (0x7 << 28) +#define NLE_R_GAIN_STEP_CUR_SFT 24 +#define NLE_R_GAIN_STEP_CUR_MASK 0xf +#define NLE_R_GAIN_STEP_CUR_MASK_SFT (0xf << 24) +#define NLE_R_TOGGLE_NUM_CUR_SFT 16 +#define NLE_R_TOGGLE_NUM_CUR_MASK 0x3f +#define NLE_R_TOGGLE_NUM_CUR_MASK_SFT (0x3f << 16) +#define NLE_R_DIG_GAIN_TARGETED_SFT 15 +#define NLE_R_DIG_GAIN_TARGETED_MASK 0x1 +#define NLE_R_DIG_GAIN_TARGETED_MASK_SFT (0x1 << 15) +#define NLE_R_DIG_GAIN_INCREASE_SFT 14 +#define NLE_R_DIG_GAIN_INCREASE_MASK 0x1 +#define NLE_R_DIG_GAIN_INCREASE_MASK_SFT (0x1 << 14) +#define NLE_R_DIG_GAIN_DECREASE_SFT 13 +#define NLE_R_DIG_GAIN_DECREASE_MASK 0x1 +#define NLE_R_DIG_GAIN_DECREASE_MASK_SFT (0x1 << 13) +#define NLE_R_ANA_GAIN_TARGETED_SFT 12 +#define NLE_R_ANA_GAIN_TARGETED_MASK 0x1 +#define NLE_R_ANA_GAIN_TARGETED_MASK_SFT (0x1 << 12) +#define NLE_R_ANA_GAIN_INCREASE_SFT 11 +#define NLE_R_ANA_GAIN_INCREASE_MASK 0x1 +#define NLE_R_ANA_GAIN_INCREASE_MASK_SFT (0x1 << 11) +#define NLE_R_ANA_GAIN_DECREASE_SFT 10 +#define NLE_R_ANA_GAIN_DECREASE_MASK 0x1 +#define NLE_R_ANA_GAIN_DECREASE_MASK_SFT (0x1 << 10) +#define NLE_R_TIME_COUNTER_CUR_SFT 0 +#define NLE_R_TIME_COUNTER_CUR_MASK 0x1ff +#define NLE_R_TIME_COUNTER_CUR_MASK_SFT (0x1ff << 0) + +/* AFE_DL_NLE_R_MON2 */ +#define NLE_R_ANA_GAIN_SFT 8 +#define NLE_R_ANA_GAIN_MASK 0x1f +#define NLE_R_ANA_GAIN_MASK_SFT (0x1f << 8) +#define NLE_MOSI2_ANA_GAIN_SFT 0 +#define NLE_MOSI2_ANA_GAIN_MASK 0x7f +#define NLE_MOSI2_ANA_GAIN_MASK_SFT (0x7f << 0) + +/* AFE_DL_NLE_L_MON0 */ +#define NLE_L_GAIN_DIG_CUR_SFT 24 +#define NLE_L_GAIN_DIG_CUR_MASK 0x3f +#define NLE_L_GAIN_DIG_CUR_MASK_SFT (0x3f << 24) +#define NLE_L_ANC_MASK_SFT 23 +#define NLE_L_ANC_MASK_MASK 0x1 +#define NLE_L_ANC_MASK_MASK_SFT (0x1 << 23) +#define NLE_L_GAIN_ANA_CUR_SFT 16 +#define NLE_L_GAIN_ANA_CUR_MASK 0x3f +#define NLE_L_GAIN_ANA_CUR_MASK_SFT (0x3f << 16) +#define NLE_L_GAIN_DIG_TAR_CUR_SFT 8 +#define NLE_L_GAIN_DIG_TAR_CUR_MASK 0x3f +#define NLE_L_GAIN_DIG_TAR_CUR_MASK_SFT (0x3f << 8) +#define NLE_L_GAIN_ANA_TAR_CUR_SFT 0 +#define NLE_L_GAIN_ANA_TAR_CUR_MASK 0x3f +#define NLE_L_GAIN_ANA_TAR_CUR_MASK_SFT (0x3f << 0) + +/* AFE_DL_NLE_L_MON1 */ +#define NLE_L_STATE_CUR_SFT 28 +#define NLE_L_STATE_CUR_MASK 0x7 +#define NLE_L_STATE_CUR_MASK_SFT (0x7 << 28) +#define NLE_L_GAIN_STEP_CUR_SFT 24 +#define NLE_L_GAIN_STEP_CUR_MASK 0xf +#define NLE_L_GAIN_STEP_CUR_MASK_SFT (0xf << 24) +#define NLE_L_TOGGLE_NUM_CUR_SFT 16 +#define NLE_L_TOGGLE_NUM_CUR_MASK 0x3f +#define NLE_L_TOGGLE_NUM_CUR_MASK_SFT (0x3f << 16) +#define NLE_L_DIG_GAIN_TARGETED_SFT 15 +#define NLE_L_DIG_GAIN_TARGETED_MASK 0x1 +#define NLE_L_DIG_GAIN_TARGETED_MASK_SFT (0x1 << 15) +#define NLE_L_DIG_GAIN_INCREASE_SFT 14 +#define NLE_L_DIG_GAIN_INCREASE_MASK 0x1 +#define NLE_L_DIG_GAIN_INCREASE_MASK_SFT (0x1 << 14) +#define NLE_L_DIG_GAIN_DECREASE_SFT 13 +#define NLE_L_DIG_GAIN_DECREASE_MASK 0x1 +#define NLE_L_DIG_GAIN_DECREASE_MASK_SFT (0x1 << 13) +#define NLE_L_ANA_GAIN_TARGETED_SFT 12 +#define NLE_L_ANA_GAIN_TARGETED_MASK 0x1 +#define NLE_L_ANA_GAIN_TARGETED_MASK_SFT (0x1 << 12) +#define NLE_L_ANA_GAIN_INCREASE_SFT 11 +#define NLE_L_ANA_GAIN_INCREASE_MASK 0x1 +#define NLE_L_ANA_GAIN_INCREASE_MASK_SFT (0x1 << 11) +#define NLE_L_ANA_GAIN_DECREASE_SFT 10 +#define NLE_L_ANA_GAIN_DECREASE_MASK 0x1 +#define NLE_L_ANA_GAIN_DECREASE_MASK_SFT (0x1 << 10) +#define NLE_L_TIME_COUNTER_CUR_SFT 0 +#define NLE_L_TIME_COUNTER_CUR_MASK 0x1ff +#define NLE_L_TIME_COUNTER_CUR_MASK_SFT (0x1ff << 0) + +/* AFE_DL_NLE_L_MON2 */ +#define NLE_L_ANA_GAIN_SFT 8 +#define NLE_L_ANA_GAIN_MASK 0x1f +#define NLE_L_ANA_GAIN_MASK_SFT (0x1f << 8) +#define NLE_MOSI1_ANA_GAIN_SFT 0 +#define NLE_MOSI1_ANA_GAIN_MASK 0x7f +#define NLE_MOSI1_ANA_GAIN_MASK_SFT (0x7f << 0) + +/* AFE_DL_NLE_GAIN_CFG0 */ +#define MISO2_SEL_SFT 4 +#define MISO2_SEL_MASK 0x3 +#define MISO2_SEL_MASK_SFT (0x3 << 4) +#define MISO1_SEL_SFT 0 +#define MISO1_SEL_MASK 0x3 +#define MISO1_SEL_MASK_SFT (0x3 << 0) + +/* AFE_DEM_IDWA_CON0 */ +#define RG_IDWA_SDM_MAV_EN_SFT 31 +#define RG_IDWA_SDM_MAV_EN_MASK 0x1 +#define RG_IDWA_SDM_MAV_EN_MASK_SFT (0x1 << 31) +#define RG_IDWA_SDM_ADITHON_SFT 30 +#define RG_IDWA_SDM_ADITHON_MASK 0x1 +#define RG_IDWA_SDM_ADITHON_MASK_SFT (0x1 << 30) +#define RG_IDWA_SDM_ADITHVAL_SFT 28 +#define RG_IDWA_SDM_ADITHVAL_MASK 0x3 +#define RG_IDWA_SDM_ADITHVAL_MASK_SFT (0x3 << 28) +#define RG_IDWA_SDM_LOOPBACK_SFT 27 +#define RG_IDWA_SDM_LOOPBACK_MASK 0x1 +#define RG_IDWA_SDM_LOOPBACK_MASK_SFT (0x1 << 27) +#define RG_IDWA_SEL_SFT 26 +#define RG_IDWA_SEL_MASK 0x1 +#define RG_IDWA_SEL_MASK_SFT (0x1 << 26) +#define RG_IDWA_ON_SFT 25 +#define RG_IDWA_ON_MASK 0x1 +#define RG_IDWA_ON_MASK_SFT (0x1 << 25) +#define RG_DEM_IN_LR_SWAP_SFT 24 +#define RG_DEM_IN_LR_SWAP_MASK 0x1 +#define RG_DEM_IN_LR_SWAP_MASK_SFT (0x1 << 24) +#define RG_DEM_IN_L_INV_SFT 23 +#define RG_DEM_IN_L_INV_MASK 0x1 +#define RG_DEM_IN_L_INV_MASK_SFT (0x1 << 23) +#define RG_DEM_IN_R_EQ_L_SFT 22 +#define RG_DEM_IN_R_EQ_L_MASK 0x1 +#define RG_DEM_IN_R_EQ_L_MASK_SFT (0x1 << 22) +#define RG_DEM_IN_L_MUTE_SFT 21 +#define RG_DEM_IN_L_MUTE_MASK 0x1 +#define RG_DEM_IN_L_MUTE_MASK_SFT (0x1 << 21) +#define RG_DEM_IN_R_MUTE_SFT 20 +#define RG_DEM_IN_R_MUTE_MASK 0x1 +#define RG_DEM_IN_R_MUTE_MASK_SFT (0x1 << 20) +#define RG_DEM_IN_SOURCE_SFT 19 +#define RG_DEM_IN_SOURCE_MASK 0x1 +#define RG_DEM_IN_SOURCE_MASK_SFT (0x1 << 19) +#define RG_DEM_SPLITTER_TRUNC_RND_SFT 18 +#define RG_DEM_SPLITTER_TRUNC_RND_MASK 0x1 +#define RG_DEM_SPLITTER_TRUNC_RND_MASK_SFT (0x1 << 18) +#define RG_DEM_SCRAMBLER_CG_EN_SFT 17 +#define RG_DEM_SCRAMBLER_CG_EN_MASK 0x1 +#define RG_DEM_SCRAMBLER_CG_EN_MASK_SFT (0x1 << 17) +#define RG_DEM_SCRAMBLER_EN_SFT 16 +#define RG_DEM_SCRAMBLER_EN_MASK 0x1 +#define RG_DEM_SCRAMBLER_EN_MASK_SFT (0x1 << 16) +#define RG_DEM_AUD_SDM_7BIT_SEL_SFT 15 +#define RG_DEM_AUD_SDM_7BIT_SEL_MASK 0x1 +#define RG_DEM_AUD_SDM_7BIT_SEL_MASK_SFT (0x1 << 15) +#define RG_DEM_ZERO_PAD_DISABLE_SFT 14 +#define RG_DEM_ZERO_PAD_DISABLE_MASK 0x1 +#define RG_DEM_ZERO_PAD_DISABLE_MASK_SFT (0x1 << 14) +#define RG_DEM_SPLITTER_TEST_EN_SFT 13 +#define RG_DEM_SPLITTER_TEST_EN_MASK 0x1 +#define RG_DEM_SPLITTER_TEST_EN_MASK_SFT (0x1 << 13) +#define RG_DEM_IDAC_TEST_EN_SFT 12 +#define RG_DEM_IDAC_TEST_EN_MASK 0x1 +#define RG_DEM_IDAC_TEST_EN_MASK_SFT (0x1 << 12) +#define RG_DEM_SPLIT_SCRAM_ON_SFT 11 +#define RG_DEM_SPLIT_SCRAM_ON_MASK 0x1 +#define RG_DEM_SPLIT_SCRAM_ON_MASK_SFT (0x1 << 11) +#define RG_DEM_RAND_EN_SFT 10 +#define RG_DEM_RAND_EN_MASK 0x1 +#define RG_DEM_RAND_EN_MASK_SFT (0x1 << 10) +#define RG_DEM_SPLITTER2_DITHER_EN_SFT 9 +#define RG_DEM_SPLITTER2_DITHER_EN_MASK 0x1 +#define RG_DEM_SPLITTER2_DITHER_EN_MASK_SFT (0x1 << 9) +#define RG_DEM_SPLITTER1_DITHER_EN_SFT 8 +#define RG_DEM_SPLITTER1_DITHER_EN_MASK 0x1 +#define RG_DEM_SPLITTER1_DITHER_EN_MASK_SFT (0x1 << 8) +#define RG_DEM_SPLITTER2_DITHER_GAIN_SFT 4 +#define RG_DEM_SPLITTER2_DITHER_GAIN_MASK 0xf +#define RG_DEM_SPLITTER2_DITHER_GAIN_MASK_SFT (0xf << 4) +#define RG_DEM_SPLITTER1_DITHER_GAIN_SFT 0 +#define RG_DEM_SPLITTER1_DITHER_GAIN_MASK 0xf +#define RG_DEM_SPLITTER1_DITHER_GAIN_MASK_SFT (0xf << 0) + +/* DEM_RECONSTRUCT_MON */ +#define DEM_RECONSTRUCT_L_MON_SFT 8 +#define DEM_RECONSTRUCT_L_MON_MASK 0xff +#define DEM_RECONSTRUCT_L_MON_MASK_SFT (0xff << 8) +#define DEM_RECONSTRUCT_R_MON_SFT 0 +#define DEM_RECONSTRUCT_R_MON_MASK 0xff +#define DEM_RECONSTRUCT_R_MON_MASK_SFT (0xff << 0) + +/* AFE_STF_CON0 */ +#define SLT_CNT_FLAG_RESET_SFT 28 +#define SLT_CNT_FLAG_RESET_MASK 0x1 +#define SLT_CNT_FLAG_RESET_MASK_SFT (0x1 << 28) +#define SLT_CNT_THD_SFT 16 +#define SLT_CNT_THD_MASK 0xfff +#define SLT_CNT_THD_MASK_SFT (0xfff << 16) +#define SIDE_TONE_HALF_TAP_NUM_SFT 4 +#define SIDE_TONE_HALF_TAP_NUM_MASK 0x7f +#define SIDE_TONE_HALF_TAP_NUM_MASK_SFT (0x7f << 4) +#define SIDE_TONE_ODD_MODE_SFT 1 +#define SIDE_TONE_ODD_MODE_MASK 0x1 +#define SIDE_TONE_ODD_MODE_MASK_SFT (0x1 << 1) +#define SIDE_TONE_ON_SFT 0 +#define SIDE_TONE_ON_MASK 0x1 +#define SIDE_TONE_ON_MASK_SFT (0x1 << 0) + +/* AFE_STF_CON1 */ +#define SIDE_TONE_IN_EN_SEL_DOMAIN_SFT 5 +#define SIDE_TONE_IN_EN_SEL_DOMAIN_MASK 0x7 +#define SIDE_TONE_IN_EN_SEL_DOMAIN_MASK_SFT (0x7 << 5) +#define SIDE_TONE_IN_EN_SEL_FS_SFT 0 +#define SIDE_TONE_IN_EN_SEL_FS_MASK 0x1f +#define SIDE_TONE_IN_EN_SEL_FS_MASK_SFT (0x1f << 0) + +/* AFE_STF_COEFF */ +#define SIDE_TONE_COEFFICIENT_R_W_SEL_SFT 24 +#define SIDE_TONE_COEFFICIENT_R_W_SEL_MASK 0x1 +#define SIDE_TONE_COEFFICIENT_R_W_SEL_MASK_SFT (0x1 << 24) +#define SIDE_TONE_COEFFICIENT_ADDR_SFT 16 +#define SIDE_TONE_COEFFICIENT_ADDR_MASK 0x1f +#define SIDE_TONE_COEFFICIENT_ADDR_MASK_SFT (0x1f << 16) +#define SIDE_TONE_COEFFICIENT_SFT 0 +#define SIDE_TONE_COEFFICIENT_MASK 0xffff +#define SIDE_TONE_COEFFICIENT_MASK_SFT (0xffff << 0) + +/* AFE_STF_GAIN */ +#define SIDE_TONE_POSITIVE_GAIN_SFT 16 +#define SIDE_TONE_POSITIVE_GAIN_MASK 0x7 +#define SIDE_TONE_POSITIVE_GAIN_MASK_SFT (0x7 << 16) +#define SIDE_TONE_GAIN_SFT 0 +#define SIDE_TONE_GAIN_MASK 0xffff +#define SIDE_TONE_GAIN_MASK_SFT (0xffff << 0) + +/* AFE_STF_MON */ +#define SIDE_TONE_R_RDY_SFT 30 +#define SIDE_TONE_R_RDY_MASK 0x1 +#define SIDE_TONE_R_RDY_MASK_SFT (0x1 << 30) +#define SIDE_TONE_W_RDY_SFT 29 +#define SIDE_TONE_W_RDY_MASK 0x1 +#define SIDE_TONE_W_RDY_MASK_SFT (0x1 << 29) +#define SLT_CNT_FLAG_SFT 28 +#define SLT_CNT_FLAG_MASK 0x1 +#define SLT_CNT_FLAG_MASK_SFT (0x1 << 28) +#define SLT_CNT_SFT 16 +#define SLT_CNT_MASK 0xfff +#define SLT_CNT_MASK_SFT (0xfff << 16) +#define SIDE_TONE_COEFF_SFT 0 +#define SIDE_TONE_COEFF_MASK 0xffff +#define SIDE_TONE_COEFF_MASK_SFT (0xffff << 0) + +/* AFE_STF_IP_VERSION */ +#define SIDE_TONE_IP_VERSION_SFT 0 +#define SIDE_TONE_IP_VERSION_MASK 0xffffffff +#define SIDE_TONE_IP_VERSION_MASK_SFT (0xffffffff << 0) + +/* AFE_CM_REG */ +#define AFE_CM_UPDATE_CNT_SFT 16 +#define AFE_CM_UPDATE_CNT_MASK 0x7fff +#define AFE_CM_UPDATE_CNT_MASK_SFT (0x7fff << 16) +#define AFE_CM_1X_EN_SEL_FS_SFT 8 +#define AFE_CM_1X_EN_SEL_FS_MASK 0x1f +#define AFE_CM_1X_EN_SEL_FS_MASK_SFT (0x1f << 8) +#define AFE_CM_CH_NUM_SFT 2 +#define AFE_CM_CH_NUM_MASK 0x1f +#define AFE_CM_CH_NUM_MASK_SFT (0x1f << 2) +#define AFE_CM_BYTE_SWAP_SFT 1 +#define AFE_CM_BYTE_SWAP_MASK 0x1 +#define AFE_CM_BYTE_SWAP_MASK_SFT (0x1 << 1) +#define AFE_CM_BYPASS_MODE_SFT 31 +#define AFE_CM_BYPASS_MODE_MASK 0x1 +#define AFE_CM_BYPASS_MODE_MASK_SFT (0x1 << 31) + +/* AFE_CM0_CON0 */ +#define AFE_CM0_BYPASS_MODE_SFT 31 +#define AFE_CM0_BYPASS_MODE_MASK 0x1 +#define AFE_CM0_BYPASS_MODE_MASK_SFT (0x1 << 31) +#define AFE_CM0_UPDATE_CNT_SFT 16 +#define AFE_CM0_UPDATE_CNT_MASK 0x7fff +#define AFE_CM0_UPDATE_CNT_MASK_SFT (0x7fff << 16) +#define AFE_CM0_1X_EN_SEL_DOMAIN_SFT 13 +#define AFE_CM0_1X_EN_SEL_DOMAIN_MASK 0x7 +#define AFE_CM0_1X_EN_SEL_DOMAIN_MASK_SFT (0x7 << 13) +#define AFE_CM0_1X_EN_SEL_FS_SFT 8 +#define AFE_CM0_1X_EN_SEL_FS_MASK 0x1f +#define AFE_CM0_1X_EN_SEL_FS_MASK_SFT (0x1f << 8) +#define AFE_CM0_OUTPUT_MUX_SFT 7 +#define AFE_CM0_OUTPUT_MUX_MASK 0x1 +#define AFE_CM0_OUTPUT_MUX_MASK_SFT (0x1 << 7) +#define AFE_CM0_CH_NUM_SFT 2 +#define AFE_CM0_CH_NUM_MASK 0x1f +#define AFE_CM0_CH_NUM_MASK_SFT (0x1f << 2) +#define AFE_CM0_BYTE_SWAP_SFT 1 +#define AFE_CM0_BYTE_SWAP_MASK 0x1 +#define AFE_CM0_BYTE_SWAP_MASK_SFT (0x1 << 1) +#define AFE_CM0_ON_SFT 0 +#define AFE_CM0_ON_MASK 0x1 +#define AFE_CM0_ON_MASK_SFT (0x1 << 0) + +/* AFE_CM0_MON */ +#define AFE_CM0_BYPASS_MODE_MON_SFT 31 +#define AFE_CM0_BYPASS_MODE_MON_MASK 0x1 +#define AFE_CM0_BYPASS_MODE_MON_MASK_SFT (0x1 << 31) +#define AFE_CM0_OUTPUT_CNT_MON_SFT 16 +#define AFE_CM0_OUTPUT_CNT_MON_MASK 0x7fff +#define AFE_CM0_OUTPUT_CNT_MON_MASK_SFT (0x7fff << 16) +#define AFE_CM0_CUR_CHSET_MON_SFT 5 +#define AFE_CM0_CUR_CHSET_MON_MASK 0xf +#define AFE_CM0_CUR_CHSET_MON_MASK_SFT (0xf << 5) +#define AFE_CM0_ODD_FLAG_MON_SFT 4 +#define AFE_CM0_ODD_FLAG_MON_MASK 0x1 +#define AFE_CM0_ODD_FLAG_MON_MASK_SFT (0x1 << 4) +#define AFE_CM0_BYTE_SWAP_MON_SFT 1 +#define AFE_CM0_BYTE_SWAP_MON_MASK 0x1 +#define AFE_CM0_BYTE_SWAP_MON_MASK_SFT (0x1 << 1) +#define AFE_CM0_ON_MON_SFT 0 +#define AFE_CM0_ON_MON_MASK 0x1 +#define AFE_CM0_ON_MON_MASK_SFT (0x1 << 0) + +/* AFE_CM0_IP_VERSION */ +#define AFE_CM0_IP_VERSION_SFT 0 +#define AFE_CM0_IP_VERSION_MASK 0xffffffff +#define AFE_CM0_IP_VERSION_MASK_SFT (0xffffffff << 0) + +/* AFE_CM1_CON0 */ +#define AFE_CM1_BYPASS_MODE_SFT 31 +#define AFE_CM1_BYPASS_MODE_MASK 0x1 +#define AFE_CM1_BYPASS_MODE_MASK_SFT (0x1 << 31) +#define AFE_CM1_UPDATE_CNT_SFT 16 +#define AFE_CM1_UPDATE_CNT_MASK 0x7fff +#define AFE_CM1_UPDATE_CNT_MASK_SFT (0x7fff << 16) +#define AFE_CM1_1X_EN_SEL_DOMAIN_SFT 13 +#define AFE_CM1_1X_EN_SEL_DOMAIN_MASK 0x7 +#define AFE_CM1_1X_EN_SEL_DOMAIN_MASK_SFT (0x7 << 13) +#define AFE_CM1_1X_EN_SEL_FS_SFT 8 +#define AFE_CM1_1X_EN_SEL_FS_MASK 0x1f +#define AFE_CM1_1X_EN_SEL_FS_MASK_SFT (0x1f << 8) +#define AFE_CM1_OUTPUT_MUX_SFT 7 +#define AFE_CM1_OUTPUT_MUX_MASK 0x1 +#define AFE_CM1_OUTPUT_MUX_MASK_SFT (0x1 << 7) +#define AFE_CM1_CH_NUM_SFT 2 +#define AFE_CM1_CH_NUM_MASK 0x1f +#define AFE_CM1_CH_NUM_MASK_SFT (0x1f << 2) +#define AFE_CM1_BYTE_SWAP_SFT 1 +#define AFE_CM1_BYTE_SWAP_MASK 0x1 +#define AFE_CM1_BYTE_SWAP_MASK_SFT (0x1 << 1) +#define AFE_CM1_ON_SFT 0 +#define AFE_CM1_ON_MASK 0x1 +#define AFE_CM1_ON_MASK_SFT (0x1 << 0) + +/* AFE_CM1_MON */ +#define AFE_CM1_BYPASS_MODE_MON_SFT 31 +#define AFE_CM1_BYPASS_MODE_MON_MASK 0x1 +#define AFE_CM1_BYPASS_MODE_MON_MASK_SFT (0x1 << 31) +#define AFE_CM1_OUTPUT_CNT_MON_SFT 16 +#define AFE_CM1_OUTPUT_CNT_MON_MASK 0x7fff +#define AFE_CM1_OUTPUT_CNT_MON_MASK_SFT (0x7fff << 16) +#define AFE_CM1_CUR_CHSET_MON_SFT 5 +#define AFE_CM1_CUR_CHSET_MON_MASK 0xf +#define AFE_CM1_CUR_CHSET_MON_MASK_SFT (0xf << 5) +#define AFE_CM1_ODD_FLAG_MON_SFT 4 +#define AFE_CM1_ODD_FLAG_MON_MASK 0x1 +#define AFE_CM1_ODD_FLAG_MON_MASK_SFT (0x1 << 4) +#define AFE_CM1_BYTE_SWAP_MON_SFT 1 +#define AFE_CM1_BYTE_SWAP_MON_MASK 0x1 +#define AFE_CM1_BYTE_SWAP_MON_MASK_SFT (0x1 << 1) +#define AFE_CM1_ON_MON_SFT 0 +#define AFE_CM1_ON_MON_MASK 0x1 +#define AFE_CM1_ON_MON_MASK_SFT (0x1 << 0) + +/* AFE_CM1_IP_VERSION */ +#define AFE_CM1_IP_VERSION_SFT 0 +#define AFE_CM1_IP_VERSION_MASK 0xffffffff +#define AFE_CM1_IP_VERSION_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL0_SRC_CON0 */ +#define ULCF_CFG_EN_CTL_SFT 31 +#define ULCF_CFG_EN_CTL_MASK 0x1 +#define ULCF_CFG_EN_CTL_MASK_SFT (0x1 << 31) +#define UL_DMIC_PHASE_SEL_CH1_SFT 27 +#define UL_DMIC_PHASE_SEL_CH1_MASK 0x7 +#define UL_DMIC_PHASE_SEL_CH1_MASK_SFT (0x7 << 27) +#define UL_DMIC_PHASE_SEL_CH2_SFT 24 +#define UL_DMIC_PHASE_SEL_CH2_MASK 0x7 +#define UL_DMIC_PHASE_SEL_CH2_MASK_SFT (0x7 << 24) +#define UL_DMIC_TWO_WIRE_CTL_SFT 23 +#define UL_DMIC_TWO_WIRE_CTL_MASK 0x1 +#define UL_DMIC_TWO_WIRE_CTL_MASK_SFT (0x1 << 23) +#define UL_MODE_3P25M_CH2_CTL_SFT 22 +#define UL_MODE_3P25M_CH2_CTL_MASK 0x1 +#define UL_MODE_3P25M_CH2_CTL_MASK_SFT (0x1 << 22) +#define UL_MODE_3P25M_CH1_CTL_SFT 21 +#define UL_MODE_3P25M_CH1_CTL_MASK 0x1 +#define UL_MODE_3P25M_CH1_CTL_MASK_SFT (0x1 << 21) +#define UL_VOICE_MODE_CH1_CH2_CTL_SFT 17 +#define UL_VOICE_MODE_CH1_CH2_CTL_MASK 0x7 +#define UL_VOICE_MODE_CH1_CH2_CTL_MASK_SFT (0x7 << 17) +#define UL_AP_DMIC_ON_SFT 16 +#define UL_AP_DMIC_ON_MASK 0x1 +#define UL_AP_DMIC_ON_MASK_SFT (0x1 << 16) +#define DMIC_LOW_POWER_MODE_CTL_SFT 14 +#define DMIC_LOW_POWER_MODE_CTL_MASK 0x3 +#define DMIC_LOW_POWER_MODE_CTL_MASK_SFT (0x3 << 14) +#define UL_DISABLE_HW_CG_CTL_SFT 12 +#define UL_DISABLE_HW_CG_CTL_MASK 0x1 +#define UL_DISABLE_HW_CG_CTL_MASK_SFT (0x1 << 12) +#define AMIC_26M_SEL_CTL_SFT 11 +#define AMIC_26M_SEL_CTL_MASK 0x1 +#define AMIC_26M_SEL_CTL_MASK_SFT (0x1 << 11) +#define UL_IIR_ON_TMP_CTL_SFT 10 +#define UL_IIR_ON_TMP_CTL_MASK 0x1 +#define UL_IIR_ON_TMP_CTL_MASK_SFT (0x1 << 10) +#define UL_IIRMODE_CTL_SFT 7 +#define UL_IIRMODE_CTL_MASK 0x7 +#define UL_IIRMODE_CTL_MASK_SFT (0x7 << 7) +#define DIGMIC_4P33M_SEL_SFT 6 +#define DIGMIC_4P33M_SEL_MASK 0x1 +#define DIGMIC_4P33M_SEL_MASK_SFT (0x1 << 6) +#define DIGMIC_3P25M_1P625M_SEL_CTL_SFT 5 +#define DIGMIC_3P25M_1P625M_SEL_CTL_MASK 0x1 +#define DIGMIC_3P25M_1P625M_SEL_CTL_MASK_SFT (0x1 << 5) +#define AMIC_6P5M_SEL_CTL_SFT 4 +#define AMIC_6P5M_SEL_CTL_MASK 0x1 +#define AMIC_6P5M_SEL_CTL_MASK_SFT (0x1 << 4) +#define AMIC_1P625M_SEL_CTL_SFT 3 +#define AMIC_1P625M_SEL_CTL_MASK 0x1 +#define AMIC_1P625M_SEL_CTL_MASK_SFT (0x1 << 3) +#define UL_LOOP_BACK_MODE_CTL_SFT 2 +#define UL_LOOP_BACK_MODE_CTL_MASK 0x1 +#define UL_LOOP_BACK_MODE_CTL_MASK_SFT (0x1 << 2) +#define UL_SDM_3_LEVEL_CTL_SFT 1 +#define UL_SDM_3_LEVEL_CTL_MASK 0x1 +#define UL_SDM_3_LEVEL_CTL_MASK_SFT (0x1 << 1) +#define UL_SRC_ON_TMP_CTL_SFT 0 +#define UL_SRC_ON_TMP_CTL_MASK 0x1 +#define UL_SRC_ON_TMP_CTL_MASK_SFT (0x1 << 0) + +/* AFE_ADDA_UL0_SRC_CON1 */ +#define ADDA_UL_GAIN_VALUE_SFT 16 +#define ADDA_UL_GAIN_VALUE_MASK 0xffff +#define ADDA_UL_GAIN_VALUE_MASK_SFT (0xffff << 16) +#define ADDA_UL_POSTIVEGAIN_SFT 12 +#define ADDA_UL_POSTIVEGAIN_MASK 0x7 +#define ADDA_UL_POSTIVEGAIN_MASK_SFT (0x7 << 12) +#define ADDA_UL_ODDTAP_MODE_SFT 11 +#define ADDA_UL_ODDTAP_MODE_MASK 0x1 +#define ADDA_UL_ODDTAP_MODE_MASK_SFT (0x1 << 11) +#define ADDA_UL_HALF_TAP_NUM_SFT 5 +#define ADDA_UL_HALF_TAP_NUM_MASK 0x3f +#define ADDA_UL_HALF_TAP_NUM_MASK_SFT (0x3f << 5) +#define FIFO_SOFT_RST_SFT 4 +#define FIFO_SOFT_RST_MASK 0x1 +#define FIFO_SOFT_RST_MASK_SFT (0x1 << 4) +#define FIFO_SOFT_RST_EN_SFT 3 +#define FIFO_SOFT_RST_EN_MASK 0x1 +#define FIFO_SOFT_RST_EN_MASK_SFT (0x1 << 3) +#define LR_SWAP_SFT 2 +#define LR_SWAP_MASK 0x1 +#define LR_SWAP_MASK_SFT (0x1 << 2) +#define GAIN_MODE_SFT 0 +#define GAIN_MODE_MASK 0x3 +#define GAIN_MODE_MASK_SFT (0x3 << 0) + +/* AFE_ADDA_UL0_SRC_CON2 */ +#define C_DAC_EN_CTL_SFT 27 +#define C_DAC_EN_CTL_MASK 0x1 +#define C_DAC_EN_CTL_MASK_SFT (0x1 << 27) +#define C_MUTE_SW_CTL_SFT 26 +#define C_MUTE_SW_CTL_MASK 0x1 +#define C_MUTE_SW_CTL_MASK_SFT (0x1 << 26) +#define C_AMP_DIV_CH2_CTL_SFT 21 +#define C_AMP_DIV_CH2_CTL_MASK 0x7 +#define C_AMP_DIV_CH2_CTL_MASK_SFT (0x7 << 21) +#define C_FREQ_DIV_CH2_CTL_SFT 16 +#define C_FREQ_DIV_CH2_CTL_MASK 0x1f +#define C_FREQ_DIV_CH2_CTL_MASK_SFT (0x1f << 16) +#define C_SINE_MODE_CH2_CTL_SFT 12 +#define C_SINE_MODE_CH2_CTL_MASK 0xf +#define C_SINE_MODE_CH2_CTL_MASK_SFT (0xf << 12) +#define C_AMP_DIV_CH1_CTL_SFT 9 +#define C_AMP_DIV_CH1_CTL_MASK 0x7 +#define C_AMP_DIV_CH1_CTL_MASK_SFT (0x7 << 9) +#define C_FREQ_DIV_CH1_CTL_SFT 4 +#define C_FREQ_DIV_CH1_CTL_MASK 0x1f +#define C_FREQ_DIV_CH1_CTL_MASK_SFT (0x1f << 4) +#define C_SINE_MODE_CH1_CTL_SFT 0 +#define C_SINE_MODE_CH1_CTL_MASK 0xf +#define C_SINE_MODE_CH1_CTL_MASK_SFT (0xf << 0) + +/* AFE_ADDA_UL0_SRC_DEBUG */ +#define UL_SLT_CNT_FLAG_RESET_CTL_SFT 16 +#define UL_SLT_CNT_FLAG_RESET_CTL_MASK 0x1 +#define UL_SLT_CNT_FLAG_RESET_CTL_MASK_SFT (0x1 << 16) +#define FIFO_DIGMIC_TESTIN_SFT 12 +#define FIFO_DIGMIC_TESTIN_MASK 0x3 +#define FIFO_DIGMIC_TESTIN_MASK_SFT (0x3 << 12) +#define FIFO_DIGMIC_WDATA_TESTEN_SFT 11 +#define FIFO_DIGMIC_WDATA_TESTEN_MASK 0x1 +#define FIFO_DIGMIC_WDATA_TESTEN_MASK_SFT (0x1 << 11) +#define SLT_CNT_THD_CTL_SFT 0 +#define SLT_CNT_THD_CTL_MASK 0x7ff +#define SLT_CNT_THD_CTL_MASK_SFT (0x7ff << 0) + +/* AFE_ADDA_UL0_SRC_DEBUG_MON0 */ +#define SLT_CNT_FLAG_CTL_SFT 16 +#define SLT_CNT_FLAG_CTL_MASK 0x1 +#define SLT_CNT_FLAG_CTL_MASK_SFT (0x1 << 16) +#define SLT_COUNTER_CTL_SFT 0 +#define SLT_COUNTER_CTL_MASK 0x7ff +#define SLT_COUNTER_CTL_MASK_SFT (0x7ff << 0) + +/* AFE_ADDA_UL0_SRC_MON1 */ +#define UL_VOICE_MODE_CTL_SFT 29 +#define UL_VOICE_MODE_CTL_MASK 0x7 +#define UL_VOICE_MODE_CTL_MASK_SFT (0x7 << 29) +#define DATA_COMB_IN_CH2_SFT 24 +#define DATA_COMB_IN_CH2_MASK 0x1f +#define DATA_COMB_IN_CH2_MASK_SFT (0x1f << 24) +#define DATA_COMB_OUT_CH2_SFT 0 +#define DATA_COMB_OUT_CH2_MASK 0xffffff +#define DATA_COMB_OUT_CH2_MASK_SFT (0xffffff << 0) + +/* AFE_ADDA_UL0_IIR_COEF_02_01 */ +#define ADDA_IIR_COEF_02_01_SFT 0 +#define ADDA_IIR_COEF_02_01_MASK 0xffffffff +#define ADDA_IIR_COEF_02_01_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL0_IIR_COEF_04_03 */ +#define ADDA_IIR_COEF_04_03_SFT 0 +#define ADDA_IIR_COEF_04_03_MASK 0xffffffff +#define ADDA_IIR_COEF_04_03_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL0_IIR_COEF_06_05 */ +#define ADDA_IIR_COEF_06_05_SFT 0 +#define ADDA_IIR_COEF_06_05_MASK 0xffffffff +#define ADDA_IIR_COEF_06_05_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL0_IIR_COEF_08_07 */ +#define ADDA_IIR_COEF_08_07_SFT 0 +#define ADDA_IIR_COEF_08_07_MASK 0xffffffff +#define ADDA_IIR_COEF_08_07_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL0_IIR_COEF_10_09 */ +#define ADDA_IIR_COEF_10_09_SFT 0 +#define ADDA_IIR_COEF_10_09_MASK 0xffffffff +#define ADDA_IIR_COEF_10_09_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL0_ULCF_CFG_02_01 */ +#define ADDA_ULCF_CFG_02_01_SFT 0 +#define ADDA_ULCF_CFG_02_01_MASK 0xffffffff +#define ADDA_ULCF_CFG_02_01_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL0_ULCF_CFG_04_03 */ +#define ADDA_ULCF_CFG_04_03_SFT 0 +#define ADDA_ULCF_CFG_04_03_MASK 0xffffffff +#define ADDA_ULCF_CFG_04_03_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL0_ULCF_CFG_06_05 */ +#define ADDA_ULCF_CFG_06_05_SFT 0 +#define ADDA_ULCF_CFG_06_05_MASK 0xffffffff +#define ADDA_ULCF_CFG_06_05_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL0_ULCF_CFG_08_07 */ +#define ADDA_ULCF_CFG_08_07_SFT 0 +#define ADDA_ULCF_CFG_08_07_MASK 0xffffffff +#define ADDA_ULCF_CFG_08_07_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL0_ULCF_CFG_10_09 */ +#define ADDA_ULCF_CFG_10_09_SFT 0 +#define ADDA_ULCF_CFG_10_09_MASK 0xffffffff +#define ADDA_ULCF_CFG_10_09_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL0_ULCF_CFG_12_11 */ +#define ADDA_ULCF_CFG_12_11_SFT 0 +#define ADDA_ULCF_CFG_12_11_MASK 0xffffffff +#define ADDA_ULCF_CFG_12_11_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL0_ULCF_CFG_14_13 */ +#define ADDA_ULCF_CFG_14_13_SFT 0 +#define ADDA_ULCF_CFG_14_13_MASK 0xffffffff +#define ADDA_ULCF_CFG_14_13_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL0_ULCF_CFG_16_15 */ +#define ADDA_ULCF_CFG_16_15_SFT 0 +#define ADDA_ULCF_CFG_16_15_MASK 0xffffffff +#define ADDA_ULCF_CFG_16_15_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL0_ULCF_CFG_18_17 */ +#define ADDA_ULCF_CFG_18_17_SFT 0 +#define ADDA_ULCF_CFG_18_17_MASK 0xffffffff +#define ADDA_ULCF_CFG_18_17_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL0_ULCF_CFG_20_19 */ +#define ADDA_ULCF_CFG_20_19_SFT 0 +#define ADDA_ULCF_CFG_20_19_MASK 0xffffffff +#define ADDA_ULCF_CFG_20_19_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL0_ULCF_CFG_22_21 */ +#define ADDA_ULCF_CFG_22_21_SFT 0 +#define ADDA_ULCF_CFG_22_21_MASK 0xffffffff +#define ADDA_ULCF_CFG_22_21_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL0_ULCF_CFG_24_23 */ +#define ADDA_ULCF_CFG_24_23_SFT 0 +#define ADDA_ULCF_CFG_24_23_MASK 0xffffffff +#define ADDA_ULCF_CFG_24_23_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL0_ULCF_CFG_26_25 */ +#define ADDA_ULCF_CFG_26_25_SFT 0 +#define ADDA_ULCF_CFG_26_25_MASK 0xffffffff +#define ADDA_ULCF_CFG_26_25_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL0_ULCF_CFG_28_27 */ +#define ADDA_ULCF_CFG_28_27_SFT 0 +#define ADDA_ULCF_CFG_28_27_MASK 0xffffffff +#define ADDA_ULCF_CFG_28_27_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL0_ULCF_CFG_30_29 */ +#define ADDA_ULCF_CFG_30_29_SFT 0 +#define ADDA_ULCF_CFG_30_29_MASK 0xffffffff +#define ADDA_ULCF_CFG_30_29_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL0_ULCF_CFG_32_31 */ +#define ADDA_ULCF_CFG_32_31_SFT 0 +#define ADDA_ULCF_CFG_32_31_MASK 0xffffffff +#define ADDA_ULCF_CFG_32_31_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL0_IP_VERSION */ +#define ADDA_ULCF_IP_VERSION_SFT 0 +#define ADDA_ULCF_IP_VERSION_MASK 0xffffffff +#define ADDA_ULCF_IP_VERSION_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL1_SRC_CON0 */ +#define ULCF_CFG_EN_CTL_SFT 31 +#define ULCF_CFG_EN_CTL_MASK 0x1 +#define ULCF_CFG_EN_CTL_MASK_SFT (0x1 << 31) +#define UL_DMIC_PHASE_SEL_CH1_SFT 27 +#define UL_DMIC_PHASE_SEL_CH1_MASK 0x7 +#define UL_DMIC_PHASE_SEL_CH1_MASK_SFT (0x7 << 27) +#define UL_DMIC_PHASE_SEL_CH2_SFT 24 +#define UL_DMIC_PHASE_SEL_CH2_MASK 0x7 +#define UL_DMIC_PHASE_SEL_CH2_MASK_SFT (0x7 << 24) +#define UL_DMIC_TWO_WIRE_CTL_SFT 23 +#define UL_DMIC_TWO_WIRE_CTL_MASK 0x1 +#define UL_DMIC_TWO_WIRE_CTL_MASK_SFT (0x1 << 23) +#define UL_MODE_3P25M_CH2_CTL_SFT 22 +#define UL_MODE_3P25M_CH2_CTL_MASK 0x1 +#define UL_MODE_3P25M_CH2_CTL_MASK_SFT (0x1 << 22) +#define UL_MODE_3P25M_CH1_CTL_SFT 21 +#define UL_MODE_3P25M_CH1_CTL_MASK 0x1 +#define UL_MODE_3P25M_CH1_CTL_MASK_SFT (0x1 << 21) +#define UL_VOICE_MODE_CH1_CH2_CTL_SFT 17 +#define UL_VOICE_MODE_CH1_CH2_CTL_MASK 0x7 +#define UL_VOICE_MODE_CH1_CH2_CTL_MASK_SFT (0x7 << 17) +#define UL_AP_DMIC_ON_SFT 16 +#define UL_AP_DMIC_ON_MASK 0x1 +#define UL_AP_DMIC_ON_MASK_SFT (0x1 << 16) +#define DMIC_LOW_POWER_MODE_CTL_SFT 14 +#define DMIC_LOW_POWER_MODE_CTL_MASK 0x3 +#define DMIC_LOW_POWER_MODE_CTL_MASK_SFT (0x3 << 14) +#define UL_DISABLE_HW_CG_CTL_SFT 12 +#define UL_DISABLE_HW_CG_CTL_MASK 0x1 +#define UL_DISABLE_HW_CG_CTL_MASK_SFT (0x1 << 12) +#define AMIC_26M_SEL_CTL_SFT 11 +#define AMIC_26M_SEL_CTL_MASK 0x1 +#define AMIC_26M_SEL_CTL_MASK_SFT (0x1 << 11) +#define UL_IIR_ON_TMP_CTL_SFT 10 +#define UL_IIR_ON_TMP_CTL_MASK 0x1 +#define UL_IIR_ON_TMP_CTL_MASK_SFT (0x1 << 10) +#define UL_IIRMODE_CTL_SFT 7 +#define UL_IIRMODE_CTL_MASK 0x7 +#define UL_IIRMODE_CTL_MASK_SFT (0x7 << 7) +#define DIGMIC_4P33M_SEL_SFT 6 +#define DIGMIC_4P33M_SEL_MASK 0x1 +#define DIGMIC_4P33M_SEL_MASK_SFT (0x1 << 6) +#define DIGMIC_3P25M_1P625M_SEL_CTL_SFT 5 +#define DIGMIC_3P25M_1P625M_SEL_CTL_MASK 0x1 +#define DIGMIC_3P25M_1P625M_SEL_CTL_MASK_SFT (0x1 << 5) +#define AMIC_6P5M_SEL_CTL_SFT 4 +#define AMIC_6P5M_SEL_CTL_MASK 0x1 +#define AMIC_6P5M_SEL_CTL_MASK_SFT (0x1 << 4) +#define AMIC_1P625M_SEL_CTL_SFT 3 +#define AMIC_1P625M_SEL_CTL_MASK 0x1 +#define AMIC_1P625M_SEL_CTL_MASK_SFT (0x1 << 3) +#define UL_LOOP_BACK_MODE_CTL_SFT 2 +#define UL_LOOP_BACK_MODE_CTL_MASK 0x1 +#define UL_LOOP_BACK_MODE_CTL_MASK_SFT (0x1 << 2) +#define UL_SDM_3_LEVEL_CTL_SFT 1 +#define UL_SDM_3_LEVEL_CTL_MASK 0x1 +#define UL_SDM_3_LEVEL_CTL_MASK_SFT (0x1 << 1) +#define UL_SRC_ON_TMP_CTL_SFT 0 +#define UL_SRC_ON_TMP_CTL_MASK 0x1 +#define UL_SRC_ON_TMP_CTL_MASK_SFT (0x1 << 0) + +/* AFE_ADDA_UL1_SRC_CON1 */ +#define ADDA_UL_GAIN_VALUE_SFT 16 +#define ADDA_UL_GAIN_VALUE_MASK 0xffff +#define ADDA_UL_GAIN_VALUE_MASK_SFT (0xffff << 16) +#define ADDA_UL_POSTIVEGAIN_SFT 12 +#define ADDA_UL_POSTIVEGAIN_MASK 0x7 +#define ADDA_UL_POSTIVEGAIN_MASK_SFT (0x7 << 12) +#define ADDA_UL_ODDTAP_MODE_SFT 11 +#define ADDA_UL_ODDTAP_MODE_MASK 0x1 +#define ADDA_UL_ODDTAP_MODE_MASK_SFT (0x1 << 11) +#define ADDA_UL_HALF_TAP_NUM_SFT 5 +#define ADDA_UL_HALF_TAP_NUM_MASK 0x3f +#define ADDA_UL_HALF_TAP_NUM_MASK_SFT (0x3f << 5) +#define FIFO_SOFT_RST_SFT 4 +#define FIFO_SOFT_RST_MASK 0x1 +#define FIFO_SOFT_RST_MASK_SFT (0x1 << 4) +#define FIFO_SOFT_RST_EN_SFT 3 +#define FIFO_SOFT_RST_EN_MASK 0x1 +#define FIFO_SOFT_RST_EN_MASK_SFT (0x1 << 3) +#define LR_SWAP_SFT 2 +#define LR_SWAP_MASK 0x1 +#define LR_SWAP_MASK_SFT (0x1 << 2) +#define GAIN_MODE_SFT 0 +#define GAIN_MODE_MASK 0x3 +#define GAIN_MODE_MASK_SFT (0x3 << 0) + +/* AFE_ADDA_UL1_SRC_CON2 */ +#define C_DAC_EN_CTL_SFT 27 +#define C_DAC_EN_CTL_MASK 0x1 +#define C_DAC_EN_CTL_MASK_SFT (0x1 << 27) +#define C_MUTE_SW_CTL_SFT 26 +#define C_MUTE_SW_CTL_MASK 0x1 +#define C_MUTE_SW_CTL_MASK_SFT (0x1 << 26) +#define C_AMP_DIV_CH2_CTL_SFT 21 +#define C_AMP_DIV_CH2_CTL_MASK 0x7 +#define C_AMP_DIV_CH2_CTL_MASK_SFT (0x7 << 21) +#define C_FREQ_DIV_CH2_CTL_SFT 16 +#define C_FREQ_DIV_CH2_CTL_MASK 0x1f +#define C_FREQ_DIV_CH2_CTL_MASK_SFT (0x1f << 16) +#define C_SINE_MODE_CH2_CTL_SFT 12 +#define C_SINE_MODE_CH2_CTL_MASK 0xf +#define C_SINE_MODE_CH2_CTL_MASK_SFT (0xf << 12) +#define C_AMP_DIV_CH1_CTL_SFT 9 +#define C_AMP_DIV_CH1_CTL_MASK 0x7 +#define C_AMP_DIV_CH1_CTL_MASK_SFT (0x7 << 9) +#define C_FREQ_DIV_CH1_CTL_SFT 4 +#define C_FREQ_DIV_CH1_CTL_MASK 0x1f +#define C_FREQ_DIV_CH1_CTL_MASK_SFT (0x1f << 4) +#define C_SINE_MODE_CH1_CTL_SFT 0 +#define C_SINE_MODE_CH1_CTL_MASK 0xf +#define C_SINE_MODE_CH1_CTL_MASK_SFT (0xf << 0) + +/* AFE_ADDA_UL1_SRC_DEBUG */ +#define UL_SLT_CNT_FLAG_RESET_CTL_SFT 16 +#define UL_SLT_CNT_FLAG_RESET_CTL_MASK 0x1 +#define UL_SLT_CNT_FLAG_RESET_CTL_MASK_SFT (0x1 << 16) +#define FIFO_DIGMIC_TESTIN_SFT 12 +#define FIFO_DIGMIC_TESTIN_MASK 0x3 +#define FIFO_DIGMIC_TESTIN_MASK_SFT (0x3 << 12) +#define FIFO_DIGMIC_WDATA_TESTEN_SFT 11 +#define FIFO_DIGMIC_WDATA_TESTEN_MASK 0x1 +#define FIFO_DIGMIC_WDATA_TESTEN_MASK_SFT (0x1 << 11) +#define SLT_CNT_THD_CTL_SFT 0 +#define SLT_CNT_THD_CTL_MASK 0x7ff +#define SLT_CNT_THD_CTL_MASK_SFT (0x7ff << 0) + +/* AFE_ADDA_UL1_SRC_DEBUG_MON0 */ +#define SLT_CNT_FLAG_CTL_SFT 16 +#define SLT_CNT_FLAG_CTL_MASK 0x1 +#define SLT_CNT_FLAG_CTL_MASK_SFT (0x1 << 16) +#define SLT_COUNTER_CTL_SFT 0 +#define SLT_COUNTER_CTL_MASK 0x7ff +#define SLT_COUNTER_CTL_MASK_SFT (0x7ff << 0) + +/* AFE_ADDA_UL1_SRC_MON1 */ +#define UL_VOICE_MODE_CTL_SFT 29 +#define UL_VOICE_MODE_CTL_MASK 0x7 +#define UL_VOICE_MODE_CTL_MASK_SFT (0x7 << 29) +#define DATA_COMB_IN_CH2_SFT 24 +#define DATA_COMB_IN_CH2_MASK 0x1f +#define DATA_COMB_IN_CH2_MASK_SFT (0x1f << 24) +#define DATA_COMB_OUT_CH2_SFT 0 +#define DATA_COMB_OUT_CH2_MASK 0xffffff +#define DATA_COMB_OUT_CH2_MASK_SFT (0xffffff << 0) + +/* AFE_ADDA_UL1_IIR_COEF_02_01 */ +#define ADDA_IIR_COEF_02_01_SFT 0 +#define ADDA_IIR_COEF_02_01_MASK 0xffffffff +#define ADDA_IIR_COEF_02_01_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL1_IIR_COEF_04_03 */ +#define ADDA_IIR_COEF_04_03_SFT 0 +#define ADDA_IIR_COEF_04_03_MASK 0xffffffff +#define ADDA_IIR_COEF_04_03_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL1_IIR_COEF_06_05 */ +#define ADDA_IIR_COEF_06_05_SFT 0 +#define ADDA_IIR_COEF_06_05_MASK 0xffffffff +#define ADDA_IIR_COEF_06_05_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL1_IIR_COEF_08_07 */ +#define ADDA_IIR_COEF_08_07_SFT 0 +#define ADDA_IIR_COEF_08_07_MASK 0xffffffff +#define ADDA_IIR_COEF_08_07_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL1_IIR_COEF_10_09 */ +#define ADDA_IIR_COEF_10_09_SFT 0 +#define ADDA_IIR_COEF_10_09_MASK 0xffffffff +#define ADDA_IIR_COEF_10_09_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL1_ULCF_CFG_02_01 */ +#define ADDA_ULCF_CFG_02_01_SFT 0 +#define ADDA_ULCF_CFG_02_01_MASK 0xffffffff +#define ADDA_ULCF_CFG_02_01_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL1_ULCF_CFG_04_03 */ +#define ADDA_ULCF_CFG_04_03_SFT 0 +#define ADDA_ULCF_CFG_04_03_MASK 0xffffffff +#define ADDA_ULCF_CFG_04_03_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL1_ULCF_CFG_06_05 */ +#define ADDA_ULCF_CFG_06_05_SFT 0 +#define ADDA_ULCF_CFG_06_05_MASK 0xffffffff +#define ADDA_ULCF_CFG_06_05_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL1_ULCF_CFG_08_07 */ +#define ADDA_ULCF_CFG_08_07_SFT 0 +#define ADDA_ULCF_CFG_08_07_MASK 0xffffffff +#define ADDA_ULCF_CFG_08_07_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL1_ULCF_CFG_10_09 */ +#define ADDA_ULCF_CFG_10_09_SFT 0 +#define ADDA_ULCF_CFG_10_09_MASK 0xffffffff +#define ADDA_ULCF_CFG_10_09_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL1_ULCF_CFG_12_11 */ +#define ADDA_ULCF_CFG_12_11_SFT 0 +#define ADDA_ULCF_CFG_12_11_MASK 0xffffffff +#define ADDA_ULCF_CFG_12_11_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL1_ULCF_CFG_14_13 */ +#define ADDA_ULCF_CFG_14_13_SFT 0 +#define ADDA_ULCF_CFG_14_13_MASK 0xffffffff +#define ADDA_ULCF_CFG_14_13_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL1_ULCF_CFG_16_15 */ +#define ADDA_ULCF_CFG_16_15_SFT 0 +#define ADDA_ULCF_CFG_16_15_MASK 0xffffffff +#define ADDA_ULCF_CFG_16_15_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL1_ULCF_CFG_18_17 */ +#define ADDA_ULCF_CFG_18_17_SFT 0 +#define ADDA_ULCF_CFG_18_17_MASK 0xffffffff +#define ADDA_ULCF_CFG_18_17_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL1_ULCF_CFG_20_19 */ +#define ADDA_ULCF_CFG_20_19_SFT 0 +#define ADDA_ULCF_CFG_20_19_MASK 0xffffffff +#define ADDA_ULCF_CFG_20_19_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL1_ULCF_CFG_22_21 */ +#define ADDA_ULCF_CFG_22_21_SFT 0 +#define ADDA_ULCF_CFG_22_21_MASK 0xffffffff +#define ADDA_ULCF_CFG_22_21_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL1_ULCF_CFG_24_23 */ +#define ADDA_ULCF_CFG_24_23_SFT 0 +#define ADDA_ULCF_CFG_24_23_MASK 0xffffffff +#define ADDA_ULCF_CFG_24_23_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL1_ULCF_CFG_26_25 */ +#define ADDA_ULCF_CFG_26_25_SFT 0 +#define ADDA_ULCF_CFG_26_25_MASK 0xffffffff +#define ADDA_ULCF_CFG_26_25_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL1_ULCF_CFG_28_27 */ +#define ADDA_ULCF_CFG_28_27_SFT 0 +#define ADDA_ULCF_CFG_28_27_MASK 0xffffffff +#define ADDA_ULCF_CFG_28_27_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL1_ULCF_CFG_30_29 */ +#define ADDA_ULCF_CFG_30_29_SFT 0 +#define ADDA_ULCF_CFG_30_29_MASK 0xffffffff +#define ADDA_ULCF_CFG_30_29_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL1_ULCF_CFG_32_31 */ +#define ADDA_ULCF_CFG_32_31_SFT 0 +#define ADDA_ULCF_CFG_32_31_MASK 0xffffffff +#define ADDA_ULCF_CFG_32_31_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL1_IP_VERSION */ +#define ADDA_ULCF_IP_VERSION_SFT 0 +#define ADDA_ULCF_IP_VERSION_MASK 0xffffffff +#define ADDA_ULCF_IP_VERSION_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_PROXIMITY_CON0 */ +#define PROXIMITY_CH1_ON_SFT 12 +#define PROXIMITY_CH1_ON_MASK 0x1 +#define PROXIMITY_CH1_ON_MASK_SFT (0x1 << 12) +#define PROXIMITY_CH1_SEL_SFT 8 +#define PROXIMITY_CH1_SEL_MASK 0xf +#define PROXIMITY_CH1_SEL_MASK_SFT (0xf << 8) +#define PROXIMITY_CH2_ON_SFT 4 +#define PROXIMITY_CH2_ON_MASK 0x1 +#define PROXIMITY_CH2_ON_MASK_SFT (0x1 << 4) +#define PROXIMITY_CH2_SEL_SFT 0 +#define PROXIMITY_CH2_SEL_MASK 0xf +#define PROXIMITY_CH2_SEL_MASK_SFT (0xf << 0) + +/* AFE_ADDA_ULSRC_PHASE_CON0 */ +#define DMIC1_PHASE_FCLK_SEL_SFT 30 +#define DMIC1_PHASE_FCLK_SEL_MASK 0x3 +#define DMIC1_PHASE_FCLK_SEL_MASK_SFT (0x3 << 30) +#define DMIC0_PHASE_FCLK_SEL_SFT 28 +#define DMIC0_PHASE_FCLK_SEL_MASK 0x3 +#define DMIC0_PHASE_FCLK_SEL_MASK_SFT (0x3 << 28) +#define UL3_PHASE_FCLK_SEL_SFT 26 +#define UL3_PHASE_FCLK_SEL_MASK 0x3 +#define UL3_PHASE_FCLK_SEL_MASK_SFT (0x3 << 26) +#define UL2_PHASE_FCLK_SEL_SFT 24 +#define UL2_PHASE_FCLK_SEL_MASK 0x3 +#define UL2_PHASE_FCLK_SEL_MASK_SFT (0x3 << 24) +#define UL1_PHASE_FCLK_SEL_SFT 22 +#define UL1_PHASE_FCLK_SEL_MASK 0x3 +#define UL1_PHASE_FCLK_SEL_MASK_SFT (0x3 << 22) +#define UL0_PHASE_FCLK_SEL_SFT 20 +#define UL0_PHASE_FCLK_SEL_MASK 0x3 +#define UL0_PHASE_FCLK_SEL_MASK_SFT (0x3 << 20) +#define UL_PHASE_SYNC_FCLK_2_ON_SFT 18 +#define UL_PHASE_SYNC_FCLK_2_ON_MASK 0x1 +#define UL_PHASE_SYNC_FCLK_2_ON_MASK_SFT (0x1 << 18) +#define UL_PHASE_SYNC_FCLK_1_ON_SFT 17 +#define UL_PHASE_SYNC_FCLK_1_ON_MASK 0x1 +#define UL_PHASE_SYNC_FCLK_1_ON_MASK_SFT (0x1 << 17) +#define UL_PHASE_SYNC_FCLK_0_ON_SFT 16 +#define UL_PHASE_SYNC_FCLK_0_ON_MASK 0x1 +#define UL_PHASE_SYNC_FCLK_0_ON_MASK_SFT (0x1 << 16) +#define DMIC1_PHASE_HCLK_SEL_SFT 14 +#define DMIC1_PHASE_HCLK_SEL_MASK 0x3 +#define DMIC1_PHASE_HCLK_SEL_MASK_SFT (0x3 << 14) +#define DMIC0_PHASE_HCLK_SEL_SFT 12 +#define DMIC0_PHASE_HCLK_SEL_MASK 0x3 +#define DMIC0_PHASE_HCLK_SEL_MASK_SFT (0x3 << 12) +#define UL3_PHASE_HCLK_SEL_SFT 10 +#define UL3_PHASE_HCLK_SEL_MASK 0x3 +#define UL3_PHASE_HCLK_SEL_MASK_SFT (0x3 << 10) +#define UL2_PHASE_HCLK_SEL_SFT 8 +#define UL2_PHASE_HCLK_SEL_MASK 0x3 +#define UL2_PHASE_HCLK_SEL_MASK_SFT (0x3 << 8) +#define UL1_PHASE_HCLK_SEL_SFT 6 +#define UL1_PHASE_HCLK_SEL_MASK 0x3 +#define UL1_PHASE_HCLK_SEL_MASK_SFT (0x3 << 6) +#define UL0_PHASE_HCLK_SEL_SFT 4 +#define UL0_PHASE_HCLK_SEL_MASK 0x3 +#define UL0_PHASE_HCLK_SEL_MASK_SFT (0x3 << 4) +#define UL_PHASE_SYNC_HCLK_2_ON_SFT 2 +#define UL_PHASE_SYNC_HCLK_2_ON_MASK 0x1 +#define UL_PHASE_SYNC_HCLK_2_ON_MASK_SFT (0x1 << 2) +#define UL_PHASE_SYNC_HCLK_1_ON_SFT 1 +#define UL_PHASE_SYNC_HCLK_1_ON_MASK 0x1 +#define UL_PHASE_SYNC_HCLK_1_ON_MASK_SFT (0x1 << 1) +#define UL_PHASE_SYNC_HCLK_0_ON_SFT 0 +#define UL_PHASE_SYNC_HCLK_0_ON_MASK 0x1 +#define UL_PHASE_SYNC_HCLK_0_ON_MASK_SFT (0x1 << 0) + +/* AFE_ADDA_ULSRC_PHASE_CON1 */ +#define DMIC_CLK_PHASE_SYNC_SET_SFT 31 +#define DMIC_CLK_PHASE_SYNC_SET_MASK 0x1 +#define DMIC_CLK_PHASE_SYNC_SET_MASK_SFT (0x1 << 31) +#define DMIC1_PHASE_SYNC_FCLK_SET_SFT 11 +#define DMIC1_PHASE_SYNC_FCLK_SET_MASK 0x1 +#define DMIC1_PHASE_SYNC_FCLK_SET_MASK_SFT (0x1 << 11) +#define DMIC1_PHASE_SYNC_HCLK_SET_SFT 10 +#define DMIC1_PHASE_SYNC_HCLK_SET_MASK 0x1 +#define DMIC1_PHASE_SYNC_HCLK_SET_MASK_SFT (0x1 << 10) +#define DMIC0_PHASE_SYNC_FCLK_SET_SFT 9 +#define DMIC0_PHASE_SYNC_FCLK_SET_MASK 0x1 +#define DMIC0_PHASE_SYNC_FCLK_SET_MASK_SFT (0x1 << 9) +#define DMIC0_PHASE_SYNC_HCLK_SET_SFT 8 +#define DMIC0_PHASE_SYNC_HCLK_SET_MASK 0x1 +#define DMIC0_PHASE_SYNC_HCLK_SET_MASK_SFT (0x1 << 8) +#define UL3_PHASE_SYNC_FCLK_SET_SFT 7 +#define UL3_PHASE_SYNC_FCLK_SET_MASK 0x1 +#define UL3_PHASE_SYNC_FCLK_SET_MASK_SFT (0x1 << 7) +#define UL3_PHASE_SYNC_HCLK_SET_SFT 6 +#define UL3_PHASE_SYNC_HCLK_SET_MASK 0x1 +#define UL3_PHASE_SYNC_HCLK_SET_MASK_SFT (0x1 << 6) +#define UL2_PHASE_SYNC_FCLK_SET_SFT 5 +#define UL2_PHASE_SYNC_FCLK_SET_MASK 0x1 +#define UL2_PHASE_SYNC_FCLK_SET_MASK_SFT (0x1 << 5) +#define UL2_PHASE_SYNC_HCLK_SET_SFT 4 +#define UL2_PHASE_SYNC_HCLK_SET_MASK 0x1 +#define UL2_PHASE_SYNC_HCLK_SET_MASK_SFT (0x1 << 4) +#define UL1_PHASE_SYNC_FCLK_SET_SFT 3 +#define UL1_PHASE_SYNC_FCLK_SET_MASK 0x1 +#define UL1_PHASE_SYNC_FCLK_SET_MASK_SFT (0x1 << 3) +#define UL1_PHASE_SYNC_HCLK_SET_SFT 2 +#define UL1_PHASE_SYNC_HCLK_SET_MASK 0x1 +#define UL1_PHASE_SYNC_HCLK_SET_MASK_SFT (0x1 << 2) +#define UL0_PHASE_SYNC_FCLK_SET_SFT 1 +#define UL0_PHASE_SYNC_FCLK_SET_MASK 0x1 +#define UL0_PHASE_SYNC_FCLK_SET_MASK_SFT (0x1 << 1) +#define UL0_PHASE_SYNC_HCLK_SET_SFT 0 +#define UL0_PHASE_SYNC_HCLK_SET_MASK 0x1 +#define UL0_PHASE_SYNC_HCLK_SET_MASK_SFT (0x1 << 0) + +/* AFE_ADDA_ULSRC_PHASE_CON2 */ +#define DMIC1_PHASE_SYNC_1X_EN_SEL_SFT 26 +#define DMIC1_PHASE_SYNC_1X_EN_SEL_MASK 0x3 +#define DMIC1_PHASE_SYNC_1X_EN_SEL_MASK_SFT (0x3 << 26) +#define DMIC0_PHASE_SYNC_1X_EN_SEL_SFT 24 +#define DMIC0_PHASE_SYNC_1X_EN_SEL_MASK 0x3 +#define DMIC0_PHASE_SYNC_1X_EN_SEL_MASK_SFT (0x3 << 24) +#define UL3_PHASE_SYNC_1X_EN_SEL_SFT 22 +#define UL3_PHASE_SYNC_1X_EN_SEL_MASK 0x3 +#define UL3_PHASE_SYNC_1X_EN_SEL_MASK_SFT (0x3 << 22) +#define UL2_PHASE_SYNC_1X_EN_SEL_SFT 20 +#define UL2_PHASE_SYNC_1X_EN_SEL_MASK 0x3 +#define UL2_PHASE_SYNC_1X_EN_SEL_MASK_SFT (0x3 << 20) +#define UL1_PHASE_SYNC_1X_EN_SEL_SFT 18 +#define UL1_PHASE_SYNC_1X_EN_SEL_MASK 0x3 +#define UL1_PHASE_SYNC_1X_EN_SEL_MASK_SFT (0x3 << 18) +#define UL0_PHASE_SYNC_1X_EN_SEL_SFT 16 +#define UL0_PHASE_SYNC_1X_EN_SEL_MASK 0x3 +#define UL0_PHASE_SYNC_1X_EN_SEL_MASK_SFT (0x3 << 16) +#define UL_PHASE_SYNC_FCLK_1X_EN_2_ON_SFT 5 +#define UL_PHASE_SYNC_FCLK_1X_EN_2_ON_MASK 0x1 +#define UL_PHASE_SYNC_FCLK_1X_EN_2_ON_MASK_SFT (0x1 << 5) +#define UL_PHASE_SYNC_FCLK_1X_EN_1_ON_SFT 4 +#define UL_PHASE_SYNC_FCLK_1X_EN_1_ON_MASK 0x1 +#define UL_PHASE_SYNC_FCLK_1X_EN_1_ON_MASK_SFT (0x1 << 4) +#define UL_PHASE_SYNC_FCLK_1X_EN_0_ON_SFT 3 +#define UL_PHASE_SYNC_FCLK_1X_EN_0_ON_MASK 0x1 +#define UL_PHASE_SYNC_FCLK_1X_EN_0_ON_MASK_SFT (0x1 << 3) +#define UL_PHASE_SYNC_HCLK_1X_EN_2_ON_SFT 2 +#define UL_PHASE_SYNC_HCLK_1X_EN_2_ON_MASK 0x1 +#define UL_PHASE_SYNC_HCLK_1X_EN_2_ON_MASK_SFT (0x1 << 2) +#define UL_PHASE_SYNC_HCLK_1X_EN_1_ON_SFT 1 +#define UL_PHASE_SYNC_HCLK_1X_EN_1_ON_MASK 0x1 +#define UL_PHASE_SYNC_HCLK_1X_EN_1_ON_MASK_SFT (0x1 << 1) +#define UL_PHASE_SYNC_HCLK_1X_EN_0_ON_SFT 0 +#define UL_PHASE_SYNC_HCLK_1X_EN_0_ON_MASK 0x1 +#define UL_PHASE_SYNC_HCLK_1X_EN_0_ON_MASK_SFT (0x1 << 0) + +/* AFE_ADDA_ULSRC_PHASE_CON3 */ +#define DMIC1_PHASE_SYNC_SOFT_RST_SEL_SFT 26 +#define DMIC1_PHASE_SYNC_SOFT_RST_SEL_MASK 0x3 +#define DMIC1_PHASE_SYNC_SOFT_RST_SEL_MASK_SFT (0x3 << 26) +#define DMIC0_PHASE_SYNC_SOFT_RST_SEL_SFT 24 +#define DMIC0_PHASE_SYNC_SOFT_RST_SEL_MASK 0x3 +#define DMIC0_PHASE_SYNC_SOFT_RST_SEL_MASK_SFT (0x3 << 24) +#define UL3_PHASE_SYNC_SOFT_RST_SEL_SFT 22 +#define UL3_PHASE_SYNC_SOFT_RST_SEL_MASK 0x3 +#define UL3_PHASE_SYNC_SOFT_RST_SEL_MASK_SFT (0x3 << 22) +#define UL2_PHASE_SYNC_SOFT_RST_SEL_SFT 20 +#define UL2_PHASE_SYNC_SOFT_RST_SEL_MASK 0x3 +#define UL2_PHASE_SYNC_SOFT_RST_SEL_MASK_SFT (0x3 << 20) +#define UL1_PHASE_SYNC_SOFT_RST_SEL_SFT 18 +#define UL1_PHASE_SYNC_SOFT_RST_SEL_MASK 0x3 +#define UL1_PHASE_SYNC_SOFT_RST_SEL_MASK_SFT (0x3 << 18) +#define UL0_PHASE_SYNC_SOFT_RST_SEL_SFT 16 +#define UL0_PHASE_SYNC_SOFT_RST_SEL_MASK 0x3 +#define UL0_PHASE_SYNC_SOFT_RST_SEL_MASK_SFT (0x3 << 16) +#define DMIC1_PHASE_SYNC_CH1_FIFO_SEL_SFT 13 +#define DMIC1_PHASE_SYNC_CH1_FIFO_SEL_MASK 0x1 +#define DMIC1_PHASE_SYNC_CH1_FIFO_SEL_MASK_SFT (0x1 << 13) +#define DMIC0_PHASE_SYNC_CH1_FIFO_SEL_SFT 12 +#define DMIC0_PHASE_SYNC_CH1_FIFO_SEL_MASK 0x1 +#define DMIC0_PHASE_SYNC_CH1_FIFO_SEL_MASK_SFT (0x1 << 12) +#define UL3_PHASE_SYNC_CH1_FIFO_SEL_SFT 11 +#define UL3_PHASE_SYNC_CH1_FIFO_SEL_MASK 0x1 +#define UL3_PHASE_SYNC_CH1_FIFO_SEL_MASK_SFT (0x1 << 11) +#define UL2_PHASE_SYNC_CH1_FIFO_SEL_SFT 10 +#define UL2_PHASE_SYNC_CH1_FIFO_SEL_MASK 0x1 +#define UL2_PHASE_SYNC_CH1_FIFO_SEL_MASK_SFT (0x1 << 10) +#define UL1_PHASE_SYNC_CH1_FIFO_SEL_SFT 9 +#define UL1_PHASE_SYNC_CH1_FIFO_SEL_MASK 0x1 +#define UL1_PHASE_SYNC_CH1_FIFO_SEL_MASK_SFT (0x1 << 9) +#define UL0_PHASE_SYNC_CH1_FIFO_SEL_SFT 8 +#define UL0_PHASE_SYNC_CH1_FIFO_SEL_MASK 0x1 +#define UL0_PHASE_SYNC_CH1_FIFO_SEL_MASK_SFT (0x1 << 8) +#define UL_PHASE_SYNC_SOFT_RST_EN_2_ON_SFT 5 +#define UL_PHASE_SYNC_SOFT_RST_EN_2_ON_MASK 0x1 +#define UL_PHASE_SYNC_SOFT_RST_EN_2_ON_MASK_SFT (0x1 << 5) +#define UL_PHASE_SYNC_SOFT_RST_EN_1_ON_SFT 4 +#define UL_PHASE_SYNC_SOFT_RST_EN_1_ON_MASK 0x1 +#define UL_PHASE_SYNC_SOFT_RST_EN_1_ON_MASK_SFT (0x1 << 4) +#define UL_PHASE_SYNC_SOFT_RST_EN_0_ON_SFT 3 +#define UL_PHASE_SYNC_SOFT_RST_EN_0_ON_MASK 0x1 +#define UL_PHASE_SYNC_SOFT_RST_EN_0_ON_MASK_SFT (0x1 << 3) +#define UL_PHASE_SYNC_SOFT_RST_2_ON_SFT 2 +#define UL_PHASE_SYNC_SOFT_RST_2_ON_MASK 0x1 +#define UL_PHASE_SYNC_SOFT_RST_2_ON_MASK_SFT (0x1 << 2) +#define UL_PHASE_SYNC_SOFT_RST_1_ON_SFT 1 +#define UL_PHASE_SYNC_SOFT_RST_1_ON_MASK 0x1 +#define UL_PHASE_SYNC_SOFT_RST_1_ON_MASK_SFT (0x1 << 1) +#define UL_PHASE_SYNC_SOFT_RST_0_ON_SFT 0 +#define UL_PHASE_SYNC_SOFT_RST_0_ON_MASK 0x1 +#define UL_PHASE_SYNC_SOFT_RST_0_ON_MASK_SFT (0x1 << 0) + +/* AFE_MTKAIF_IPM_VER_MON */ +#define RG_MTKAIF_IPM_VER_MON_SFT 0 +#define RG_MTKAIF_IPM_VER_MON_MASK 0xffffffff +#define RG_MTKAIF_IPM_VER_MON_MASK_SFT (0xffffffff << 0) + +/* AFE_MTKAIF_MON_SEL */ +#define RG_MTKAIF_MON_SEL_SFT 0 +#define RG_MTKAIF_MON_SEL_MASK 0xff +#define RG_MTKAIF_MON_SEL_MASK_SFT (0xff << 0) + +/* AFE_MTKAIF_MON */ +#define RG_MTKAIF_MON_SFT 0 +#define RG_MTKAIF_MON_MASK 0xffffffff +#define RG_MTKAIF_MON_MASK_SFT (0xffffffff << 0) + +/* AFE_MTKAIF0_CFG0 */ +#define RG_MTKAIF0_RXIF_CLKINV_SFT 31 +#define RG_MTKAIF0_RXIF_CLKINV_MASK 0x1 +#define RG_MTKAIF0_RXIF_CLKINV_MASK_SFT (0x1 << 31) +#define RG_MTKAIF0_RXIF_BYPASS_SRC_SFT 17 +#define RG_MTKAIF0_RXIF_BYPASS_SRC_MASK 0x1 +#define RG_MTKAIF0_RXIF_BYPASS_SRC_MASK_SFT (0x1 << 17) +#define RG_MTKAIF0_RXIF_PROTOCOL2_SFT 16 +#define RG_MTKAIF0_RXIF_PROTOCOL2_MASK 0x1 +#define RG_MTKAIF0_RXIF_PROTOCOL2_MASK_SFT (0x1 << 16) +#define RG_MTKAIF0_TXIF_NLE_DEBUG_SFT 8 +#define RG_MTKAIF0_TXIF_NLE_DEBUG_MASK 0x1 +#define RG_MTKAIF0_TXIF_NLE_DEBUG_MASK_SFT (0x1 << 8) +#define RG_MTKAIF0_TXIF_BYPASS_SRC_SFT 5 +#define RG_MTKAIF0_TXIF_BYPASS_SRC_MASK 0x1 +#define RG_MTKAIF0_TXIF_BYPASS_SRC_MASK_SFT (0x1 << 5) +#define RG_MTKAIF0_TXIF_PROTOCOL2_SFT 4 +#define RG_MTKAIF0_TXIF_PROTOCOL2_MASK 0x1 +#define RG_MTKAIF0_TXIF_PROTOCOL2_MASK_SFT (0x1 << 4) +#define RG_MTKAIF0_TXIF_8TO5_SFT 2 +#define RG_MTKAIF0_TXIF_8TO5_MASK 0x1 +#define RG_MTKAIF0_TXIF_8TO5_MASK_SFT (0x1 << 2) +#define RG_MTKAIF0_RXIF_8TO5_SFT 1 +#define RG_MTKAIF0_RXIF_8TO5_MASK 0x1 +#define RG_MTKAIF0_RXIF_8TO5_MASK_SFT (0x1 << 1) +#define RG_MTKAIF0_TX2RX_LOOPBACK1_SFT 0 +#define RG_MTKAIF0_TX2RX_LOOPBACK1_MASK 0x1 +#define RG_MTKAIF0_TX2RX_LOOPBACK1_MASK_SFT (0x1 << 0) + +/* AFE_MTKAIF0_TX_CFG0 */ +#define RG_MTKAIF0_TXIF_NLE_FIFO_SWAP_SFT 23 +#define RG_MTKAIF0_TXIF_NLE_FIFO_SWAP_MASK 0x1 +#define RG_MTKAIF0_TXIF_NLE_FIFO_SWAP_MASK_SFT (0x1 << 23) +#define RG_MTKAIF0_TXIF_NLE_FIFO_RSP_SFT 20 +#define RG_MTKAIF0_TXIF_NLE_FIFO_RSP_MASK 0x7 +#define RG_MTKAIF0_TXIF_NLE_FIFO_RSP_MASK_SFT (0x7 << 20) +#define RG_MTKAIF0_TXIF_FIFO_SWAP_SFT 15 +#define RG_MTKAIF0_TXIF_FIFO_SWAP_MASK 0x1 +#define RG_MTKAIF0_TXIF_FIFO_SWAP_MASK_SFT (0x1 << 15) +#define RG_MTKAIF0_TXIF_FIFO_RSP_SFT 12 +#define RG_MTKAIF0_TXIF_FIFO_RSP_MASK 0x7 +#define RG_MTKAIF0_TXIF_FIFO_RSP_MASK_SFT (0x7 << 12) +#define RG_MTKAIF0_TXIF_SYNC_WORD1_SFT 4 +#define RG_MTKAIF0_TXIF_SYNC_WORD1_MASK 0x7 +#define RG_MTKAIF0_TXIF_SYNC_WORD1_MASK_SFT (0x7 << 4) +#define RG_MTKAIF0_TXIF_SYNC_WORD0_SFT 0 +#define RG_MTKAIF0_TXIF_SYNC_WORD0_MASK 0x7 +#define RG_MTKAIF0_TXIF_SYNC_WORD0_MASK_SFT (0x7 << 0) + +/* AFE_MTKAIF0_RX_CFG0 */ +#define RG_MTKAIF0_RXIF_VOICE_MODE_SFT 20 +#define RG_MTKAIF0_RXIF_VOICE_MODE_MASK 0xf +#define RG_MTKAIF0_RXIF_VOICE_MODE_MASK_SFT (0xf << 20) +#define RG_MTKAIF0_RXIF_DETECT_ON_SFT 16 +#define RG_MTKAIF0_RXIF_DETECT_ON_MASK 0x1 +#define RG_MTKAIF0_RXIF_DETECT_ON_MASK_SFT (0x1 << 16) +#define RG_MTKAIF0_RXIF_DATA_BIT_SFT 8 +#define RG_MTKAIF0_RXIF_DATA_BIT_MASK 0x7 +#define RG_MTKAIF0_RXIF_DATA_BIT_MASK_SFT (0x7 << 8) +#define RG_MTKAIF0_RXIF_FIFO_RSP_SFT 4 +#define RG_MTKAIF0_RXIF_FIFO_RSP_MASK 0x7 +#define RG_MTKAIF0_RXIF_FIFO_RSP_MASK_SFT (0x7 << 4) +#define RG_MTKAIF0_RXIF_DATA_MODE_SFT 0 +#define RG_MTKAIF0_RXIF_DATA_MODE_MASK 0x1 +#define RG_MTKAIF0_RXIF_DATA_MODE_MASK_SFT (0x1 << 0) + +/* AFE_MTKAIF0_RX_CFG1 */ +#define RG_MTKAIF0_RXIF_CLEAR_SYNC_FAIL_SFT 28 +#define RG_MTKAIF0_RXIF_CLEAR_SYNC_FAIL_MASK 0x1 +#define RG_MTKAIF0_RXIF_CLEAR_SYNC_FAIL_MASK_SFT (0x1 << 28) +#define RG_MTKAIF0_RXIF_SYNC_CNT_TABLE_SFT 16 +#define RG_MTKAIF0_RXIF_SYNC_CNT_TABLE_MASK 0xfff +#define RG_MTKAIF0_RXIF_SYNC_CNT_TABLE_MASK_SFT (0xfff << 16) +#define RG_MTKAIF0_RXIF_SYNC_SEARCH_TABLE_SFT 12 +#define RG_MTKAIF0_RXIF_SYNC_SEARCH_TABLE_MASK 0xf +#define RG_MTKAIF0_RXIF_SYNC_SEARCH_TABLE_MASK_SFT (0xf << 12) +#define RG_MTKAIF0_RXIF_INVALID_SYNC_CHECK_ROUND_SFT 8 +#define RG_MTKAIF0_RXIF_INVALID_SYNC_CHECK_ROUND_MASK 0xf +#define RG_MTKAIF0_RXIF_INVALID_SYNC_CHECK_ROUND_MASK_SFT (0xf << 8) +#define RG_MTKAIF0_RXIF_SYNC_CHECK_ROUND_SFT 4 +#define RG_MTKAIF0_RXIF_SYNC_CHECK_ROUND_MASK 0xf +#define RG_MTKAIF0_RXIF_SYNC_CHECK_ROUND_MASK_SFT (0xf << 4) + +/* AFE_MTKAIF0_RX_CFG2 */ +#define RG_MTKAIF0_RXIF_SYNC_WORD1_DISABLE_SFT 27 +#define RG_MTKAIF0_RXIF_SYNC_WORD1_DISABLE_MASK 0x1 +#define RG_MTKAIF0_RXIF_SYNC_WORD1_DISABLE_MASK_SFT (0x1 << 27) +#define RG_MTKAIF0_RXIF_SYNC_WORD1_SFT 24 +#define RG_MTKAIF0_RXIF_SYNC_WORD1_MASK 0x7 +#define RG_MTKAIF0_RXIF_SYNC_WORD1_MASK_SFT (0x7 << 24) +#define RG_MTKAIF0_RXIF_SYNC_WORD0_DISABLE_SFT 23 +#define RG_MTKAIF0_RXIF_SYNC_WORD0_DISABLE_MASK 0x1 +#define RG_MTKAIF0_RXIF_SYNC_WORD0_DISABLE_MASK_SFT (0x1 << 23) +#define RG_MTKAIF0_RXIF_SYNC_WORD0_SFT 20 +#define RG_MTKAIF0_RXIF_SYNC_WORD0_MASK 0x7 +#define RG_MTKAIF0_RXIF_SYNC_WORD0_MASK_SFT (0x7 << 20) +#define RG_MTKAIF0_RXIF_DELAY_CYCLE_SFT 12 +#define RG_MTKAIF0_RXIF_DELAY_CYCLE_MASK 0xf +#define RG_MTKAIF0_RXIF_DELAY_CYCLE_MASK_SFT (0xf << 12) +#define RG_MTKAIF0_RXIF_DELAY_DATA_SFT 8 +#define RG_MTKAIF0_RXIF_DELAY_DATA_MASK 0x1 +#define RG_MTKAIF0_RXIF_DELAY_DATA_MASK_SFT (0x1 << 8) + +/* AFE_MTKAIF1_CFG0 */ +#define RG_MTKAIF1_RXIF_CLKINV_ADC_SFT 31 +#define RG_MTKAIF1_RXIF_CLKINV_ADC_MASK 0x1 +#define RG_MTKAIF1_RXIF_CLKINV_ADC_MASK_SFT (0x1 << 31) +#define RG_MTKAIF1_RXIF_BYPASS_SRC_SFT 17 +#define RG_MTKAIF1_RXIF_BYPASS_SRC_MASK 0x1 +#define RG_MTKAIF1_RXIF_BYPASS_SRC_MASK_SFT (0x1 << 17) +#define RG_MTKAIF1_RXIF_PROTOCOL2_SFT 16 +#define RG_MTKAIF1_RXIF_PROTOCOL2_MASK 0x1 +#define RG_MTKAIF1_RXIF_PROTOCOL2_MASK_SFT (0x1 << 16) +#define RG_MTKAIF1_TXIF_NLE_DEBUG_SFT 8 +#define RG_MTKAIF1_TXIF_NLE_DEBUG_MASK 0x1 +#define RG_MTKAIF1_TXIF_NLE_DEBUG_MASK_SFT (0x1 << 8) +#define RG_MTKAIF1_TXIF_BYPASS_SRC_SFT 5 +#define RG_MTKAIF1_TXIF_BYPASS_SRC_MASK 0x1 +#define RG_MTKAIF1_TXIF_BYPASS_SRC_MASK_SFT (0x1 << 5) +#define RG_MTKAIF1_TXIF_PROTOCOL2_SFT 4 +#define RG_MTKAIF1_TXIF_PROTOCOL2_MASK 0x1 +#define RG_MTKAIF1_TXIF_PROTOCOL2_MASK_SFT (0x1 << 4) +#define RG_MTKAIF1_TXIF_8TO5_SFT 2 +#define RG_MTKAIF1_TXIF_8TO5_MASK 0x1 +#define RG_MTKAIF1_TXIF_8TO5_MASK_SFT (0x1 << 2) +#define RG_MTKAIF1_RXIF_8TO5_SFT 1 +#define RG_MTKAIF1_RXIF_8TO5_MASK 0x1 +#define RG_MTKAIF1_RXIF_8TO5_MASK_SFT (0x1 << 1) +#define RG_MTKAIF1_IF_LOOPBACK1_SFT 0 +#define RG_MTKAIF1_IF_LOOPBACK1_MASK 0x1 +#define RG_MTKAIF1_IF_LOOPBACK1_MASK_SFT (0x1 << 0) + +/* AFE_MTKAIF1_TX_CFG0 */ +#define RG_MTKAIF1_TXIF_NLE_FIFO_SWAP_SFT 23 +#define RG_MTKAIF1_TXIF_NLE_FIFO_SWAP_MASK 0x1 +#define RG_MTKAIF1_TXIF_NLE_FIFO_SWAP_MASK_SFT (0x1 << 23) +#define RG_MTKAIF1_TXIF_NLE_FIFO_RSP_SFT 20 +#define RG_MTKAIF1_TXIF_NLE_FIFO_RSP_MASK 0x7 +#define RG_MTKAIF1_TXIF_NLE_FIFO_RSP_MASK_SFT (0x7 << 20) +#define RG_MTKAIF1_TXIF_FIFO_SWAP_SFT 15 +#define RG_MTKAIF1_TXIF_FIFO_SWAP_MASK 0x1 +#define RG_MTKAIF1_TXIF_FIFO_SWAP_MASK_SFT (0x1 << 15) +#define RG_MTKAIF1_TXIF_FIFO_RSP_SFT 12 +#define RG_MTKAIF1_TXIF_FIFO_RSP_MASK 0x7 +#define RG_MTKAIF1_TXIF_FIFO_RSP_MASK_SFT (0x7 << 12) +#define RG_MTKAIF1_TXIF_SYNC_WORD1_SFT 4 +#define RG_MTKAIF1_TXIF_SYNC_WORD1_MASK 0x7 +#define RG_MTKAIF1_TXIF_SYNC_WORD1_MASK_SFT (0x7 << 4) +#define RG_MTKAIF1_TXIF_SYNC_WORD0_SFT 0 +#define RG_MTKAIF1_TXIF_SYNC_WORD0_MASK 0x7 +#define RG_MTKAIF1_TXIF_SYNC_WORD0_MASK_SFT (0x7 << 0) + +/* AFE_MTKAIF1_RX_CFG0 */ +#define RG_MTKAIF1_RXIF_VOICE_MODE_SFT 20 +#define RG_MTKAIF1_RXIF_VOICE_MODE_MASK 0xf +#define RG_MTKAIF1_RXIF_VOICE_MODE_MASK_SFT (0xf << 20) +#define RG_MTKAIF1_RXIF_DETECT_ON_SFT 16 +#define RG_MTKAIF1_RXIF_DETECT_ON_MASK 0x1 +#define RG_MTKAIF1_RXIF_DETECT_ON_MASK_SFT (0x1 << 16) +#define RG_MTKAIF1_RXIF_DATA_BIT_SFT 8 +#define RG_MTKAIF1_RXIF_DATA_BIT_MASK 0x7 +#define RG_MTKAIF1_RXIF_DATA_BIT_MASK_SFT (0x7 << 8) +#define RG_MTKAIF1_RXIF_FIFO_RSP_SFT 4 +#define RG_MTKAIF1_RXIF_FIFO_RSP_MASK 0x7 +#define RG_MTKAIF1_RXIF_FIFO_RSP_MASK_SFT (0x7 << 4) +#define RG_MTKAIF1_RXIF_DATA_MODE_SFT 0 +#define RG_MTKAIF1_RXIF_DATA_MODE_MASK 0x1 +#define RG_MTKAIF1_RXIF_DATA_MODE_MASK_SFT (0x1 << 0) + +/* AFE_MTKAIF1_RX_CFG1 */ +#define RG_MTKAIF1_RXIF_CLEAR_SYNC_FAIL_SFT 28 +#define RG_MTKAIF1_RXIF_CLEAR_SYNC_FAIL_MASK 0x1 +#define RG_MTKAIF1_RXIF_CLEAR_SYNC_FAIL_MASK_SFT (0x1 << 28) +#define RG_MTKAIF1_RXIF_SYNC_CNT_TABLE_SFT 16 +#define RG_MTKAIF1_RXIF_SYNC_CNT_TABLE_MASK 0xfff +#define RG_MTKAIF1_RXIF_SYNC_CNT_TABLE_MASK_SFT (0xfff << 16) +#define RG_MTKAIF1_RXIF_SYNC_SEARCH_TABLE_SFT 12 +#define RG_MTKAIF1_RXIF_SYNC_SEARCH_TABLE_MASK 0xf +#define RG_MTKAIF1_RXIF_SYNC_SEARCH_TABLE_MASK_SFT (0xf << 12) +#define RG_MTKAIF1_RXIF_INVALID_SYNC_CHECK_ROUND_SFT 8 +#define RG_MTKAIF1_RXIF_INVALID_SYNC_CHECK_ROUND_MASK 0xf +#define RG_MTKAIF1_RXIF_INVALID_SYNC_CHECK_ROUND_MASK_SFT (0xf << 8) +#define RG_MTKAIF1_RXIF_SYNC_CHECK_ROUND_SFT 4 +#define RG_MTKAIF1_RXIF_SYNC_CHECK_ROUND_MASK 0xf +#define RG_MTKAIF1_RXIF_SYNC_CHECK_ROUND_MASK_SFT (0xf << 4) + +/* AFE_MTKAIF1_RX_CFG2 */ +#define RG_MTKAIF1_RXIF_SYNC_WORD1_DISABLE_SFT 27 +#define RG_MTKAIF1_RXIF_SYNC_WORD1_DISABLE_MASK 0x1 +#define RG_MTKAIF1_RXIF_SYNC_WORD1_DISABLE_MASK_SFT (0x1 << 27) +#define RG_MTKAIF1_RXIF_SYNC_WORD1_SFT 24 +#define RG_MTKAIF1_RXIF_SYNC_WORD1_MASK 0x7 +#define RG_MTKAIF1_RXIF_SYNC_WORD1_MASK_SFT (0x7 << 24) +#define RG_MTKAIF1_RXIF_SYNC_WORD0_DISABLE_SFT 23 +#define RG_MTKAIF1_RXIF_SYNC_WORD0_DISABLE_MASK 0x1 +#define RG_MTKAIF1_RXIF_SYNC_WORD0_DISABLE_MASK_SFT (0x1 << 23) +#define RG_MTKAIF1_RXIF_SYNC_WORD0_SFT 20 +#define RG_MTKAIF1_RXIF_SYNC_WORD0_MASK 0x7 +#define RG_MTKAIF1_RXIF_SYNC_WORD0_MASK_SFT (0x7 << 20) +#define RG_MTKAIF1_RXIF_DELAY_CYCLE_SFT 12 +#define RG_MTKAIF1_RXIF_DELAY_CYCLE_MASK 0xf +#define RG_MTKAIF1_RXIF_DELAY_CYCLE_MASK_SFT (0xf << 12) +#define RG_MTKAIF1_RXIF_DELAY_DATA_SFT 8 +#define RG_MTKAIF1_RXIF_DELAY_DATA_MASK 0x1 +#define RG_MTKAIF1_RXIF_DELAY_DATA_MASK_SFT (0x1 << 8) + +/* AFE_AUD_PAD_TOP_CFG0 */ +#define AUD_PAD_TOP_FIFO_RSP_SFT 4 +#define AUD_PAD_TOP_FIFO_RSP_MASK 0xf +#define AUD_PAD_TOP_FIFO_RSP_MASK_SFT (0xf << 4) +#define RG_RX_PROTOCOL2_SFT 3 +#define RG_RX_PROTOCOL2_MASK 0x1 +#define RG_RX_PROTOCOL2_MASK_SFT (0x1 << 3) +#define RG_RX_FIFO_ON_SFT 0 +#define RG_RX_FIFO_ON_MASK 0x1 +#define RG_RX_FIFO_ON_MASK_SFT (0x1 << 0) + +/* AFE_AUD_PAD_TOP_MON */ +#define AUD_PAD_TOP_MON_SFT 0 +#define AUD_PAD_TOP_MON_MASK 0xffff +#define AUD_PAD_TOP_MON_MASK_SFT (0xffff << 0) + +/* AFE_ADDA_MTKAIFV4_TX_CFG0 */ +#define MTKAIFV4_TXIF_EN_SEL_SFT 12 +#define MTKAIFV4_TXIF_EN_SEL_MASK 0x1 +#define MTKAIFV4_TXIF_EN_SEL_MASK_SFT (0x1 << 12) +#define MTKAIFV4_TXIF_V4_SFT 11 +#define MTKAIFV4_TXIF_V4_MASK 0x1 +#define MTKAIFV4_TXIF_V4_MASK_SFT (0x1 << 11) +#define MTKAIFV4_ADDA6_OUT_EN_SEL_SFT 10 +#define MTKAIFV4_ADDA6_OUT_EN_SEL_MASK 0x1 +#define MTKAIFV4_ADDA6_OUT_EN_SEL_MASK_SFT (0x1 << 10) +#define MTKAIFV4_ADDA_OUT_EN_SEL_SFT 9 +#define MTKAIFV4_ADDA_OUT_EN_SEL_MASK 0x1 +#define MTKAIFV4_ADDA_OUT_EN_SEL_MASK_SFT (0x1 << 9) +#define MTKAIFV4_TXIF_INPUT_MODE_SFT 4 +#define MTKAIFV4_TXIF_INPUT_MODE_MASK 0x1f +#define MTKAIFV4_TXIF_INPUT_MODE_MASK_SFT (0x1f << 4) +#define MTKAIFV4_TXIF_FOUR_CHANNEL_SFT 1 +#define MTKAIFV4_TXIF_FOUR_CHANNEL_MASK 0x1 +#define MTKAIFV4_TXIF_FOUR_CHANNEL_MASK_SFT (0x1 << 1) +#define MTKAIFV4_TXIF_AFE_ON_SFT 0 +#define MTKAIFV4_TXIF_AFE_ON_MASK 0x1 +#define MTKAIFV4_TXIF_AFE_ON_MASK_SFT (0x1 << 0) + +/* AFE_ADDA6_MTKAIFV4_TX_CFG0 */ +#define ADDA6_MTKAIFV4_TXIF_EN_SEL_SFT 12 +#define ADDA6_MTKAIFV4_TXIF_EN_SEL_MASK 0x1 +#define ADDA6_MTKAIFV4_TXIF_EN_SEL_MASK_SFT (0x1 << 12) +#define ADDA6_MTKAIFV4_TXIF_INPUT_MODE_SFT 4 +#define ADDA6_MTKAIFV4_TXIF_INPUT_MODE_MASK 0x1f +#define ADDA6_MTKAIFV4_TXIF_INPUT_MODE_MASK_SFT (0x1f << 4) +#define ADDA6_MTKAIFV4_TXIF_FOUR_CHANNEL_SFT 1 +#define ADDA6_MTKAIFV4_TXIF_FOUR_CHANNEL_MASK 0x1 +#define ADDA6_MTKAIFV4_TXIF_FOUR_CHANNEL_MASK_SFT (0x1 << 1) +#define ADDA6_MTKAIFV4_TXIF_AFE_ON_SFT 0 +#define ADDA6_MTKAIFV4_TXIF_AFE_ON_MASK 0x1 +#define ADDA6_MTKAIFV4_TXIF_AFE_ON_MASK_SFT (0x1 << 0) + +/* AFE_ADDA_MTKAIFV4_RX_CFG0 */ +#define MTKAIFV4_RXIF_CLKINV_SFT 31 +#define MTKAIFV4_RXIF_CLKINV_MASK 0x1 +#define MTKAIFV4_RXIF_CLKINV_MASK_SFT (0x1 << 31) +#define MTKAIFV4_RXIF_LOOPBACK_MODE_SFT 28 +#define MTKAIFV4_RXIF_LOOPBACK_MODE_MASK 0x1 +#define MTKAIFV4_RXIF_LOOPBACK_MODE_MASK_SFT (0x1 << 28) +#define MTKAIFV4_UL_CH7CH8_IN_EN_SEL_SFT 19 +#define MTKAIFV4_UL_CH7CH8_IN_EN_SEL_MASK 0x1 +#define MTKAIFV4_UL_CH7CH8_IN_EN_SEL_MASK_SFT (0x1 << 19) +#define MTKAIFV4_UL_CH5CH6_IN_EN_SEL_SFT 18 +#define MTKAIFV4_UL_CH5CH6_IN_EN_SEL_MASK 0x1 +#define MTKAIFV4_UL_CH5CH6_IN_EN_SEL_MASK_SFT (0x1 << 18) +#define MTKAIFV4_UL_CH3CH4_IN_EN_SEL_SFT 17 +#define MTKAIFV4_UL_CH3CH4_IN_EN_SEL_MASK 0x1 +#define MTKAIFV4_UL_CH3CH4_IN_EN_SEL_MASK_SFT (0x1 << 17) +#define MTKAIFV4_UL_CH1CH2_IN_EN_SEL_SFT 16 +#define MTKAIFV4_UL_CH1CH2_IN_EN_SEL_MASK 0x1 +#define MTKAIFV4_UL_CH1CH2_IN_EN_SEL_MASK_SFT (0x1 << 16) +#define MTKAIFV4_RXIF_EN_SEL_SFT 12 +#define MTKAIFV4_RXIF_EN_SEL_MASK 0x1 +#define MTKAIFV4_RXIF_EN_SEL_MASK_SFT (0x1 << 12) +#define MTKAIFV4_RXIF_INPUT_MODE_SFT 4 +#define MTKAIFV4_RXIF_INPUT_MODE_MASK 0x1f +#define MTKAIFV4_RXIF_INPUT_MODE_MASK_SFT (0x1f << 4) +#define MTKAIFV4_RXIF_FOUR_CHANNEL_SFT 1 +#define MTKAIFV4_RXIF_FOUR_CHANNEL_MASK 0x1 +#define MTKAIFV4_RXIF_FOUR_CHANNEL_MASK_SFT (0x1 << 1) +#define MTKAIFV4_RXIF_AFE_ON_SFT 0 +#define MTKAIFV4_RXIF_AFE_ON_MASK 0x1 +#define MTKAIFV4_RXIF_AFE_ON_MASK_SFT (0x1 << 0) + +/* AFE_ADDA_MTKAIFV4_RX_CFG1 */ +#define MTKAIFV4_RXIF_SYNC_CNT_TABLE_SFT 17 +#define MTKAIFV4_RXIF_SYNC_CNT_TABLE_MASK 0xfff +#define MTKAIFV4_RXIF_SYNC_CNT_TABLE_MASK_SFT (0xfff << 17) +#define MTKAIFV4_RXIF_SYNC_SEARCH_TABLE_SFT 12 +#define MTKAIFV4_RXIF_SYNC_SEARCH_TABLE_MASK 0x1f +#define MTKAIFV4_RXIF_SYNC_SEARCH_TABLE_MASK_SFT (0x1f << 12) +#define MTKAIFV4_RXIF_INVAILD_SYNC_CHECK_ROUND_SFT 8 +#define MTKAIFV4_RXIF_INVAILD_SYNC_CHECK_ROUND_MASK 0xf +#define MTKAIFV4_RXIF_INVAILD_SYNC_CHECK_ROUND_MASK_SFT (0xf << 8) +#define MTKAIFV4_RXIF_SYNC_CHECK_ROUND_SFT 4 +#define MTKAIFV4_RXIF_SYNC_CHECK_ROUND_MASK 0xf +#define MTKAIFV4_RXIF_SYNC_CHECK_ROUND_MASK_SFT (0xf << 4) +#define MTKAIFV4_RXIF_FIFO_RSP_SFT 1 +#define MTKAIFV4_RXIF_FIFO_RSP_MASK 0x7 +#define MTKAIFV4_RXIF_FIFO_RSP_MASK_SFT (0x7 << 1) +#define MTKAIFV4_RXIF_SELF_DEFINE_TABLE_SFT 0 +#define MTKAIFV4_RXIF_SELF_DEFINE_TABLE_MASK 0x1 +#define MTKAIFV4_RXIF_SELF_DEFINE_TABLE_MASK_SFT (0x1 << 0) + +/* AFE_ADDA6_MTKAIFV4_RX_CFG0 */ +#define ADDA6_MTKAIFV4_RXIF_CLKINV_SFT 31 +#define ADDA6_MTKAIFV4_RXIF_CLKINV_MASK 0x1 +#define ADDA6_MTKAIFV4_RXIF_CLKINV_MASK_SFT (0x1 << 31) +#define ADDA6_MTKAIFV4_RXIF_LOOPBACK_MODE_SFT 28 +#define ADDA6_MTKAIFV4_RXIF_LOOPBACK_MODE_MASK 0x1 +#define ADDA6_MTKAIFV4_RXIF_LOOPBACK_MODE_MASK_SFT (0x1 << 28) +#define ADDA6_MTKAIFV4_RXIF_EN_SEL_SFT 12 +#define ADDA6_MTKAIFV4_RXIF_EN_SEL_MASK 0x1 +#define ADDA6_MTKAIFV4_RXIF_EN_SEL_MASK_SFT (0x1 << 12) +#define ADDA6_MTKAIFV4_RXIF_INPUT_MODE_SFT 4 +#define ADDA6_MTKAIFV4_RXIF_INPUT_MODE_MASK 0x1f +#define ADDA6_MTKAIFV4_RXIF_INPUT_MODE_MASK_SFT (0x1f << 4) +#define ADDA6_MTKAIFV4_RXIF_FOUR_CHANNEL_SFT 1 +#define ADDA6_MTKAIFV4_RXIF_FOUR_CHANNEL_MASK 0x1 +#define ADDA6_MTKAIFV4_RXIF_FOUR_CHANNEL_MASK_SFT (0x1 << 1) +#define ADDA6_MTKAIFV4_RXIF_AFE_ON_SFT 0 +#define ADDA6_MTKAIFV4_RXIF_AFE_ON_MASK 0x1 +#define ADDA6_MTKAIFV4_RXIF_AFE_ON_MASK_SFT (0x1 << 0) + +/* AFE_ADDA6_MTKAIFV4_RX_CFG1 */ +#define ADDA6_MTKAIFV4_RXIF_SYNC_CNT_TABLE_SFT 17 +#define ADDA6_MTKAIFV4_RXIF_SYNC_CNT_TABLE_MASK 0xfff +#define ADDA6_MTKAIFV4_RXIF_SYNC_CNT_TABLE_MASK_SFT (0xfff << 17) +#define ADDA6_MTKAIFV4_RXIF_SYNC_SEARCH_TABLE_SFT 12 +#define ADDA6_MTKAIFV4_RXIF_SYNC_SEARCH_TABLE_MASK 0x1f +#define ADDA6_MTKAIFV4_RXIF_SYNC_SEARCH_TABLE_MASK_SFT (0x1f << 12) +#define ADDA6_MTKAIFV4_RXIF_INVAILD_SYNC_CHECK_ROUND_SFT 8 +#define ADDA6_MTKAIFV4_RXIF_INVAILD_SYNC_CHECK_ROUND_MASK 0xf +#define ADDA6_MTKAIFV4_RXIF_INVAILD_SYNC_CHECK_ROUND_MASK_SFT (0xf << 8) +#define ADDA6_MTKAIFV4_RXIF_SYNC_CHECK_ROUND_SFT 4 +#define ADDA6_MTKAIFV4_RXIF_SYNC_CHECK_ROUND_MASK 0xf +#define ADDA6_MTKAIFV4_RXIF_SYNC_CHECK_ROUND_MASK_SFT (0xf << 4) +#define ADDA6_MTKAIFV4_RXIF_FIFO_RSP_SFT 1 +#define ADDA6_MTKAIFV4_RXIF_FIFO_RSP_MASK 0x7 +#define ADDA6_MTKAIFV4_RXIF_FIFO_RSP_MASK_SFT (0x7 << 1) +#define ADDA6_MTKAIFV4_RXIF_SELF_DEFINE_TABLE_SFT 0 +#define ADDA6_MTKAIFV4_RXIF_SELF_DEFINE_TABLE_MASK 0x1 +#define ADDA6_MTKAIFV4_RXIF_SELF_DEFINE_TABLE_MASK_SFT (0x1 << 0) + +/* AFE_ADDA_MTKAIFV4_TX_SYNCWORD_CFG */ +#define ADDA6_MTKAIFV4_TXIF_SYNCWORD_SFT 16 +#define ADDA6_MTKAIFV4_TXIF_SYNCWORD_MASK 0xffff +#define ADDA6_MTKAIFV4_TXIF_SYNCWORD_MASK_SFT (0xffff << 16) +#define ADDA_MTKAIFV4_TXIF_SYNCWORD_SFT 0 +#define ADDA_MTKAIFV4_TXIF_SYNCWORD_MASK 0xffff +#define ADDA_MTKAIFV4_TXIF_SYNCWORD_MASK_SFT (0xffff << 0) + +/* AFE_ADDA_MTKAIFV4_RX_SYNCWORD_CFG */ +#define ADDA6_MTKAIFV4_RXIF_SYNCWORD_SFT 16 +#define ADDA6_MTKAIFV4_RXIF_SYNCWORD_MASK 0xffff +#define ADDA6_MTKAIFV4_RXIF_SYNCWORD_MASK_SFT (0xffff << 16) +#define ADDA_MTKAIFV4_RXIF_SYNCWORD_SFT 0 +#define ADDA_MTKAIFV4_RXIF_SYNCWORD_MASK 0xffff +#define ADDA_MTKAIFV4_RXIF_SYNCWORD_MASK_SFT (0xffff << 0) + +/* AFE_ADDA_MTKAIFV4_MON0 */ +#define MTKAIFV4_TXIF_SDATA_OUT_SFT 23 +#define MTKAIFV4_TXIF_SDATA_OUT_MASK 0x1 +#define MTKAIFV4_TXIF_SDATA_OUT_MASK_SFT (0x1 << 23) +#define MTKAIFV4_RXIF_SDATA_IN_SFT 22 +#define MTKAIFV4_RXIF_SDATA_IN_MASK 0x1 +#define MTKAIFV4_RXIF_SDATA_IN_MASK_SFT (0x1 << 22) +#define MTKAIFV4_RXIF_SEARCH_FAIL_FLAG_SFT 21 +#define MTKAIFV4_RXIF_SEARCH_FAIL_FLAG_MASK 0x1 +#define MTKAIFV4_RXIF_SEARCH_FAIL_FLAG_MASK_SFT (0x1 << 21) +#define MTKAIFV4_RXIF_ADC_FIFO_STATUS_SFT 0 +#define MTKAIFV4_RXIF_ADC_FIFO_STATUS_MASK 0xfff +#define MTKAIFV4_RXIF_ADC_FIFO_STATUS_MASK_SFT (0xfff << 0) + +/* AFE_ADDA_MTKAIFV4_MON1 */ +#define MTKAIFV4_RXIF_OUT_CH4_SFT 24 +#define MTKAIFV4_RXIF_OUT_CH4_MASK 0xff +#define MTKAIFV4_RXIF_OUT_CH4_MASK_SFT (0xff << 24) +#define MTKAIFV4_RXIF_OUT_CH3_SFT 16 +#define MTKAIFV4_RXIF_OUT_CH3_MASK 0xff +#define MTKAIFV4_RXIF_OUT_CH3_MASK_SFT (0xff << 16) +#define MTKAIFV4_RXIF_OUT_CH2_SFT 8 +#define MTKAIFV4_RXIF_OUT_CH2_MASK 0xff +#define MTKAIFV4_RXIF_OUT_CH2_MASK_SFT (0xff << 8) +#define MTKAIFV4_RXIF_OUT_CH1_SFT 0 +#define MTKAIFV4_RXIF_OUT_CH1_MASK 0xff +#define MTKAIFV4_RXIF_OUT_CH1_MASK_SFT (0xff << 0) + +/* AFE_ADDA6_MTKAIFV4_MON0 */ +#define ADDA6_MTKAIFV4_TXIF_SDATA_OUT_SFT 23 +#define ADDA6_MTKAIFV4_TXIF_SDATA_OUT_MASK 0x1 +#define ADDA6_MTKAIFV4_TXIF_SDATA_OUT_MASK_SFT (0x1 << 23) +#define ADDA6_MTKAIFV4_RXIF_SDATA_IN_SFT 22 +#define ADDA6_MTKAIFV4_RXIF_SDATA_IN_MASK 0x1 +#define ADDA6_MTKAIFV4_RXIF_SDATA_IN_MASK_SFT (0x1 << 22) +#define ADDA6_MTKAIFV4_RXIF_SEARCH_FAIL_FLAG_SFT 21 +#define ADDA6_MTKAIFV4_RXIF_SEARCH_FAIL_FLAG_MASK 0x1 +#define ADDA6_MTKAIFV4_RXIF_SEARCH_FAIL_FLAG_MASK_SFT (0x1 << 21) +#define ADDA6_MTKAIFV3P3_RXIF_ADC_FIFO_STATUS_SFT 0 +#define ADDA6_MTKAIFV3P3_RXIF_ADC_FIFO_STATUS_MASK 0xfff +#define ADDA6_MTKAIFV3P3_RXIF_ADC_FIFO_STATUS_MASK_SFT (0xfff << 0) + +/* ETDM_IN0_CON0 */ +/* ETDM_IN1_CON0 */ +#define REG_ETDM_IN_EN_SFT 0 +#define REG_ETDM_IN_EN_MASK 0x1 +#define REG_ETDM_IN_EN_MASK_SFT (0x1 << 0) +#define REG_SYNC_MODE_SFT 1 +#define REG_SYNC_MODE_MASK 0x1 +#define REG_SYNC_MODE_MASK_SFT (0x1 << 1) +#define REG_LSB_FIRST_SFT 3 +#define REG_LSB_FIRST_MASK 0x1 +#define REG_LSB_FIRST_MASK_SFT (0x1 << 3) +#define REG_SOFT_RST_SFT 4 +#define REG_SOFT_RST_MASK 0x1 +#define REG_SOFT_RST_MASK_SFT (0x1 << 4) +#define REG_SLAVE_MODE_SFT 5 +#define REG_SLAVE_MODE_MASK 0x1 +#define REG_SLAVE_MODE_MASK_SFT (0x1 << 5) +#define REG_FMT_SFT 6 +#define REG_FMT_MASK 0x7 +#define REG_FMT_MASK_SFT (0x7 << 6) +#define REG_LRCK_EDGE_SEL_SFT 10 +#define REG_LRCK_EDGE_SEL_MASK 0x1 +#define REG_LRCK_EDGE_SEL_MASK_SFT (0x1 << 10) +#define REG_BIT_LENGTH_SFT 11 +#define REG_BIT_LENGTH_MASK 0x1f +#define REG_BIT_LENGTH_MASK_SFT (0x1f << 11) +#define REG_WORD_LENGTH_SFT 16 +#define REG_WORD_LENGTH_MASK 0x1f +#define REG_WORD_LENGTH_MASK_SFT (0x1f << 16) +#define REG_CH_NUM_SFT 23 +#define REG_CH_NUM_MASK 0x1f +#define REG_CH_NUM_MASK_SFT (0x1f << 23) +#define REG_RELATCH_1X_EN_DOMAIN_SEL_SFT 28 +#define REG_RELATCH_1X_EN_DOMAIN_SEL_MASK 0x7 +#define REG_RELATCH_1X_EN_DOMAIN_SEL_MASK_SFT (0x7 << 28) +#define REG_VALID_TOGETHER_SFT 31 +#define REG_VALID_TOGETHER_MASK 0x1 +#define REG_VALID_TOGETHER_MASK_SFT (0x1 << 31) + +/* ETDM_IN0_CON1 */ +/* ETDM_IN1_CON1 */ +#define REG_INITIAL_COUNT_SFT 0 +#define REG_INITIAL_COUNT_MASK 0x1f +#define REG_INITIAL_COUNT_MASK_SFT (0x1f << 0) +#define REG_INITIAL_POINT_SFT 5 +#define REG_INITIAL_POINT_MASK 0x1f +#define REG_INITIAL_POINT_MASK_SFT (0x1f << 5) +#define REG_LRCK_AUTO_OFF_SFT 10 +#define REG_LRCK_AUTO_OFF_MASK 0x1 +#define REG_LRCK_AUTO_OFF_MASK_SFT (0x1 << 10) +#define REG_BCK_AUTO_OFF_SFT 11 +#define REG_BCK_AUTO_OFF_MASK 0x1 +#define REG_BCK_AUTO_OFF_MASK_SFT (0x1 << 11) +#define REG_INITIAL_LRCK_SFT 13 +#define REG_INITIAL_LRCK_MASK 0x1 +#define REG_INITIAL_LRCK_MASK_SFT (0x1 << 13) +#define REG_NO_ALIGN_1X_EN_SFT 14 +#define REG_NO_ALIGN_1X_EN_MASK 0x1 +#define REG_NO_ALIGN_1X_EN_MASK_SFT (0x1 << 14) +#define REG_LRCK_RESET_SFT 15 +#define REG_LRCK_RESET_MASK 0x1 +#define REG_LRCK_RESET_MASK_SFT (0x1 << 15) +#define PINMUX_MCLK_CTRL_OE_SFT 16 +#define PINMUX_MCLK_CTRL_OE_MASK 0x1 +#define PINMUX_MCLK_CTRL_OE_MASK_SFT (0x1 << 16) +#define REG_OUTPUT_CR_EN_SFT 18 +#define REG_OUTPUT_CR_EN_MASK 0x1 +#define REG_OUTPUT_CR_EN_MASK_SFT (0x1 << 18) +#define REG_LR_ALIGN_SFT 19 +#define REG_LR_ALIGN_MASK 0x1 +#define REG_LR_ALIGN_MASK_SFT (0x1 << 19) +#define REG_LRCK_WIDTH_SFT 20 +#define REG_LRCK_WIDTH_MASK 0x3ff +#define REG_LRCK_WIDTH_MASK_SFT (0x3ff << 20) +#define REG_DIRECT_INPUT_MASTER_BCK_SFT 30 +#define REG_DIRECT_INPUT_MASTER_BCK_MASK 0x1 +#define REG_DIRECT_INPUT_MASTER_BCK_MASK_SFT (0x1 << 30) +#define REG_LRCK_AUTO_MODE_SFT 31 +#define REG_LRCK_AUTO_MODE_MASK 0x1 +#define REG_LRCK_AUTO_MODE_MASK_SFT (0x1 << 31) + +/* ETDM_IN0_CON2 */ +/* ETDM_IN1_CON2 */ +#define REG_UPDATE_POINT_SFT 0 +#define REG_UPDATE_POINT_MASK 0x1f +#define REG_UPDATE_POINT_MASK_SFT (0x1f << 0) +#define REG_UPDATE_GAP_SFT 5 +#define REG_UPDATE_GAP_MASK 0x1f +#define REG_UPDATE_GAP_MASK_SFT (0x1f << 5) +#define REG_CLOCK_SOURCE_SEL_SFT 10 +#define REG_CLOCK_SOURCE_SEL_MASK 0x7 +#define REG_CLOCK_SOURCE_SEL_MASK_SFT (0x7 << 10) +#define REG_CK_EN_SEL_AUTO_SFT 14 +#define REG_CK_EN_SEL_AUTO_MASK 0x1 +#define REG_CK_EN_SEL_AUTO_MASK_SFT (0x1 << 14) +#define REG_MULTI_IP_TOTAL_CHNUM_SFT 15 +#define REG_MULTI_IP_TOTAL_CHNUM_MASK 0x1f +#define REG_MULTI_IP_TOTAL_CHNUM_MASK_SFT (0x1f << 15) +#define REG_MASK_AUTO_SFT 20 +#define REG_MASK_AUTO_MASK 0x1 +#define REG_MASK_AUTO_MASK_SFT (0x1 << 20) +#define REG_MASK_NUM_SFT 21 +#define REG_MASK_NUM_MASK 0x1f +#define REG_MASK_NUM_MASK_SFT (0x1f << 21) +#define REG_UPDATE_POINT_AUTO_SFT 26 +#define REG_UPDATE_POINT_AUTO_MASK 0x1 +#define REG_UPDATE_POINT_AUTO_MASK_SFT (0x1 << 26) +#define REG_SDATA_DELAY_0P5T_EN_SFT 27 +#define REG_SDATA_DELAY_0P5T_EN_MASK 0x1 +#define REG_SDATA_DELAY_0P5T_EN_MASK_SFT (0x1 << 27) +#define REG_SDATA_DELAY_BCK_INV_SFT 28 +#define REG_SDATA_DELAY_BCK_INV_MASK 0x1 +#define REG_SDATA_DELAY_BCK_INV_MASK_SFT (0x1 << 28) +#define REG_LRCK_DELAY_0P5T_EN_SFT 29 +#define REG_LRCK_DELAY_0P5T_EN_MASK 0x1 +#define REG_LRCK_DELAY_0P5T_EN_MASK_SFT (0x1 << 29) +#define REG_LRCK_DELAY_BCK_INV_SFT 30 +#define REG_LRCK_DELAY_BCK_INV_MASK 0x1 +#define REG_LRCK_DELAY_BCK_INV_MASK_SFT (0x1 << 30) +#define REG_MULTI_IP_MODE_SFT 31 +#define REG_MULTI_IP_MODE_MASK 0x1 +#define REG_MULTI_IP_MODE_MASK_SFT (0x1 << 31) + +/* ETDM_IN0_CON3 */ +/* ETDM_IN1_CON3 */ +#define REG_DISABLE_OUT_SFT 0 +#define REG_DISABLE_OUT_MASK 0xffff +#define REG_DISABLE_OUT_MASK_SFT (0xffff << 0) +#define REG_RJ_DATA_RIGHT_ALIGN_SFT 16 +#define REG_RJ_DATA_RIGHT_ALIGN_MASK 0x1 +#define REG_RJ_DATA_RIGHT_ALIGN_MASK_SFT (0x1 << 16) +#define REG_MONITOR_SEL_SFT 17 +#define REG_MONITOR_SEL_MASK 0x3 +#define REG_MONITOR_SEL_MASK_SFT (0x3 << 17) +#define REG_CNT_UPPER_LIMIT_SFT 19 +#define REG_CNT_UPPER_LIMIT_MASK 0x3f +#define REG_CNT_UPPER_LIMIT_MASK_SFT (0x3f << 19) +#define REG_COMPACT_SAMPLE_END_DIS_SFT 25 +#define REG_COMPACT_SAMPLE_END_DIS_MASK 0x1 +#define REG_COMPACT_SAMPLE_END_DIS_MASK_SFT (0x1 << 25) +#define REG_FS_TIMING_SEL_SFT 26 +#define REG_FS_TIMING_SEL_MASK 0x1f +#define REG_FS_TIMING_SEL_MASK_SFT (0x1f << 26) +#define REG_SAMPLE_END_MODE_SFT 31 +#define REG_SAMPLE_END_MODE_MASK 0x1 +#define REG_SAMPLE_END_MODE_MASK_SFT (0x1 << 31) + +/* ETDM_IN0_CON4 */ +/* ETDM_IN1_CON4 */ +#define REG_ALWAYS_OPEN_1X_EN_SFT 31 +#define REG_ALWAYS_OPEN_1X_EN_MASK 0x1 +#define REG_ALWAYS_OPEN_1X_EN_MASK_SFT (0x1 << 31) +#define REG_WAIT_LAST_SAMPLE_SFT 30 +#define REG_WAIT_LAST_SAMPLE_MASK 0x1 +#define REG_WAIT_LAST_SAMPLE_MASK_SFT (0x1 << 30) +#define REG_SAMPLE_END_POINT_SFT 25 +#define REG_SAMPLE_END_POINT_MASK 0x1f +#define REG_SAMPLE_END_POINT_MASK_SFT (0x1f << 25) +#define REG_RELATCH_1X_EN_SEL_SFT 20 +#define REG_RELATCH_1X_EN_SEL_MASK 0x1f +#define REG_RELATCH_1X_EN_SEL_MASK_SFT (0x1f << 20) +#define REG_MASTER_WS_INV_SFT 19 +#define REG_MASTER_WS_INV_MASK 0x1 +#define REG_MASTER_WS_INV_MASK_SFT (0x1 << 19) +#define REG_MASTER_BCK_INV_SFT 18 +#define REG_MASTER_BCK_INV_MASK 0x1 +#define REG_MASTER_BCK_INV_MASK_SFT (0x1 << 18) +#define REG_SLAVE_LRCK_INV_SFT 17 +#define REG_SLAVE_LRCK_INV_MASK 0x1 +#define REG_SLAVE_LRCK_INV_MASK_SFT (0x1 << 17) +#define REG_SLAVE_BCK_INV_SFT 16 +#define REG_SLAVE_BCK_INV_MASK 0x1 +#define REG_SLAVE_BCK_INV_MASK_SFT (0x1 << 16) +#define REG_REPACK_CHNUM_SFT 12 +#define REG_REPACK_CHNUM_MASK 0xf +#define REG_REPACK_CHNUM_MASK_SFT (0xf << 12) +#define REG_ASYNC_RESET_SFT 11 +#define REG_ASYNC_RESET_MASK 0x1 +#define REG_ASYNC_RESET_MASK_SFT (0x1 << 11) +#define REG_REPACK_WORD_LENGTH_SFT 9 +#define REG_REPACK_WORD_LENGTH_MASK 0x3 +#define REG_REPACK_WORD_LENGTH_MASK_SFT (0x3 << 9) +#define REG_REPACK_AUTO_MODE_SFT 8 +#define REG_REPACK_AUTO_MODE_MASK 0x1 +#define REG_REPACK_AUTO_MODE_MASK_SFT (0x1 << 8) +#define REG_REPACK_MODE_SFT 0 +#define REG_REPACK_MODE_MASK 0x3f +#define REG_REPACK_MODE_MASK_SFT (0x3f << 0) + +/* ETDM_IN0_CON5 */ +/* ETDM_IN1_CON5 */ +#define REG_LR_SWAP_SFT 16 +#define REG_LR_SWAP_MASK 0xffff +#define REG_LR_SWAP_MASK_SFT (0xffff << 16) +#define REG_ODD_FLAG_EN_SFT 0 +#define REG_ODD_FLAG_EN_MASK 0xffff +#define REG_ODD_FLAG_EN_MASK_SFT (0xffff << 0) + +/* ETDM_IN0_CON6 */ +/* ETDM_IN1_CON6 */ +#define LCH_DATA_REG_SFT 0 +#define LCH_DATA_REG_MASK 0xffffffff +#define LCH_DATA_REG_MASK_SFT (0xffffffff << 0) + +/* ETDM_IN0_CON7 */ +/* ETDM_IN1_CON7 */ +#define RCH_DATA_REG_SFT 0 +#define RCH_DATA_REG_MASK 0xffffffff +#define RCH_DATA_REG_MASK_SFT (0xffffffff << 0) + +/* ETDM_IN0_CON8 */ +/* ETDM_IN1_CON8 */ +#define REG_AFIFO_THRESHOLD_SFT 29 +#define REG_AFIFO_THRESHOLD_MASK 0x3 +#define REG_AFIFO_THRESHOLD_MASK_SFT (0x3 << 29) +#define REG_CK_EN_SEL_MANUAL_SFT 16 +#define REG_CK_EN_SEL_MANUAL_MASK 0x3ff +#define REG_CK_EN_SEL_MANUAL_MASK_SFT (0x3ff << 16) +#define REG_AFIFO_SW_RESET_SFT 15 +#define REG_AFIFO_SW_RESET_MASK 0x1 +#define REG_AFIFO_SW_RESET_MASK_SFT (0x1 << 15) +#define REG_AFIFO_RESET_SEL_SFT 14 +#define REG_AFIFO_RESET_SEL_MASK 0x1 +#define REG_AFIFO_RESET_SEL_MASK_SFT (0x1 << 14) +#define REG_AFIFO_AUTO_RESET_DIS_SFT 9 +#define REG_AFIFO_AUTO_RESET_DIS_MASK 0x1 +#define REG_AFIFO_AUTO_RESET_DIS_MASK_SFT (0x1 << 9) +#define REG_ETDM_USE_AFIFO_SFT 8 +#define REG_ETDM_USE_AFIFO_MASK 0x1 +#define REG_ETDM_USE_AFIFO_MASK_SFT (0x1 << 8) +#define REG_AFIFO_CLOCK_DOMAIN_SEL_SFT 5 +#define REG_AFIFO_CLOCK_DOMAIN_SEL_MASK 0x7 +#define REG_AFIFO_CLOCK_DOMAIN_SEL_MASK_SFT (0x7 << 5) +#define REG_AFIFO_MODE_SFT 0 +#define REG_AFIFO_MODE_MASK 0x1f +#define REG_AFIFO_MODE_MASK_SFT (0x1f << 0) + +/* ETDM_IN0_CON9 */ +/* ETDM_IN1_CON9 */ +#define REG_OUT2LATCH_TIME_SFT 10 +#define REG_OUT2LATCH_TIME_MASK 0x1f +#define REG_OUT2LATCH_TIME_MASK_SFT (0x1f << 10) +#define REG_ALMOST_END_BIT_COUNT_SFT 5 +#define REG_ALMOST_END_BIT_COUNT_MASK 0x1f +#define REG_ALMOST_END_BIT_COUNT_MASK_SFT (0x1f << 5) +#define REG_ALMOST_END_CH_COUNT_SFT 0 +#define REG_ALMOST_END_CH_COUNT_MASK 0x1f +#define REG_ALMOST_END_CH_COUNT_MASK_SFT (0x1f << 0) + +/* ETDM_IN0_MON */ +/* ETDM_IN1_MON */ +#define LRCK_INV_SFT 30 +#define LRCK_INV_MASK 0x1 +#define LRCK_INV_MASK_SFT (0x1 << 30) +#define EN_SYNC_OUT_SFT 29 +#define EN_SYNC_OUT_MASK 0x1 +#define EN_SYNC_OUT_MASK_SFT (0x1 << 29) +#define HOPPING_EN_SYNC_OUT_PRE_SFT 28 +#define HOPPING_EN_SYNC_OUT_PRE_MASK 0x1 +#define HOPPING_EN_SYNC_OUT_PRE_MASK_SFT (0x1 << 28) +#define WFULL_SFT 27 +#define WFULL_MASK 0x1 +#define WFULL_MASK_SFT (0x1 << 27) +#define REMPTY_SFT 26 +#define REMPTY_MASK 0x1 +#define REMPTY_MASK_SFT (0x1 << 26) +#define ETDM_2X_CK_EN_SFT 25 +#define ETDM_2X_CK_EN_MASK 0x1 +#define ETDM_2X_CK_EN_MASK_SFT (0x1 << 25) +#define ETDM_1X_CK_EN_SFT 24 +#define ETDM_1X_CK_EN_MASK 0x1 +#define ETDM_1X_CK_EN_MASK_SFT (0x1 << 24) +#define SDATA0_SFT 23 +#define SDATA0_MASK 0x1 +#define SDATA0_MASK_SFT (0x1 << 23) +#define CURRENT_STATUS_SFT 21 +#define CURRENT_STATUS_MASK 0x3 +#define CURRENT_STATUS_MASK_SFT (0x3 << 21) +#define BIT_POINT_SFT 16 +#define BIT_POINT_MASK 0x1f +#define BIT_POINT_MASK_SFT (0x1f << 16) +#define BIT_CH_COUNT_SFT 10 +#define BIT_CH_COUNT_MASK 0x3f +#define BIT_CH_COUNT_MASK_SFT (0x3f << 10) +#define BIT_COUNT_SFT 5 +#define BIT_COUNT_MASK 0x1f +#define BIT_COUNT_MASK_SFT (0x1f << 5) +#define CH_COUNT_SFT 0 +#define CH_COUNT_MASK 0x1f +#define CH_COUNT_MASK_SFT (0x1f << 0) + +/* ETDM_OUT0_CON0 */ +/* ETDM_OUT1_CON0 */ +/* ETDM_OUT4_CON0 */ +#define OUT_REG_ETDM_OUT_EN_SFT 0 +#define OUT_REG_ETDM_OUT_EN_MASK 0x1 +#define OUT_REG_ETDM_OUT_EN_MASK_SFT (0x1 << 0) +#define OUT_REG_SYNC_MODE_SFT 1 +#define OUT_REG_SYNC_MODE_MASK 0x1 +#define OUT_REG_SYNC_MODE_MASK_SFT (0x1 << 1) +#define OUT_REG_LSB_FIRST_SFT 3 +#define OUT_REG_LSB_FIRST_MASK 0x1 +#define OUT_REG_LSB_FIRST_MASK_SFT (0x1 << 3) +#define OUT_REG_SOFT_RST_SFT 4 +#define OUT_REG_SOFT_RST_MASK 0x1 +#define OUT_REG_SOFT_RST_MASK_SFT (0x1 << 4) +#define OUT_REG_SLAVE_MODE_SFT 5 +#define OUT_REG_SLAVE_MODE_MASK 0x1 +#define OUT_REG_SLAVE_MODE_MASK_SFT (0x1 << 5) +#define OUT_REG_FMT_SFT 6 +#define OUT_REG_FMT_MASK 0x7 +#define OUT_REG_FMT_MASK_SFT (0x7 << 6) +#define OUT_REG_LRCK_EDGE_SEL_SFT 10 +#define OUT_REG_LRCK_EDGE_SEL_MASK 0x1 +#define OUT_REG_LRCK_EDGE_SEL_MASK_SFT (0x1 << 10) +#define OUT_REG_BIT_LENGTH_SFT 11 +#define OUT_REG_BIT_LENGTH_MASK 0x1f +#define OUT_REG_BIT_LENGTH_MASK_SFT (0x1f << 11) +#define OUT_REG_WORD_LENGTH_SFT 16 +#define OUT_REG_WORD_LENGTH_MASK 0x1f +#define OUT_REG_WORD_LENGTH_MASK_SFT (0x1f << 16) +#define OUT_REG_CH_NUM_SFT 23 +#define OUT_REG_CH_NUM_MASK 0x1f +#define OUT_REG_CH_NUM_MASK_SFT (0x1f << 23) +#define OUT_REG_RELATCH_DOMAIN_SEL_SFT 28 +#define OUT_REG_RELATCH_DOMAIN_SEL_MASK 0x7 +#define OUT_REG_RELATCH_DOMAIN_SEL_MASK_SFT (0x7 << 28) +#define OUT_REG_VALID_TOGETHER_SFT 31 +#define OUT_REG_VALID_TOGETHER_MASK 0x1 +#define OUT_REG_VALID_TOGETHER_MASK_SFT (0x1 << 31) + +/* ETDM_OUT0_CON1 */ +/* ETDM_OUT1_CON1 */ +/* ETDM_OUT4_CON1 */ +#define OUT_REG_INITIAL_COUNT_SFT 0 +#define OUT_REG_INITIAL_COUNT_MASK 0x1f +#define OUT_REG_INITIAL_COUNT_MASK_SFT (0x1f << 0) +#define OUT_REG_INITIAL_POINT_SFT 5 +#define OUT_REG_INITIAL_POINT_MASK 0x1f +#define OUT_REG_INITIAL_POINT_MASK_SFT (0x1f << 5) +#define OUT_REG_LRCK_AUTO_OFF_SFT 10 +#define OUT_REG_LRCK_AUTO_OFF_MASK 0x1 +#define OUT_REG_LRCK_AUTO_OFF_MASK_SFT (0x1 << 10) +#define OUT_REG_BCK_AUTO_OFF_SFT 11 +#define OUT_REG_BCK_AUTO_OFF_MASK 0x1 +#define OUT_REG_BCK_AUTO_OFF_MASK_SFT (0x1 << 11) +#define OUT_REG_INITIAL_LRCK_SFT 13 +#define OUT_REG_INITIAL_LRCK_MASK 0x1 +#define OUT_REG_INITIAL_LRCK_MASK_SFT (0x1 << 13) +#define OUT_REG_NO_ALIGN_1X_EN_SFT 14 +#define OUT_REG_NO_ALIGN_1X_EN_MASK 0x1 +#define OUT_REG_NO_ALIGN_1X_EN_MASK_SFT (0x1 << 14) +#define OUT_REG_LRCK_RESET_SFT 15 +#define OUT_REG_LRCK_RESET_MASK 0x1 +#define OUT_REG_LRCK_RESET_MASK_SFT (0x1 << 15) +#define OUT_PINMUX_MCLK_CTRL_OE_SFT 16 +#define OUT_PINMUX_MCLK_CTRL_OE_MASK 0x1 +#define OUT_PINMUX_MCLK_CTRL_OE_MASK_SFT (0x1 << 16) +#define OUT_REG_OUTPUT_CR_EN_SFT 18 +#define OUT_REG_OUTPUT_CR_EN_MASK 0x1 +#define OUT_REG_OUTPUT_CR_EN_MASK_SFT (0x1 << 18) +#define OUT_REG_LRCK_WIDTH_SFT 19 +#define OUT_REG_LRCK_WIDTH_MASK 0x3ff +#define OUT_REG_LRCK_WIDTH_MASK_SFT (0x3ff << 19) +#define OUT_REG_LRCK_AUTO_MODE_SFT 29 +#define OUT_REG_LRCK_AUTO_MODE_MASK 0x1 +#define OUT_REG_LRCK_AUTO_MODE_MASK_SFT (0x1 << 29) +#define OUT_REG_DIRECT_INPUT_MASTER_BCK_SFT 30 +#define OUT_REG_DIRECT_INPUT_MASTER_BCK_MASK 0x1 +#define OUT_REG_DIRECT_INPUT_MASTER_BCK_MASK_SFT (0x1 << 30) +#define OUT_REG_16B_COMPACT_MODE_SFT 31 +#define OUT_REG_16B_COMPACT_MODE_MASK 0x1 +#define OUT_REG_16B_COMPACT_MODE_MASK_SFT (0x1 << 31) + +/* ETDM_OUT0_CON2 */ +/* ETDM_OUT1_CON2 */ +/* ETDM_OUT4_CON2 */ +#define OUT_REG_IN2LATCH_TIME_SFT 0 +#define OUT_REG_IN2LATCH_TIME_MASK 0x1f +#define OUT_REG_IN2LATCH_TIME_MASK_SFT (0x1f << 0) +#define OUT_REG_MASK_NUM_SFT 5 +#define OUT_REG_MASK_NUM_MASK 0x1f +#define OUT_REG_MASK_NUM_MASK_SFT (0x1f << 5) +#define OUT_REG_MASK_AUTO_SFT 10 +#define OUT_REG_MASK_AUTO_MASK 0x1 +#define OUT_REG_MASK_AUTO_MASK_SFT (0x1 << 10) +#define OUT_REG_SDATA_SHIFT_SFT 11 +#define OUT_REG_SDATA_SHIFT_MASK 0x3 +#define OUT_REG_SDATA_SHIFT_MASK_SFT (0x3 << 11) +#define OUT_REG_ALMOST_END_BIT_COUNT_SFT 13 +#define OUT_REG_ALMOST_END_BIT_COUNT_MASK 0x1f +#define OUT_REG_ALMOST_END_BIT_COUNT_MASK_SFT (0x1f << 13) +#define OUT_REG_SDATA_CON_SFT 18 +#define OUT_REG_SDATA_CON_MASK 0x3 +#define OUT_REG_SDATA_CON_MASK_SFT (0x3 << 18) +#define OUT_REG_REDUNDANT_0_SFT 20 +#define OUT_REG_REDUNDANT_0_MASK 0x1 +#define OUT_REG_REDUNDANT_0_MASK_SFT (0x1 << 20) +#define OUT_REG_SDATA_AUTO_OFF_SFT 21 +#define OUT_REG_SDATA_AUTO_OFF_MASK 0x1 +#define OUT_REG_SDATA_AUTO_OFF_MASK_SFT (0x1 << 21) +#define OUT_REG_BCK_OFF_TIME_SFT 22 +#define OUT_REG_BCK_OFF_TIME_MASK 0x3 +#define OUT_REG_BCK_OFF_TIME_MASK_SFT (0x3 << 22) +#define OUT_REG_MONITOR_SEL_SFT 24 +#define OUT_REG_MONITOR_SEL_MASK 0x3 +#define OUT_REG_MONITOR_SEL_MASK_SFT (0x3 << 24) +#define OUT_REG_SHIFT_AUTO_SFT 26 +#define OUT_REG_SHIFT_AUTO_MASK 0x1 +#define OUT_REG_SHIFT_AUTO_MASK_SFT (0x1 << 26) +#define OUT_REG_SDATA_DELAY_0P5T_EN_SFT 27 +#define OUT_REG_SDATA_DELAY_0P5T_EN_MASK 0x1 +#define OUT_REG_SDATA_DELAY_0P5T_EN_MASK_SFT (0x1 << 27) +#define OUT_REG_SDATA_DELAY_BCK_INV_SFT 28 +#define OUT_REG_SDATA_DELAY_BCK_INV_MASK 0x1 +#define OUT_REG_SDATA_DELAY_BCK_INV_MASK_SFT (0x1 << 28) +#define OUT_REG_LRCK_DELAY_0P5T_EN_SFT 29 +#define OUT_REG_LRCK_DELAY_0P5T_EN_MASK 0x1 +#define OUT_REG_LRCK_DELAY_0P5T_EN_MASK_SFT (0x1 << 29) +#define OUT_REG_LRCK_DELAY_BCK_INV_SFT 30 +#define OUT_REG_LRCK_DELAY_BCK_INV_MASK 0x1 +#define OUT_REG_LRCK_DELAY_BCK_INV_MASK_SFT (0x1 << 30) +#define OUT_REG_OFF_CR_EN_SFT 31 +#define OUT_REG_OFF_CR_EN_MASK 0x1 +#define OUT_REG_OFF_CR_EN_MASK_SFT (0x1 << 31) + +/* ETDM_OUT0_CON3 */ +/* ETDM_OUT1_CON3 */ +/* ETDM_OUT4_CON3 */ +#define OUT_REG_START_CH_PAIR0_SFT 0 +#define OUT_REG_START_CH_PAIR0_MASK 0xf +#define OUT_REG_START_CH_PAIR0_MASK_SFT (0xf << 0) +#define OUT_REG_START_CH_PAIR1_SFT 4 +#define OUT_REG_START_CH_PAIR1_MASK 0xf +#define OUT_REG_START_CH_PAIR1_MASK_SFT (0xf << 4) +#define OUT_REG_START_CH_PAIR2_SFT 8 +#define OUT_REG_START_CH_PAIR2_MASK 0xf +#define OUT_REG_START_CH_PAIR2_MASK_SFT (0xf << 8) +#define OUT_REG_START_CH_PAIR3_SFT 12 +#define OUT_REG_START_CH_PAIR3_MASK 0xf +#define OUT_REG_START_CH_PAIR3_MASK_SFT (0xf << 12) +#define OUT_REG_START_CH_PAIR4_SFT 16 +#define OUT_REG_START_CH_PAIR4_MASK 0xf +#define OUT_REG_START_CH_PAIR4_MASK_SFT (0xf << 16) +#define OUT_REG_START_CH_PAIR5_SFT 20 +#define OUT_REG_START_CH_PAIR5_MASK 0xf +#define OUT_REG_START_CH_PAIR5_MASK_SFT (0xf << 20) +#define OUT_REG_START_CH_PAIR6_SFT 24 +#define OUT_REG_START_CH_PAIR6_MASK 0xf +#define OUT_REG_START_CH_PAIR6_MASK_SFT (0xf << 24) +#define OUT_REG_START_CH_PAIR7_SFT 28 +#define OUT_REG_START_CH_PAIR7_MASK 0xf +#define OUT_REG_START_CH_PAIR7_MASK_SFT (0xf << 28) + +/* ETDM_OUT0_CON4 */ +/* ETDM_OUT1_CON4 */ +/* ETDM_OUT4_CON4 */ +#define OUT_REG_FS_TIMING_SEL_SFT 0 +#define OUT_REG_FS_TIMING_SEL_MASK 0x1f +#define OUT_REG_FS_TIMING_SEL_MASK_SFT (0x1f << 0) +#define OUT_REG_CLOCK_SOURCE_SEL_SFT 6 +#define OUT_REG_CLOCK_SOURCE_SEL_MASK 0x7 +#define OUT_REG_CLOCK_SOURCE_SEL_MASK_SFT (0x7 << 6) +#define OUT_REG_CK_EN_SEL_AUTO_SFT 10 +#define OUT_REG_CK_EN_SEL_AUTO_MASK 0x1 +#define OUT_REG_CK_EN_SEL_AUTO_MASK_SFT (0x1 << 10) +#define OUT_REG_ASYNC_RESET_SFT 11 +#define OUT_REG_ASYNC_RESET_MASK 0x1 +#define OUT_REG_ASYNC_RESET_MASK_SFT (0x1 << 11) +#define OUT_REG_CK_EN_SEL_MANUAL_SFT 14 +#define OUT_REG_CK_EN_SEL_MANUAL_MASK 0x3ff +#define OUT_REG_CK_EN_SEL_MANUAL_MASK_SFT (0x3ff << 14) +#define OUT_REG_RELATCH_EN_SEL_SFT 24 +#define OUT_REG_RELATCH_EN_SEL_MASK 0x1f +#define OUT_REG_RELATCH_EN_SEL_MASK_SFT (0x1f << 24) +#define OUT_REG_WAIT_LAST_SAMPLE_SFT 30 +#define OUT_REG_WAIT_LAST_SAMPLE_MASK 0x1 +#define OUT_REG_WAIT_LAST_SAMPLE_MASK_SFT (0x1 << 30) +#define OUT_REG_ALWAYS_OPEN_1X_EN_SFT 31 +#define OUT_REG_ALWAYS_OPEN_1X_EN_MASK 0x1 +#define OUT_REG_ALWAYS_OPEN_1X_EN_MASK_SFT (0x1 << 31) + +/* ETDM_OUT0_CON5 */ +/* ETDM_OUT1_CON5 */ +/* ETDM_OUT4_CON5 */ +#define OUT_REG_REPACK_BITNUM_SFT 0 +#define OUT_REG_REPACK_BITNUM_MASK 0x3 +#define OUT_REG_REPACK_BITNUM_MASK_SFT (0x3 << 0) +#define OUT_REG_REPACK_CHNUM_SFT 2 +#define OUT_REG_REPACK_CHNUM_MASK 0xf +#define OUT_REG_REPACK_CHNUM_MASK_SFT (0xf << 2) +#define OUT_REG_SLAVE_BCK_INV_SFT 7 +#define OUT_REG_SLAVE_BCK_INV_MASK 0x1 +#define OUT_REG_SLAVE_BCK_INV_MASK_SFT (0x1 << 7) +#define OUT_REG_SLAVE_LRCK_INV_SFT 8 +#define OUT_REG_SLAVE_LRCK_INV_MASK 0x1 +#define OUT_REG_SLAVE_LRCK_INV_MASK_SFT (0x1 << 8) +#define OUT_REG_MASTER_BCK_INV_SFT 9 +#define OUT_REG_MASTER_BCK_INV_MASK 0x1 +#define OUT_REG_MASTER_BCK_INV_MASK_SFT (0x1 << 9) +#define OUT_REG_MASTER_WS_INV_SFT 10 +#define OUT_REG_MASTER_WS_INV_MASK 0x1 +#define OUT_REG_MASTER_WS_INV_MASK_SFT (0x1 << 10) +#define OUT_REG_REPACK_24B_MSB_ALIGN_SFT 11 +#define OUT_REG_REPACK_24B_MSB_ALIGN_MASK 0x1 +#define OUT_REG_REPACK_24B_MSB_ALIGN_MASK_SFT (0x1 << 11) +#define OUT_REG_LR_SWAP_SFT 16 +#define OUT_REG_LR_SWAP_MASK 0xffff +#define OUT_REG_LR_SWAP_MASK_SFT (0xffff << 16) + +/* ETDM_OUT0_CON6 */ +/* ETDM_OUT1_CON6 */ +/* ETDM_OUT4_CON6 */ +#define OUT_LCH_DATA_REG_SFT 0 +#define OUT_LCH_DATA_REG_MASK 0xffffffff +#define OUT_LCH_DATA_REG_MASK_SFT (0xffffffff << 0) + +/* ETDM_OUT0_CON7 */ +/* ETDM_OUT1_CON7 */ +/* ETDM_OUT4_CON7 */ +#define OUT_RCH_DATA_REG_SFT 0 +#define OUT_RCH_DATA_REG_MASK 0xffffffff +#define OUT_RCH_DATA_REG_MASK_SFT (0xffffffff << 0) + +/* ETDM_OUT0_CON8 */ +/* ETDM_OUT1_CON8 */ +/* ETDM_OUT4_CON8 */ +#define OUT_REG_START_CH_PAIR8_SFT 0 +#define OUT_REG_START_CH_PAIR8_MASK 0xf +#define OUT_REG_START_CH_PAIR8_MASK_SFT (0xf << 0) +#define OUT_REG_START_CH_PAIR9_SFT 4 +#define OUT_REG_START_CH_PAIR9_MASK 0xf +#define OUT_REG_START_CH_PAIR9_MASK_SFT (0xf << 4) +#define OUT_REG_START_CH_PAIR10_SFT 8 +#define OUT_REG_START_CH_PAIR10_MASK 0xf +#define OUT_REG_START_CH_PAIR10_MASK_SFT (0xf << 8) +#define OUT_REG_START_CH_PAIR11_SFT 12 +#define OUT_REG_START_CH_PAIR11_MASK 0xf +#define OUT_REG_START_CH_PAIR11_MASK_SFT (0xf << 12) +#define OUT_REG_START_CH_PAIR12_SFT 16 +#define OUT_REG_START_CH_PAIR12_MASK 0xf +#define OUT_REG_START_CH_PAIR12_MASK_SFT (0xf << 16) +#define OUT_REG_START_CH_PAIR13_SFT 20 +#define OUT_REG_START_CH_PAIR13_MASK 0xf +#define OUT_REG_START_CH_PAIR13_MASK_SFT (0xf << 20) +#define OUT_REG_START_CH_PAIR14_SFT 24 +#define OUT_REG_START_CH_PAIR14_MASK 0xf +#define OUT_REG_START_CH_PAIR14_MASK_SFT (0xf << 24) +#define OUT_REG_START_CH_PAIR15_SFT 28 +#define OUT_REG_START_CH_PAIR15_MASK 0xf +#define OUT_REG_START_CH_PAIR15_MASK_SFT (0xf << 28) + +/* ETDM_OUT0_CON9 */ +/* ETDM_OUT1_CON9 */ +/* ETDM_OUT4_CON9 */ +#define OUT_REG_AFIFO_THRESHOLD_SFT 29 +#define OUT_REG_AFIFO_THRESHOLD_MASK 0x3 +#define OUT_REG_AFIFO_THRESHOLD_MASK_SFT (0x3 << 29) +#define OUT_REG_AFIFO_SW_RESET_SFT 15 +#define OUT_REG_AFIFO_SW_RESET_MASK 0x1 +#define OUT_REG_AFIFO_SW_RESET_MASK_SFT (0x1 << 15) +#define OUT_REG_AFIFO_RESET_SEL_SFT 14 +#define OUT_REG_AFIFO_RESET_SEL_MASK 0x1 +#define OUT_REG_AFIFO_RESET_SEL_MASK_SFT (0x1 << 14) +#define OUT_REG_AFIFO_AUTO_RESET_DIS_SFT 9 +#define OUT_REG_AFIFO_AUTO_RESET_DIS_MASK 0x1 +#define OUT_REG_AFIFO_AUTO_RESET_DIS_MASK_SFT (0x1 << 9) +#define OUT_REG_ETDM_USE_AFIFO_SFT 8 +#define OUT_REG_ETDM_USE_AFIFO_MASK 0x1 +#define OUT_REG_ETDM_USE_AFIFO_MASK_SFT (0x1 << 8) +#define OUT_REG_AFIFO_CLOCK_DOMAIN_SEL_SFT 5 +#define OUT_REG_AFIFO_CLOCK_DOMAIN_SEL_MASK 0x7 +#define OUT_REG_AFIFO_CLOCK_DOMAIN_SEL_MASK_SFT (0x7 << 5) +#define OUT_REG_AFIFO_MODE_SFT 0 +#define OUT_REG_AFIFO_MODE_MASK 0x1f +#define OUT_REG_AFIFO_MODE_MASK_SFT (0x1f << 0) + +/* ETDM_OUT0_MON */ +/* ETDM_OUT1_MON */ +/* ETDM_OUT4_MON */ +#define LRCK_INV_SFT 30 +#define LRCK_INV_MASK 0x1 +#define LRCK_INV_MASK_SFT (0x1 << 30) +#define EN_SYNC_OUT_SFT 29 +#define EN_SYNC_OUT_MASK 0x1 +#define EN_SYNC_OUT_MASK_SFT (0x1 << 29) +#define HOPPING_EN_SYNC_OUT_PRE_SFT 28 +#define HOPPING_EN_SYNC_OUT_PRE_MASK 0x1 +#define HOPPING_EN_SYNC_OUT_PRE_MASK_SFT (0x1 << 28) +#define ETDM_2X_CK_EN_SFT 25 +#define ETDM_2X_CK_EN_MASK 0x1 +#define ETDM_2X_CK_EN_MASK_SFT (0x1 << 25) +#define ETDM_1X_CK_EN_SFT 24 +#define ETDM_1X_CK_EN_MASK 0x1 +#define ETDM_1X_CK_EN_MASK_SFT (0x1 << 24) +#define SDATA0_SFT 23 +#define SDATA0_MASK 0x1 +#define SDATA0_MASK_SFT (0x1 << 23) +#define CURRENT_STATUS_SFT 21 +#define CURRENT_STATUS_MASK 0x3 +#define CURRENT_STATUS_MASK_SFT (0x3 << 21) +#define BIT_POINT_SFT 16 +#define BIT_POINT_MASK 0x1f +#define BIT_POINT_MASK_SFT (0x1f << 16) +#define BIT_CH_COUNT_SFT 10 +#define BIT_CH_COUNT_MASK 0x3f +#define BIT_CH_COUNT_MASK_SFT (0x3f << 10) +#define BIT_COUNT_SFT 5 +#define BIT_COUNT_MASK 0x1f +#define BIT_COUNT_MASK_SFT (0x1f << 5) +#define CH_COUNT_SFT 0 +#define CH_COUNT_MASK 0x1f +#define CH_COUNT_MASK_SFT (0x1f << 0) + +/* ETDM_0_3_COWORK_CON0 */ +#define ETDM_OUT0_DATA_SEL_SFT 0 +#define ETDM_OUT0_DATA_SEL_MASK 0xf +#define ETDM_OUT0_DATA_SEL_MASK_SFT (0xf << 0) +#define ETDM_OUT0_SYNC_SEL_SFT 4 +#define ETDM_OUT0_SYNC_SEL_MASK 0xf +#define ETDM_OUT0_SYNC_SEL_MASK_SFT (0xf << 4) +#define ETDM_OUT0_SLAVE_SEL_SFT 8 +#define ETDM_OUT0_SLAVE_SEL_MASK 0xf +#define ETDM_OUT0_SLAVE_SEL_MASK_SFT (0xf << 8) +#define ETDM_OUT1_DATA_SEL_SFT 12 +#define ETDM_OUT1_DATA_SEL_MASK 0xf +#define ETDM_OUT1_DATA_SEL_MASK_SFT (0xf << 12) +#define ETDM_OUT1_SYNC_SEL_SFT 16 +#define ETDM_OUT1_SYNC_SEL_MASK 0xf +#define ETDM_OUT1_SYNC_SEL_MASK_SFT (0xf << 16) +#define ETDM_OUT1_SLAVE_SEL_SFT 20 +#define ETDM_OUT1_SLAVE_SEL_MASK 0xf +#define ETDM_OUT1_SLAVE_SEL_MASK_SFT (0xf << 20) +#define ETDM_IN0_SLAVE_SEL_SFT 24 +#define ETDM_IN0_SLAVE_SEL_MASK 0xf +#define ETDM_IN0_SLAVE_SEL_MASK_SFT (0xf << 24) +#define ETDM_IN0_SYNC_SEL_SFT 28 +#define ETDM_IN0_SYNC_SEL_MASK 0xf +#define ETDM_IN0_SYNC_SEL_MASK_SFT (0xf << 28) + +/* ETDM_0_3_COWORK_CON1 */ +#define ETDM_IN0_SDATA0_SEL_SFT 0 +#define ETDM_IN0_SDATA0_SEL_MASK 0xf +#define ETDM_IN0_SDATA0_SEL_MASK_SFT (0xf << 0) +#define ETDM_IN0_SDATA1_15_SEL_SFT 4 +#define ETDM_IN0_SDATA1_15_SEL_MASK 0xf +#define ETDM_IN0_SDATA1_15_SEL_MASK_SFT (0xf << 4) +#define ETDM_IN1_SLAVE_SEL_SFT 8 +#define ETDM_IN1_SLAVE_SEL_MASK 0xf +#define ETDM_IN1_SLAVE_SEL_MASK_SFT (0xf << 8) +#define ETDM_IN1_SYNC_SEL_SFT 12 +#define ETDM_IN1_SYNC_SEL_MASK 0xf +#define ETDM_IN1_SYNC_SEL_MASK_SFT (0xf << 12) +#define ETDM_IN1_SDATA0_SEL_SFT 16 +#define ETDM_IN1_SDATA0_SEL_MASK 0xf +#define ETDM_IN1_SDATA0_SEL_MASK_SFT (0xf << 16) +#define ETDM_IN1_SDATA1_15_SEL_SFT 20 +#define ETDM_IN1_SDATA1_15_SEL_MASK 0xf +#define ETDM_IN1_SDATA1_15_SEL_MASK_SFT (0xf << 20) + +/* ETDM_4_7_COWORK_CON0 */ +#define ETDM_OUT4_DATA_SEL_SFT 0 +#define ETDM_OUT4_DATA_SEL_MASK 0xf +#define ETDM_OUT4_DATA_SEL_MASK_SFT (0xf << 0) +#define ETDM_OUT4_SYNC_SEL_SFT 4 +#define ETDM_OUT4_SYNC_SEL_MASK 0xf +#define ETDM_OUT4_SYNC_SEL_MASK_SFT (0xf << 4) +#define ETDM_OUT4_SLAVE_SEL_SFT 8 +#define ETDM_OUT4_SLAVE_SEL_MASK 0xf +#define ETDM_OUT4_SLAVE_SEL_MASK_SFT (0xf << 8) + +/* AFE_DPTX_CON */ +#define DPTX_CHANNEL_ENABLE_SFT 8 +#define DPTX_CHANNEL_ENABLE_MASK 0xff +#define DPTX_CHANNEL_ENABLE_MASK_SFT (0xff << 8) +#define DPTX_REGISTER_MONITOR_SELECT_SFT 3 +#define DPTX_REGISTER_MONITOR_SELECT_MASK 0xf +#define DPTX_REGISTER_MONITOR_SELECT_MASK_SFT (0xf << 3) +#define DPTX_16BIT_SFT 2 +#define DPTX_16BIT_MASK 0x1 +#define DPTX_16BIT_MASK_SFT (0x1 << 2) +#define DPTX_CHANNEL_NUMBER_SFT 1 +#define DPTX_CHANNEL_NUMBER_MASK 0x1 +#define DPTX_CHANNEL_NUMBER_MASK_SFT (0x1 << 1) +#define DPTX_ON_SFT 0 +#define DPTX_ON_MASK 0x1 +#define DPTX_ON_MASK_SFT (0x1 << 0) + +/* AFE_DPTX_MON */ +#define AFE_DPTX_MON0_SFT 0 +#define AFE_DPTX_MON0_MASK 0xffffffff +#define AFE_DPTX_MON0_MASK_SFT (0xffffffff << 0) + +/* AFE_TDM_CON1 */ +#define TDM_EN_SFT 0 +#define TDM_EN_MASK 0x1 +#define TDM_EN_MASK_SFT (0x1 << 0) +#define BCK_INVERSE_SFT 1 +#define BCK_INVERSE_MASK 0x1 +#define BCK_INVERSE_MASK_SFT (0x1 << 1) +#define LRCK_INVERSE_SFT 2 +#define LRCK_INVERSE_MASK 0x1 +#define LRCK_INVERSE_MASK_SFT (0x1 << 2) +#define DELAY_DATA_SFT 3 +#define DELAY_DATA_MASK 0x1 +#define DELAY_DATA_MASK_SFT (0x1 << 3) +#define LEFT_ALIGN_SFT 4 +#define LEFT_ALIGN_MASK 0x1 +#define LEFT_ALIGN_MASK_SFT (0x1 << 4) +#define TDM_LRCK_D0P5T_SFT 5 +#define TDM_LRCK_D0P5T_MASK 0x1 +#define TDM_LRCK_D0P5T_MASK_SFT (0x1 << 5) +#define TDM_SDATA_D0P5T_SFT 6 +#define TDM_SDATA_D0P5T_MASK 0x1 +#define TDM_SDATA_D0P5T_MASK_SFT (0x1 << 6) +#define WLEN_SFT 8 +#define WLEN_MASK 0x3 +#define WLEN_MASK_SFT (0x3 << 8) +#define CHANNEL_NUM_SFT 10 +#define CHANNEL_NUM_MASK 0x3 +#define CHANNEL_NUM_MASK_SFT (0x3 << 10) +#define CHANNEL_BCK_CYCLES_SFT 12 +#define CHANNEL_BCK_CYCLES_MASK 0x3 +#define CHANNEL_BCK_CYCLES_MASK_SFT (0x3 << 12) +#define HDMI_CLK_INV_SEL_SFT 15 +#define HDMI_CLK_INV_SEL_MASK 0x1 +#define HDMI_CLK_INV_SEL_MASK_SFT (0x1 << 15) +#define DAC_BIT_NUM_SFT 16 +#define DAC_BIT_NUM_MASK 0x1f +#define DAC_BIT_NUM_MASK_SFT (0x1f << 16) +#define LRCK_TDM_WIDTH_SFT 24 +#define LRCK_TDM_WIDTH_MASK 0xff +#define LRCK_TDM_WIDTH_MASK_SFT (0xff << 24) + +/* AFE_TDM_CON2 */ +#define ST_CH_PAIR_SOUT0_SFT 0 +#define ST_CH_PAIR_SOUT0_MASK 0x7 +#define ST_CH_PAIR_SOUT0_MASK_SFT (0x7 << 0) +#define ST_CH_PAIR_SOUT1_SFT 4 +#define ST_CH_PAIR_SOUT1_MASK 0x7 +#define ST_CH_PAIR_SOUT1_MASK_SFT (0x7 << 4) +#define ST_CH_PAIR_SOUT2_SFT 8 +#define ST_CH_PAIR_SOUT2_MASK 0x7 +#define ST_CH_PAIR_SOUT2_MASK_SFT (0x7 << 8) +#define ST_CH_PAIR_SOUT3_SFT 12 +#define ST_CH_PAIR_SOUT3_MASK 0x7 +#define ST_CH_PAIR_SOUT3_MASK_SFT (0x7 << 12) +#define TDM_FIX_VALUE_SEL_SFT 16 +#define TDM_FIX_VALUE_SEL_MASK 0x1 +#define TDM_FIX_VALUE_SEL_MASK_SFT (0x1 << 16) +#define TDM_I2S_LOOPBACK_SFT 20 +#define TDM_I2S_LOOPBACK_MASK 0x1 +#define TDM_I2S_LOOPBACK_MASK_SFT (0x1 << 20) +#define TDM_I2S_LOOPBACK_CH_SFT 21 +#define TDM_I2S_LOOPBACK_CH_MASK 0x3 +#define TDM_I2S_LOOPBACK_CH_MASK_SFT (0x3 << 21) +#define TDM_USE_SINEGEN_INPUT_SFT 23 +#define TDM_USE_SINEGEN_INPUT_MASK 0x1 +#define TDM_USE_SINEGEN_INPUT_MASK_SFT (0x1 << 23) +#define TDM_FIX_VALUE_SFT 24 +#define TDM_FIX_VALUE_MASK 0xff +#define TDM_FIX_VALUE_MASK_SFT (0xff << 24) + +/* AFE_TDM_CON3 */ +#define TDM_OUT_SEL_DOMAIN_SFT 29 +#define TDM_OUT_SEL_DOMAIN_MASK 0x7 +#define TDM_OUT_SEL_DOMAIN_MASK_SFT (0x7 << 29) +#define TDM_OUT_SEL_FS_SFT 24 +#define TDM_OUT_SEL_FS_MASK 0x1f +#define TDM_OUT_SEL_FS_MASK_SFT (0x1f << 24) +#define TDM_OUT_MON_SEL_SFT 3 +#define TDM_OUT_MON_SEL_MASK 0x1 +#define TDM_OUT_MON_SEL_MASK_SFT (0x1 << 3) +#define RG_TDM_OUT_ASYNC_FIFO_SOFT_RST_EN_SFT 2 +#define RG_TDM_OUT_ASYNC_FIFO_SOFT_RST_EN_MASK 0x1 +#define RG_TDM_OUT_ASYNC_FIFO_SOFT_RST_EN_MASK_SFT (0x1 << 2) +#define RG_TDM_OUT_ASYNC_FIFO_SOFT_RST_SFT 1 +#define RG_TDM_OUT_ASYNC_FIFO_SOFT_RST_MASK 0x1 +#define RG_TDM_OUT_ASYNC_FIFO_SOFT_RST_MASK_SFT (0x1 << 1) +#define TDM_UPDATE_EN_SEL_SFT 0 +#define TDM_UPDATE_EN_SEL_MASK 0x1 +#define TDM_UPDATE_EN_SEL_MASK_SFT (0x1 << 0) + +/* AFE_TDM_OUT_MON */ +#define AFE_TDM_OUT_MON_SFT 0 +#define AFE_TDM_OUT_MON_MASK 0xffffffff +#define AFE_TDM_OUT_MON_MASK_SFT (0xffffffff << 0) + +/* AFE_HDMI_CONN0 */ +#define HDMI_O_7_SFT 21 +#define HDMI_O_7_MASK 0x7 +#define HDMI_O_7_MASK_SFT (0x7 << 21) +#define HDMI_O_6_SFT 18 +#define HDMI_O_6_MASK 0x7 +#define HDMI_O_6_MASK_SFT (0x7 << 18) +#define HDMI_O_5_SFT 15 +#define HDMI_O_5_MASK 0x7 +#define HDMI_O_5_MASK_SFT (0x7 << 15) +#define HDMI_O_4_SFT 12 +#define HDMI_O_4_MASK 0x7 +#define HDMI_O_4_MASK_SFT (0x7 << 12) +#define HDMI_O_3_SFT 9 +#define HDMI_O_3_MASK 0x7 +#define HDMI_O_3_MASK_SFT (0x7 << 9) +#define HDMI_O_2_SFT 6 +#define HDMI_O_2_MASK 0x7 +#define HDMI_O_2_MASK_SFT (0x7 << 6) +#define HDMI_O_1_SFT 3 +#define HDMI_O_1_MASK 0x7 +#define HDMI_O_1_MASK_SFT (0x7 << 3) +#define HDMI_O_0_SFT 0 +#define HDMI_O_0_MASK 0x7 +#define HDMI_O_0_MASK_SFT (0x7 << 0) + +/* AFE_TDM_TOP_IP_VERSION */ +#define AFE_TDM_TOP_IP_VERSION_SFT 0 +#define AFE_TDM_TOP_IP_VERSION_MASK 0xffffffff +#define AFE_TDM_TOP_IP_VERSION_MASK_SFT (0xffffffff << 0) + +/* AFE_HDMI_OUT_BASE_MSB */ +#define AFE_HDMI_OUT_BASE_MSB_SFT 0 +#define AFE_HDMI_OUT_BASE_MSB_MASK 0x1ff +#define AFE_HDMI_OUT_BASE_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_HDMI_OUT_BASE */ +#define AFE_HDMI_OUT_BASE_SFT 4 +#define AFE_HDMI_OUT_BASE_MASK 0xfffffff +#define AFE_HDMI_OUT_BASE_MASK_SFT (0xfffffff << 4) + +/* AFE_HDMI_OUT_CUR_MSB */ +#define AFE_HDMI_OUT_CUR_MSB_SFT 0 +#define AFE_HDMI_OUT_CUR_MSB_MASK 0x1ff +#define AFE_HDMI_OUT_CUR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_HDMI_OUT_CUR */ +#define AFE_HDMI_OUT_CUR_SFT 0 +#define AFE_HDMI_OUT_CUR_MASK 0xffffffff +#define AFE_HDMI_OUT_CUR_MASK_SFT (0xffffffff << 0) + +/* AFE_HDMI_OUT_END_MSB */ +#define AFE_HDMI_OUT_END_MSB_SFT 0 +#define AFE_HDMI_OUT_END_MSB_MASK 0x1ff +#define AFE_HDMI_OUT_END_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_HDMI_OUT_END */ +#define AFE_HDMI_OUT_END_SFT 4 +#define AFE_HDMI_OUT_END_MASK 0xfffffff +#define AFE_HDMI_OUT_END_MASK_SFT (0xfffffff << 4) +#define AFE_HDMI_OUT_END_LSB_SFT 0 +#define AFE_HDMI_OUT_END_LSB_MASK 0xf +#define AFE_HDMI_OUT_END_LSB_MASK_SFT (0xf << 0) + +/* AFE_HDMI_OUT_CON0 */ +#define HDMI_OUT_ON_SFT 28 +#define HDMI_OUT_ON_MASK 0x1 +#define HDMI_OUT_ON_MASK_SFT (0x1 << 28) +#define HDMI_CH_NUM_SFT 24 +#define HDMI_CH_NUM_MASK 0xf +#define HDMI_CH_NUM_MASK_SFT (0xf << 24) +#define HDMI_OUT_ONE_HEART_SEL_SFT 22 +#define HDMI_OUT_ONE_HEART_SEL_MASK 0x3 +#define HDMI_OUT_ONE_HEART_SEL_MASK_SFT (0x3 << 22) +#define HDMI_OUT_MINLEN_SFT 20 +#define HDMI_OUT_MINLEN_MASK 0x3 +#define HDMI_OUT_MINLEN_MASK_SFT (0x3 << 20) +#define HDMI_OUT_MAXLEN_SFT 16 +#define HDMI_OUT_MAXLEN_MASK 0x3 +#define HDMI_OUT_MAXLEN_MASK_SFT (0x3 << 16) +#define HDMI_OUT_SW_CLEAR_BUF_EMPTY_SFT 15 +#define HDMI_OUT_SW_CLEAR_BUF_EMPTY_MASK 0x1 +#define HDMI_OUT_SW_CLEAR_BUF_EMPTY_MASK_SFT (0x1 << 15) +#define HDMI_OUT_PBUF_SIZE_SFT 12 +#define HDMI_OUT_PBUF_SIZE_MASK 0x3 +#define HDMI_OUT_PBUF_SIZE_MASK_SFT (0x3 << 12) +#define HDMI_OUT_SW_CLEAR_HDMI_BUF_EMPTY_SFT 7 +#define HDMI_OUT_SW_CLEAR_HDMI_BUF_EMPTY_MASK 0x1 +#define HDMI_OUT_SW_CLEAR_HDMI_BUF_EMPTY_MASK_SFT (0x1 << 7) +#define HDMI_OUT_NORMAL_MODE_SFT 5 +#define HDMI_OUT_NORMAL_MODE_MASK 0x1 +#define HDMI_OUT_NORMAL_MODE_MASK_SFT (0x1 << 5) +#define HDMI_OUT_HALIGN_SFT 4 +#define HDMI_OUT_HALIGN_MASK 0x1 +#define HDMI_OUT_HALIGN_MASK_SFT (0x1 << 4) +#define HDMI_OUT_HD_MODE_SFT 0 +#define HDMI_OUT_HD_MODE_MASK 0x3 +#define HDMI_OUT_HD_MODE_MASK_SFT (0x3 << 0) + +/* AFE_CBIP_CFG0 */ +#define CBIP_TOP_SLV_MUX_WAY_EN_SFT 16 +#define CBIP_TOP_SLV_MUX_WAY_EN_MASK 0xffff +#define CBIP_TOP_SLV_MUX_WAY_EN_MASK_SFT (0xffff << 16) +#define RESERVED_04_SFT 15 +#define RESERVED_04_MASK 0x1 +#define RESERVED_04_MASK_SFT (0x1 << 15) +#define CBIP_ASYNC_MST_RG_FIFO_THRE_SFT 13 +#define CBIP_ASYNC_MST_RG_FIFO_THRE_MASK 0x3 +#define CBIP_ASYNC_MST_RG_FIFO_THRE_MASK_SFT (0x3 << 13) +#define CBIP_ASYNC_MST_POSTWRITE_DIS_SFT 12 +#define CBIP_ASYNC_MST_POSTWRITE_DIS_MASK 0x1 +#define CBIP_ASYNC_MST_POSTWRITE_DIS_MASK_SFT (0x1 << 12) +#define RESERVED_03_SFT 11 +#define RESERVED_03_MASK 0x1 +#define RESERVED_03_MASK_SFT (0x1 << 11) +#define CBIP_ASYNC_SLV_RG_FIFO_THRE_SFT 9 +#define CBIP_ASYNC_SLV_RG_FIFO_THRE_MASK 0x3 +#define CBIP_ASYNC_SLV_RG_FIFO_THRE_MASK_SFT (0x3 << 9) +#define CBIP_ASYNC_SLV_POSTWRITE_DIS_SFT 8 +#define CBIP_ASYNC_SLV_POSTWRITE_DIS_MASK 0x1 +#define CBIP_ASYNC_SLV_POSTWRITE_DIS_MASK_SFT (0x1 << 8) +#define AUDIOSYS_BUSY_SFT 7 +#define AUDIOSYS_BUSY_MASK 0x1 +#define AUDIOSYS_BUSY_MASK_SFT (0x1 << 7) +#define CBIP_SLV_DECODER_ERR_FLAG_EN_SFT 6 +#define CBIP_SLV_DECODER_ERR_FLAG_EN_MASK 0x1 +#define CBIP_SLV_DECODER_ERR_FLAG_EN_MASK_SFT (0x1 << 6) +#define CBIP_SLV_DECODER_SLAVE_WAY_EN_SFT 5 +#define CBIP_SLV_DECODER_SLAVE_WAY_EN_MASK 0x1 +#define CBIP_SLV_DECODER_SLAVE_WAY_EN_MASK_SFT (0x1 << 5) +#define APB_R2T_SFT 3 +#define APB_R2T_MASK 0x1 +#define APB_R2T_MASK_SFT (0x1 << 3) +#define APB_W2T_SFT 2 +#define APB_W2T_MASK 0x1 +#define APB_W2T_MASK_SFT (0x1 << 2) +#define AHB_IDLE_EN_INT_SFT 1 +#define AHB_IDLE_EN_INT_MASK 0x1 +#define AHB_IDLE_EN_INT_MASK_SFT (0x1 << 1) +#define AHB_IDLE_EN_EXT_SFT 0 +#define AHB_IDLE_EN_EXT_MASK 0x1 +#define AHB_IDLE_EN_EXT_MASK_SFT (0x1 << 0) + +/* AFE_CBIP_SLV_DECODER_MON0 */ +#define CBIP_SLV_DECODER_ERR_DOMAIN_SFT 4 +#define CBIP_SLV_DECODER_ERR_DOMAIN_MASK 0x1 +#define CBIP_SLV_DECODER_ERR_DOMAIN_MASK_SFT (0x1 << 4) +#define CBIP_SLV_DECODER_ERR_ID_SFT 3 +#define CBIP_SLV_DECODER_ERR_ID_MASK 0x1 +#define CBIP_SLV_DECODER_ERR_ID_MASK_SFT (0x1 << 3) +#define CBIP_SLV_DECODER_ERR_RW_SFT 2 +#define CBIP_SLV_DECODER_ERR_RW_MASK 0x1 +#define CBIP_SLV_DECODER_ERR_RW_MASK_SFT (0x1 << 2) +#define CBIP_SLV_DECODER_ERR_DECERR_SFT 1 +#define CBIP_SLV_DECODER_ERR_DECERR_MASK 0x1 +#define CBIP_SLV_DECODER_ERR_DECERR_MASK_SFT (0x1 << 1) +#define CBIP_SLV_DECODER_CTRL_UPDATE_STATUS_SFT 0 +#define CBIP_SLV_DECODER_CTRL_UPDATE_STATUS_MASK 0x1 +#define CBIP_SLV_DECODER_CTRL_UPDATE_STATUS_MASK_SFT (0x1 << 0) + +/* AFE_CBIP_SLV_DECODER_MON1 */ +#define CBIP_SLV_DECODER_ERR_ADDR_SFT 0 +#define CBIP_SLV_DECODER_ERR_ADDR_MASK 0xffffffff +#define CBIP_SLV_DECODER_ERR_ADDR_MASK_SFT (0xffffffff << 0) + +/* AFE_CBIP_SLV_MUX_MON_CFG */ +#define CBIP_SLV_MUX_ERR_FLAG_EN_SFT 3 +#define CBIP_SLV_MUX_ERR_FLAG_EN_MASK 0x1 +#define CBIP_SLV_MUX_ERR_FLAG_EN_MASK_SFT (0x1 << 3) +#define CBIP_SLV_MUX_REG_SLAVE_WAY_EN_SFT 2 +#define CBIP_SLV_MUX_REG_SLAVE_WAY_EN_MASK 0x1 +#define CBIP_SLV_MUX_REG_SLAVE_WAY_EN_MASK_SFT (0x1 << 2) +#define CBIP_SLV_MUX_REG_LAYER_WAY_EN_SFT 0 +#define CBIP_SLV_MUX_REG_LAYER_WAY_EN_MASK 0x3 +#define CBIP_SLV_MUX_REG_LAYER_WAY_EN_MASK_SFT (0x3 << 0) + +/* AFE_CBIP_SLV_MUX_MON0 */ +#define CBIP_SLV_MUX_ERR_DOMAIN_SFT 8 +#define CBIP_SLV_MUX_ERR_DOMAIN_MASK 0x1 +#define CBIP_SLV_MUX_ERR_DOMAIN_MASK_SFT (0x1 << 8) +#define CBIP_SLV_MUX_ERR_ID_SFT 7 +#define CBIP_SLV_MUX_ERR_ID_MASK 0x1 +#define CBIP_SLV_MUX_ERR_ID_MASK_SFT (0x1 << 7) +#define CBIP_SLV_MUX_ERR_RD_SFT 6 +#define CBIP_SLV_MUX_ERR_RD_MASK 0x1 +#define CBIP_SLV_MUX_ERR_RD_MASK_SFT (0x1 << 6) +#define CBIP_SLV_MUX_ERR_WR_SFT 5 +#define CBIP_SLV_MUX_ERR_WR_MASK 0x1 +#define CBIP_SLV_MUX_ERR_WR_MASK_SFT (0x1 << 5) +#define CBIP_SLV_MUX_ERR_EN_SLV_SFT 4 +#define CBIP_SLV_MUX_ERR_EN_SLV_MASK 0x1 +#define CBIP_SLV_MUX_ERR_EN_SLV_MASK_SFT (0x1 << 4) +#define CBIP_SLV_MUX_ERR_EN_MST_SFT 2 +#define CBIP_SLV_MUX_ERR_EN_MST_MASK 0x3 +#define CBIP_SLV_MUX_ERR_EN_MST_MASK_SFT (0x3 << 2) +#define CBIP_SLV_MUX_CTRL_UPDATE_STATUS_SFT 0 +#define CBIP_SLV_MUX_CTRL_UPDATE_STATUS_MASK 0x3 +#define CBIP_SLV_MUX_CTRL_UPDATE_STATUS_MASK_SFT (0x3 << 0) + +/* AFE_CBIP_SLV_MUX_MON1 */ +#define CBIP_SLV_MUX_ERR_ADDR_SFT 0 +#define CBIP_SLV_MUX_ERR_ADDR_MASK 0xffffffff +#define CBIP_SLV_MUX_ERR_ADDR_MASK_SFT (0xffffffff << 0) + +/* AFE_MEMIF_CON0 */ +#define CPU_COMPACT_MODE_SFT 2 +#define CPU_COMPACT_MODE_MASK 0x1 +#define CPU_COMPACT_MODE_MASK_SFT (0x1 << 2) +#define CPU_HD_ALIGN_SFT 1 +#define CPU_HD_ALIGN_MASK 0x1 +#define CPU_HD_ALIGN_MASK_SFT (0x1 << 1) +#define SYSRAM_SIGN_SFT 0 +#define SYSRAM_SIGN_MASK 0x1 +#define SYSRAM_SIGN_MASK_SFT (0x1 << 0) + +/* AFE_MEMIF_ONE_HEART */ +#define DL_ONE_HEART_ON_2_SFT 2 +#define DL_ONE_HEART_ON_2_MASK 0x1 +#define DL_ONE_HEART_ON_2_MASK_SFT (0x1 << 2) +#define DL_ONE_HEART_ON_1_SFT 1 +#define DL_ONE_HEART_ON_1_MASK 0x1 +#define DL_ONE_HEART_ON_1_MASK_SFT (0x1 << 1) +#define DL_ONE_HEART_ON_0_SFT 0 +#define DL_ONE_HEART_ON_0_MASK 0x1 +#define DL_ONE_HEART_ON_0_MASK_SFT (0x1 << 0) + +/* AFE_DL0_BASE_MSB */ +#define DL0_BASE_ADDR_MSB_SFT 0 +#define DL0_BASE_ADDR_MSB_MASK 0x1ff +#define DL0_BASE_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL0_BASE */ +#define DL0_BASE_ADDR_SFT 4 +#define DL0_BASE_ADDR_MASK 0xfffffff +#define DL0_BASE_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_DL0_CUR_MSB */ +#define DL0_CUR_PTR_MSB_SFT 0 +#define DL0_CUR_PTR_MSB_MASK 0x1ff +#define DL0_CUR_PTR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL0_CUR */ +#define DL0_CUR_PTR_SFT 0 +#define DL0_CUR_PTR_MASK 0xffffffff +#define DL0_CUR_PTR_MASK_SFT (0xffffffff << 0) + +/* AFE_DL0_END_MSB */ +#define DL0_END_ADDR_MSB_SFT 0 +#define DL0_END_ADDR_MSB_MASK 0x1ff +#define DL0_END_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL0_END */ +#define DL0_END_ADDR_SFT 4 +#define DL0_END_ADDR_MASK 0xfffffff +#define DL0_END_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_DL0_RCH_MON */ +#define DL0_RCH_DATA_SFT 0 +#define DL0_RCH_DATA_MASK 0xffffffff +#define DL0_RCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_DL0_LCH_MON */ +#define DL0_LCH_DATA_SFT 0 +#define DL0_LCH_DATA_MASK 0xffffffff +#define DL0_LCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_DL0_CON0 */ +#define DL0_ON_SFT 28 +#define DL0_ON_MASK 0x1 +#define DL0_ON_MASK_SFT (0x1 << 28) +#define DL0_ONE_HEART_SEL_SFT 22 +#define DL0_ONE_HEART_SEL_MASK 0x3 +#define DL0_ONE_HEART_SEL_MASK_SFT (0x3 << 22) +#define DL0_MINLEN_SFT 20 +#define DL0_MINLEN_MASK 0x3 +#define DL0_MINLEN_MASK_SFT (0x3 << 20) +#define DL0_MAXLEN_SFT 16 +#define DL0_MAXLEN_MASK 0x3 +#define DL0_MAXLEN_MASK_SFT (0x3 << 16) +#define DL0_SEL_DOMAIN_SFT 13 +#define DL0_SEL_DOMAIN_MASK 0x7 +#define DL0_SEL_DOMAIN_MASK_SFT (0x7 << 13) +#define DL0_SEL_FS_SFT 8 +#define DL0_SEL_FS_MASK 0x1f +#define DL0_SEL_FS_MASK_SFT (0x1f << 8) +#define DL0_SW_CLEAR_BUF_EMPTY_SFT 7 +#define DL0_SW_CLEAR_BUF_EMPTY_MASK 0x1 +#define DL0_SW_CLEAR_BUF_EMPTY_MASK_SFT (0x1 << 7) +#define DL0_PBUF_SIZE_SFT 5 +#define DL0_PBUF_SIZE_MASK 0x3 +#define DL0_PBUF_SIZE_MASK_SFT (0x3 << 5) +#define DL0_MONO_SFT 4 +#define DL0_MONO_MASK 0x1 +#define DL0_MONO_MASK_SFT (0x1 << 4) +#define DL0_NORMAL_MODE_SFT 3 +#define DL0_NORMAL_MODE_MASK 0x1 +#define DL0_NORMAL_MODE_MASK_SFT (0x1 << 3) +#define DL0_HALIGN_SFT 2 +#define DL0_HALIGN_MASK 0x1 +#define DL0_HALIGN_MASK_SFT (0x1 << 2) +#define DL0_HD_MODE_SFT 0 +#define DL0_HD_MODE_MASK 0x3 +#define DL0_HD_MODE_MASK_SFT (0x3 << 0) + +/* AFE_DL0_MON0 */ +#define RESERVED_01_SFT 20 +#define RESERVED_01_MASK 0xfff +#define RESERVED_01_MASK_SFT (0xfff << 20) +#define MEM_REQ_PENDING_SFT 19 +#define MEM_REQ_PENDING_MASK 0x1 +#define MEM_REQ_PENDING_MASK_SFT (0x1 << 19) +#define BUF_EMPTY_SFT 18 +#define BUF_EMPTY_MASK 0x1 +#define BUF_EMPTY_MASK_SFT (0x1 << 18) +#define ENABLE_SYNC_MEM_SFT 17 +#define ENABLE_SYNC_MEM_MASK 0x1 +#define ENABLE_SYNC_MEM_MASK_SFT (0x1 << 17) +#define ENABLE_SYNC_AGENT_SFT 16 +#define ENABLE_SYNC_AGENT_MASK 0x1 +#define ENABLE_SYNC_AGENT_MASK_SFT (0x1 << 16) +#define RESERVED_02_SFT 6 +#define RESERVED_02_MASK 0x3ff +#define RESERVED_02_MASK_SFT (0x3ff << 6) +#define MEM_ADDR_DIFF_SFT 0 +#define MEM_ADDR_DIFF_MASK 0x3f +#define MEM_ADDR_DIFF_MASK_SFT (0x3f << 0) + +/* AFE_DL1_BASE_MSB */ +#define DL1_BASE_ADDR_MSB_SFT 0 +#define DL1_BASE_ADDR_MSB_MASK 0x1ff +#define DL1_BASE_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL1_BASE */ +#define DL1_BASE_ADDR_SFT 4 +#define DL1_BASE_ADDR_MASK 0xfffffff +#define DL1_BASE_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_DL1_CUR_MSB */ +#define DL1_CUR_PTR_MSB_SFT 0 +#define DL1_CUR_PTR_MSB_MASK 0x1ff +#define DL1_CUR_PTR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL1_CUR */ +#define DL1_CUR_PTR_SFT 0 +#define DL1_CUR_PTR_MASK 0xffffffff +#define DL1_CUR_PTR_MASK_SFT (0xffffffff << 0) + +/* AFE_DL1_END_MSB */ +#define DL1_END_ADDR_MSB_SFT 0 +#define DL1_END_ADDR_MSB_MASK 0x1ff +#define DL1_END_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL1_END */ +#define DL1_END_ADDR_SFT 4 +#define DL1_END_ADDR_MASK 0xfffffff +#define DL1_END_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_DL1_RCH_MON */ +#define DL1_RCH_DATA_SFT 0 +#define DL1_RCH_DATA_MASK 0xffffffff +#define DL1_RCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_DL1_LCH_MON */ +#define DL1_LCH_DATA_SFT 0 +#define DL1_LCH_DATA_MASK 0xffffffff +#define DL1_LCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_DL1_CON0 */ +#define DL1_ON_SFT 28 +#define DL1_ON_MASK 0x1 +#define DL1_ON_MASK_SFT (0x1 << 28) +#define DL1_ONE_HEART_SEL_SFT 22 +#define DL1_ONE_HEART_SEL_MASK 0x3 +#define DL1_ONE_HEART_SEL_MASK_SFT (0x3 << 22) +#define DL1_MINLEN_SFT 20 +#define DL1_MINLEN_MASK 0x3 +#define DL1_MINLEN_MASK_SFT (0x3 << 20) +#define DL1_MAXLEN_SFT 16 +#define DL1_MAXLEN_MASK 0x3 +#define DL1_MAXLEN_MASK_SFT (0x3 << 16) +#define DL1_SEL_DOMAIN_SFT 13 +#define DL1_SEL_DOMAIN_MASK 0x7 +#define DL1_SEL_DOMAIN_MASK_SFT (0x7 << 13) +#define DL1_SEL_FS_SFT 8 +#define DL1_SEL_FS_MASK 0x1f +#define DL1_SEL_FS_MASK_SFT (0x1f << 8) +#define DL1_SW_CLEAR_BUF_EMPTY_SFT 7 +#define DL1_SW_CLEAR_BUF_EMPTY_MASK 0x1 +#define DL1_SW_CLEAR_BUF_EMPTY_MASK_SFT (0x1 << 7) +#define DL1_PBUF_SIZE_SFT 5 +#define DL1_PBUF_SIZE_MASK 0x3 +#define DL1_PBUF_SIZE_MASK_SFT (0x3 << 5) +#define DL1_MONO_SFT 4 +#define DL1_MONO_MASK 0x1 +#define DL1_MONO_MASK_SFT (0x1 << 4) +#define DL1_NORMAL_MODE_SFT 3 +#define DL1_NORMAL_MODE_MASK 0x1 +#define DL1_NORMAL_MODE_MASK_SFT (0x1 << 3) +#define DL1_HALIGN_SFT 2 +#define DL1_HALIGN_MASK 0x1 +#define DL1_HALIGN_MASK_SFT (0x1 << 2) +#define DL1_HD_MODE_SFT 0 +#define DL1_HD_MODE_MASK 0x3 +#define DL1_HD_MODE_MASK_SFT (0x3 << 0) + +/* AFE_DL1_MON0 */ +#define RESERVED_01_SFT 20 +#define RESERVED_01_MASK 0xfff +#define RESERVED_01_MASK_SFT (0xfff << 20) +#define MEM_REQ_PENDING_SFT 19 +#define MEM_REQ_PENDING_MASK 0x1 +#define MEM_REQ_PENDING_MASK_SFT (0x1 << 19) +#define BUF_EMPTY_SFT 18 +#define BUF_EMPTY_MASK 0x1 +#define BUF_EMPTY_MASK_SFT (0x1 << 18) +#define ENABLE_SYNC_MEM_SFT 17 +#define ENABLE_SYNC_MEM_MASK 0x1 +#define ENABLE_SYNC_MEM_MASK_SFT (0x1 << 17) +#define ENABLE_SYNC_AGENT_SFT 16 +#define ENABLE_SYNC_AGENT_MASK 0x1 +#define ENABLE_SYNC_AGENT_MASK_SFT (0x1 << 16) +#define RESERVED_02_SFT 6 +#define RESERVED_02_MASK 0x3ff +#define RESERVED_02_MASK_SFT (0x3ff << 6) +#define MEM_ADDR_DIFF_SFT 0 +#define MEM_ADDR_DIFF_MASK 0x3f +#define MEM_ADDR_DIFF_MASK_SFT (0x3f << 0) + +/* AFE_DL2_BASE_MSB */ +#define DL2_BASE__ADDR_MSB_SFT 0 +#define DL2_BASE__ADDR_MSB_MASK 0x1ff +#define DL2_BASE__ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL2_BASE */ +#define DL2_BASE_ADDR_SFT 4 +#define DL2_BASE_ADDR_MASK 0xfffffff +#define DL2_BASE_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_DL2_CUR_MSB */ +#define DL2_CUR_PTR_MSB_SFT 0 +#define DL2_CUR_PTR_MSB_MASK 0x1ff +#define DL2_CUR_PTR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL2_CUR */ +#define DL2_CUR_PTR_SFT 0 +#define DL2_CUR_PTR_MASK 0xffffffff +#define DL2_CUR_PTR_MASK_SFT (0xffffffff << 0) + +/* AFE_DL2_END_MSB */ +#define DL2_END_ADDR_MSB_SFT 0 +#define DL2_END_ADDR_MSB_MASK 0x1ff +#define DL2_END_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL2_END */ +#define DL2_END_ADDR_SFT 4 +#define DL2_END_ADDR_MASK 0xfffffff +#define DL2_END_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_DL2_RCH_MON */ +#define DL2_RCH_DATA_SFT 0 +#define DL2_RCH_DATA_MASK 0xffffffff +#define DL2_RCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_DL2_LCH_MON */ +#define DL2_LCH_DATA_SFT 0 +#define DL2_LCH_DATA_MASK 0xffffffff +#define DL2_LCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_DL2_CON0 */ +#define DL2_ON_SFT 28 +#define DL2_ON_MASK 0x1 +#define DL2_ON_MASK_SFT (0x1 << 28) +#define DL2_ONE_HEART_SEL_SFT 22 +#define DL2_ONE_HEART_SEL_MASK 0x3 +#define DL2_ONE_HEART_SEL_MASK_SFT (0x3 << 22) +#define DL2_MINLEN_SFT 20 +#define DL2_MINLEN_MASK 0x3 +#define DL2_MINLEN_MASK_SFT (0x3 << 20) +#define DL2_MAXLEN_SFT 16 +#define DL2_MAXLEN_MASK 0x3 +#define DL2_MAXLEN_MASK_SFT (0x3 << 16) +#define DL2_SEL_DOMAIN_SFT 13 +#define DL2_SEL_DOMAIN_MASK 0x7 +#define DL2_SEL_DOMAIN_MASK_SFT (0x7 << 13) +#define DL2_SEL_FS_SFT 8 +#define DL2_SEL_FS_MASK 0x1f +#define DL2_SEL_FS_MASK_SFT (0x1f << 8) +#define DL2_SW_CLEAR_BUF_EMPTY_SFT 7 +#define DL2_SW_CLEAR_BUF_EMPTY_MASK 0x1 +#define DL2_SW_CLEAR_BUF_EMPTY_MASK_SFT (0x1 << 7) +#define DL2_PBUF_SIZE_SFT 5 +#define DL2_PBUF_SIZE_MASK 0x3 +#define DL2_PBUF_SIZE_MASK_SFT (0x3 << 5) +#define DL2_MONO_SFT 4 +#define DL2_MONO_MASK 0x1 +#define DL2_MONO_MASK_SFT (0x1 << 4) +#define DL2_NORMAL_MODE_SFT 3 +#define DL2_NORMAL_MODE_MASK 0x1 +#define DL2_NORMAL_MODE_MASK_SFT (0x1 << 3) +#define DL2_HALIGN_SFT 2 +#define DL2_HALIGN_MASK 0x1 +#define DL2_HALIGN_MASK_SFT (0x1 << 2) +#define DL2_HD_MODE_SFT 0 +#define DL2_HD_MODE_MASK 0x3 +#define DL2_HD_MODE_MASK_SFT (0x3 << 0) + +/* AFE_DL2_MON0 */ +#define RESERVED_01_SFT 20 +#define RESERVED_01_MASK 0xfff +#define RESERVED_01_MASK_SFT (0xfff << 20) +#define MEM_REQ_PENDING_SFT 19 +#define MEM_REQ_PENDING_MASK 0x1 +#define MEM_REQ_PENDING_MASK_SFT (0x1 << 19) +#define BUF_EMPTY_SFT 18 +#define BUF_EMPTY_MASK 0x1 +#define BUF_EMPTY_MASK_SFT (0x1 << 18) +#define ENABLE_SYNC_MEM_SFT 17 +#define ENABLE_SYNC_MEM_MASK 0x1 +#define ENABLE_SYNC_MEM_MASK_SFT (0x1 << 17) +#define ENABLE_SYNC_AGENT_SFT 16 +#define ENABLE_SYNC_AGENT_MASK 0x1 +#define ENABLE_SYNC_AGENT_MASK_SFT (0x1 << 16) +#define RESERVED_02_SFT 6 +#define RESERVED_02_MASK 0x3ff +#define RESERVED_02_MASK_SFT (0x3ff << 6) +#define MEM_ADDR_DIFF_SFT 0 +#define MEM_ADDR_DIFF_MASK 0x3f +#define MEM_ADDR_DIFF_MASK_SFT (0x3f << 0) + +/* AFE_DL3_BASE_MSB */ +#define DL3_BASE__ADDR_MSB_SFT 0 +#define DL3_BASE__ADDR_MSB_MASK 0x1ff +#define DL3_BASE__ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL3_BASE */ +#define DL3_BASE_ADDR_SFT 4 +#define DL3_BASE_ADDR_MASK 0xfffffff +#define DL3_BASE_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_DL3_CUR_MSB */ +#define DL3_CUR_PTR_MSB_SFT 0 +#define DL3_CUR_PTR_MSB_MASK 0x1ff +#define DL3_CUR_PTR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL3_CUR */ +#define DL3_CUR_PTR_SFT 0 +#define DL3_CUR_PTR_MASK 0xffffffff +#define DL3_CUR_PTR_MASK_SFT (0xffffffff << 0) + +/* AFE_DL3_END_MSB */ +#define DL3_END_ADDR_MSB_SFT 0 +#define DL3_END_ADDR_MSB_MASK 0x1ff +#define DL3_END_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL3_END */ +#define DL3_END_ADDR_SFT 4 +#define DL3_END_ADDR_MASK 0xfffffff +#define DL3_END_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_DL3_RCH_MON */ +#define DL3_RCH_DATA_SFT 0 +#define DL3_RCH_DATA_MASK 0xffffffff +#define DL3_RCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_DL3_LCH_MON */ +#define DL3_LCH_DATA_SFT 0 +#define DL3_LCH_DATA_MASK 0xffffffff +#define DL3_LCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_DL3_CON0 */ +#define DL3_ON_SFT 28 +#define DL3_ON_MASK 0x1 +#define DL3_ON_MASK_SFT (0x1 << 28) +#define DL3_ONE_HEART_SEL_SFT 22 +#define DL3_ONE_HEART_SEL_MASK 0x3 +#define DL3_ONE_HEART_SEL_MASK_SFT (0x3 << 22) +#define DL3_MINLEN_SFT 20 +#define DL3_MINLEN_MASK 0x3 +#define DL3_MINLEN_MASK_SFT (0x3 << 20) +#define DL3_MAXLEN_SFT 16 +#define DL3_MAXLEN_MASK 0x3 +#define DL3_MAXLEN_MASK_SFT (0x3 << 16) +#define DL3_SEL_DOMAIN_SFT 13 +#define DL3_SEL_DOMAIN_MASK 0x7 +#define DL3_SEL_DOMAIN_MASK_SFT (0x7 << 13) +#define DL3_SEL_FS_SFT 8 +#define DL3_SEL_FS_MASK 0x1f +#define DL3_SEL_FS_MASK_SFT (0x1f << 8) +#define DL3_SW_CLEAR_BUF_EMPTY_SFT 7 +#define DL3_SW_CLEAR_BUF_EMPTY_MASK 0x1 +#define DL3_SW_CLEAR_BUF_EMPTY_MASK_SFT (0x1 << 7) +#define DL3_PBUF_SIZE_SFT 5 +#define DL3_PBUF_SIZE_MASK 0x3 +#define DL3_PBUF_SIZE_MASK_SFT (0x3 << 5) +#define DL3_MONO_SFT 4 +#define DL3_MONO_MASK 0x1 +#define DL3_MONO_MASK_SFT (0x1 << 4) +#define DL3_NORMAL_MODE_SFT 3 +#define DL3_NORMAL_MODE_MASK 0x1 +#define DL3_NORMAL_MODE_MASK_SFT (0x1 << 3) +#define DL3_HALIGN_SFT 2 +#define DL3_HALIGN_MASK 0x1 +#define DL3_HALIGN_MASK_SFT (0x1 << 2) +#define DL3_HD_MODE_SFT 0 +#define DL3_HD_MODE_MASK 0x3 +#define DL3_HD_MODE_MASK_SFT (0x3 << 0) + +/* AFE_DL3_MON0 */ +#define RESERVED_01_SFT 20 +#define RESERVED_01_MASK 0xfff +#define RESERVED_01_MASK_SFT (0xfff << 20) +#define MEM_REQ_PENDING_SFT 19 +#define MEM_REQ_PENDING_MASK 0x1 +#define MEM_REQ_PENDING_MASK_SFT (0x1 << 19) +#define BUF_EMPTY_SFT 18 +#define BUF_EMPTY_MASK 0x1 +#define BUF_EMPTY_MASK_SFT (0x1 << 18) +#define ENABLE_SYNC_MEM_SFT 17 +#define ENABLE_SYNC_MEM_MASK 0x1 +#define ENABLE_SYNC_MEM_MASK_SFT (0x1 << 17) +#define ENABLE_SYNC_AGENT_SFT 16 +#define ENABLE_SYNC_AGENT_MASK 0x1 +#define ENABLE_SYNC_AGENT_MASK_SFT (0x1 << 16) +#define RESERVED_02_SFT 6 +#define RESERVED_02_MASK 0x3ff +#define RESERVED_02_MASK_SFT (0x3ff << 6) +#define MEM_ADDR_DIFF_SFT 0 +#define MEM_ADDR_DIFF_MASK 0x3f +#define MEM_ADDR_DIFF_MASK_SFT (0x3f << 0) + +/* AFE_DL4_BASE_MSB */ +#define DL4_BASE__ADDR_MSB_SFT 0 +#define DL4_BASE__ADDR_MSB_MASK 0x1ff +#define DL4_BASE__ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL4_BASE */ +#define DL4_BASE_ADDR_SFT 4 +#define DL4_BASE_ADDR_MASK 0xfffffff +#define DL4_BASE_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_DL4_CUR_MSB */ +#define DL4_CUR_PTR_MSB_SFT 0 +#define DL4_CUR_PTR_MSB_MASK 0x1ff +#define DL4_CUR_PTR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL4_CUR */ +#define DL4_CUR_PTR_SFT 0 +#define DL4_CUR_PTR_MASK 0xffffffff +#define DL4_CUR_PTR_MASK_SFT (0xffffffff << 0) + +/* AFE_DL4_END_MSB */ +#define DL4_END_ADDR_MSB_SFT 0 +#define DL4_END_ADDR_MSB_MASK 0x1ff +#define DL4_END_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL4_END */ +#define DL4_END_ADDR_SFT 4 +#define DL4_END_ADDR_MASK 0xfffffff +#define DL4_END_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_DL4_RCH_MON */ +#define DL4_RCH_DATA_SFT 0 +#define DL4_RCH_DATA_MASK 0xffffffff +#define DL4_RCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_DL4_LCH_MON */ +#define DL4_LCH_DATA_SFT 0 +#define DL4_LCH_DATA_MASK 0xffffffff +#define DL4_LCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_DL4_CON0 */ +#define DL4_ON_SFT 28 +#define DL4_ON_MASK 0x1 +#define DL4_ON_MASK_SFT (0x1 << 28) +#define DL4_ONE_HEART_SEL_SFT 22 +#define DL4_ONE_HEART_SEL_MASK 0x3 +#define DL4_ONE_HEART_SEL_MASK_SFT (0x3 << 22) +#define DL4_MINLEN_SFT 20 +#define DL4_MINLEN_MASK 0x3 +#define DL4_MINLEN_MASK_SFT (0x3 << 20) +#define DL4_MAXLEN_SFT 16 +#define DL4_MAXLEN_MASK 0x3 +#define DL4_MAXLEN_MASK_SFT (0x3 << 16) +#define DL4_SEL_DOMAIN_SFT 13 +#define DL4_SEL_DOMAIN_MASK 0x7 +#define DL4_SEL_DOMAIN_MASK_SFT (0x7 << 13) +#define DL4_SEL_FS_SFT 8 +#define DL4_SEL_FS_MASK 0x1f +#define DL4_SEL_FS_MASK_SFT (0x1f << 8) +#define DL4_SW_CLEAR_BUF_EMPTY_SFT 7 +#define DL4_SW_CLEAR_BUF_EMPTY_MASK 0x1 +#define DL4_SW_CLEAR_BUF_EMPTY_MASK_SFT (0x1 << 7) +#define DL4_PBUF_SIZE_SFT 5 +#define DL4_PBUF_SIZE_MASK 0x3 +#define DL4_PBUF_SIZE_MASK_SFT (0x3 << 5) +#define DL4_MONO_SFT 4 +#define DL4_MONO_MASK 0x1 +#define DL4_MONO_MASK_SFT (0x1 << 4) +#define DL4_NORMAL_MODE_SFT 3 +#define DL4_NORMAL_MODE_MASK 0x1 +#define DL4_NORMAL_MODE_MASK_SFT (0x1 << 3) +#define DL4_HALIGN_SFT 2 +#define DL4_HALIGN_MASK 0x1 +#define DL4_HALIGN_MASK_SFT (0x1 << 2) +#define DL4_HD_MODE_SFT 0 +#define DL4_HD_MODE_MASK 0x3 +#define DL4_HD_MODE_MASK_SFT (0x3 << 0) + +/* AFE_DL4_MON0 */ +#define RESERVED_01_SFT 20 +#define RESERVED_01_MASK 0xfff +#define RESERVED_01_MASK_SFT (0xfff << 20) +#define MEM_REQ_PENDING_SFT 19 +#define MEM_REQ_PENDING_MASK 0x1 +#define MEM_REQ_PENDING_MASK_SFT (0x1 << 19) +#define BUF_EMPTY_SFT 18 +#define BUF_EMPTY_MASK 0x1 +#define BUF_EMPTY_MASK_SFT (0x1 << 18) +#define ENABLE_SYNC_MEM_SFT 17 +#define ENABLE_SYNC_MEM_MASK 0x1 +#define ENABLE_SYNC_MEM_MASK_SFT (0x1 << 17) +#define ENABLE_SYNC_AGENT_SFT 16 +#define ENABLE_SYNC_AGENT_MASK 0x1 +#define ENABLE_SYNC_AGENT_MASK_SFT (0x1 << 16) +#define RESERVED_02_SFT 6 +#define RESERVED_02_MASK 0x3ff +#define RESERVED_02_MASK_SFT (0x3ff << 6) +#define MEM_ADDR_DIFF_SFT 0 +#define MEM_ADDR_DIFF_MASK 0x3f +#define MEM_ADDR_DIFF_MASK_SFT (0x3f << 0) + +/* AFE_DL5_BASE_MSB */ +#define DL5_BASE__ADDR_MSB_SFT 0 +#define DL5_BASE__ADDR_MSB_MASK 0x1ff +#define DL5_BASE__ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL5_BASE */ +#define DL5_BASE_ADDR_SFT 4 +#define DL5_BASE_ADDR_MASK 0xfffffff +#define DL5_BASE_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_DL5_CUR_MSB */ +#define DL5_CUR_PTR_MSB_SFT 0 +#define DL5_CUR_PTR_MSB_MASK 0x1ff +#define DL5_CUR_PTR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL5_CUR */ +#define DL5_CUR_PTR_SFT 0 +#define DL5_CUR_PTR_MASK 0xffffffff +#define DL5_CUR_PTR_MASK_SFT (0xffffffff << 0) + +/* AFE_DL5_END_MSB */ +#define DL5_END_ADDR_MSB_SFT 0 +#define DL5_END_ADDR_MSB_MASK 0x1ff +#define DL5_END_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL5_END */ +#define DL5_END_ADDR_SFT 4 +#define DL5_END_ADDR_MASK 0xfffffff +#define DL5_END_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_DL5_RCH_MON */ +#define DL5_RCH_DATA_SFT 0 +#define DL5_RCH_DATA_MASK 0xffffffff +#define DL5_RCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_DL5_LCH_MON */ +#define DL5_LCH_DATA_SFT 0 +#define DL5_LCH_DATA_MASK 0xffffffff +#define DL5_LCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_DL5_CON0 */ +#define DL5_ON_SFT 28 +#define DL5_ON_MASK 0x1 +#define DL5_ON_MASK_SFT (0x1 << 28) +#define DL5_ONE_HEART_SEL_SFT 22 +#define DL5_ONE_HEART_SEL_MASK 0x3 +#define DL5_ONE_HEART_SEL_MASK_SFT (0x3 << 22) +#define DL5_MINLEN_SFT 20 +#define DL5_MINLEN_MASK 0x3 +#define DL5_MINLEN_MASK_SFT (0x3 << 20) +#define DL5_MAXLEN_SFT 16 +#define DL5_MAXLEN_MASK 0x3 +#define DL5_MAXLEN_MASK_SFT (0x3 << 16) +#define DL5_SEL_DOMAIN_SFT 13 +#define DL5_SEL_DOMAIN_MASK 0x7 +#define DL5_SEL_DOMAIN_MASK_SFT (0x7 << 13) +#define DL5_SEL_FS_SFT 8 +#define DL5_SEL_FS_MASK 0x1f +#define DL5_SEL_FS_MASK_SFT (0x1f << 8) +#define DL5_SW_CLEAR_BUF_EMPTY_SFT 7 +#define DL5_SW_CLEAR_BUF_EMPTY_MASK 0x1 +#define DL5_SW_CLEAR_BUF_EMPTY_MASK_SFT (0x1 << 7) +#define DL5_PBUF_SIZE_SFT 5 +#define DL5_PBUF_SIZE_MASK 0x3 +#define DL5_PBUF_SIZE_MASK_SFT (0x3 << 5) +#define DL5_MONO_SFT 4 +#define DL5_MONO_MASK 0x1 +#define DL5_MONO_MASK_SFT (0x1 << 4) +#define DL5_NORMAL_MODE_SFT 3 +#define DL5_NORMAL_MODE_MASK 0x1 +#define DL5_NORMAL_MODE_MASK_SFT (0x1 << 3) +#define DL5_HALIGN_SFT 2 +#define DL5_HALIGN_MASK 0x1 +#define DL5_HALIGN_MASK_SFT (0x1 << 2) +#define DL5_HD_MODE_SFT 0 +#define DL5_HD_MODE_MASK 0x3 +#define DL5_HD_MODE_MASK_SFT (0x3 << 0) + +/* AFE_DL5_MON0 */ +#define RESERVED_01_SFT 20 +#define RESERVED_01_MASK 0xfff +#define RESERVED_01_MASK_SFT (0xfff << 20) +#define MEM_REQ_PENDING_SFT 19 +#define MEM_REQ_PENDING_MASK 0x1 +#define MEM_REQ_PENDING_MASK_SFT (0x1 << 19) +#define BUF_EMPTY_SFT 18 +#define BUF_EMPTY_MASK 0x1 +#define BUF_EMPTY_MASK_SFT (0x1 << 18) +#define ENABLE_SYNC_MEM_SFT 17 +#define ENABLE_SYNC_MEM_MASK 0x1 +#define ENABLE_SYNC_MEM_MASK_SFT (0x1 << 17) +#define ENABLE_SYNC_AGENT_SFT 16 +#define ENABLE_SYNC_AGENT_MASK 0x1 +#define ENABLE_SYNC_AGENT_MASK_SFT (0x1 << 16) +#define RESERVED_02_SFT 6 +#define RESERVED_02_MASK 0x3ff +#define RESERVED_02_MASK_SFT (0x3ff << 6) +#define MEM_ADDR_DIFF_SFT 0 +#define MEM_ADDR_DIFF_MASK 0x3f +#define MEM_ADDR_DIFF_MASK_SFT (0x3f << 0) + +/* AFE_DL6_BASE_MSB */ +#define DL6_BASE__ADDR_MSB_SFT 0 +#define DL6_BASE__ADDR_MSB_MASK 0x1ff +#define DL6_BASE__ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL6_BASE */ +#define DL6_BASE_ADDR_SFT 4 +#define DL6_BASE_ADDR_MASK 0xfffffff +#define DL6_BASE_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_DL6_CUR_MSB */ +#define DL6_CUR_PTR_MSB_SFT 0 +#define DL6_CUR_PTR_MSB_MASK 0x1ff +#define DL6_CUR_PTR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL6_CUR */ +#define DL6_CUR_PTR_SFT 0 +#define DL6_CUR_PTR_MASK 0xffffffff +#define DL6_CUR_PTR_MASK_SFT (0xffffffff << 0) + +/* AFE_DL6_END_MSB */ +#define DL6_END_ADDR_MSB_SFT 0 +#define DL6_END_ADDR_MSB_MASK 0x1ff +#define DL6_END_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL6_END */ +#define DL6_END_ADDR_SFT 4 +#define DL6_END_ADDR_MASK 0xfffffff +#define DL6_END_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_DL6_RCH_MON */ +#define DL6_RCH_DATA_SFT 0 +#define DL6_RCH_DATA_MASK 0xffffffff +#define DL6_RCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_DL6_LCH_MON */ +#define DL6_LCH_DATA_SFT 0 +#define DL6_LCH_DATA_MASK 0xffffffff +#define DL6_LCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_DL6_CON0 */ +#define DL6_ON_SFT 28 +#define DL6_ON_MASK 0x1 +#define DL6_ON_MASK_SFT (0x1 << 28) +#define DL6_ONE_HEART_SEL_SFT 22 +#define DL6_ONE_HEART_SEL_MASK 0x3 +#define DL6_ONE_HEART_SEL_MASK_SFT (0x3 << 22) +#define DL6_MINLEN_SFT 20 +#define DL6_MINLEN_MASK 0x3 +#define DL6_MINLEN_MASK_SFT (0x3 << 20) +#define DL6_MAXLEN_SFT 16 +#define DL6_MAXLEN_MASK 0x3 +#define DL6_MAXLEN_MASK_SFT (0x3 << 16) +#define DL6_SEL_DOMAIN_SFT 13 +#define DL6_SEL_DOMAIN_MASK 0x7 +#define DL6_SEL_DOMAIN_MASK_SFT (0x7 << 13) +#define DL6_SEL_FS_SFT 8 +#define DL6_SEL_FS_MASK 0x1f +#define DL6_SEL_FS_MASK_SFT (0x1f << 8) +#define DL6_SW_CLEAR_BUF_EMPTY_SFT 7 +#define DL6_SW_CLEAR_BUF_EMPTY_MASK 0x1 +#define DL6_SW_CLEAR_BUF_EMPTY_MASK_SFT (0x1 << 7) +#define DL6_PBUF_SIZE_SFT 5 +#define DL6_PBUF_SIZE_MASK 0x3 +#define DL6_PBUF_SIZE_MASK_SFT (0x3 << 5) +#define DL6_MONO_SFT 4 +#define DL6_MONO_MASK 0x1 +#define DL6_MONO_MASK_SFT (0x1 << 4) +#define DL6_NORMAL_MODE_SFT 3 +#define DL6_NORMAL_MODE_MASK 0x1 +#define DL6_NORMAL_MODE_MASK_SFT (0x1 << 3) +#define DL6_HALIGN_SFT 2 +#define DL6_HALIGN_MASK 0x1 +#define DL6_HALIGN_MASK_SFT (0x1 << 2) +#define DL6_HD_MODE_SFT 0 +#define DL6_HD_MODE_MASK 0x3 +#define DL6_HD_MODE_MASK_SFT (0x3 << 0) + +/* AFE_DL6_MON0 */ +#define RESERVED_01_SFT 20 +#define RESERVED_01_MASK 0xfff +#define RESERVED_01_MASK_SFT (0xfff << 20) +#define MEM_REQ_PENDING_SFT 19 +#define MEM_REQ_PENDING_MASK 0x1 +#define MEM_REQ_PENDING_MASK_SFT (0x1 << 19) +#define BUF_EMPTY_SFT 18 +#define BUF_EMPTY_MASK 0x1 +#define BUF_EMPTY_MASK_SFT (0x1 << 18) +#define ENABLE_SYNC_MEM_SFT 17 +#define ENABLE_SYNC_MEM_MASK 0x1 +#define ENABLE_SYNC_MEM_MASK_SFT (0x1 << 17) +#define ENABLE_SYNC_AGENT_SFT 16 +#define ENABLE_SYNC_AGENT_MASK 0x1 +#define ENABLE_SYNC_AGENT_MASK_SFT (0x1 << 16) +#define RESERVED_02_SFT 6 +#define RESERVED_02_MASK 0x3ff +#define RESERVED_02_MASK_SFT (0x3ff << 6) +#define MEM_ADDR_DIFF_SFT 0 +#define MEM_ADDR_DIFF_MASK 0x3f +#define MEM_ADDR_DIFF_MASK_SFT (0x3f << 0) + +/* AFE_DL7_BASE_MSB */ +#define DL7_BASE__ADDR_MSB_SFT 0 +#define DL7_BASE__ADDR_MSB_MASK 0x1ff +#define DL7_BASE__ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL7_BASE */ +#define DL7_BASE_ADDR_SFT 4 +#define DL7_BASE_ADDR_MASK 0xfffffff +#define DL7_BASE_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_DL7_CUR_MSB */ +#define DL7_CUR_PTR_MSB_SFT 0 +#define DL7_CUR_PTR_MSB_MASK 0x1ff +#define DL7_CUR_PTR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL7_CUR */ +#define DL7_CUR_PTR_SFT 0 +#define DL7_CUR_PTR_MASK 0xffffffff +#define DL7_CUR_PTR_MASK_SFT (0xffffffff << 0) + +/* AFE_DL7_END_MSB */ +#define DL7_END_ADDR_MSB_SFT 0 +#define DL7_END_ADDR_MSB_MASK 0x1ff +#define DL7_END_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL7_END */ +#define DL7_END_ADDR_SFT 4 +#define DL7_END_ADDR_MASK 0xfffffff +#define DL7_END_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_DL7_RCH_MON */ +#define DL7_RCH_DATA_SFT 0 +#define DL7_RCH_DATA_MASK 0xffffffff +#define DL7_RCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_DL7_LCH_MON */ +#define DL7_LCH_DATA_SFT 0 +#define DL7_LCH_DATA_MASK 0xffffffff +#define DL7_LCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_DL7_CON0 */ +#define DL7_ON_SFT 28 +#define DL7_ON_MASK 0x1 +#define DL7_ON_MASK_SFT (0x1 << 28) +#define DL7_ONE_HEART_SEL_SFT 22 +#define DL7_ONE_HEART_SEL_MASK 0x3 +#define DL7_ONE_HEART_SEL_MASK_SFT (0x3 << 22) +#define DL7_MINLEN_SFT 20 +#define DL7_MINLEN_MASK 0x3 +#define DL7_MINLEN_MASK_SFT (0x3 << 20) +#define DL7_MAXLEN_SFT 16 +#define DL7_MAXLEN_MASK 0x3 +#define DL7_MAXLEN_MASK_SFT (0x3 << 16) +#define DL7_SEL_DOMAIN_SFT 13 +#define DL7_SEL_DOMAIN_MASK 0x7 +#define DL7_SEL_DOMAIN_MASK_SFT (0x7 << 13) +#define DL7_SEL_FS_SFT 8 +#define DL7_SEL_FS_MASK 0x1f +#define DL7_SEL_FS_MASK_SFT (0x1f << 8) +#define DL7_SW_CLEAR_BUF_EMPTY_SFT 7 +#define DL7_SW_CLEAR_BUF_EMPTY_MASK 0x1 +#define DL7_SW_CLEAR_BUF_EMPTY_MASK_SFT (0x1 << 7) +#define DL7_PBUF_SIZE_SFT 5 +#define DL7_PBUF_SIZE_MASK 0x3 +#define DL7_PBUF_SIZE_MASK_SFT (0x3 << 5) +#define DL7_MONO_SFT 4 +#define DL7_MONO_MASK 0x1 +#define DL7_MONO_MASK_SFT (0x1 << 4) +#define DL7_NORMAL_MODE_SFT 3 +#define DL7_NORMAL_MODE_MASK 0x1 +#define DL7_NORMAL_MODE_MASK_SFT (0x1 << 3) +#define DL7_HALIGN_SFT 2 +#define DL7_HALIGN_MASK 0x1 +#define DL7_HALIGN_MASK_SFT (0x1 << 2) +#define DL7_HD_MODE_SFT 0 +#define DL7_HD_MODE_MASK 0x3 +#define DL7_HD_MODE_MASK_SFT (0x3 << 0) + +/* AFE_DL7_MON0 */ +#define RESERVED_01_SFT 20 +#define RESERVED_01_MASK 0xfff +#define RESERVED_01_MASK_SFT (0xfff << 20) +#define MEM_REQ_PENDING_SFT 19 +#define MEM_REQ_PENDING_MASK 0x1 +#define MEM_REQ_PENDING_MASK_SFT (0x1 << 19) +#define BUF_EMPTY_SFT 18 +#define BUF_EMPTY_MASK 0x1 +#define BUF_EMPTY_MASK_SFT (0x1 << 18) +#define ENABLE_SYNC_MEM_SFT 17 +#define ENABLE_SYNC_MEM_MASK 0x1 +#define ENABLE_SYNC_MEM_MASK_SFT (0x1 << 17) +#define ENABLE_SYNC_AGENT_SFT 16 +#define ENABLE_SYNC_AGENT_MASK 0x1 +#define ENABLE_SYNC_AGENT_MASK_SFT (0x1 << 16) +#define RESERVED_02_SFT 6 +#define RESERVED_02_MASK 0x3ff +#define RESERVED_02_MASK_SFT (0x3ff << 6) +#define MEM_ADDR_DIFF_SFT 0 +#define MEM_ADDR_DIFF_MASK 0x3f +#define MEM_ADDR_DIFF_MASK_SFT (0x3f << 0) + +/* AFE_DL8_BASE_MSB */ +#define DL8_BASE__ADDR_MSB_SFT 0 +#define DL8_BASE__ADDR_MSB_MASK 0x1ff +#define DL8_BASE__ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL8_BASE */ +#define DL8_BASE_ADDR_SFT 4 +#define DL8_BASE_ADDR_MASK 0xfffffff +#define DL8_BASE_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_DL8_CUR_MSB */ +#define DL8_CUR_PTR_MSB_SFT 0 +#define DL8_CUR_PTR_MSB_MASK 0x1ff +#define DL8_CUR_PTR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL8_CUR */ +#define DL8_CUR_PTR_SFT 0 +#define DL8_CUR_PTR_MASK 0xffffffff +#define DL8_CUR_PTR_MASK_SFT (0xffffffff << 0) + +/* AFE_DL8_END_MSB */ +#define DL8_END_ADDR_MSB_SFT 0 +#define DL8_END_ADDR_MSB_MASK 0x1ff +#define DL8_END_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL8_END */ +#define DL8_END_ADDR_SFT 4 +#define DL8_END_ADDR_MASK 0xfffffff +#define DL8_END_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_DL8_RCH_MON */ +#define DL8_RCH_DATA_SFT 0 +#define DL8_RCH_DATA_MASK 0xffffffff +#define DL8_RCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_DL8_LCH_MON */ +#define DL8_LCH_DATA_SFT 0 +#define DL8_LCH_DATA_MASK 0xffffffff +#define DL8_LCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_DL8_CON0 */ +#define DL8_ON_SFT 28 +#define DL8_ON_MASK 0x1 +#define DL8_ON_MASK_SFT (0x1 << 28) +#define DL8_ONE_HEART_SEL_SFT 22 +#define DL8_ONE_HEART_SEL_MASK 0x3 +#define DL8_ONE_HEART_SEL_MASK_SFT (0x3 << 22) +#define DL8_MINLEN_SFT 20 +#define DL8_MINLEN_MASK 0x3 +#define DL8_MINLEN_MASK_SFT (0x3 << 20) +#define DL8_MAXLEN_SFT 16 +#define DL8_MAXLEN_MASK 0x3 +#define DL8_MAXLEN_MASK_SFT (0x3 << 16) +#define DL8_SEL_DOMAIN_SFT 13 +#define DL8_SEL_DOMAIN_MASK 0x7 +#define DL8_SEL_DOMAIN_MASK_SFT (0x7 << 13) +#define DL8_SEL_FS_SFT 8 +#define DL8_SEL_FS_MASK 0x1f +#define DL8_SEL_FS_MASK_SFT (0x1f << 8) +#define DL8_SW_CLEAR_BUF_EMPTY_SFT 7 +#define DL8_SW_CLEAR_BUF_EMPTY_MASK 0x1 +#define DL8_SW_CLEAR_BUF_EMPTY_MASK_SFT (0x1 << 7) +#define DL8_PBUF_SIZE_SFT 5 +#define DL8_PBUF_SIZE_MASK 0x3 +#define DL8_PBUF_SIZE_MASK_SFT (0x3 << 5) +#define DL8_MONO_SFT 4 +#define DL8_MONO_MASK 0x1 +#define DL8_MONO_MASK_SFT (0x1 << 4) +#define DL8_NORMAL_MODE_SFT 3 +#define DL8_NORMAL_MODE_MASK 0x1 +#define DL8_NORMAL_MODE_MASK_SFT (0x1 << 3) +#define DL8_HALIGN_SFT 2 +#define DL8_HALIGN_MASK 0x1 +#define DL8_HALIGN_MASK_SFT (0x1 << 2) +#define DL8_HD_MODE_SFT 0 +#define DL8_HD_MODE_MASK 0x3 +#define DL8_HD_MODE_MASK_SFT (0x3 << 0) + +/* AFE_DL8_MON0 */ +#define RESERVED_01_SFT 20 +#define RESERVED_01_MASK 0xfff +#define RESERVED_01_MASK_SFT (0xfff << 20) +#define MEM_REQ_PENDING_SFT 19 +#define MEM_REQ_PENDING_MASK 0x1 +#define MEM_REQ_PENDING_MASK_SFT (0x1 << 19) +#define BUF_EMPTY_SFT 18 +#define BUF_EMPTY_MASK 0x1 +#define BUF_EMPTY_MASK_SFT (0x1 << 18) +#define ENABLE_SYNC_MEM_SFT 17 +#define ENABLE_SYNC_MEM_MASK 0x1 +#define ENABLE_SYNC_MEM_MASK_SFT (0x1 << 17) +#define ENABLE_SYNC_AGENT_SFT 16 +#define ENABLE_SYNC_AGENT_MASK 0x1 +#define ENABLE_SYNC_AGENT_MASK_SFT (0x1 << 16) +#define RESERVED_02_SFT 6 +#define RESERVED_02_MASK 0x3ff +#define RESERVED_02_MASK_SFT (0x3ff << 6) +#define MEM_ADDR_DIFF_SFT 0 +#define MEM_ADDR_DIFF_MASK 0x3f +#define MEM_ADDR_DIFF_MASK_SFT (0x3f << 0) + +/* AFE_DL_24CH_BASE_MSB */ +#define DL_24CH_BASE__ADDR_MSB_SFT 0 +#define DL_24CH_BASE__ADDR_MSB_MASK 0x1ff +#define DL_24CH_BASE__ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL_24CH_BASE */ +#define DL_24CH_BASE_ADDR_SFT 4 +#define DL_24CH_BASE_ADDR_MASK 0xfffffff +#define DL_24CH_BASE_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_DL_24CH_CUR_MSB */ +#define DL_24CH_CUR_PTR_MSB_SFT 0 +#define DL_24CH_CUR_PTR_MSB_MASK 0x1ff +#define DL_24CH_CUR_PTR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL_24CH_CUR */ +#define DL_24CH_CUR_PTR_SFT 0 +#define DL_24CH_CUR_PTR_MASK 0xffffffff +#define DL_24CH_CUR_PTR_MASK_SFT (0xffffffff << 0) + +/* AFE_DL_24CH_END_MSB */ +#define DL_24CH_END_ADDR_MSB_SFT 0 +#define DL_24CH_END_ADDR_MSB_MASK 0x1ff +#define DL_24CH_END_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL_24CH_END */ +#define DL_24CH_END_ADDR_SFT 4 +#define DL_24CH_END_ADDR_MASK 0xfffffff +#define DL_24CH_END_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_DL_24CH_CON0 */ +#define DL_24CH_ON_SFT 31 +#define DL_24CH_ON_MASK 0x1 +#define DL_24CH_ON_MASK_SFT (0x1 << 31) +#define DL_24CH_NUM_SFT 24 +#define DL_24CH_NUM_MASK 0x3f +#define DL_24CH_NUM_MASK_SFT (0x3f << 24) +#define DL_24CH_ONE_HEART_SEL_SFT 22 +#define DL_24CH_ONE_HEART_SEL_MASK 0x3 +#define DL_24CH_ONE_HEART_SEL_MASK_SFT (0x3 << 22) +#define DL_24CH_MINLEN_SFT 20 +#define DL_24CH_MINLEN_MASK 0x3 +#define DL_24CH_MINLEN_MASK_SFT (0x3 << 20) +#define DL_24CH_MAXLEN_SFT 16 +#define DL_24CH_MAXLEN_MASK 0x3 +#define DL_24CH_MAXLEN_MASK_SFT (0x3 << 16) +#define DL_24CH_SEL_DOMAIN_SFT 13 +#define DL_24CH_SEL_DOMAIN_MASK 0x7 +#define DL_24CH_SEL_DOMAIN_MASK_SFT (0x7 << 13) +#define DL_24CH_SEL_FS_SFT 8 +#define DL_24CH_SEL_FS_MASK 0x1f +#define DL_24CH_SEL_FS_MASK_SFT (0x1f << 8) +#define DL_24CH_BUF_EMPTY_CLR_SFT 7 +#define DL_24CH_BUF_EMPTY_CLR_MASK 0x1 +#define DL_24CH_BUF_EMPTY_CLR_MASK_SFT (0x1 << 7) +#define DL_24CH_PBUF_SIZE_SFT 5 +#define DL_24CH_PBUF_SIZE_MASK 0x3 +#define DL_24CH_PBUF_SIZE_MASK_SFT (0x3 << 5) +#define DL_24CH_HANG_CLR_SFT 4 +#define DL_24CH_HANG_CLR_MASK 0x1 +#define DL_24CH_HANG_CLR_MASK_SFT (0x1 << 4) +#define DL_24CH_NORMAL_MODE_SFT 3 +#define DL_24CH_NORMAL_MODE_MASK 0x1 +#define DL_24CH_NORMAL_MODE_MASK_SFT (0x1 << 3) +#define DL_24CH_HALIGN_SFT 2 +#define DL_24CH_HALIGN_MASK 0x1 +#define DL_24CH_HALIGN_MASK_SFT (0x1 << 2) +#define DL_24CH_HD_MODE_SFT 0 +#define DL_24CH_HD_MODE_MASK 0x3 +#define DL_24CH_HD_MODE_MASK_SFT (0x3 << 0) + +/* AFE_DL23_BASE_MSB */ +#define DL23_BASE__ADDR_MSB_SFT 0 +#define DL23_BASE__ADDR_MSB_MASK 0x1ff +#define DL23_BASE__ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL23_BASE */ +#define DL23_BASE_ADDR_SFT 4 +#define DL23_BASE_ADDR_MASK 0xfffffff +#define DL23_BASE_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_DL23_CUR_MSB */ +#define DL23_CUR_PTR_MSB_SFT 0 +#define DL23_CUR_PTR_MSB_MASK 0x1ff +#define DL23_CUR_PTR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL23_CUR */ +#define DL23_CUR_PTR_SFT 0 +#define DL23_CUR_PTR_MASK 0xffffffff +#define DL23_CUR_PTR_MASK_SFT (0xffffffff << 0) + +/* AFE_DL23_END_MSB */ +#define DL23_END_ADDR_MSB_SFT 0 +#define DL23_END_ADDR_MSB_MASK 0x1ff +#define DL23_END_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL23_END */ +#define DL23_END_ADDR_SFT 4 +#define DL23_END_ADDR_MASK 0xfffffff +#define DL23_END_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_DL23_RCH_MON */ +#define DL23_RCH_DATA_SFT 0 +#define DL23_RCH_DATA_MASK 0xffffffff +#define DL23_RCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_DL23_LCH_MON */ +#define DL23_LCH_DATA_SFT 0 +#define DL23_LCH_DATA_MASK 0xffffffff +#define DL23_LCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_DL23_CON0 */ +#define DL23_ON_SFT 28 +#define DL23_ON_MASK 0x1 +#define DL23_ON_MASK_SFT (0x1 << 28) +#define DL23_ONE_HEART_SEL_SFT 22 +#define DL23_ONE_HEART_SEL_MASK 0x3 +#define DL23_ONE_HEART_SEL_MASK_SFT (0x3 << 22) +#define DL23_MINLEN_SFT 20 +#define DL23_MINLEN_MASK 0x3 +#define DL23_MINLEN_MASK_SFT (0x3 << 20) +#define DL23_MAXLEN_SFT 16 +#define DL23_MAXLEN_MASK 0x3 +#define DL23_MAXLEN_MASK_SFT (0x3 << 16) +#define DL23_SEL_DOMAIN_SFT 13 +#define DL23_SEL_DOMAIN_MASK 0x7 +#define DL23_SEL_DOMAIN_MASK_SFT (0x7 << 13) +#define DL23_SEL_FS_SFT 8 +#define DL23_SEL_FS_MASK 0x1f +#define DL23_SEL_FS_MASK_SFT (0x1f << 8) +#define DL23_SW_CLEAR_BUF_EMPTY_SFT 7 +#define DL23_SW_CLEAR_BUF_EMPTY_MASK 0x1 +#define DL23_SW_CLEAR_BUF_EMPTY_MASK_SFT (0x1 << 7) +#define DL23_PBUF_SIZE_SFT 5 +#define DL23_PBUF_SIZE_MASK 0x3 +#define DL23_PBUF_SIZE_MASK_SFT (0x3 << 5) +#define DL23_MONO_SFT 4 +#define DL23_MONO_MASK 0x1 +#define DL23_MONO_MASK_SFT (0x1 << 4) +#define DL23_NORMAL_MODE_SFT 3 +#define DL23_NORMAL_MODE_MASK 0x1 +#define DL23_NORMAL_MODE_MASK_SFT (0x1 << 3) +#define DL23_HALIGN_SFT 2 +#define DL23_HALIGN_MASK 0x1 +#define DL23_HALIGN_MASK_SFT (0x1 << 2) +#define DL23_HD_MODE_SFT 0 +#define DL23_HD_MODE_MASK 0x3 +#define DL23_HD_MODE_MASK_SFT (0x3 << 0) + +/* AFE_DL24_BASE_MSB */ +#define DL24_BASE__ADDR_MSB_SFT 0 +#define DL24_BASE__ADDR_MSB_MASK 0x1ff +#define DL24_BASE__ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL24_BASE */ +#define DL24_BASE_ADDR_SFT 4 +#define DL24_BASE_ADDR_MASK 0xfffffff +#define DL24_BASE_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_DL24_CUR_MSB */ +#define DL24_CUR_PTR_MSB_SFT 0 +#define DL24_CUR_PTR_MSB_MASK 0x1ff +#define DL24_CUR_PTR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL24_CUR */ +#define DL24_CUR_PTR_SFT 0 +#define DL24_CUR_PTR_MASK 0xffffffff +#define DL24_CUR_PTR_MASK_SFT (0xffffffff << 0) + +/* AFE_DL24_END_MSB */ +#define DL24_END_ADDR_MSB_SFT 0 +#define DL24_END_ADDR_MSB_MASK 0x1ff +#define DL24_END_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL24_END */ +#define DL24_END_ADDR_SFT 4 +#define DL24_END_ADDR_MASK 0xfffffff +#define DL24_END_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_DL24_RCH_MON */ +#define DL24_RCH_DATA_SFT 0 +#define DL24_RCH_DATA_MASK 0xffffffff +#define DL24_RCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_DL24_LCH_MON */ +#define DL24_LCH_DATA_SFT 0 +#define DL24_LCH_DATA_MASK 0xffffffff +#define DL24_LCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_DL24_CON0 */ +#define DL24_ON_SFT 28 +#define DL24_ON_MASK 0x1 +#define DL24_ON_MASK_SFT (0x1 << 28) +#define DL24_ONE_HEART_SEL_SFT 22 +#define DL24_ONE_HEART_SEL_MASK 0x3 +#define DL24_ONE_HEART_SEL_MASK_SFT (0x3 << 22) +#define DL24_MINLEN_SFT 20 +#define DL24_MINLEN_MASK 0x3 +#define DL24_MINLEN_MASK_SFT (0x3 << 20) +#define DL24_MAXLEN_SFT 16 +#define DL24_MAXLEN_MASK 0x3 +#define DL24_MAXLEN_MASK_SFT (0x3 << 16) +#define DL24_SEL_DOMAIN_SFT 13 +#define DL24_SEL_DOMAIN_MASK 0x7 +#define DL24_SEL_DOMAIN_MASK_SFT (0x7 << 13) +#define DL24_SEL_FS_SFT 8 +#define DL24_SEL_FS_MASK 0x1f +#define DL24_SEL_FS_MASK_SFT (0x1f << 8) +#define DL24_SW_CLEAR_BUF_EMPTY_SFT 7 +#define DL24_SW_CLEAR_BUF_EMPTY_MASK 0x1 +#define DL24_SW_CLEAR_BUF_EMPTY_MASK_SFT (0x1 << 7) +#define DL24_PBUF_SIZE_SFT 5 +#define DL24_PBUF_SIZE_MASK 0x3 +#define DL24_PBUF_SIZE_MASK_SFT (0x3 << 5) +#define DL24_MONO_SFT 4 +#define DL24_MONO_MASK 0x1 +#define DL24_MONO_MASK_SFT (0x1 << 4) +#define DL24_NORMAL_MODE_SFT 3 +#define DL24_NORMAL_MODE_MASK 0x1 +#define DL24_NORMAL_MODE_MASK_SFT (0x1 << 3) +#define DL24_HALIGN_SFT 2 +#define DL24_HALIGN_MASK 0x1 +#define DL24_HALIGN_MASK_SFT (0x1 << 2) +#define DL24_HD_MODE_SFT 0 +#define DL24_HD_MODE_MASK 0x3 +#define DL24_HD_MODE_MASK_SFT (0x3 << 0) + +/* AFE_DL25_BASE_MSB */ +#define DL25_BASE__ADDR_MSB_SFT 0 +#define DL25_BASE__ADDR_MSB_MASK 0x1ff +#define DL25_BASE__ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL25_BASE */ +#define DL25_BASE_ADDR_SFT 4 +#define DL25_BASE_ADDR_MASK 0xfffffff +#define DL25_BASE_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_DL25_CUR_MSB */ +#define DL25_CUR_PTR_MSB_SFT 0 +#define DL25_CUR_PTR_MSB_MASK 0x1ff +#define DL25_CUR_PTR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL25_CUR */ +#define DL25_CUR_PTR_SFT 0 +#define DL25_CUR_PTR_MASK 0xffffffff +#define DL25_CUR_PTR_MASK_SFT (0xffffffff << 0) + +/* AFE_DL25_END_MSB */ +#define DL25_END_ADDR_MSB_SFT 0 +#define DL25_END_ADDR_MSB_MASK 0x1ff +#define DL25_END_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_DL25_END */ +#define DL25_END_ADDR_SFT 4 +#define DL25_END_ADDR_MASK 0xfffffff +#define DL25_END_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_DL25_RCH_MON */ +#define DL25_RCH_DATA_SFT 0 +#define DL25_RCH_DATA_MASK 0xffffffff +#define DL25_RCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_DL25_LCH_MON */ +#define DL25_LCH_DATA_SFT 0 +#define DL25_LCH_DATA_MASK 0xffffffff +#define DL25_LCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_DL25_CON0 */ +#define DL25_ON_SFT 28 +#define DL25_ON_MASK 0x1 +#define DL25_ON_MASK_SFT (0x1 << 28) +#define DL25_ONE_HEART_SEL_SFT 22 +#define DL25_ONE_HEART_SEL_MASK 0x3 +#define DL25_ONE_HEART_SEL_MASK_SFT (0x3 << 22) +#define DL25_MINLEN_SFT 20 +#define DL25_MINLEN_MASK 0x3 +#define DL25_MINLEN_MASK_SFT (0x3 << 20) +#define DL25_MAXLEN_SFT 16 +#define DL25_MAXLEN_MASK 0x3 +#define DL25_MAXLEN_MASK_SFT (0x3 << 16) +#define DL25_SEL_DOMAIN_SFT 13 +#define DL25_SEL_DOMAIN_MASK 0x7 +#define DL25_SEL_DOMAIN_MASK_SFT (0x7 << 13) +#define DL25_SEL_FS_SFT 8 +#define DL25_SEL_FS_MASK 0x1f +#define DL25_SEL_FS_MASK_SFT (0x1f << 8) +#define DL25_SW_CLEAR_BUF_EMPTY_SFT 7 +#define DL25_SW_CLEAR_BUF_EMPTY_MASK 0x1 +#define DL25_SW_CLEAR_BUF_EMPTY_MASK_SFT (0x1 << 7) +#define DL25_PBUF_SIZE_SFT 5 +#define DL25_PBUF_SIZE_MASK 0x3 +#define DL25_PBUF_SIZE_MASK_SFT (0x3 << 5) +#define DL25_MONO_SFT 4 +#define DL25_MONO_MASK 0x1 +#define DL25_MONO_MASK_SFT (0x1 << 4) +#define DL25_NORMAL_MODE_SFT 3 +#define DL25_NORMAL_MODE_MASK 0x1 +#define DL25_NORMAL_MODE_MASK_SFT (0x1 << 3) +#define DL25_HALIGN_SFT 2 +#define DL25_HALIGN_MASK 0x1 +#define DL25_HALIGN_MASK_SFT (0x1 << 2) +#define DL25_HD_MODE_SFT 0 +#define DL25_HD_MODE_MASK 0x3 +#define DL25_HD_MODE_MASK_SFT (0x3 << 0) + +/* AFE_VUL0_BASE_MSB */ +#define VUL0_BASE_ADDR_MSB_SFT 0 +#define VUL0_BASE_ADDR_MSB_MASK 0x1ff +#define VUL0_BASE_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL0_BASE */ +#define VUL0_BASE_ADDR_SFT 4 +#define VUL0_BASE_ADDR_MASK 0xfffffff +#define VUL0_BASE_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_VUL0_CUR_MSB */ +#define VUL0_CUR_PTR_MSB_SFT 0 +#define VUL0_CUR_PTR_MSB_MASK 0x1ff +#define VUL0_CUR_PTR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL0_CUR */ +#define VUL0_CUR_PTR_SFT 0 +#define VUL0_CUR_PTR_MASK 0xffffffff +#define VUL0_CUR_PTR_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL0_END_MSB */ +#define VUL0_END_ADDR_MSB_SFT 0 +#define VUL0_END_ADDR_MSB_MASK 0x1ff +#define VUL0_END_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL0_END */ +#define VUL0_END_ADDR_SFT 4 +#define VUL0_END_ADDR_MASK 0xfffffff +#define VUL0_END_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_VUL0_RCH_MON */ +#define VUL0_RCH_DATA_SFT 0 +#define VUL0_RCH_DATA_MASK 0xffffffff +#define VUL0_RCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL0_LCH_MON */ +#define VUL0_LCH_DATA_SFT 0 +#define VUL0_LCH_DATA_MASK 0xffffffff +#define VUL0_LCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL0_CON0 */ +#define VUL0_ON_SFT 28 +#define VUL0_ON_MASK 0x1 +#define VUL0_ON_MASK_SFT (0x1 << 28) +#define VUL0_MINLEN_SFT 20 +#define VUL0_MINLEN_MASK 0x3 +#define VUL0_MINLEN_MASK_SFT (0x3 << 20) +#define VUL0_MAXLEN_SFT 16 +#define VUL0_MAXLEN_MASK 0x3 +#define VUL0_MAXLEN_MASK_SFT (0x3 << 16) +#define VUL0_SEL_DOMAIN_SFT 13 +#define VUL0_SEL_DOMAIN_MASK 0x7 +#define VUL0_SEL_DOMAIN_MASK_SFT (0x7 << 13) +#define VUL0_SEL_FS_SFT 8 +#define VUL0_SEL_FS_MASK 0x1f +#define VUL0_SEL_FS_MASK_SFT (0x1f << 8) +#define VUL0_SW_CLEAR_BUF_FULL_SFT 7 +#define VUL0_SW_CLEAR_BUF_FULL_MASK 0x1 +#define VUL0_SW_CLEAR_BUF_FULL_MASK_SFT (0x1 << 7) +#define VUL0_WR_SIGN_SFT 6 +#define VUL0_WR_SIGN_MASK 0x1 +#define VUL0_WR_SIGN_MASK_SFT (0x1 << 6) +#define VUL0_R_MONO_SFT 5 +#define VUL0_R_MONO_MASK 0x1 +#define VUL0_R_MONO_MASK_SFT (0x1 << 5) +#define VUL0_MONO_SFT 4 +#define VUL0_MONO_MASK 0x1 +#define VUL0_MONO_MASK_SFT (0x1 << 4) +#define VUL0_NORMAL_MODE_SFT 3 +#define VUL0_NORMAL_MODE_MASK 0x1 +#define VUL0_NORMAL_MODE_MASK_SFT (0x1 << 3) +#define VUL0_HALIGN_SFT 2 +#define VUL0_HALIGN_MASK 0x1 +#define VUL0_HALIGN_MASK_SFT (0x1 << 2) +#define VUL0_HD_MODE_SFT 0 +#define VUL0_HD_MODE_MASK 0x3 +#define VUL0_HD_MODE_MASK_SFT (0x3 << 0) + +/* AFE_VUL1_BASE_MSB */ +#define VUL1_BASE_ADDR_MSB_SFT 0 +#define VUL1_BASE_ADDR_MSB_MASK 0x1ff +#define VUL1_BASE_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL1_BASE */ +#define VUL1_BASE_ADDR_SFT 4 +#define VUL1_BASE_ADDR_MASK 0xfffffff +#define VUL1_BASE_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_VUL1_CUR_MSB */ +#define VUL1_CUR_PTR_MSB_SFT 0 +#define VUL1_CUR_PTR_MSB_MASK 0x1ff +#define VUL1_CUR_PTR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL1_CUR */ +#define VUL1_CUR_PTR_SFT 0 +#define VUL1_CUR_PTR_MASK 0xffffffff +#define VUL1_CUR_PTR_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL1_END_MSB */ +#define VUL1_END_ADDR_MSB_SFT 0 +#define VUL1_END_ADDR_MSB_MASK 0x1ff +#define VUL1_END_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL1_END */ +#define VUL1_END_ADDR_SFT 4 +#define VUL1_END_ADDR_MASK 0xfffffff +#define VUL1_END_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_VUL1_RCH_MON */ +#define VUL1_RCH_DATA_SFT 0 +#define VUL1_RCH_DATA_MASK 0xffffffff +#define VUL1_RCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL1_LCH_MON */ +#define VUL1_LCH_DATA_SFT 0 +#define VUL1_LCH_DATA_MASK 0xffffffff +#define VUL1_LCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL1_CON0 */ +#define VUL1_ON_SFT 28 +#define VUL1_ON_MASK 0x1 +#define VUL1_ON_MASK_SFT (0x1 << 28) +#define VUL1_MINLEN_SFT 20 +#define VUL1_MINLEN_MASK 0x3 +#define VUL1_MINLEN_MASK_SFT (0x3 << 20) +#define VUL1_MAXLEN_SFT 16 +#define VUL1_MAXLEN_MASK 0x3 +#define VUL1_MAXLEN_MASK_SFT (0x3 << 16) +#define VUL1_SEL_DOMAIN_SFT 13 +#define VUL1_SEL_DOMAIN_MASK 0x7 +#define VUL1_SEL_DOMAIN_MASK_SFT (0x7 << 13) +#define VUL1_SEL_FS_SFT 8 +#define VUL1_SEL_FS_MASK 0x1f +#define VUL1_SEL_FS_MASK_SFT (0x1f << 8) +#define VUL1_SW_CLEAR_BUF_FULL_SFT 7 +#define VUL1_SW_CLEAR_BUF_FULL_MASK 0x1 +#define VUL1_SW_CLEAR_BUF_FULL_MASK_SFT (0x1 << 7) +#define VUL1_WR_SIGN_SFT 6 +#define VUL1_WR_SIGN_MASK 0x1 +#define VUL1_WR_SIGN_MASK_SFT (0x1 << 6) +#define VUL1_R_MONO_SFT 5 +#define VUL1_R_MONO_MASK 0x1 +#define VUL1_R_MONO_MASK_SFT (0x1 << 5) +#define VUL1_MONO_SFT 4 +#define VUL1_MONO_MASK 0x1 +#define VUL1_MONO_MASK_SFT (0x1 << 4) +#define VUL1_NORMAL_MODE_SFT 3 +#define VUL1_NORMAL_MODE_MASK 0x1 +#define VUL1_NORMAL_MODE_MASK_SFT (0x1 << 3) +#define VUL1_HALIGN_SFT 2 +#define VUL1_HALIGN_MASK 0x1 +#define VUL1_HALIGN_MASK_SFT (0x1 << 2) +#define VUL1_HD_MODE_SFT 0 +#define VUL1_HD_MODE_MASK 0x3 +#define VUL1_HD_MODE_MASK_SFT (0x3 << 0) + +/* AFE_VUL1_MON0 */ +#define MEM_HW_WEN_SFT 20 +#define MEM_HW_WEN_MASK 0xf +#define MEM_HW_WEN_MASK_SFT (0xf << 20) +#define MEM_REQ_PENDING_SFT 19 +#define MEM_REQ_PENDING_MASK 0x1 +#define MEM_REQ_PENDING_MASK_SFT (0x1 << 19) +#define BUF_FULL_SFT 18 +#define BUF_FULL_MASK 0x1 +#define BUF_FULL_MASK_SFT (0x1 << 18) +#define ENABLE_SYNC_MEM_SFT 17 +#define ENABLE_SYNC_MEM_MASK 0x1 +#define ENABLE_SYNC_MEM_MASK_SFT (0x1 << 17) +#define ENABLE_SYNC_AGENT_SFT 16 +#define ENABLE_SYNC_AGENT_MASK 0x1 +#define ENABLE_SYNC_AGENT_MASK_SFT (0x1 << 16) +#define RESERVED_02_SFT 6 +#define RESERVED_02_MASK 0x3ff +#define RESERVED_02_MASK_SFT (0x3ff << 6) +#define MEM_ADDR_DIFF_SFT 0 +#define MEM_ADDR_DIFF_MASK 0x3f +#define MEM_ADDR_DIFF_MASK_SFT (0x3f << 0) + +/* AFE_VUL2_BASE_MSB */ +#define VUL2_BASE_ADDR_MSB_SFT 0 +#define VUL2_BASE_ADDR_MSB_MASK 0x1ff +#define VUL2_BASE_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL2_BASE */ +#define VUL2_BASE_ADDR_SFT 4 +#define VUL2_BASE_ADDR_MASK 0xfffffff +#define VUL2_BASE_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_VUL2_CUR_MSB */ +#define VUL2_CUR_PTR_MSB_SFT 0 +#define VUL2_CUR_PTR_MSB_MASK 0x1ff +#define VUL2_CUR_PTR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL2_CUR */ +#define VUL2_CUR_PTR_SFT 0 +#define VUL2_CUR_PTR_MASK 0xffffffff +#define VUL2_CUR_PTR_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL2_END_MSB */ +#define VUL2_END_ADDR_MSB_SFT 0 +#define VUL2_END_ADDR_MSB_MASK 0x1ff +#define VUL2_END_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL2_END */ +#define VUL2_END_ADDR_SFT 4 +#define VUL2_END_ADDR_MASK 0xfffffff +#define VUL2_END_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_VUL2_RCH_MON */ +#define VUL2_RCH_DATA_SFT 0 +#define VUL2_RCH_DATA_MASK 0xffffffff +#define VUL2_RCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL2_LCH_MON */ +#define VUL2_LCH_DATA_SFT 0 +#define VUL2_LCH_DATA_MASK 0xffffffff +#define VUL2_LCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL2_CON0 */ +#define VUL2_ON_SFT 28 +#define VUL2_ON_MASK 0x1 +#define VUL2_ON_MASK_SFT (0x1 << 28) +#define VUL2_MINLEN_SFT 20 +#define VUL2_MINLEN_MASK 0x3 +#define VUL2_MINLEN_MASK_SFT (0x3 << 20) +#define VUL2_MAXLEN_SFT 16 +#define VUL2_MAXLEN_MASK 0x3 +#define VUL2_MAXLEN_MASK_SFT (0x3 << 16) +#define VUL2_SEL_DOMAIN_SFT 13 +#define VUL2_SEL_DOMAIN_MASK 0x7 +#define VUL2_SEL_DOMAIN_MASK_SFT (0x7 << 13) +#define VUL2_SEL_FS_SFT 8 +#define VUL2_SEL_FS_MASK 0x1f +#define VUL2_SEL_FS_MASK_SFT (0x1f << 8) +#define VUL2_SW_CLEAR_BUF_FULL_SFT 7 +#define VUL2_SW_CLEAR_BUF_FULL_MASK 0x1 +#define VUL2_SW_CLEAR_BUF_FULL_MASK_SFT (0x1 << 7) +#define VUL2_WR_SIGN_SFT 6 +#define VUL2_WR_SIGN_MASK 0x1 +#define VUL2_WR_SIGN_MASK_SFT (0x1 << 6) +#define VUL2_R_MONO_SFT 5 +#define VUL2_R_MONO_MASK 0x1 +#define VUL2_R_MONO_MASK_SFT (0x1 << 5) +#define VUL2_MONO_SFT 4 +#define VUL2_MONO_MASK 0x1 +#define VUL2_MONO_MASK_SFT (0x1 << 4) +#define VUL2_NORMAL_MODE_SFT 3 +#define VUL2_NORMAL_MODE_MASK 0x1 +#define VUL2_NORMAL_MODE_MASK_SFT (0x1 << 3) +#define VUL2_HALIGN_SFT 2 +#define VUL2_HALIGN_MASK 0x1 +#define VUL2_HALIGN_MASK_SFT (0x1 << 2) +#define VUL2_HD_MODE_SFT 0 +#define VUL2_HD_MODE_MASK 0x3 +#define VUL2_HD_MODE_MASK_SFT (0x3 << 0) + +/* AFE_VUL2_MON0 */ +#define MEM_HW_WEN_SFT 20 +#define MEM_HW_WEN_MASK 0xf +#define MEM_HW_WEN_MASK_SFT (0xf << 20) +#define MEM_REQ_PENDING_SFT 19 +#define MEM_REQ_PENDING_MASK 0x1 +#define MEM_REQ_PENDING_MASK_SFT (0x1 << 19) +#define BUF_FULL_SFT 18 +#define BUF_FULL_MASK 0x1 +#define BUF_FULL_MASK_SFT (0x1 << 18) +#define ENABLE_SYNC_MEM_SFT 17 +#define ENABLE_SYNC_MEM_MASK 0x1 +#define ENABLE_SYNC_MEM_MASK_SFT (0x1 << 17) +#define ENABLE_SYNC_AGENT_SFT 16 +#define ENABLE_SYNC_AGENT_MASK 0x1 +#define ENABLE_SYNC_AGENT_MASK_SFT (0x1 << 16) +#define RESERVED_02_SFT 6 +#define RESERVED_02_MASK 0x3ff +#define RESERVED_02_MASK_SFT (0x3ff << 6) +#define MEM_ADDR_DIFF_SFT 0 +#define MEM_ADDR_DIFF_MASK 0x3f +#define MEM_ADDR_DIFF_MASK_SFT (0x3f << 0) + +/* AFE_VUL3_BASE_MSB */ +#define VUL3_BASE_ADDR_MSB_SFT 0 +#define VUL3_BASE_ADDR_MSB_MASK 0x1ff +#define VUL3_BASE_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL3_BASE */ +#define VUL3_BASE_ADDR_SFT 4 +#define VUL3_BASE_ADDR_MASK 0xfffffff +#define VUL3_BASE_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_VUL3_CUR_MSB */ +#define VUL3_CUR_PTR_MSB_SFT 0 +#define VUL3_CUR_PTR_MSB_MASK 0x1ff +#define VUL3_CUR_PTR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL3_CUR */ +#define VUL3_CUR_PTR_SFT 0 +#define VUL3_CUR_PTR_MASK 0xffffffff +#define VUL3_CUR_PTR_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL3_END_MSB */ +#define VUL3_END_ADDR_MSB_SFT 0 +#define VUL3_END_ADDR_MSB_MASK 0x1ff +#define VUL3_END_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL3_END */ +#define VUL3_END_ADDR_SFT 4 +#define VUL3_END_ADDR_MASK 0xfffffff +#define VUL3_END_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_VUL3_RCH_MON */ +#define VUL3_RCH_DATA_SFT 0 +#define VUL3_RCH_DATA_MASK 0xffffffff +#define VUL3_RCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL3_LCH_MON */ +#define VUL3_LCH_DATA_SFT 0 +#define VUL3_LCH_DATA_MASK 0xffffffff +#define VUL3_LCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL3_CON0 */ +#define VUL3_ON_SFT 28 +#define VUL3_ON_MASK 0x1 +#define VUL3_ON_MASK_SFT (0x1 << 28) +#define VUL3_MINLEN_SFT 20 +#define VUL3_MINLEN_MASK 0x3 +#define VUL3_MINLEN_MASK_SFT (0x3 << 20) +#define VUL3_MAXLEN_SFT 16 +#define VUL3_MAXLEN_MASK 0x3 +#define VUL3_MAXLEN_MASK_SFT (0x3 << 16) +#define VUL3_SEL_DOMAIN_SFT 13 +#define VUL3_SEL_DOMAIN_MASK 0x7 +#define VUL3_SEL_DOMAIN_MASK_SFT (0x7 << 13) +#define VUL3_SEL_FS_SFT 8 +#define VUL3_SEL_FS_MASK 0x1f +#define VUL3_SEL_FS_MASK_SFT (0x1f << 8) +#define VUL3_SW_CLEAR_BUF_FULL_SFT 7 +#define VUL3_SW_CLEAR_BUF_FULL_MASK 0x1 +#define VUL3_SW_CLEAR_BUF_FULL_MASK_SFT (0x1 << 7) +#define VUL3_WR_SIGN_SFT 6 +#define VUL3_WR_SIGN_MASK 0x1 +#define VUL3_WR_SIGN_MASK_SFT (0x1 << 6) +#define VUL3_R_MONO_SFT 5 +#define VUL3_R_MONO_MASK 0x1 +#define VUL3_R_MONO_MASK_SFT (0x1 << 5) +#define VUL3_MONO_SFT 4 +#define VUL3_MONO_MASK 0x1 +#define VUL3_MONO_MASK_SFT (0x1 << 4) +#define VUL3_NORMAL_MODE_SFT 3 +#define VUL3_NORMAL_MODE_MASK 0x1 +#define VUL3_NORMAL_MODE_MASK_SFT (0x1 << 3) +#define VUL3_HALIGN_SFT 2 +#define VUL3_HALIGN_MASK 0x1 +#define VUL3_HALIGN_MASK_SFT (0x1 << 2) +#define VUL3_HD_MODE_SFT 0 +#define VUL3_HD_MODE_MASK 0x3 +#define VUL3_HD_MODE_MASK_SFT (0x3 << 0) + +/* AFE_VUL3_MON0 */ +#define MEM_HW_WEN_SFT 20 +#define MEM_HW_WEN_MASK 0xf +#define MEM_HW_WEN_MASK_SFT (0xf << 20) +#define MEM_REQ_PENDING_SFT 19 +#define MEM_REQ_PENDING_MASK 0x1 +#define MEM_REQ_PENDING_MASK_SFT (0x1 << 19) +#define BUF_FULL_SFT 18 +#define BUF_FULL_MASK 0x1 +#define BUF_FULL_MASK_SFT (0x1 << 18) +#define ENABLE_SYNC_MEM_SFT 17 +#define ENABLE_SYNC_MEM_MASK 0x1 +#define ENABLE_SYNC_MEM_MASK_SFT (0x1 << 17) +#define ENABLE_SYNC_AGENT_SFT 16 +#define ENABLE_SYNC_AGENT_MASK 0x1 +#define ENABLE_SYNC_AGENT_MASK_SFT (0x1 << 16) +#define RESERVED_02_SFT 6 +#define RESERVED_02_MASK 0x3ff +#define RESERVED_02_MASK_SFT (0x3ff << 6) +#define MEM_ADDR_DIFF_SFT 0 +#define MEM_ADDR_DIFF_MASK 0x3f +#define MEM_ADDR_DIFF_MASK_SFT (0x3f << 0) + +/* AFE_VUL4_BASE_MSB */ +#define VUL4_BASE_ADDR_MSB_SFT 0 +#define VUL4_BASE_ADDR_MSB_MASK 0x1ff +#define VUL4_BASE_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL4_BASE */ +#define VUL4_BASE_ADDR_SFT 4 +#define VUL4_BASE_ADDR_MASK 0xfffffff +#define VUL4_BASE_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_VUL4_CUR_MSB */ +#define VUL4_CUR_PTR_MSB_SFT 0 +#define VUL4_CUR_PTR_MSB_MASK 0x1ff +#define VUL4_CUR_PTR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL4_CUR */ +#define VUL4_CUR_PTR_SFT 0 +#define VUL4_CUR_PTR_MASK 0xffffffff +#define VUL4_CUR_PTR_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL4_END_MSB */ +#define VUL4_END_ADDR_MSB_SFT 0 +#define VUL4_END_ADDR_MSB_MASK 0x1ff +#define VUL4_END_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL4_END */ +#define VUL4_END_ADDR_SFT 4 +#define VUL4_END_ADDR_MASK 0xfffffff +#define VUL4_END_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_VUL4_RCH_MON */ +#define VUL4_RCH_DATA_SFT 0 +#define VUL4_RCH_DATA_MASK 0xffffffff +#define VUL4_RCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL4_LCH_MON */ +#define VUL4_LCH_DATA_SFT 0 +#define VUL4_LCH_DATA_MASK 0xffffffff +#define VUL4_LCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL4_CON0 */ +#define VUL4_ON_SFT 28 +#define VUL4_ON_MASK 0x1 +#define VUL4_ON_MASK_SFT (0x1 << 28) +#define VUL4_MINLEN_SFT 20 +#define VUL4_MINLEN_MASK 0x3 +#define VUL4_MINLEN_MASK_SFT (0x3 << 20) +#define VUL4_MAXLEN_SFT 16 +#define VUL4_MAXLEN_MASK 0x3 +#define VUL4_MAXLEN_MASK_SFT (0x3 << 16) +#define VUL4_SEL_DOMAIN_SFT 13 +#define VUL4_SEL_DOMAIN_MASK 0x7 +#define VUL4_SEL_DOMAIN_MASK_SFT (0x7 << 13) +#define VUL4_SEL_FS_SFT 8 +#define VUL4_SEL_FS_MASK 0x1f +#define VUL4_SEL_FS_MASK_SFT (0x1f << 8) +#define VUL4_SW_CLEAR_BUF_FULL_SFT 7 +#define VUL4_SW_CLEAR_BUF_FULL_MASK 0x1 +#define VUL4_SW_CLEAR_BUF_FULL_MASK_SFT (0x1 << 7) +#define VUL4_WR_SIGN_SFT 6 +#define VUL4_WR_SIGN_MASK 0x1 +#define VUL4_WR_SIGN_MASK_SFT (0x1 << 6) +#define VUL4_R_MONO_SFT 5 +#define VUL4_R_MONO_MASK 0x1 +#define VUL4_R_MONO_MASK_SFT (0x1 << 5) +#define VUL4_MONO_SFT 4 +#define VUL4_MONO_MASK 0x1 +#define VUL4_MONO_MASK_SFT (0x1 << 4) +#define VUL4_NORMAL_MODE_SFT 3 +#define VUL4_NORMAL_MODE_MASK 0x1 +#define VUL4_NORMAL_MODE_MASK_SFT (0x1 << 3) +#define VUL4_HALIGN_SFT 2 +#define VUL4_HALIGN_MASK 0x1 +#define VUL4_HALIGN_MASK_SFT (0x1 << 2) +#define VUL4_HD_MODE_SFT 0 +#define VUL4_HD_MODE_MASK 0x3 +#define VUL4_HD_MODE_MASK_SFT (0x3 << 0) + +/* AFE_VUL4_MON0 */ +#define MEM_HW_WEN_SFT 20 +#define MEM_HW_WEN_MASK 0xf +#define MEM_HW_WEN_MASK_SFT (0xf << 20) +#define MEM_REQ_PENDING_SFT 19 +#define MEM_REQ_PENDING_MASK 0x1 +#define MEM_REQ_PENDING_MASK_SFT (0x1 << 19) +#define BUF_FULL_SFT 18 +#define BUF_FULL_MASK 0x1 +#define BUF_FULL_MASK_SFT (0x1 << 18) +#define ENABLE_SYNC_MEM_SFT 17 +#define ENABLE_SYNC_MEM_MASK 0x1 +#define ENABLE_SYNC_MEM_MASK_SFT (0x1 << 17) +#define ENABLE_SYNC_AGENT_SFT 16 +#define ENABLE_SYNC_AGENT_MASK 0x1 +#define ENABLE_SYNC_AGENT_MASK_SFT (0x1 << 16) +#define RESERVED_02_SFT 6 +#define RESERVED_02_MASK 0x3ff +#define RESERVED_02_MASK_SFT (0x3ff << 6) +#define MEM_ADDR_DIFF_SFT 0 +#define MEM_ADDR_DIFF_MASK 0x3f +#define MEM_ADDR_DIFF_MASK_SFT (0x3f << 0) + +/* AFE_VUL5_BASE_MSB */ +#define VUL5_BASE_ADDR_MSB_SFT 0 +#define VUL5_BASE_ADDR_MSB_MASK 0x1ff +#define VUL5_BASE_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL5_BASE */ +#define VUL5_BASE_ADDR_SFT 4 +#define VUL5_BASE_ADDR_MASK 0xfffffff +#define VUL5_BASE_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_VUL5_CUR_MSB */ +#define VUL5_CUR_PTR_MSB_SFT 0 +#define VUL5_CUR_PTR_MSB_MASK 0x1ff +#define VUL5_CUR_PTR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL5_CUR */ +#define VUL5_CUR_PTR_SFT 0 +#define VUL5_CUR_PTR_MASK 0xffffffff +#define VUL5_CUR_PTR_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL5_END_MSB */ +#define VUL5_END_ADDR_MSB_SFT 0 +#define VUL5_END_ADDR_MSB_MASK 0x1ff +#define VUL5_END_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL5_END */ +#define VUL5_END_ADDR_SFT 4 +#define VUL5_END_ADDR_MASK 0xfffffff +#define VUL5_END_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_VUL5_RCH_MON */ +#define VUL5_RCH_DATA_SFT 0 +#define VUL5_RCH_DATA_MASK 0xffffffff +#define VUL5_RCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL5_LCH_MON */ +#define VUL5_LCH_DATA_SFT 0 +#define VUL5_LCH_DATA_MASK 0xffffffff +#define VUL5_LCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL5_CON0 */ +#define VUL5_ON_SFT 28 +#define VUL5_ON_MASK 0x1 +#define VUL5_ON_MASK_SFT (0x1 << 28) +#define VUL5_MINLEN_SFT 20 +#define VUL5_MINLEN_MASK 0x3 +#define VUL5_MINLEN_MASK_SFT (0x3 << 20) +#define VUL5_MAXLEN_SFT 16 +#define VUL5_MAXLEN_MASK 0x3 +#define VUL5_MAXLEN_MASK_SFT (0x3 << 16) +#define VUL5_SEL_DOMAIN_SFT 13 +#define VUL5_SEL_DOMAIN_MASK 0x7 +#define VUL5_SEL_DOMAIN_MASK_SFT (0x7 << 13) +#define VUL5_SEL_FS_SFT 8 +#define VUL5_SEL_FS_MASK 0x1f +#define VUL5_SEL_FS_MASK_SFT (0x1f << 8) +#define VUL5_SW_CLEAR_BUF_FULL_SFT 7 +#define VUL5_SW_CLEAR_BUF_FULL_MASK 0x1 +#define VUL5_SW_CLEAR_BUF_FULL_MASK_SFT (0x1 << 7) +#define VUL5_WR_SIGN_SFT 6 +#define VUL5_WR_SIGN_MASK 0x1 +#define VUL5_WR_SIGN_MASK_SFT (0x1 << 6) +#define VUL5_R_MONO_SFT 5 +#define VUL5_R_MONO_MASK 0x1 +#define VUL5_R_MONO_MASK_SFT (0x1 << 5) +#define VUL5_MONO_SFT 4 +#define VUL5_MONO_MASK 0x1 +#define VUL5_MONO_MASK_SFT (0x1 << 4) +#define VUL5_NORMAL_MODE_SFT 3 +#define VUL5_NORMAL_MODE_MASK 0x1 +#define VUL5_NORMAL_MODE_MASK_SFT (0x1 << 3) +#define VUL5_HALIGN_SFT 2 +#define VUL5_HALIGN_MASK 0x1 +#define VUL5_HALIGN_MASK_SFT (0x1 << 2) +#define VUL5_HD_MODE_SFT 0 +#define VUL5_HD_MODE_MASK 0x3 +#define VUL5_HD_MODE_MASK_SFT (0x3 << 0) + +/* AFE_VUL5_MON0 */ +#define MEM_HW_WEN_SFT 20 +#define MEM_HW_WEN_MASK 0xf +#define MEM_HW_WEN_MASK_SFT (0xf << 20) +#define MEM_REQ_PENDING_SFT 19 +#define MEM_REQ_PENDING_MASK 0x1 +#define MEM_REQ_PENDING_MASK_SFT (0x1 << 19) +#define BUF_FULL_SFT 18 +#define BUF_FULL_MASK 0x1 +#define BUF_FULL_MASK_SFT (0x1 << 18) +#define ENABLE_SYNC_MEM_SFT 17 +#define ENABLE_SYNC_MEM_MASK 0x1 +#define ENABLE_SYNC_MEM_MASK_SFT (0x1 << 17) +#define ENABLE_SYNC_AGENT_SFT 16 +#define ENABLE_SYNC_AGENT_MASK 0x1 +#define ENABLE_SYNC_AGENT_MASK_SFT (0x1 << 16) +#define RESERVED_02_SFT 6 +#define RESERVED_02_MASK 0x3ff +#define RESERVED_02_MASK_SFT (0x3ff << 6) +#define MEM_ADDR_DIFF_SFT 0 +#define MEM_ADDR_DIFF_MASK 0x3f +#define MEM_ADDR_DIFF_MASK_SFT (0x3f << 0) + +/* AFE_VUL6_BASE_MSB */ +#define VUL6_BASE_ADDR_MSB_SFT 0 +#define VUL6_BASE_ADDR_MSB_MASK 0x1ff +#define VUL6_BASE_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL6_BASE */ +#define VUL6_BASE_ADDR_SFT 4 +#define VUL6_BASE_ADDR_MASK 0xfffffff +#define VUL6_BASE_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_VUL6_CUR_MSB */ +#define VUL6_CUR_PTR_MSB_SFT 0 +#define VUL6_CUR_PTR_MSB_MASK 0x1ff +#define VUL6_CUR_PTR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL6_CUR */ +#define VUL6_CUR_PTR_SFT 0 +#define VUL6_CUR_PTR_MASK 0xffffffff +#define VUL6_CUR_PTR_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL6_END_MSB */ +#define VUL6_END_ADDR_MSB_SFT 0 +#define VUL6_END_ADDR_MSB_MASK 0x1ff +#define VUL6_END_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL6_END */ +#define VUL6_END_ADDR_SFT 4 +#define VUL6_END_ADDR_MASK 0xfffffff +#define VUL6_END_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_VUL6_RCH_MON */ +#define VUL6_RCH_DATA_SFT 0 +#define VUL6_RCH_DATA_MASK 0xffffffff +#define VUL6_RCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL6_LCH_MON */ +#define VUL6_LCH_DATA_SFT 0 +#define VUL6_LCH_DATA_MASK 0xffffffff +#define VUL6_LCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL6_CON0 */ +#define VUL6_ON_SFT 28 +#define VUL6_ON_MASK 0x1 +#define VUL6_ON_MASK_SFT (0x1 << 28) +#define VUL6_MINLEN_SFT 20 +#define VUL6_MINLEN_MASK 0x3 +#define VUL6_MINLEN_MASK_SFT (0x3 << 20) +#define VUL6_MAXLEN_SFT 16 +#define VUL6_MAXLEN_MASK 0x3 +#define VUL6_MAXLEN_MASK_SFT (0x3 << 16) +#define VUL6_SEL_DOMAIN_SFT 13 +#define VUL6_SEL_DOMAIN_MASK 0x7 +#define VUL6_SEL_DOMAIN_MASK_SFT (0x7 << 13) +#define VUL6_SEL_FS_SFT 8 +#define VUL6_SEL_FS_MASK 0x1f +#define VUL6_SEL_FS_MASK_SFT (0x1f << 8) +#define VUL6_SW_CLEAR_BUF_FULL_SFT 7 +#define VUL6_SW_CLEAR_BUF_FULL_MASK 0x1 +#define VUL6_SW_CLEAR_BUF_FULL_MASK_SFT (0x1 << 7) +#define VUL6_WR_SIGN_SFT 6 +#define VUL6_WR_SIGN_MASK 0x1 +#define VUL6_WR_SIGN_MASK_SFT (0x1 << 6) +#define VUL6_R_MONO_SFT 5 +#define VUL6_R_MONO_MASK 0x1 +#define VUL6_R_MONO_MASK_SFT (0x1 << 5) +#define VUL6_MONO_SFT 4 +#define VUL6_MONO_MASK 0x1 +#define VUL6_MONO_MASK_SFT (0x1 << 4) +#define VUL6_NORMAL_MODE_SFT 3 +#define VUL6_NORMAL_MODE_MASK 0x1 +#define VUL6_NORMAL_MODE_MASK_SFT (0x1 << 3) +#define VUL6_HALIGN_SFT 2 +#define VUL6_HALIGN_MASK 0x1 +#define VUL6_HALIGN_MASK_SFT (0x1 << 2) +#define VUL6_HD_MODE_SFT 0 +#define VUL6_HD_MODE_MASK 0x3 +#define VUL6_HD_MODE_MASK_SFT (0x3 << 0) + +/* AFE_VUL6_MON0 */ +#define MEM_HW_WEN_SFT 20 +#define MEM_HW_WEN_MASK 0xf +#define MEM_HW_WEN_MASK_SFT (0xf << 20) +#define MEM_REQ_PENDING_SFT 19 +#define MEM_REQ_PENDING_MASK 0x1 +#define MEM_REQ_PENDING_MASK_SFT (0x1 << 19) +#define BUF_FULL_SFT 18 +#define BUF_FULL_MASK 0x1 +#define BUF_FULL_MASK_SFT (0x1 << 18) +#define ENABLE_SYNC_MEM_SFT 17 +#define ENABLE_SYNC_MEM_MASK 0x1 +#define ENABLE_SYNC_MEM_MASK_SFT (0x1 << 17) +#define ENABLE_SYNC_AGENT_SFT 16 +#define ENABLE_SYNC_AGENT_MASK 0x1 +#define ENABLE_SYNC_AGENT_MASK_SFT (0x1 << 16) +#define RESERVED_02_SFT 6 +#define RESERVED_02_MASK 0x3ff +#define RESERVED_02_MASK_SFT (0x3ff << 6) +#define MEM_ADDR_DIFF_SFT 0 +#define MEM_ADDR_DIFF_MASK 0x3f +#define MEM_ADDR_DIFF_MASK_SFT (0x3f << 0) + +/* AFE_VUL7_BASE_MSB */ +#define VUL7_BASE_ADDR_MSB_SFT 0 +#define VUL7_BASE_ADDR_MSB_MASK 0x1ff +#define VUL7_BASE_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL7_BASE */ +#define VUL7_BASE_ADDR_SFT 4 +#define VUL7_BASE_ADDR_MASK 0xfffffff +#define VUL7_BASE_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_VUL7_CUR_MSB */ +#define VUL7_CUR_PTR_MSB_SFT 0 +#define VUL7_CUR_PTR_MSB_MASK 0x1ff +#define VUL7_CUR_PTR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL7_CUR */ +#define VUL7_CUR_PTR_SFT 0 +#define VUL7_CUR_PTR_MASK 0xffffffff +#define VUL7_CUR_PTR_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL7_END_MSB */ +#define VUL7_END_ADDR_MSB_SFT 0 +#define VUL7_END_ADDR_MSB_MASK 0x1ff +#define VUL7_END_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL7_END */ +#define VUL7_END_ADDR_SFT 4 +#define VUL7_END_ADDR_MASK 0xfffffff +#define VUL7_END_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_VUL7_RCH_MON */ +#define VUL7_RCH_DATA_SFT 0 +#define VUL7_RCH_DATA_MASK 0xffffffff +#define VUL7_RCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL7_LCH_MON */ +#define VUL7_LCH_DATA_SFT 0 +#define VUL7_LCH_DATA_MASK 0xffffffff +#define VUL7_LCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL7_CON0 */ +#define VUL7_ON_SFT 28 +#define VUL7_ON_MASK 0x1 +#define VUL7_ON_MASK_SFT (0x1 << 28) +#define VUL7_MINLEN_SFT 20 +#define VUL7_MINLEN_MASK 0x3 +#define VUL7_MINLEN_MASK_SFT (0x3 << 20) +#define VUL7_MAXLEN_SFT 16 +#define VUL7_MAXLEN_MASK 0x3 +#define VUL7_MAXLEN_MASK_SFT (0x3 << 16) +#define VUL7_SEL_DOMAIN_SFT 13 +#define VUL7_SEL_DOMAIN_MASK 0x7 +#define VUL7_SEL_DOMAIN_MASK_SFT (0x7 << 13) +#define VUL7_SEL_FS_SFT 8 +#define VUL7_SEL_FS_MASK 0x1f +#define VUL7_SEL_FS_MASK_SFT (0x1f << 8) +#define VUL7_SW_CLEAR_BUF_FULL_SFT 7 +#define VUL7_SW_CLEAR_BUF_FULL_MASK 0x1 +#define VUL7_SW_CLEAR_BUF_FULL_MASK_SFT (0x1 << 7) +#define VUL7_WR_SIGN_SFT 6 +#define VUL7_WR_SIGN_MASK 0x1 +#define VUL7_WR_SIGN_MASK_SFT (0x1 << 6) +#define VUL7_R_MONO_SFT 5 +#define VUL7_R_MONO_MASK 0x1 +#define VUL7_R_MONO_MASK_SFT (0x1 << 5) +#define VUL7_MONO_SFT 4 +#define VUL7_MONO_MASK 0x1 +#define VUL7_MONO_MASK_SFT (0x1 << 4) +#define VUL7_NORMAL_MODE_SFT 3 +#define VUL7_NORMAL_MODE_MASK 0x1 +#define VUL7_NORMAL_MODE_MASK_SFT (0x1 << 3) +#define VUL7_HALIGN_SFT 2 +#define VUL7_HALIGN_MASK 0x1 +#define VUL7_HALIGN_MASK_SFT (0x1 << 2) +#define VUL7_HD_MODE_SFT 0 +#define VUL7_HD_MODE_MASK 0x3 +#define VUL7_HD_MODE_MASK_SFT (0x3 << 0) + +/* AFE_VUL7_MON0 */ +#define MEM_HW_WEN_SFT 20 +#define MEM_HW_WEN_MASK 0xf +#define MEM_HW_WEN_MASK_SFT (0xf << 20) +#define MEM_REQ_PENDING_SFT 19 +#define MEM_REQ_PENDING_MASK 0x1 +#define MEM_REQ_PENDING_MASK_SFT (0x1 << 19) +#define BUF_FULL_SFT 18 +#define BUF_FULL_MASK 0x1 +#define BUF_FULL_MASK_SFT (0x1 << 18) +#define ENABLE_SYNC_MEM_SFT 17 +#define ENABLE_SYNC_MEM_MASK 0x1 +#define ENABLE_SYNC_MEM_MASK_SFT (0x1 << 17) +#define ENABLE_SYNC_AGENT_SFT 16 +#define ENABLE_SYNC_AGENT_MASK 0x1 +#define ENABLE_SYNC_AGENT_MASK_SFT (0x1 << 16) +#define RESERVED_02_SFT 6 +#define RESERVED_02_MASK 0x3ff +#define RESERVED_02_MASK_SFT (0x3ff << 6) +#define MEM_ADDR_DIFF_SFT 0 +#define MEM_ADDR_DIFF_MASK 0x3f +#define MEM_ADDR_DIFF_MASK_SFT (0x3f << 0) + +/* AFE_VUL8_BASE_MSB */ +#define VUL8_BASE_ADDR_MSB_SFT 0 +#define VUL8_BASE_ADDR_MSB_MASK 0x1ff +#define VUL8_BASE_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL8_BASE */ +#define VUL8_BASE_ADDR_SFT 4 +#define VUL8_BASE_ADDR_MASK 0xfffffff +#define VUL8_BASE_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_VUL8_CUR_MSB */ +#define VUL8_CUR_PTR_MSB_SFT 0 +#define VUL8_CUR_PTR_MSB_MASK 0x1ff +#define VUL8_CUR_PTR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL8_CUR */ +#define VUL8_CUR_PTR_SFT 0 +#define VUL8_CUR_PTR_MASK 0xffffffff +#define VUL8_CUR_PTR_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL8_END_MSB */ +#define VUL8_END_ADDR_MSB_SFT 0 +#define VUL8_END_ADDR_MSB_MASK 0x1ff +#define VUL8_END_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL8_END */ +#define VUL8_END_ADDR_SFT 4 +#define VUL8_END_ADDR_MASK 0xfffffff +#define VUL8_END_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_VUL8_RCH_MON */ +#define VUL8_RCH_DATA_SFT 0 +#define VUL8_RCH_DATA_MASK 0xffffffff +#define VUL8_RCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL8_LCH_MON */ +#define VUL8_LCH_DATA_SFT 0 +#define VUL8_LCH_DATA_MASK 0xffffffff +#define VUL8_LCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL8_CON0 */ +#define VUL8_ON_SFT 28 +#define VUL8_ON_MASK 0x1 +#define VUL8_ON_MASK_SFT (0x1 << 28) +#define VUL8_MINLEN_SFT 20 +#define VUL8_MINLEN_MASK 0x3 +#define VUL8_MINLEN_MASK_SFT (0x3 << 20) +#define VUL8_MAXLEN_SFT 16 +#define VUL8_MAXLEN_MASK 0x3 +#define VUL8_MAXLEN_MASK_SFT (0x3 << 16) +#define VUL8_SEL_DOMAIN_SFT 13 +#define VUL8_SEL_DOMAIN_MASK 0x7 +#define VUL8_SEL_DOMAIN_MASK_SFT (0x7 << 13) +#define VUL8_SEL_FS_SFT 8 +#define VUL8_SEL_FS_MASK 0x1f +#define VUL8_SEL_FS_MASK_SFT (0x1f << 8) +#define VUL8_SW_CLEAR_BUF_FULL_SFT 7 +#define VUL8_SW_CLEAR_BUF_FULL_MASK 0x1 +#define VUL8_SW_CLEAR_BUF_FULL_MASK_SFT (0x1 << 7) +#define VUL8_WR_SIGN_SFT 6 +#define VUL8_WR_SIGN_MASK 0x1 +#define VUL8_WR_SIGN_MASK_SFT (0x1 << 6) +#define VUL8_R_MONO_SFT 5 +#define VUL8_R_MONO_MASK 0x1 +#define VUL8_R_MONO_MASK_SFT (0x1 << 5) +#define VUL8_MONO_SFT 4 +#define VUL8_MONO_MASK 0x1 +#define VUL8_MONO_MASK_SFT (0x1 << 4) +#define VUL8_NORMAL_MODE_SFT 3 +#define VUL8_NORMAL_MODE_MASK 0x1 +#define VUL8_NORMAL_MODE_MASK_SFT (0x1 << 3) +#define VUL8_HALIGN_SFT 2 +#define VUL8_HALIGN_MASK 0x1 +#define VUL8_HALIGN_MASK_SFT (0x1 << 2) +#define VUL8_HD_MODE_SFT 0 +#define VUL8_HD_MODE_MASK 0x3 +#define VUL8_HD_MODE_MASK_SFT (0x3 << 0) + +/* AFE_VUL8_MON0 */ +#define MEM_HW_WEN_SFT 20 +#define MEM_HW_WEN_MASK 0xf +#define MEM_HW_WEN_MASK_SFT (0xf << 20) +#define MEM_REQ_PENDING_SFT 19 +#define MEM_REQ_PENDING_MASK 0x1 +#define MEM_REQ_PENDING_MASK_SFT (0x1 << 19) +#define BUF_FULL_SFT 18 +#define BUF_FULL_MASK 0x1 +#define BUF_FULL_MASK_SFT (0x1 << 18) +#define ENABLE_SYNC_MEM_SFT 17 +#define ENABLE_SYNC_MEM_MASK 0x1 +#define ENABLE_SYNC_MEM_MASK_SFT (0x1 << 17) +#define ENABLE_SYNC_AGENT_SFT 16 +#define ENABLE_SYNC_AGENT_MASK 0x1 +#define ENABLE_SYNC_AGENT_MASK_SFT (0x1 << 16) +#define RESERVED_02_SFT 6 +#define RESERVED_02_MASK 0x3ff +#define RESERVED_02_MASK_SFT (0x3ff << 6) +#define MEM_ADDR_DIFF_SFT 0 +#define MEM_ADDR_DIFF_MASK 0x3f +#define MEM_ADDR_DIFF_MASK_SFT (0x3f << 0) + +/* AFE_VUL9_BASE_MSB */ +#define VUL9_BASE_ADDR_MSB_SFT 0 +#define VUL9_BASE_ADDR_MSB_MASK 0x1ff +#define VUL9_BASE_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL9_BASE */ +#define VUL9_BASE_ADDR_SFT 4 +#define VUL9_BASE_ADDR_MASK 0xfffffff +#define VUL9_BASE_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_VUL9_CUR_MSB */ +#define VUL9_CUR_PTR_MSB_SFT 0 +#define VUL9_CUR_PTR_MSB_MASK 0x1ff +#define VUL9_CUR_PTR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL9_CUR */ +#define VUL9_CUR_PTR_SFT 0 +#define VUL9_CUR_PTR_MASK 0xffffffff +#define VUL9_CUR_PTR_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL9_END_MSB */ +#define VUL9_END_ADDR_MSB_SFT 0 +#define VUL9_END_ADDR_MSB_MASK 0x1ff +#define VUL9_END_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL9_END */ +#define VUL9_END_ADDR_SFT 4 +#define VUL9_END_ADDR_MASK 0xfffffff +#define VUL9_END_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_VUL9_RCH_MON */ +#define VUL9_RCH_DATA_SFT 0 +#define VUL9_RCH_DATA_MASK 0xffffffff +#define VUL9_RCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL9_LCH_MON */ +#define VUL9_LCH_DATA_SFT 0 +#define VUL9_LCH_DATA_MASK 0xffffffff +#define VUL9_LCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL9_CON0 */ +#define VUL9_ON_SFT 28 +#define VUL9_ON_MASK 0x1 +#define VUL9_ON_MASK_SFT (0x1 << 28) +#define VUL9_MINLEN_SFT 20 +#define VUL9_MINLEN_MASK 0x3 +#define VUL9_MINLEN_MASK_SFT (0x3 << 20) +#define VUL9_MAXLEN_SFT 16 +#define VUL9_MAXLEN_MASK 0x3 +#define VUL9_MAXLEN_MASK_SFT (0x3 << 16) +#define VUL9_SEL_DOMAIN_SFT 13 +#define VUL9_SEL_DOMAIN_MASK 0x7 +#define VUL9_SEL_DOMAIN_MASK_SFT (0x7 << 13) +#define VUL9_SEL_FS_SFT 8 +#define VUL9_SEL_FS_MASK 0x1f +#define VUL9_SEL_FS_MASK_SFT (0x1f << 8) +#define VUL9_SW_CLEAR_BUF_FULL_SFT 7 +#define VUL9_SW_CLEAR_BUF_FULL_MASK 0x1 +#define VUL9_SW_CLEAR_BUF_FULL_MASK_SFT (0x1 << 7) +#define VUL9_WR_SIGN_SFT 6 +#define VUL9_WR_SIGN_MASK 0x1 +#define VUL9_WR_SIGN_MASK_SFT (0x1 << 6) +#define VUL9_R_MONO_SFT 5 +#define VUL9_R_MONO_MASK 0x1 +#define VUL9_R_MONO_MASK_SFT (0x1 << 5) +#define VUL9_MONO_SFT 4 +#define VUL9_MONO_MASK 0x1 +#define VUL9_MONO_MASK_SFT (0x1 << 4) +#define VUL9_NORMAL_MODE_SFT 3 +#define VUL9_NORMAL_MODE_MASK 0x1 +#define VUL9_NORMAL_MODE_MASK_SFT (0x1 << 3) +#define VUL9_HALIGN_SFT 2 +#define VUL9_HALIGN_MASK 0x1 +#define VUL9_HALIGN_MASK_SFT (0x1 << 2) +#define VUL9_HD_MODE_SFT 0 +#define VUL9_HD_MODE_MASK 0x3 +#define VUL9_HD_MODE_MASK_SFT (0x3 << 0) + +/* AFE_VUL9_MON0 */ +#define MEM_HW_WEN_SFT 20 +#define MEM_HW_WEN_MASK 0xf +#define MEM_HW_WEN_MASK_SFT (0xf << 20) +#define MEM_REQ_PENDING_SFT 19 +#define MEM_REQ_PENDING_MASK 0x1 +#define MEM_REQ_PENDING_MASK_SFT (0x1 << 19) +#define BUF_FULL_SFT 18 +#define BUF_FULL_MASK 0x1 +#define BUF_FULL_MASK_SFT (0x1 << 18) +#define ENABLE_SYNC_MEM_SFT 17 +#define ENABLE_SYNC_MEM_MASK 0x1 +#define ENABLE_SYNC_MEM_MASK_SFT (0x1 << 17) +#define ENABLE_SYNC_AGENT_SFT 16 +#define ENABLE_SYNC_AGENT_MASK 0x1 +#define ENABLE_SYNC_AGENT_MASK_SFT (0x1 << 16) +#define RESERVED_02_SFT 6 +#define RESERVED_02_MASK 0x3ff +#define RESERVED_02_MASK_SFT (0x3ff << 6) +#define MEM_ADDR_DIFF_SFT 0 +#define MEM_ADDR_DIFF_MASK 0x3f +#define MEM_ADDR_DIFF_MASK_SFT (0x3f << 0) + +/* AFE_VUL10_BASE_MSB */ +#define VUL10_BASE_ADDR_MSB_SFT 0 +#define VUL10_BASE_ADDR_MSB_MASK 0x1ff +#define VUL10_BASE_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL10_BASE */ +#define VUL10_BASE_ADDR_SFT 4 +#define VUL10_BASE_ADDR_MASK 0xfffffff +#define VUL10_BASE_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_VUL10_CUR_MSB */ +#define VUL10_CUR_PTR_MSB_SFT 0 +#define VUL10_CUR_PTR_MSB_MASK 0x1ff +#define VUL10_CUR_PTR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL10_CUR */ +#define VUL10_CUR_PTR_SFT 0 +#define VUL10_CUR_PTR_MASK 0xffffffff +#define VUL10_CUR_PTR_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL10_END_MSB */ +#define VUL10_END_ADDR_MSB_SFT 0 +#define VUL10_END_ADDR_MSB_MASK 0x1ff +#define VUL10_END_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL10_END */ +#define VUL10_END_ADDR_SFT 4 +#define VUL10_END_ADDR_MASK 0xfffffff +#define VUL10_END_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_VUL10_RCH_MON */ +#define VUL10_RCH_DATA_SFT 0 +#define VUL10_RCH_DATA_MASK 0xffffffff +#define VUL10_RCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL10_LCH_MON */ +#define VUL10_LCH_DATA_SFT 0 +#define VUL10_LCH_DATA_MASK 0xffffffff +#define VUL10_LCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL10_CON0 */ +#define VUL10_ON_SFT 28 +#define VUL10_ON_MASK 0x1 +#define VUL10_ON_MASK_SFT (0x1 << 28) +#define VUL10_MINLEN_SFT 20 +#define VUL10_MINLEN_MASK 0x3 +#define VUL10_MINLEN_MASK_SFT (0x3 << 20) +#define VUL10_MAXLEN_SFT 16 +#define VUL10_MAXLEN_MASK 0x3 +#define VUL10_MAXLEN_MASK_SFT (0x3 << 16) +#define VUL10_SEL_DOMAIN_SFT 13 +#define VUL10_SEL_DOMAIN_MASK 0x7 +#define VUL10_SEL_DOMAIN_MASK_SFT (0x7 << 13) +#define VUL10_SEL_FS_SFT 8 +#define VUL10_SEL_FS_MASK 0x1f +#define VUL10_SEL_FS_MASK_SFT (0x1f << 8) +#define VUL10_SW_CLEAR_BUF_FULL_SFT 7 +#define VUL10_SW_CLEAR_BUF_FULL_MASK 0x1 +#define VUL10_SW_CLEAR_BUF_FULL_MASK_SFT (0x1 << 7) +#define VUL10_WR_SIGN_SFT 6 +#define VUL10_WR_SIGN_MASK 0x1 +#define VUL10_WR_SIGN_MASK_SFT (0x1 << 6) +#define VUL10_R_MONO_SFT 5 +#define VUL10_R_MONO_MASK 0x1 +#define VUL10_R_MONO_MASK_SFT (0x1 << 5) +#define VUL10_MONO_SFT 4 +#define VUL10_MONO_MASK 0x1 +#define VUL10_MONO_MASK_SFT (0x1 << 4) +#define VUL10_NORMAL_MODE_SFT 3 +#define VUL10_NORMAL_MODE_MASK 0x1 +#define VUL10_NORMAL_MODE_MASK_SFT (0x1 << 3) +#define VUL10_HALIGN_SFT 2 +#define VUL10_HALIGN_MASK 0x1 +#define VUL10_HALIGN_MASK_SFT (0x1 << 2) +#define VUL10_HD_MODE_SFT 0 +#define VUL10_HD_MODE_MASK 0x3 +#define VUL10_HD_MODE_MASK_SFT (0x3 << 0) + +/* AFE_VUL10_MON0 */ +#define MEM_HW_WEN_SFT 20 +#define MEM_HW_WEN_MASK 0xf +#define MEM_HW_WEN_MASK_SFT (0xf << 20) +#define MEM_REQ_PENDING_SFT 19 +#define MEM_REQ_PENDING_MASK 0x1 +#define MEM_REQ_PENDING_MASK_SFT (0x1 << 19) +#define BUF_FULL_SFT 18 +#define BUF_FULL_MASK 0x1 +#define BUF_FULL_MASK_SFT (0x1 << 18) +#define ENABLE_SYNC_MEM_SFT 17 +#define ENABLE_SYNC_MEM_MASK 0x1 +#define ENABLE_SYNC_MEM_MASK_SFT (0x1 << 17) +#define ENABLE_SYNC_AGENT_SFT 16 +#define ENABLE_SYNC_AGENT_MASK 0x1 +#define ENABLE_SYNC_AGENT_MASK_SFT (0x1 << 16) +#define RESERVED_02_SFT 6 +#define RESERVED_02_MASK 0x3ff +#define RESERVED_02_MASK_SFT (0x3ff << 6) +#define MEM_ADDR_DIFF_SFT 0 +#define MEM_ADDR_DIFF_MASK 0x3f +#define MEM_ADDR_DIFF_MASK_SFT (0x3f << 0) + +/* AFE_VUL24_BASE_MSB */ +#define VUL24_BASE_ADDR_MSB_SFT 0 +#define VUL24_BASE_ADDR_MSB_MASK 0x1ff +#define VUL24_BASE_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL24_BASE */ +#define VUL24_BASE_ADDR_SFT 4 +#define VUL24_BASE_ADDR_MASK 0xfffffff +#define VUL24_BASE_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_VUL24_CUR_MSB */ +#define VUL24_CUR_PTR_MSB_SFT 0 +#define VUL24_CUR_PTR_MSB_MASK 0x1ff +#define VUL24_CUR_PTR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL24_CUR */ +#define VUL24_CUR_PTR_SFT 0 +#define VUL24_CUR_PTR_MASK 0xffffffff +#define VUL24_CUR_PTR_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL24_END_MSB */ +#define VUL24_END_ADDR_MSB_SFT 0 +#define VUL24_END_ADDR_MSB_MASK 0x1ff +#define VUL24_END_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL24_END */ +#define VUL24_END_ADDR_SFT 4 +#define VUL24_END_ADDR_MASK 0xfffffff +#define VUL24_END_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_VUL24_CON0 */ +#define OUT_ON_USE_VUL24_SFT 29 +#define OUT_ON_USE_VUL24_MASK 0x1 +#define OUT_ON_USE_VUL24_MASK_SFT (0x1 << 29) +#define VUL24_ON_SFT 28 +#define VUL24_ON_MASK 0x1 +#define VUL24_ON_MASK_SFT (0x1 << 28) +#define VUL24_MINLEN_SFT 20 +#define VUL24_MINLEN_MASK 0x3 +#define VUL24_MINLEN_MASK_SFT (0x3 << 20) +#define VUL24_MAXLEN_SFT 16 +#define VUL24_MAXLEN_MASK 0x3 +#define VUL24_MAXLEN_MASK_SFT (0x3 << 16) +#define VUL24_SEL_DOMAIN_SFT 13 +#define VUL24_SEL_DOMAIN_MASK 0x7 +#define VUL24_SEL_DOMAIN_MASK_SFT (0x7 << 13) +#define VUL24_SEL_FS_SFT 8 +#define VUL24_SEL_FS_MASK 0x1f +#define VUL24_SEL_FS_MASK_SFT (0x1f << 8) +#define VUL24_SW_CLEAR_BUF_FULL_SFT 7 +#define VUL24_SW_CLEAR_BUF_FULL_MASK 0x1 +#define VUL24_SW_CLEAR_BUF_FULL_MASK_SFT (0x1 << 7) +#define VUL24_WR_SIGN_SFT 6 +#define VUL24_WR_SIGN_MASK 0x1 +#define VUL24_WR_SIGN_MASK_SFT (0x1 << 6) +#define VUL24_R_MONO_SFT 5 +#define VUL24_R_MONO_MASK 0x1 +#define VUL24_R_MONO_MASK_SFT (0x1 << 5) +#define VUL24_MONO_SFT 4 +#define VUL24_MONO_MASK 0x1 +#define VUL24_MONO_MASK_SFT (0x1 << 4) +#define VUL24_NORMAL_MODE_SFT 3 +#define VUL24_NORMAL_MODE_MASK 0x1 +#define VUL24_NORMAL_MODE_MASK_SFT (0x1 << 3) +#define VUL24_HALIGN_SFT 2 +#define VUL24_HALIGN_MASK 0x1 +#define VUL24_HALIGN_MASK_SFT (0x1 << 2) +#define VUL24_HD_MODE_SFT 0 +#define VUL24_HD_MODE_MASK 0x3 +#define VUL24_HD_MODE_MASK_SFT (0x3 << 0) + +/* AFE_VUL24_MON0 */ +#define MEM_HW_WEN_SFT 20 +#define MEM_HW_WEN_MASK 0xf +#define MEM_HW_WEN_MASK_SFT (0xf << 20) +#define MEM_REQ_PENDING_SFT 19 +#define MEM_REQ_PENDING_MASK 0x1 +#define MEM_REQ_PENDING_MASK_SFT (0x1 << 19) +#define BUF_FULL_SFT 18 +#define BUF_FULL_MASK 0x1 +#define BUF_FULL_MASK_SFT (0x1 << 18) +#define ENABLE_SYNC_MEM_SFT 17 +#define ENABLE_SYNC_MEM_MASK 0x1 +#define ENABLE_SYNC_MEM_MASK_SFT (0x1 << 17) +#define ENABLE_SYNC_AGENT_SFT 16 +#define ENABLE_SYNC_AGENT_MASK 0x1 +#define ENABLE_SYNC_AGENT_MASK_SFT (0x1 << 16) +#define RESERVED_02_SFT 6 +#define RESERVED_02_MASK 0x3ff +#define RESERVED_02_MASK_SFT (0x3ff << 6) +#define MEM_ADDR_DIFF_SFT 0 +#define MEM_ADDR_DIFF_MASK 0x3f +#define MEM_ADDR_DIFF_MASK_SFT (0x3f << 0) + +/* AFE_VUL25_BASE_MSB */ +#define VUL25_BASE_ADDR_MSB_SFT 0 +#define VUL25_BASE_ADDR_MSB_MASK 0x1ff +#define VUL25_BASE_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL25_BASE */ +#define VUL25_BASE_ADDR_SFT 4 +#define VUL25_BASE_ADDR_MASK 0xfffffff +#define VUL25_BASE_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_VUL25_CUR_MSB */ +#define VUL25_CUR_PTR_MSB_SFT 0 +#define VUL25_CUR_PTR_MSB_MASK 0x1ff +#define VUL25_CUR_PTR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL25_CUR */ +#define VUL25_CUR_PTR_SFT 0 +#define VUL25_CUR_PTR_MASK 0xffffffff +#define VUL25_CUR_PTR_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL25_END_MSB */ +#define VUL25_END_ADDR_MSB_SFT 0 +#define VUL25_END_ADDR_MSB_MASK 0x1ff +#define VUL25_END_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL25_END */ +#define VUL25_END_ADDR_SFT 4 +#define VUL25_END_ADDR_MASK 0xfffffff +#define VUL25_END_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_VUL25_CON0 */ +#define OUT_ON_USE_VUL25_SFT 29 +#define OUT_ON_USE_VUL25_MASK 0x1 +#define OUT_ON_USE_VUL25_MASK_SFT (0x1 << 29) +#define VUL25_ON_SFT 28 +#define VUL25_ON_MASK 0x1 +#define VUL25_ON_MASK_SFT (0x1 << 28) +#define VUL25_MINLEN_SFT 20 +#define VUL25_MINLEN_MASK 0x3 +#define VUL25_MINLEN_MASK_SFT (0x3 << 20) +#define VUL25_MAXLEN_SFT 16 +#define VUL25_MAXLEN_MASK 0x3 +#define VUL25_MAXLEN_MASK_SFT (0x3 << 16) +#define VUL25_SEL_DOMAIN_SFT 13 +#define VUL25_SEL_DOMAIN_MASK 0x7 +#define VUL25_SEL_DOMAIN_MASK_SFT (0x7 << 13) +#define VUL25_SEL_FS_SFT 8 +#define VUL25_SEL_FS_MASK 0x1f +#define VUL25_SEL_FS_MASK_SFT (0x1f << 8) +#define VUL25_SW_CLEAR_BUF_FULL_SFT 7 +#define VUL25_SW_CLEAR_BUF_FULL_MASK 0x1 +#define VUL25_SW_CLEAR_BUF_FULL_MASK_SFT (0x1 << 7) +#define VUL25_WR_SIGN_SFT 6 +#define VUL25_WR_SIGN_MASK 0x1 +#define VUL25_WR_SIGN_MASK_SFT (0x1 << 6) +#define VUL25_R_MONO_SFT 5 +#define VUL25_R_MONO_MASK 0x1 +#define VUL25_R_MONO_MASK_SFT (0x1 << 5) +#define VUL25_MONO_SFT 4 +#define VUL25_MONO_MASK 0x1 +#define VUL25_MONO_MASK_SFT (0x1 << 4) +#define VUL25_NORMAL_MODE_SFT 3 +#define VUL25_NORMAL_MODE_MASK 0x1 +#define VUL25_NORMAL_MODE_MASK_SFT (0x1 << 3) +#define VUL25_HALIGN_SFT 2 +#define VUL25_HALIGN_MASK 0x1 +#define VUL25_HALIGN_MASK_SFT (0x1 << 2) +#define VUL25_HD_MODE_SFT 0 +#define VUL25_HD_MODE_MASK 0x3 +#define VUL25_HD_MODE_MASK_SFT (0x3 << 0) + +/* AFE_VUL25_MON0 */ +#define MEM_HW_WEN_SFT 20 +#define MEM_HW_WEN_MASK 0xf +#define MEM_HW_WEN_MASK_SFT (0xf << 20) +#define MEM_REQ_PENDING_SFT 19 +#define MEM_REQ_PENDING_MASK 0x1 +#define MEM_REQ_PENDING_MASK_SFT (0x1 << 19) +#define BUF_FULL_SFT 18 +#define BUF_FULL_MASK 0x1 +#define BUF_FULL_MASK_SFT (0x1 << 18) +#define ENABLE_SYNC_MEM_SFT 17 +#define ENABLE_SYNC_MEM_MASK 0x1 +#define ENABLE_SYNC_MEM_MASK_SFT (0x1 << 17) +#define ENABLE_SYNC_AGENT_SFT 16 +#define ENABLE_SYNC_AGENT_MASK 0x1 +#define ENABLE_SYNC_AGENT_MASK_SFT (0x1 << 16) +#define RESERVED_02_SFT 6 +#define RESERVED_02_MASK 0x3ff +#define RESERVED_02_MASK_SFT (0x3ff << 6) +#define MEM_ADDR_DIFF_SFT 0 +#define MEM_ADDR_DIFF_MASK 0x3f +#define MEM_ADDR_DIFF_MASK_SFT (0x3f << 0) + +/* AFE_VUL_CM0_BASE_MSB */ +#define VUL_CM0_BASE_ADDR_MSB_SFT 0 +#define VUL_CM0_BASE_ADDR_MSB_MASK 0x1ff +#define VUL_CM0_BASE_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL_CM0_BASE */ +#define VUL_CM0_BASE_ADDR_SFT 4 +#define VUL_CM0_BASE_ADDR_MASK 0xfffffff +#define VUL_CM0_BASE_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_VUL_CM0_CUR_MSB */ +#define VUL_CM0_CUR_PTR_MSB_SFT 0 +#define VUL_CM0_CUR_PTR_MSB_MASK 0x1ff +#define VUL_CM0_CUR_PTR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL_CM0_CUR */ +#define VUL_CM0_CUR_PTR_SFT 0 +#define VUL_CM0_CUR_PTR_MASK 0xffffffff +#define VUL_CM0_CUR_PTR_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL_CM0_END_MSB */ +#define VUL_CM0_END_ADDR_MSB_SFT 0 +#define VUL_CM0_END_ADDR_MSB_MASK 0x1ff +#define VUL_CM0_END_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL_CM0_END */ +#define VUL_CM0_END_ADDR_SFT 4 +#define VUL_CM0_END_ADDR_MASK 0xfffffff +#define VUL_CM0_END_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_VUL_CM0_CON0 */ +#define VUL_CM0_ON_SFT 28 +#define VUL_CM0_ON_MASK 0x1 +#define VUL_CM0_ON_MASK_SFT (0x1 << 28) +#define VUL_CM0_REG_CH_SHIFT_MODE_SFT 26 +#define VUL_CM0_REG_CH_SHIFT_MODE_MASK 0x1 +#define VUL_CM0_REG_CH_SHIFT_MODE_MASK_SFT (0x1 << 26) +#define VUL_CM0_RG_FORCE_NO_MASK_EXTRA_SFT 25 +#define VUL_CM0_RG_FORCE_NO_MASK_EXTRA_MASK 0x1 +#define VUL_CM0_RG_FORCE_NO_MASK_EXTRA_MASK_SFT (0x1 << 25) +#define VUL_CM0_SW_CLEAR_BUF_FULL_SFT 24 +#define VUL_CM0_SW_CLEAR_BUF_FULL_MASK 0x1 +#define VUL_CM0_SW_CLEAR_BUF_FULL_MASK_SFT (0x1 << 24) +#define VUL_CM0_ULTRA_TH_SFT 20 +#define VUL_CM0_ULTRA_TH_MASK 0xf +#define VUL_CM0_ULTRA_TH_MASK_SFT (0xf << 20) +#define VUL_CM0_NORMAL_MODE_SFT 17 +#define VUL_CM0_NORMAL_MODE_MASK 0x1 +#define VUL_CM0_NORMAL_MODE_MASK_SFT (0x1 << 17) +#define VUL_CM0_ODD_USE_EVEN_SFT 16 +#define VUL_CM0_ODD_USE_EVEN_MASK 0x1 +#define VUL_CM0_ODD_USE_EVEN_MASK_SFT (0x1 << 16) +#define VUL_CM0_AXI_REQ_MAXLEN_SFT 12 +#define VUL_CM0_AXI_REQ_MAXLEN_MASK 0x3 +#define VUL_CM0_AXI_REQ_MAXLEN_MASK_SFT (0x3 << 12) +#define VUL_CM0_AXI_REQ_MINLEN_SFT 8 +#define VUL_CM0_AXI_REQ_MINLEN_MASK 0x3 +#define VUL_CM0_AXI_REQ_MINLEN_MASK_SFT (0x3 << 8) +#define VUL_CM0_HALIGN_SFT 7 +#define VUL_CM0_HALIGN_MASK 0x1 +#define VUL_CM0_HALIGN_MASK_SFT (0x1 << 7) +#define VUL_CM0_SIGN_EXT_SFT 6 +#define VUL_CM0_SIGN_EXT_MASK 0x1 +#define VUL_CM0_SIGN_EXT_MASK_SFT (0x1 << 6) +#define VUL_CM0_HD_MODE_SFT 4 +#define VUL_CM0_HD_MODE_MASK 0x3 +#define VUL_CM0_HD_MODE_MASK_SFT (0x3 << 4) +#define VUL_CM0_MAKE_EXTRA_UPDATE_SFT 3 +#define VUL_CM0_MAKE_EXTRA_UPDATE_MASK 0x1 +#define VUL_CM0_MAKE_EXTRA_UPDATE_MASK_SFT (0x1 << 3) +#define VUL_CM0_AGENT_FREE_RUN_SFT 2 +#define VUL_CM0_AGENT_FREE_RUN_MASK 0x1 +#define VUL_CM0_AGENT_FREE_RUN_MASK_SFT (0x1 << 2) +#define VUL_CM0_USE_INT_ODD_SFT 1 +#define VUL_CM0_USE_INT_ODD_MASK 0x1 +#define VUL_CM0_USE_INT_ODD_MASK_SFT (0x1 << 1) +#define VUL_CM0_INT_ODD_FLAG_SFT 0 +#define VUL_CM0_INT_ODD_FLAG_MASK 0x1 +#define VUL_CM0_INT_ODD_FLAG_MASK_SFT (0x1 << 0) + +/* AFE_VUL_CM1_BASE_MSB */ +#define VUL_CM1_BASE_ADDR_MSB_SFT 0 +#define VUL_CM1_BASE_ADDR_MSB_MASK 0x1ff +#define VUL_CM1_BASE_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL_CM1_BASE */ +#define VUL_CM1_BASE_ADDR_SFT 4 +#define VUL_CM1_BASE_ADDR_MASK 0xfffffff +#define VUL_CM1_BASE_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_VUL_CM1_CUR_MSB */ +#define VUL_CM1_CUR_PTR_MSB_SFT 0 +#define VUL_CM1_CUR_PTR_MSB_MASK 0x1ff +#define VUL_CM1_CUR_PTR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL_CM1_CUR */ +#define VUL_CM1_CUR_PTR_SFT 0 +#define VUL_CM1_CUR_PTR_MASK 0xffffffff +#define VUL_CM1_CUR_PTR_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL_CM1_END_MSB */ +#define VUL_CM1_END_ADDR_MSB_SFT 0 +#define VUL_CM1_END_ADDR_MSB_MASK 0x1ff +#define VUL_CM1_END_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_VUL_CM1_END */ +#define VUL_CM1_END_ADDR_SFT 4 +#define VUL_CM1_END_ADDR_MASK 0xfffffff +#define VUL_CM1_END_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_VUL_CM1_CON0 */ +#define VUL_CM1_ON_SFT 28 +#define VUL_CM1_ON_MASK 0x1 +#define VUL_CM1_ON_MASK_SFT (0x1 << 28) +#define VUL_CM1_REG_CH_SHIFT_MODE_SFT 26 +#define VUL_CM1_REG_CH_SHIFT_MODE_MASK 0x1 +#define VUL_CM1_REG_CH_SHIFT_MODE_MASK_SFT (0x1 << 26) +#define VUL_CM1_RG_FORCE_NO_MASK_EXTRA_SFT 25 +#define VUL_CM1_RG_FORCE_NO_MASK_EXTRA_MASK 0x1 +#define VUL_CM1_RG_FORCE_NO_MASK_EXTRA_MASK_SFT (0x1 << 25) +#define VUL_CM1_SW_CLEAR_BUF_FULL_SFT 24 +#define VUL_CM1_SW_CLEAR_BUF_FULL_MASK 0x1 +#define VUL_CM1_SW_CLEAR_BUF_FULL_MASK_SFT (0x1 << 24) +#define VUL_CM1_ULTRA_TH_SFT 20 +#define VUL_CM1_ULTRA_TH_MASK 0xf +#define VUL_CM1_ULTRA_TH_MASK_SFT (0xf << 20) +#define VUL_CM1_NORMAL_MODE_SFT 17 +#define VUL_CM1_NORMAL_MODE_MASK 0x1 +#define VUL_CM1_NORMAL_MODE_MASK_SFT (0x1 << 17) +#define VUL_CM1_ODD_USE_EVEN_SFT 16 +#define VUL_CM1_ODD_USE_EVEN_MASK 0x1 +#define VUL_CM1_ODD_USE_EVEN_MASK_SFT (0x1 << 16) +#define VUL_CM1_AXI_REQ_MAXLEN_SFT 12 +#define VUL_CM1_AXI_REQ_MAXLEN_MASK 0x3 +#define VUL_CM1_AXI_REQ_MAXLEN_MASK_SFT (0x3 << 12) +#define VUL_CM1_AXI_REQ_MINLEN_SFT 8 +#define VUL_CM1_AXI_REQ_MINLEN_MASK 0x3 +#define VUL_CM1_AXI_REQ_MINLEN_MASK_SFT (0x3 << 8) +#define VUL_CM1_HALIGN_SFT 7 +#define VUL_CM1_HALIGN_MASK 0x1 +#define VUL_CM1_HALIGN_MASK_SFT (0x1 << 7) +#define VUL_CM1_SIGN_EXT_SFT 6 +#define VUL_CM1_SIGN_EXT_MASK 0x1 +#define VUL_CM1_SIGN_EXT_MASK_SFT (0x1 << 6) +#define VUL_CM1_HD_MODE_SFT 4 +#define VUL_CM1_HD_MODE_MASK 0x3 +#define VUL_CM1_HD_MODE_MASK_SFT (0x3 << 4) +#define VUL_CM1_MAKE_EXTRA_UPDATE_SFT 3 +#define VUL_CM1_MAKE_EXTRA_UPDATE_MASK 0x1 +#define VUL_CM1_MAKE_EXTRA_UPDATE_MASK_SFT (0x1 << 3) +#define VUL_CM1_AGENT_FREE_RUN_SFT 2 +#define VUL_CM1_AGENT_FREE_RUN_MASK 0x1 +#define VUL_CM1_AGENT_FREE_RUN_MASK_SFT (0x1 << 2) +#define VUL_CM1_USE_INT_ODD_SFT 1 +#define VUL_CM1_USE_INT_ODD_MASK 0x1 +#define VUL_CM1_USE_INT_ODD_MASK_SFT (0x1 << 1) +#define VUL_CM1_INT_ODD_FLAG_SFT 0 +#define VUL_CM1_INT_ODD_FLAG_MASK 0x1 +#define VUL_CM1_INT_ODD_FLAG_MASK_SFT (0x1 << 0) + +/* AFE_ETDM_IN0_BASE_MSB */ +#define ETDM_IN0_BASE_ADDR_MSB_SFT 0 +#define ETDM_IN0_BASE_ADDR_MSB_MASK 0x1ff +#define ETDM_IN0_BASE_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_ETDM_IN0_BASE */ +#define ETDM_IN0_BASE_ADDR_SFT 4 +#define ETDM_IN0_BASE_ADDR_MASK 0xfffffff +#define ETDM_IN0_BASE_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_ETDM_IN0_CUR_MSB */ +#define ETDM_IN0_CUR_PTR_MSB_SFT 0 +#define ETDM_IN0_CUR_PTR_MSB_MASK 0x1ff +#define ETDM_IN0_CUR_PTR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_ETDM_IN0_CUR */ +#define ETDM_IN0_CUR_PTR_SFT 0 +#define ETDM_IN0_CUR_PTR_MASK 0xffffffff +#define ETDM_IN0_CUR_PTR_MASK_SFT (0xffffffff << 0) + +/* AFE_ETDM_IN0_END_MSB */ +#define ETDM_IN0_END_ADDR_MSB_SFT 0 +#define ETDM_IN0_END_ADDR_MSB_MASK 0x1ff +#define ETDM_IN0_END_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_ETDM_IN0_END */ +#define ETDM_IN0_END_ADDR_SFT 4 +#define ETDM_IN0_END_ADDR_MASK 0xfffffff +#define ETDM_IN0_END_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_ETDM_IN0_CON0 */ +#define ETDM_IN0_CH_NUM_SFT 28 +#define ETDM_IN0_CH_NUM_MASK 0xf +#define ETDM_IN0_CH_NUM_MASK_SFT (0xf << 28) +#define ETDM_IN0_ON_SFT 27 +#define ETDM_IN0_ON_MASK 0x1 +#define ETDM_IN0_ON_MASK_SFT (0x1 << 27) +#define ETDM_IN0_REG_CH_SHIFT_MODE_SFT 26 +#define ETDM_IN0_REG_CH_SHIFT_MODE_MASK 0x1 +#define ETDM_IN0_REG_CH_SHIFT_MODE_MASK_SFT (0x1 << 26) +#define ETDM_IN0_RG_FORCE_NO_MASK_EXTRA_SFT 25 +#define ETDM_IN0_RG_FORCE_NO_MASK_EXTRA_MASK 0x1 +#define ETDM_IN0_RG_FORCE_NO_MASK_EXTRA_MASK_SFT (0x1 << 25) +#define ETDM_IN0_SW_CLEAR_BUF_FULL_SFT 24 +#define ETDM_IN0_SW_CLEAR_BUF_FULL_MASK 0x1 +#define ETDM_IN0_SW_CLEAR_BUF_FULL_MASK_SFT (0x1 << 24) +#define ETDM_IN0_ULTRA_TH_SFT 20 +#define ETDM_IN0_ULTRA_TH_MASK 0xf +#define ETDM_IN0_ULTRA_TH_MASK_SFT (0xf << 20) +#define ETDM_IN0_NORMAL_MODE_SFT 17 +#define ETDM_IN0_NORMAL_MODE_MASK 0x1 +#define ETDM_IN0_NORMAL_MODE_MASK_SFT (0x1 << 17) +#define ETDM_IN0_ODD_USE_EVEN_SFT 16 +#define ETDM_IN0_ODD_USE_EVEN_MASK 0x1 +#define ETDM_IN0_ODD_USE_EVEN_MASK_SFT (0x1 << 16) +#define ETDM_IN0_AXI_REQ_MAXLEN_SFT 12 +#define ETDM_IN0_AXI_REQ_MAXLEN_MASK 0x3 +#define ETDM_IN0_AXI_REQ_MAXLEN_MASK_SFT (0x3 << 12) +#define ETDM_IN0_AXI_REQ_MINLEN_SFT 8 +#define ETDM_IN0_AXI_REQ_MINLEN_MASK 0x3 +#define ETDM_IN0_AXI_REQ_MINLEN_MASK_SFT (0x3 << 8) +#define ETDM_IN0_HALIGN_SFT 7 +#define ETDM_IN0_HALIGN_MASK 0x1 +#define ETDM_IN0_HALIGN_MASK_SFT (0x1 << 7) +#define ETDM_IN0_SIGN_EXT_SFT 6 +#define ETDM_IN0_SIGN_EXT_MASK 0x1 +#define ETDM_IN0_SIGN_EXT_MASK_SFT (0x1 << 6) +#define ETDM_IN0_HD_MODE_SFT 4 +#define ETDM_IN0_HD_MODE_MASK 0x3 +#define ETDM_IN0_HD_MODE_MASK_SFT (0x3 << 4) +#define ETDM_IN0_MAKE_EXTRA_UPDATE_SFT 3 +#define ETDM_IN0_MAKE_EXTRA_UPDATE_MASK 0x1 +#define ETDM_IN0_MAKE_EXTRA_UPDATE_MASK_SFT (0x1 << 3) +#define ETDM_IN0_AGENT_FREE_RUN_SFT 2 +#define ETDM_IN0_AGENT_FREE_RUN_MASK 0x1 +#define ETDM_IN0_AGENT_FREE_RUN_MASK_SFT (0x1 << 2) +#define ETDM_IN0_USE_INT_ODD_SFT 1 +#define ETDM_IN0_USE_INT_ODD_MASK 0x1 +#define ETDM_IN0_USE_INT_ODD_MASK_SFT (0x1 << 1) +#define ETDM_IN0_INT_ODD_FLAG_SFT 0 +#define ETDM_IN0_INT_ODD_FLAG_MASK 0x1 +#define ETDM_IN0_INT_ODD_FLAG_MASK_SFT (0x1 << 0) + +/* AFE_ETDM_IN1_BASE_MSB */ +#define ETDM_IN1_BASE_ADDR_MSB_SFT 0 +#define ETDM_IN1_BASE_ADDR_MSB_MASK 0x1ff +#define ETDM_IN1_BASE_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_ETDM_IN1_BASE */ +#define ETDM_IN1_BASE_ADDR_SFT 4 +#define ETDM_IN1_BASE_ADDR_MASK 0xfffffff +#define ETDM_IN1_BASE_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_ETDM_IN1_CUR_MSB */ +#define ETDM_IN1_CUR_PTR_MSB_SFT 0 +#define ETDM_IN1_CUR_PTR_MSB_MASK 0x1ff +#define ETDM_IN1_CUR_PTR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_ETDM_IN1_CUR */ +#define ETDM_IN1_CUR_PTR_SFT 0 +#define ETDM_IN1_CUR_PTR_MASK 0xffffffff +#define ETDM_IN1_CUR_PTR_MASK_SFT (0xffffffff << 0) + +/* AFE_ETDM_IN1_END_MSB */ +#define ETDM_IN1_END_ADDR_MSB_SFT 0 +#define ETDM_IN1_END_ADDR_MSB_MASK 0x1ff +#define ETDM_IN1_END_ADDR_MSB_MASK_SFT (0x1ff << 0) + +/* AFE_ETDM_IN1_END */ +#define ETDM_IN1_END_ADDR_SFT 4 +#define ETDM_IN1_END_ADDR_MASK 0xfffffff +#define ETDM_IN1_END_ADDR_MASK_SFT (0xfffffff << 4) + +/* AFE_ETDM_IN1_CON0 */ +#define ETDM_IN1_CH_NUM_SFT 28 +#define ETDM_IN1_CH_NUM_MASK 0xf +#define ETDM_IN1_CH_NUM_MASK_SFT (0xf << 28) +#define ETDM_IN1_ON_SFT 27 +#define ETDM_IN1_ON_MASK 0x1 +#define ETDM_IN1_ON_MASK_SFT (0x1 << 27) +#define ETDM_IN1_REG_CH_SHIFT_MODE_SFT 26 +#define ETDM_IN1_REG_CH_SHIFT_MODE_MASK 0x1 +#define ETDM_IN1_REG_CH_SHIFT_MODE_MASK_SFT (0x1 << 26) +#define ETDM_IN1_RG_FORCE_NO_MASK_EXTRA_SFT 25 +#define ETDM_IN1_RG_FORCE_NO_MASK_EXTRA_MASK 0x1 +#define ETDM_IN1_RG_FORCE_NO_MASK_EXTRA_MASK_SFT (0x1 << 25) +#define ETDM_IN1_SW_CLEAR_BUF_FULL_SFT 24 +#define ETDM_IN1_SW_CLEAR_BUF_FULL_MASK 0x1 +#define ETDM_IN1_SW_CLEAR_BUF_FULL_MASK_SFT (0x1 << 24) +#define ETDM_IN1_ULTRA_TH_SFT 20 +#define ETDM_IN1_ULTRA_TH_MASK 0xf +#define ETDM_IN1_ULTRA_TH_MASK_SFT (0xf << 20) +#define ETDM_IN1_NORMAL_MODE_SFT 17 +#define ETDM_IN1_NORMAL_MODE_MASK 0x1 +#define ETDM_IN1_NORMAL_MODE_MASK_SFT (0x1 << 17) +#define ETDM_IN1_ODD_USE_EVEN_SFT 16 +#define ETDM_IN1_ODD_USE_EVEN_MASK 0x1 +#define ETDM_IN1_ODD_USE_EVEN_MASK_SFT (0x1 << 16) +#define ETDM_IN1_AXI_REQ_MAXLEN_SFT 12 +#define ETDM_IN1_AXI_REQ_MAXLEN_MASK 0x3 +#define ETDM_IN1_AXI_REQ_MAXLEN_MASK_SFT (0x3 << 12) +#define ETDM_IN1_AXI_REQ_MINLEN_SFT 8 +#define ETDM_IN1_AXI_REQ_MINLEN_MASK 0x3 +#define ETDM_IN1_AXI_REQ_MINLEN_MASK_SFT (0x3 << 8) +#define ETDM_IN1_HALIGN_SFT 7 +#define ETDM_IN1_HALIGN_MASK 0x1 +#define ETDM_IN1_HALIGN_MASK_SFT (0x1 << 7) +#define ETDM_IN1_SIGN_EXT_SFT 6 +#define ETDM_IN1_SIGN_EXT_MASK 0x1 +#define ETDM_IN1_SIGN_EXT_MASK_SFT (0x1 << 6) +#define ETDM_IN1_HD_MODE_SFT 4 +#define ETDM_IN1_HD_MODE_MASK 0x3 +#define ETDM_IN1_HD_MODE_MASK_SFT (0x3 << 4) +#define ETDM_IN1_MAKE_EXTRA_UPDATE_SFT 3 +#define ETDM_IN1_MAKE_EXTRA_UPDATE_MASK 0x1 +#define ETDM_IN1_MAKE_EXTRA_UPDATE_MASK_SFT (0x1 << 3) +#define ETDM_IN1_AGENT_FREE_RUN_SFT 2 +#define ETDM_IN1_AGENT_FREE_RUN_MASK 0x1 +#define ETDM_IN1_AGENT_FREE_RUN_MASK_SFT (0x1 << 2) +#define ETDM_IN1_USE_INT_ODD_SFT 1 +#define ETDM_IN1_USE_INT_ODD_MASK 0x1 +#define ETDM_IN1_USE_INT_ODD_MASK_SFT (0x1 << 1) +#define ETDM_IN1_INT_ODD_FLAG_SFT 0 +#define ETDM_IN1_INT_ODD_FLAG_MASK 0x1 +#define ETDM_IN1_INT_ODD_FLAG_MASK_SFT (0x1 << 0) + +/* AFE_VUL24_RCH_MON */ +#define VUL24_RCH_DATA_SFT 0 +#define VUL24_RCH_DATA_MASK 0xffffffff +#define VUL24_RCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL24_LCH_MON */ +#define VUL24_LCH_DATA_SFT 0 +#define VUL24_LCH_DATA_MASK 0xffffffff +#define VUL24_LCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL25_RCH_MON */ +#define VUL25_RCH_DATA_SFT 0 +#define VUL25_RCH_DATA_MASK 0xffffffff +#define VUL25_RCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL25_LCH_MON */ +#define VUL25_LCH_DATA_SFT 0 +#define VUL25_LCH_DATA_MASK 0xffffffff +#define VUL25_LCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL_CM0_RCH_MON */ +#define VUL_CM0_RCH_DATA_SFT 0 +#define VUL_CM0_RCH_DATA_MASK 0xffffffff +#define VUL_CM0_RCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL_CM0_LCH_MON */ +#define VUL_CM0_LCH_DATA_SFT 0 +#define VUL_CM0_LCH_DATA_MASK 0xffffffff +#define VUL_CM0_LCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL_CM1_RCH_MON */ +#define VUL_CM1_RCH_DATA_SFT 0 +#define VUL_CM1_RCH_DATA_MASK 0xffffffff +#define VUL_CM1_RCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_VUL_CM1_LCH_MON */ +#define VUL_CM1_LCH_DATA_SFT 0 +#define VUL_CM1_LCH_DATA_MASK 0xffffffff +#define VUL_CM1_LCH_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_DL_24CH_CH0_MON */ +#define DL_24CH_CH0_DATA_SFT 0 +#define DL_24CH_CH0_DATA_MASK 0xffffffff +#define DL_24CH_CH0_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_DL_24CH_CH1_MON */ +#define DL_24CH_CH1_DATA_SFT 0 +#define DL_24CH_CH1_DATA_MASK 0xffffffff +#define DL_24CH_CH1_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_DL_24CH_CH2_MON */ +#define DL_24CH_CH2_DATA_SFT 0 +#define DL_24CH_CH2_DATA_MASK 0xffffffff +#define DL_24CH_CH2_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_DL_24CH_CH3_MON */ +#define DL_24CH_CH3_DATA_SFT 0 +#define DL_24CH_CH3_DATA_MASK 0xffffffff +#define DL_24CH_CH3_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_DL_24CH_CH4_MON */ +#define DL_24CH_CH4_DATA_SFT 0 +#define DL_24CH_CH4_DATA_MASK 0xffffffff +#define DL_24CH_CH4_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_DL_24CH_CH5_MON */ +#define DL_24CH_CH5_DATA_SFT 0 +#define DL_24CH_CH5_DATA_MASK 0xffffffff +#define DL_24CH_CH5_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_DL_24CH_CH6_MON */ +#define DL_24CH_CH6_DATA_SFT 0 +#define DL_24CH_CH6_DATA_MASK 0xffffffff +#define DL_24CH_CH6_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_DL_24CH_CH7_MON */ +#define DL_24CH_CH7_DATA_SFT 0 +#define DL_24CH_CH7_DATA_MASK 0xffffffff +#define DL_24CH_CH7_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_SRAM_BOUND */ +#define SECURE_BIT_SFT 19 +#define SECURE_BIT_MASK 0x1 +#define SECURE_BIT_MASK_SFT (0x1 << 19) +#define SECURE_SRAM_BOUND_SFT 0 +#define SECURE_SRAM_BOUND_MASK 0x7ffff +#define SECURE_SRAM_BOUND_MASK_SFT (0x7ffff << 0) + +/* AFE_SECURE_CON0 */ +#define READ_EN15_NS_SFT 31 +#define READ_EN15_NS_MASK 0x1 +#define READ_EN15_NS_MASK_SFT (0x1 << 31) +#define WRITE_EN15_NS_SFT 30 +#define WRITE_EN15_NS_MASK 0x1 +#define WRITE_EN15_NS_MASK_SFT (0x1 << 30) +#define READ_EN14_NS_SFT 29 +#define READ_EN14_NS_MASK 0x1 +#define READ_EN14_NS_MASK_SFT (0x1 << 29) +#define WRITE_EN14_NS_SFT 28 +#define WRITE_EN14_NS_MASK 0x1 +#define WRITE_EN14_NS_MASK_SFT (0x1 << 28) +#define READ_EN13_NS_SFT 27 +#define READ_EN13_NS_MASK 0x1 +#define READ_EN13_NS_MASK_SFT (0x1 << 27) +#define WRITE_EN13_NS_SFT 26 +#define WRITE_EN13_NS_MASK 0x1 +#define WRITE_EN13_NS_MASK_SFT (0x1 << 26) +#define READ_EN12_NS_SFT 25 +#define READ_EN12_NS_MASK 0x1 +#define READ_EN12_NS_MASK_SFT (0x1 << 25) +#define WRITE_EN12_NS_SFT 24 +#define WRITE_EN12_NS_MASK 0x1 +#define WRITE_EN12_NS_MASK_SFT (0x1 << 24) +#define READ_EN11_NS_SFT 23 +#define READ_EN11_NS_MASK 0x1 +#define READ_EN11_NS_MASK_SFT (0x1 << 23) +#define WRITE_EN11_NS_SFT 22 +#define WRITE_EN11_NS_MASK 0x1 +#define WRITE_EN11_NS_MASK_SFT (0x1 << 22) +#define READ_EN10_NS_SFT 21 +#define READ_EN10_NS_MASK 0x1 +#define READ_EN10_NS_MASK_SFT (0x1 << 21) +#define WRITE_EN10_NS_SFT 20 +#define WRITE_EN10_NS_MASK 0x1 +#define WRITE_EN10_NS_MASK_SFT (0x1 << 20) +#define READ_EN9_NS_SFT 19 +#define READ_EN9_NS_MASK 0x1 +#define READ_EN9_NS_MASK_SFT (0x1 << 19) +#define WRITE_EN9_NS_SFT 18 +#define WRITE_EN9_NS_MASK 0x1 +#define WRITE_EN9_NS_MASK_SFT (0x1 << 18) +#define READ_EN8_NS_SFT 17 +#define READ_EN8_NS_MASK 0x1 +#define READ_EN8_NS_MASK_SFT (0x1 << 17) +#define WRITE_EN8_NS_SFT 16 +#define WRITE_EN8_NS_MASK 0x1 +#define WRITE_EN8_NS_MASK_SFT (0x1 << 16) +#define READ_EN7_NS_SFT 15 +#define READ_EN7_NS_MASK 0x1 +#define READ_EN7_NS_MASK_SFT (0x1 << 15) +#define WRITE_EN7_NS_SFT 14 +#define WRITE_EN7_NS_MASK 0x1 +#define WRITE_EN7_NS_MASK_SFT (0x1 << 14) +#define READ_EN6_NS_SFT 13 +#define READ_EN6_NS_MASK 0x1 +#define READ_EN6_NS_MASK_SFT (0x1 << 13) +#define WRITE_EN6_NS_SFT 12 +#define WRITE_EN6_NS_MASK 0x1 +#define WRITE_EN6_NS_MASK_SFT (0x1 << 12) +#define READ_EN5_NS_SFT 11 +#define READ_EN5_NS_MASK 0x1 +#define READ_EN5_NS_MASK_SFT (0x1 << 11) +#define WRITE_EN5_NS_SFT 10 +#define WRITE_EN5_NS_MASK 0x1 +#define WRITE_EN5_NS_MASK_SFT (0x1 << 10) +#define READ_EN4_NS_SFT 9 +#define READ_EN4_NS_MASK 0x1 +#define READ_EN4_NS_MASK_SFT (0x1 << 9) +#define WRITE_EN4_NS_SFT 8 +#define WRITE_EN4_NS_MASK 0x1 +#define WRITE_EN4_NS_MASK_SFT (0x1 << 8) +#define READ_EN3_NS_SFT 7 +#define READ_EN3_NS_MASK 0x1 +#define READ_EN3_NS_MASK_SFT (0x1 << 7) +#define WRITE_EN3_NS_SFT 6 +#define WRITE_EN3_NS_MASK 0x1 +#define WRITE_EN3_NS_MASK_SFT (0x1 << 6) +#define READ_EN2_NS_SFT 5 +#define READ_EN2_NS_MASK 0x1 +#define READ_EN2_NS_MASK_SFT (0x1 << 5) +#define WRITE_EN2_NS_SFT 4 +#define WRITE_EN2_NS_MASK 0x1 +#define WRITE_EN2_NS_MASK_SFT (0x1 << 4) +#define READ_EN1_NS_SFT 3 +#define READ_EN1_NS_MASK 0x1 +#define READ_EN1_NS_MASK_SFT (0x1 << 3) +#define WRITE_EN1_NS_SFT 2 +#define WRITE_EN1_NS_MASK 0x1 +#define WRITE_EN1_NS_MASK_SFT (0x1 << 2) +#define READ_EN0_NS_SFT 1 +#define READ_EN0_NS_MASK 0x1 +#define READ_EN0_NS_MASK_SFT (0x1 << 1) +#define WRITE_EN0_NS_SFT 0 +#define WRITE_EN0_NS_MASK 0x1 +#define WRITE_EN0_NS_MASK_SFT (0x1 << 0) + +/* AFE_SECURE_CON1 */ +#define READ_EN15_S_SFT 31 +#define READ_EN15_S_MASK 0x1 +#define READ_EN15_S_MASK_SFT (0x1 << 31) +#define WRITE_EN15_S_SFT 30 +#define WRITE_EN15_S_MASK 0x1 +#define WRITE_EN15_S_MASK_SFT (0x1 << 30) +#define READ_EN14_S_SFT 29 +#define READ_EN14_S_MASK 0x1 +#define READ_EN14_S_MASK_SFT (0x1 << 29) +#define WRITE_EN14_S_SFT 28 +#define WRITE_EN14_S_MASK 0x1 +#define WRITE_EN14_S_MASK_SFT (0x1 << 28) +#define READ_EN13_S_SFT 27 +#define READ_EN13_S_MASK 0x1 +#define READ_EN13_S_MASK_SFT (0x1 << 27) +#define WRITE_EN13_S_SFT 26 +#define WRITE_EN13_S_MASK 0x1 +#define WRITE_EN13_S_MASK_SFT (0x1 << 26) +#define READ_EN12_S_SFT 25 +#define READ_EN12_S_MASK 0x1 +#define READ_EN12_S_MASK_SFT (0x1 << 25) +#define WRITE_EN12_S_SFT 24 +#define WRITE_EN12_S_MASK 0x1 +#define WRITE_EN12_S_MASK_SFT (0x1 << 24) +#define READ_EN11_S_SFT 23 +#define READ_EN11_S_MASK 0x1 +#define READ_EN11_S_MASK_SFT (0x1 << 23) +#define WRITE_EN11_S_SFT 22 +#define WRITE_EN11_S_MASK 0x1 +#define WRITE_EN11_S_MASK_SFT (0x1 << 22) +#define READ_EN10_S_SFT 21 +#define READ_EN10_S_MASK 0x1 +#define READ_EN10_S_MASK_SFT (0x1 << 21) +#define WRITE_EN10_S_SFT 20 +#define WRITE_EN10_S_MASK 0x1 +#define WRITE_EN10_S_MASK_SFT (0x1 << 20) +#define READ_EN9_S_SFT 19 +#define READ_EN9_S_MASK 0x1 +#define READ_EN9_S_MASK_SFT (0x1 << 19) +#define WRITE_EN9_S_SFT 18 +#define WRITE_EN9_S_MASK 0x1 +#define WRITE_EN9_S_MASK_SFT (0x1 << 18) +#define READ_EN8_S_SFT 17 +#define READ_EN8_S_MASK 0x1 +#define READ_EN8_S_MASK_SFT (0x1 << 17) +#define WRITE_EN8_S_SFT 16 +#define WRITE_EN8_S_MASK 0x1 +#define WRITE_EN8_S_MASK_SFT (0x1 << 16) +#define READ_EN7_S_SFT 15 +#define READ_EN7_S_MASK 0x1 +#define READ_EN7_S_MASK_SFT (0x1 << 15) +#define WRITE_EN7_S_SFT 14 +#define WRITE_EN7_S_MASK 0x1 +#define WRITE_EN7_S_MASK_SFT (0x1 << 14) +#define READ_EN6_S_SFT 13 +#define READ_EN6_S_MASK 0x1 +#define READ_EN6_S_MASK_SFT (0x1 << 13) +#define WRITE_EN6_S_SFT 12 +#define WRITE_EN6_S_MASK 0x1 +#define WRITE_EN6_S_MASK_SFT (0x1 << 12) +#define READ_EN5_S_SFT 11 +#define READ_EN5_S_MASK 0x1 +#define READ_EN5_S_MASK_SFT (0x1 << 11) +#define WRITE_EN5_S_SFT 10 +#define WRITE_EN5_S_MASK 0x1 +#define WRITE_EN5_S_MASK_SFT (0x1 << 10) +#define READ_EN4_S_SFT 9 +#define READ_EN4_S_MASK 0x1 +#define READ_EN4_S_MASK_SFT (0x1 << 9) +#define WRITE_EN4_S_SFT 8 +#define WRITE_EN4_S_MASK 0x1 +#define WRITE_EN4_S_MASK_SFT (0x1 << 8) +#define READ_EN3_S_SFT 7 +#define READ_EN3_S_MASK 0x1 +#define READ_EN3_S_MASK_SFT (0x1 << 7) +#define WRITE_EN3_S_SFT 6 +#define WRITE_EN3_S_MASK 0x1 +#define WRITE_EN3_S_MASK_SFT (0x1 << 6) +#define READ_EN2_S_SFT 5 +#define READ_EN2_S_MASK 0x1 +#define READ_EN2_S_MASK_SFT (0x1 << 5) +#define WRITE_EN2_S_SFT 4 +#define WRITE_EN2_S_MASK 0x1 +#define WRITE_EN2_S_MASK_SFT (0x1 << 4) +#define READ_EN1_S_SFT 3 +#define READ_EN1_S_MASK 0x1 +#define READ_EN1_S_MASK_SFT (0x1 << 3) +#define WRITE_EN1_S_SFT 2 +#define WRITE_EN1_S_MASK 0x1 +#define WRITE_EN1_S_MASK_SFT (0x1 << 2) +#define READ_EN0_S_SFT 1 +#define READ_EN0_S_MASK 0x1 +#define READ_EN0_S_MASK_SFT (0x1 << 1) +#define WRITE_EN0_S_SFT 0 +#define WRITE_EN0_S_MASK 0x1 +#define WRITE_EN0_S_MASK_SFT (0x1 << 0) + +/* AFE_SE_SECURE_CON0 */ +#define AFE_HDMI_SE_SECURE_BIT_SFT 11 +#define AFE_HDMI_SE_SECURE_BIT_MASK 0x1 +#define AFE_HDMI_SE_SECURE_BIT_MASK_SFT (0x1 << 11) +#define AFE_SPDIF2_OUT_SE_SECURE_BIT_SFT 10 +#define AFE_SPDIF2_OUT_SE_SECURE_BIT_MASK 0x1 +#define AFE_SPDIF2_OUT_SE_SECURE_BIT_MASK_SFT (0x1 << 10) +#define AFE_SPDIF_OUT_SE_SECURE_BIT_SFT 9 +#define AFE_SPDIF_OUT_SE_SECURE_BIT_MASK 0x1 +#define AFE_SPDIF_OUT_SE_SECURE_BIT_MASK_SFT (0x1 << 9) +#define AFE_DL8_SE_SECURE_BIT_SFT 8 +#define AFE_DL8_SE_SECURE_BIT_MASK 0x1 +#define AFE_DL8_SE_SECURE_BIT_MASK_SFT (0x1 << 8) +#define AFE_DL7_SE_SECURE_BIT_SFT 7 +#define AFE_DL7_SE_SECURE_BIT_MASK 0x1 +#define AFE_DL7_SE_SECURE_BIT_MASK_SFT (0x1 << 7) +#define AFE_DL6_SE_SECURE_BIT_SFT 6 +#define AFE_DL6_SE_SECURE_BIT_MASK 0x1 +#define AFE_DL6_SE_SECURE_BIT_MASK_SFT (0x1 << 6) +#define AFE_DL5_SE_SECURE_BIT_SFT 5 +#define AFE_DL5_SE_SECURE_BIT_MASK 0x1 +#define AFE_DL5_SE_SECURE_BIT_MASK_SFT (0x1 << 5) +#define AFE_DL4_SE_SECURE_BIT_SFT 4 +#define AFE_DL4_SE_SECURE_BIT_MASK 0x1 +#define AFE_DL4_SE_SECURE_BIT_MASK_SFT (0x1 << 4) +#define AFE_DL3_SE_SECURE_BIT_SFT 3 +#define AFE_DL3_SE_SECURE_BIT_MASK 0x1 +#define AFE_DL3_SE_SECURE_BIT_MASK_SFT (0x1 << 3) +#define AFE_DL2_SE_SECURE_BIT_SFT 2 +#define AFE_DL2_SE_SECURE_BIT_MASK 0x1 +#define AFE_DL2_SE_SECURE_BIT_MASK_SFT (0x1 << 2) +#define AFE_DL1_SE_SECURE_BIT_SFT 1 +#define AFE_DL1_SE_SECURE_BIT_MASK 0x1 +#define AFE_DL1_SE_SECURE_BIT_MASK_SFT (0x1 << 1) +#define AFE_DL0_SE_SECURE_BIT_SFT 0 +#define AFE_DL0_SE_SECURE_BIT_MASK 0x1 +#define AFE_DL0_SE_SECURE_BIT_MASK_SFT (0x1 << 0) + +/* AFE_SE_SECURE_CON1 */ +#define AFE_DL46_SE_SECURE_BIT_SFT 26 +#define AFE_DL46_SE_SECURE_BIT_MASK 0x1 +#define AFE_DL46_SE_SECURE_BIT_MASK_SFT (0x1 << 26) +#define AFE_DL45_SE_SECURE_BIT_SFT 25 +#define AFE_DL45_SE_SECURE_BIT_MASK 0x1 +#define AFE_DL45_SE_SECURE_BIT_MASK_SFT (0x1 << 25) +#define AFE_DL44_SE_SECURE_BIT_SFT 24 +#define AFE_DL44_SE_SECURE_BIT_MASK 0x1 +#define AFE_DL44_SE_SECURE_BIT_MASK_SFT (0x1 << 24) +#define AFE_DL43_SE_SECURE_BIT_SFT 23 +#define AFE_DL43_SE_SECURE_BIT_MASK 0x1 +#define AFE_DL43_SE_SECURE_BIT_MASK_SFT (0x1 << 23) +#define AFE_DL42_SE_SECURE_BIT_SFT 22 +#define AFE_DL42_SE_SECURE_BIT_MASK 0x1 +#define AFE_DL42_SE_SECURE_BIT_MASK_SFT (0x1 << 22) +#define AFE_DL41_SE_SECURE_BIT_SFT 21 +#define AFE_DL41_SE_SECURE_BIT_MASK 0x1 +#define AFE_DL41_SE_SECURE_BIT_MASK_SFT (0x1 << 21) +#define AFE_DL40_SE_SECURE_BIT_SFT 20 +#define AFE_DL40_SE_SECURE_BIT_MASK 0x1 +#define AFE_DL40_SE_SECURE_BIT_MASK_SFT (0x1 << 20) +#define AFE_DL39_SE_SECURE_BIT_SFT 19 +#define AFE_DL39_SE_SECURE_BIT_MASK 0x1 +#define AFE_DL39_SE_SECURE_BIT_MASK_SFT (0x1 << 19) +#define AFE_DL38_SE_SECURE_BIT_SFT 18 +#define AFE_DL38_SE_SECURE_BIT_MASK 0x1 +#define AFE_DL38_SE_SECURE_BIT_MASK_SFT (0x1 << 18) +#define AFE_DL37_SE_SECURE_BIT_SFT 17 +#define AFE_DL37_SE_SECURE_BIT_MASK 0x1 +#define AFE_DL37_SE_SECURE_BIT_MASK_SFT (0x1 << 17) +#define AFE_DL36_SE_SECURE_BIT_SFT 16 +#define AFE_DL36_SE_SECURE_BIT_MASK 0x1 +#define AFE_DL36_SE_SECURE_BIT_MASK_SFT (0x1 << 16) +#define AFE_DL35_SE_SECURE_BIT_SFT 15 +#define AFE_DL35_SE_SECURE_BIT_MASK 0x1 +#define AFE_DL35_SE_SECURE_BIT_MASK_SFT (0x1 << 15) +#define AFE_DL34_SE_SECURE_BIT_SFT 14 +#define AFE_DL34_SE_SECURE_BIT_MASK 0x1 +#define AFE_DL34_SE_SECURE_BIT_MASK_SFT (0x1 << 14) +#define AFE_DL33_SE_SECURE_BIT_SFT 13 +#define AFE_DL33_SE_SECURE_BIT_MASK 0x1 +#define AFE_DL33_SE_SECURE_BIT_MASK_SFT (0x1 << 13) +#define AFE_DL32_SE_SECURE_BIT_SFT 12 +#define AFE_DL32_SE_SECURE_BIT_MASK 0x1 +#define AFE_DL32_SE_SECURE_BIT_MASK_SFT (0x1 << 12) +#define AFE_DL31_SE_SECURE_BIT_SFT 11 +#define AFE_DL31_SE_SECURE_BIT_MASK 0x1 +#define AFE_DL31_SE_SECURE_BIT_MASK_SFT (0x1 << 11) +#define AFE_DL30_SE_SECURE_BIT_SFT 10 +#define AFE_DL30_SE_SECURE_BIT_MASK 0x1 +#define AFE_DL30_SE_SECURE_BIT_MASK_SFT (0x1 << 10) +#define AFE_DL29_SE_SECURE_BIT_SFT 9 +#define AFE_DL29_SE_SECURE_BIT_MASK 0x1 +#define AFE_DL29_SE_SECURE_BIT_MASK_SFT (0x1 << 9) +#define AFE_DL28_SE_SECURE_BIT_SFT 8 +#define AFE_DL28_SE_SECURE_BIT_MASK 0x1 +#define AFE_DL28_SE_SECURE_BIT_MASK_SFT (0x1 << 8) +#define AFE_DL27_SE_SECURE_BIT_SFT 7 +#define AFE_DL27_SE_SECURE_BIT_MASK 0x1 +#define AFE_DL27_SE_SECURE_BIT_MASK_SFT (0x1 << 7) +#define AFE_DL26_SE_SECURE_BIT_SFT 6 +#define AFE_DL26_SE_SECURE_BIT_MASK 0x1 +#define AFE_DL26_SE_SECURE_BIT_MASK_SFT (0x1 << 6) +#define AFE_DL25_SE_SECURE_BIT_SFT 5 +#define AFE_DL25_SE_SECURE_BIT_MASK 0x1 +#define AFE_DL25_SE_SECURE_BIT_MASK_SFT (0x1 << 5) +#define AFE_DL24_SE_SECURE_BIT_SFT 4 +#define AFE_DL24_SE_SECURE_BIT_MASK 0x1 +#define AFE_DL24_SE_SECURE_BIT_MASK_SFT (0x1 << 4) +#define AFE_DL23_SE_SECURE_BIT_SFT 3 +#define AFE_DL23_SE_SECURE_BIT_MASK 0x1 +#define AFE_DL23_SE_SECURE_BIT_MASK_SFT (0x1 << 3) +#define AFE_DL_48CH_SE_SECURE_BIT_SFT 2 +#define AFE_DL_48CH_SE_SECURE_BIT_MASK 0x1 +#define AFE_DL_48CH_SE_SECURE_BIT_MASK_SFT (0x1 << 2) +#define AFE_DL_24CH_SE_SECURE_BIT_SFT 1 +#define AFE_DL_24CH_SE_SECURE_BIT_MASK 0x1 +#define AFE_DL_24CH_SE_SECURE_BIT_MASK_SFT (0x1 << 1) +#define AFE_DL_4CH_SE_SECURE_BIT_SFT 0 +#define AFE_DL_4CH_SE_SECURE_BIT_MASK 0x1 +#define AFE_DL_4CH_SE_SECURE_BIT_MASK_SFT (0x1 << 0) + +/* AFE_SE_SECURE_CON2 */ +#define AFE_VUL38_SE_SECURE_BIT_SFT 28 +#define AFE_VUL38_SE_SECURE_BIT_MASK 0x1 +#define AFE_VUL38_SE_SECURE_BIT_MASK_SFT (0x1 << 28) +#define AFE_VUL37_SE_SECURE_BIT_SFT 27 +#define AFE_VUL37_SE_SECURE_BIT_MASK 0x1 +#define AFE_VUL37_SE_SECURE_BIT_MASK_SFT (0x1 << 27) +#define AFE_VUL36_SE_SECURE_BIT_SFT 26 +#define AFE_VUL36_SE_SECURE_BIT_MASK 0x1 +#define AFE_VUL36_SE_SECURE_BIT_MASK_SFT (0x1 << 26) +#define AFE_VUL35_SE_SECURE_BIT_SFT 25 +#define AFE_VUL35_SE_SECURE_BIT_MASK 0x1 +#define AFE_VUL35_SE_SECURE_BIT_MASK_SFT (0x1 << 25) +#define AFE_VUL34_SE_SECURE_BIT_SFT 24 +#define AFE_VUL34_SE_SECURE_BIT_MASK 0x1 +#define AFE_VUL34_SE_SECURE_BIT_MASK_SFT (0x1 << 24) +#define AFE_VUL33_SE_SECURE_BIT_SFT 23 +#define AFE_VUL33_SE_SECURE_BIT_MASK 0x1 +#define AFE_VUL33_SE_SECURE_BIT_MASK_SFT (0x1 << 23) +#define AFE_VUL32_SE_SECURE_BIT_SFT 22 +#define AFE_VUL32_SE_SECURE_BIT_MASK 0x1 +#define AFE_VUL32_SE_SECURE_BIT_MASK_SFT (0x1 << 22) +#define AFE_VUL31_SE_SECURE_BIT_SFT 21 +#define AFE_VUL31_SE_SECURE_BIT_MASK 0x1 +#define AFE_VUL31_SE_SECURE_BIT_MASK_SFT (0x1 << 21) +#define AFE_VUL30_SE_SECURE_BIT_SFT 20 +#define AFE_VUL30_SE_SECURE_BIT_MASK 0x1 +#define AFE_VUL30_SE_SECURE_BIT_MASK_SFT (0x1 << 20) +#define AFE_VUL29_SE_SECURE_BIT_SFT 19 +#define AFE_VUL29_SE_SECURE_BIT_MASK 0x1 +#define AFE_VUL29_SE_SECURE_BIT_MASK_SFT (0x1 << 19) +#define AFE_VUL28_SE_SECURE_BIT_SFT 18 +#define AFE_VUL28_SE_SECURE_BIT_MASK 0x1 +#define AFE_VUL28_SE_SECURE_BIT_MASK_SFT (0x1 << 18) +#define AFE_VUL27_SE_SECURE_BIT_SFT 17 +#define AFE_VUL27_SE_SECURE_BIT_MASK 0x1 +#define AFE_VUL27_SE_SECURE_BIT_MASK_SFT (0x1 << 17) +#define AFE_VUL26_SE_SECURE_BIT_SFT 16 +#define AFE_VUL26_SE_SECURE_BIT_MASK 0x1 +#define AFE_VUL26_SE_SECURE_BIT_MASK_SFT (0x1 << 16) +#define AFE_VUL25_SE_SECURE_BIT_SFT 15 +#define AFE_VUL25_SE_SECURE_BIT_MASK 0x1 +#define AFE_VUL25_SE_SECURE_BIT_MASK_SFT (0x1 << 15) +#define AFE_VUL24_SE_SECURE_BIT_SFT 14 +#define AFE_VUL24_SE_SECURE_BIT_MASK 0x1 +#define AFE_VUL24_SE_SECURE_BIT_MASK_SFT (0x1 << 14) +#define AFE_VUL_CM2_SE_SECURE_BIT_SFT 13 +#define AFE_VUL_CM2_SE_SECURE_BIT_MASK 0x1 +#define AFE_VUL_CM2_SE_SECURE_BIT_MASK_SFT (0x1 << 13) +#define AFE_VUL_CM1_SE_SECURE_BIT_SFT 12 +#define AFE_VUL_CM1_SE_SECURE_BIT_MASK 0x1 +#define AFE_VUL_CM1_SE_SECURE_BIT_MASK_SFT (0x1 << 12) +#define AFE_VUL_CM0_SE_SECURE_BIT_SFT 11 +#define AFE_VUL_CM0_SE_SECURE_BIT_MASK 0x1 +#define AFE_VUL_CM0_SE_SECURE_BIT_MASK_SFT (0x1 << 11) +#define AFE_VUL10_SE_SECURE_BIT_SFT 10 +#define AFE_VUL10_SE_SECURE_BIT_MASK 0x1 +#define AFE_VUL10_SE_SECURE_BIT_MASK_SFT (0x1 << 10) +#define AFE_VUL9_SE_SECURE_BIT_SFT 9 +#define AFE_VUL9_SE_SECURE_BIT_MASK 0x1 +#define AFE_VUL9_SE_SECURE_BIT_MASK_SFT (0x1 << 9) +#define AFE_VUL8_SE_SECURE_BIT_SFT 8 +#define AFE_VUL8_SE_SECURE_BIT_MASK 0x1 +#define AFE_VUL8_SE_SECURE_BIT_MASK_SFT (0x1 << 8) +#define AFE_VUL7_SE_SECURE_BIT_SFT 7 +#define AFE_VUL7_SE_SECURE_BIT_MASK 0x1 +#define AFE_VUL7_SE_SECURE_BIT_MASK_SFT (0x1 << 7) +#define AFE_VUL6_SE_SECURE_BIT_SFT 6 +#define AFE_VUL6_SE_SECURE_BIT_MASK 0x1 +#define AFE_VUL6_SE_SECURE_BIT_MASK_SFT (0x1 << 6) +#define AFE_VUL5_SE_SECURE_BIT_SFT 5 +#define AFE_VUL5_SE_SECURE_BIT_MASK 0x1 +#define AFE_VUL5_SE_SECURE_BIT_MASK_SFT (0x1 << 5) +#define AFE_VUL4_SE_SECURE_BIT_SFT 4 +#define AFE_VUL4_SE_SECURE_BIT_MASK 0x1 +#define AFE_VUL4_SE_SECURE_BIT_MASK_SFT (0x1 << 4) +#define AFE_VUL3_SE_SECURE_BIT_SFT 3 +#define AFE_VUL3_SE_SECURE_BIT_MASK 0x1 +#define AFE_VUL3_SE_SECURE_BIT_MASK_SFT (0x1 << 3) +#define AFE_VUL2_SE_SECURE_BIT_SFT 2 +#define AFE_VUL2_SE_SECURE_BIT_MASK 0x1 +#define AFE_VUL2_SE_SECURE_BIT_MASK_SFT (0x1 << 2) +#define AFE_VUL1_SE_SECURE_BIT_SFT 1 +#define AFE_VUL1_SE_SECURE_BIT_MASK 0x1 +#define AFE_VUL1_SE_SECURE_BIT_MASK_SFT (0x1 << 1) +#define AFE_VUL0_SE_SECURE_BIT_SFT 0 +#define AFE_VUL0_SE_SECURE_BIT_MASK 0x1 +#define AFE_VUL0_SE_SECURE_BIT_MASK_SFT (0x1 << 0) + +/* AFE_SE_SECURE_CON3 */ +#define AFE_SPDIFIN_SE_SECURE_BIT_SFT 10 +#define AFE_SPDIFIN_SE_SECURE_BIT_MASK 0x1 +#define AFE_SPDIFIN_SE_SECURE_BIT_MASK_SFT (0x1 << 10) +#define AFE_TDM_IN_SE_SECURE_BIT_SFT 9 +#define AFE_TDM_IN_SE_SECURE_BIT_MASK 0x1 +#define AFE_TDM_IN_SE_SECURE_BIT_MASK_SFT (0x1 << 9) +#define AFE_MPHONE_EARC_SE_SECURE_BIT_SFT 8 +#define AFE_MPHONE_EARC_SE_SECURE_BIT_MASK 0x1 +#define AFE_MPHONE_EARC_SE_SECURE_BIT_MASK_SFT (0x1 << 8) +#define AFE_MPHONE_SPDIF_SE_SECURE_BIT_SFT 7 +#define AFE_MPHONE_SPDIF_SE_SECURE_BIT_MASK 0x1 +#define AFE_MPHONE_SPDIF_SE_SECURE_BIT_MASK_SFT (0x1 << 7) +#define AFE_ETDM_IN1_SE_SECURE_BIT_SFT 1 +#define AFE_ETDM_IN1_SE_SECURE_BIT_MASK 0x1 +#define AFE_ETDM_IN1_SE_SECURE_BIT_MASK_SFT (0x1 << 1) +#define AFE_ETDM_IN0_SE_SECURE_BIT_SFT 0 +#define AFE_ETDM_IN0_SE_SECURE_BIT_MASK 0x1 +#define AFE_ETDM_IN0_SE_SECURE_BIT_MASK_SFT (0x1 << 0) + +/* AFE_SE_PROT_SIDEBAND0 */ +#define HDMI_HPROT_SFT 11 +#define HDMI_HPROT_MASK 0x1 +#define HDMI_HPROT_MASK_SFT (0x1 << 11) +#define SPDIF2_OUT_HPROT_SFT 10 +#define SPDIF2_OUT_HPROT_MASK 0x1 +#define SPDIF2_OUT_HPROT_MASK_SFT (0x1 << 10) +#define SPDIF_OUT_HPROT_SFT 9 +#define SPDIF_OUT_HPROT_MASK 0x1 +#define SPDIF_OUT_HPROT_MASK_SFT (0x1 << 9) +#define DL8_HPROT_SFT 8 +#define DL8_HPROT_MASK 0x1 +#define DL8_HPROT_MASK_SFT (0x1 << 8) +#define DL7_HPROT_SFT 7 +#define DL7_HPROT_MASK 0x1 +#define DL7_HPROT_MASK_SFT (0x1 << 7) +#define DL6_HPROT_SFT 6 +#define DL6_HPROT_MASK 0x1 +#define DL6_HPROT_MASK_SFT (0x1 << 6) +#define DL5_HPROT_SFT 5 +#define DL5_HPROT_MASK 0x1 +#define DL5_HPROT_MASK_SFT (0x1 << 5) +#define DL4_HPROT_SFT 4 +#define DL4_HPROT_MASK 0x1 +#define DL4_HPROT_MASK_SFT (0x1 << 4) +#define DL3_HPROT_SFT 3 +#define DL3_HPROT_MASK 0x1 +#define DL3_HPROT_MASK_SFT (0x1 << 3) +#define DL2_HPROT_SFT 2 +#define DL2_HPROT_MASK 0x1 +#define DL2_HPROT_MASK_SFT (0x1 << 2) +#define DL1_HPROT_SFT 1 +#define DL1_HPROT_MASK 0x1 +#define DL1_HPROT_MASK_SFT (0x1 << 1) +#define DL0_HPROT_SFT 0 +#define DL0_HPROT_MASK 0x1 +#define DL0_HPROT_MASK_SFT (0x1 << 0) + +/* AFE_SE_PROT_SIDEBAND1 */ +#define DL46_HPROT_SFT 26 +#define DL46_HPROT_MASK 0x1 +#define DL46_HPROT_MASK_SFT (0x1 << 26) +#define DL45_HPROT_SFT 25 +#define DL45_HPROT_MASK 0x1 +#define DL45_HPROT_MASK_SFT (0x1 << 25) +#define DL44_HPROT_SFT 24 +#define DL44_HPROT_MASK 0x1 +#define DL44_HPROT_MASK_SFT (0x1 << 24) +#define DL43_HPROT_SFT 23 +#define DL43_HPROT_MASK 0x1 +#define DL43_HPROT_MASK_SFT (0x1 << 23) +#define DL42_HPROT_SFT 22 +#define DL42_HPROT_MASK 0x1 +#define DL42_HPROT_MASK_SFT (0x1 << 22) +#define DL41_HPROT_SFT 21 +#define DL41_HPROT_MASK 0x1 +#define DL41_HPROT_MASK_SFT (0x1 << 21) +#define DL40_HPROT_SFT 20 +#define DL40_HPROT_MASK 0x1 +#define DL40_HPROT_MASK_SFT (0x1 << 20) +#define DL39_HPROT_SFT 19 +#define DL39_HPROT_MASK 0x1 +#define DL39_HPROT_MASK_SFT (0x1 << 19) +#define DL38_HPROT_SFT 18 +#define DL38_HPROT_MASK 0x1 +#define DL38_HPROT_MASK_SFT (0x1 << 18) +#define DL37_HPROT_SFT 17 +#define DL37_HPROT_MASK 0x1 +#define DL37_HPROT_MASK_SFT (0x1 << 17) +#define DL36_HPROT_SFT 16 +#define DL36_HPROT_MASK 0x1 +#define DL36_HPROT_MASK_SFT (0x1 << 16) +#define DL35_HPROT_SFT 15 +#define DL35_HPROT_MASK 0x1 +#define DL35_HPROT_MASK_SFT (0x1 << 15) +#define DL34_HPROT_SFT 14 +#define DL34_HPROT_MASK 0x1 +#define DL34_HPROT_MASK_SFT (0x1 << 14) +#define DL33_HPROT_SFT 13 +#define DL33_HPROT_MASK 0x1 +#define DL33_HPROT_MASK_SFT (0x1 << 13) +#define DL32_HPROT_SFT 12 +#define DL32_HPROT_MASK 0x1 +#define DL32_HPROT_MASK_SFT (0x1 << 12) +#define DL31_HPROT_SFT 11 +#define DL31_HPROT_MASK 0x1 +#define DL31_HPROT_MASK_SFT (0x1 << 11) +#define DL30_HPROT_SFT 10 +#define DL30_HPROT_MASK 0x1 +#define DL30_HPROT_MASK_SFT (0x1 << 10) +#define DL29_HPROT_SFT 9 +#define DL29_HPROT_MASK 0x1 +#define DL29_HPROT_MASK_SFT (0x1 << 9) +#define DL28_HPROT_SFT 8 +#define DL28_HPROT_MASK 0x1 +#define DL28_HPROT_MASK_SFT (0x1 << 8) +#define DL27_HPROT_SFT 7 +#define DL27_HPROT_MASK 0x1 +#define DL27_HPROT_MASK_SFT (0x1 << 7) +#define DL26_HPROT_SFT 6 +#define DL26_HPROT_MASK 0x1 +#define DL26_HPROT_MASK_SFT (0x1 << 6) +#define DL25_HPROT_SFT 5 +#define DL25_HPROT_MASK 0x1 +#define DL25_HPROT_MASK_SFT (0x1 << 5) +#define DL24_HPROT_SFT 4 +#define DL24_HPROT_MASK 0x1 +#define DL24_HPROT_MASK_SFT (0x1 << 4) +#define DL23_HPROT_SFT 3 +#define DL23_HPROT_MASK 0x1 +#define DL23_HPROT_MASK_SFT (0x1 << 3) +#define DL_48CH_PROT_SFT 2 +#define DL_48CH_PROT_MASK 0x1 +#define DL_48CH_PROT_MASK_SFT (0x1 << 2) +#define DL_24CH_PROT_SFT 1 +#define DL_24CH_PROT_MASK 0x1 +#define DL_24CH_PROT_MASK_SFT (0x1 << 1) +#define DL_4CH_PROT_SFT 0 +#define DL_4CH_PROT_MASK 0x1 +#define DL_4CH_PROT_MASK_SFT (0x1 << 0) + +/* AFE_SE_PROT_SIDEBAND2 */ +#define VUL38_HPROT_SFT 28 +#define VUL38_HPROT_MASK 0x1 +#define VUL38_HPROT_MASK_SFT (0x1 << 28) +#define VUL37_HPROT_SFT 27 +#define VUL37_HPROT_MASK 0x1 +#define VUL37_HPROT_MASK_SFT (0x1 << 27) +#define VUL36_HPROT_SFT 26 +#define VUL36_HPROT_MASK 0x1 +#define VUL36_HPROT_MASK_SFT (0x1 << 26) +#define VUL35_HPROT_SFT 25 +#define VUL35_HPROT_MASK 0x1 +#define VUL35_HPROT_MASK_SFT (0x1 << 25) +#define VUL34_HPROT_SFT 24 +#define VUL34_HPROT_MASK 0x1 +#define VUL34_HPROT_MASK_SFT (0x1 << 24) +#define VUL33_HPROT_SFT 23 +#define VUL33_HPROT_MASK 0x1 +#define VUL33_HPROT_MASK_SFT (0x1 << 23) +#define VUL32_HPROT_SFT 22 +#define VUL32_HPROT_MASK 0x1 +#define VUL32_HPROT_MASK_SFT (0x1 << 22) +#define VUL31_HPROT_SFT 21 +#define VUL31_HPROT_MASK 0x1 +#define VUL31_HPROT_MASK_SFT (0x1 << 21) +#define VUL30_HPROT_SFT 20 +#define VUL30_HPROT_MASK 0x1 +#define VUL30_HPROT_MASK_SFT (0x1 << 20) +#define VUL29_HPROT_SFT 19 +#define VUL29_HPROT_MASK 0x1 +#define VUL29_HPROT_MASK_SFT (0x1 << 19) +#define VUL28_HPROT_SFT 18 +#define VUL28_HPROT_MASK 0x1 +#define VUL28_HPROT_MASK_SFT (0x1 << 18) +#define VUL27_HPROT_SFT 17 +#define VUL27_HPROT_MASK 0x1 +#define VUL27_HPROT_MASK_SFT (0x1 << 17) +#define VUL26_HPROT_SFT 16 +#define VUL26_HPROT_MASK 0x1 +#define VUL26_HPROT_MASK_SFT (0x1 << 16) +#define VUL25_HPROT_SFT 15 +#define VUL25_HPROT_MASK 0x1 +#define VUL25_HPROT_MASK_SFT (0x1 << 15) +#define VUL24_HPROT_SFT 14 +#define VUL24_HPROT_MASK 0x1 +#define VUL24_HPROT_MASK_SFT (0x1 << 14) +#define VUL_CM2_HPROT_SFT 13 +#define VUL_CM2_HPROT_MASK 0x1 +#define VUL_CM2_HPROT_MASK_SFT (0x1 << 13) +#define VUL_CM1_HPROT_SFT 12 +#define VUL_CM1_HPROT_MASK 0x1 +#define VUL_CM1_HPROT_MASK_SFT (0x1 << 12) +#define VUL_CM0_HPROT_SFT 11 +#define VUL_CM0_HPROT_MASK 0x1 +#define VUL_CM0_HPROT_MASK_SFT (0x1 << 11) +#define VUL10_HPROT_SFT 10 +#define VUL10_HPROT_MASK 0x1 +#define VUL10_HPROT_MASK_SFT (0x1 << 10) +#define VUL9_HPROT_SFT 9 +#define VUL9_HPROT_MASK 0x1 +#define VUL9_HPROT_MASK_SFT (0x1 << 9) +#define VUL8_HPROT_SFT 8 +#define VUL8_HPROT_MASK 0x1 +#define VUL8_HPROT_MASK_SFT (0x1 << 8) +#define VUL7_HPROT_SFT 7 +#define VUL7_HPROT_MASK 0x1 +#define VUL7_HPROT_MASK_SFT (0x1 << 7) +#define VUL6_HPROT_SFT 6 +#define VUL6_HPROT_MASK 0x1 +#define VUL6_HPROT_MASK_SFT (0x1 << 6) +#define VUL5_HPROT_SFT 5 +#define VUL5_HPROT_MASK 0x1 +#define VUL5_HPROT_MASK_SFT (0x1 << 5) +#define VUL4_HPROT_SFT 4 +#define VUL4_HPROT_MASK 0x1 +#define VUL4_HPROT_MASK_SFT (0x1 << 4) +#define VUL3_HPROT_SFT 3 +#define VUL3_HPROT_MASK 0x1 +#define VUL3_HPROT_MASK_SFT (0x1 << 3) +#define VUL2_HPROT_SFT 2 +#define VUL2_HPROT_MASK 0x1 +#define VUL2_HPROT_MASK_SFT (0x1 << 2) +#define VUL1_HPROT_SFT 1 +#define VUL1_HPROT_MASK 0x1 +#define VUL1_HPROT_MASK_SFT (0x1 << 1) +#define VUL0_HPROT_SFT 0 +#define VUL0_HPROT_MASK 0x1 +#define VUL0_HPROT_MASK_SFT (0x1 << 0) + +/* AFE_SE_PROT_SIDEBAND3 */ +#define MPHONE_EARC_HPROT_SFT 10 +#define MPHONE_EARC_HPROT_MASK 0x1 +#define MPHONE_EARC_HPROT_MASK_SFT (0x1 << 10) +#define MPHONE_SPDIF_HPROT_SFT 9 +#define MPHONE_SPDIF_HPROT_MASK 0x1 +#define MPHONE_SPDIF_HPROT_MASK_SFT (0x1 << 9) +#define SPDIFIN_HPROT_SFT 8 +#define SPDIFIN_HPROT_MASK 0x1 +#define SPDIFIN_HPROT_MASK_SFT (0x1 << 8) +#define TDMIN_HPROT_SFT 7 +#define TDMIN_HPROT_MASK 0x1 +#define TDMIN_HPROT_MASK_SFT (0x1 << 7) +#define ETDM_IN1_HPROT_SFT 1 +#define ETDM_IN1_HPROT_MASK 0x1 +#define ETDM_IN1_HPROT_MASK_SFT (0x1 << 1) +#define ETDM_IN0_HPROT_SFT 0 +#define ETDM_IN0_HPROT_MASK 0x1 +#define ETDM_IN0_HPROT_MASK_SFT (0x1 << 0) + +/* AFE_SE_DOMAIN_SIDEBAND0 */ +#define DL7_HDOMAIN_SFT 28 +#define DL7_HDOMAIN_MASK 0xf +#define DL7_HDOMAIN_MASK_SFT (0xf << 28) +#define DL6_HDOMAIN_SFT 24 +#define DL6_HDOMAIN_MASK 0xf +#define DL6_HDOMAIN_MASK_SFT (0xf << 24) +#define DL5_HDOMAIN_SFT 20 +#define DL5_HDOMAIN_MASK 0xf +#define DL5_HDOMAIN_MASK_SFT (0xf << 20) +#define DL4_HDOMAIN_SFT 16 +#define DL4_HDOMAIN_MASK 0xf +#define DL4_HDOMAIN_MASK_SFT (0xf << 16) +#define DL3_HDOMAIN_SFT 12 +#define DL3_HDOMAIN_MASK 0xf +#define DL3_HDOMAIN_MASK_SFT (0xf << 12) +#define DL2_HDOMAIN_SFT 8 +#define DL2_HDOMAIN_MASK 0xf +#define DL2_HDOMAIN_MASK_SFT (0xf << 8) +#define DL1_HDOMAIN_SFT 4 +#define DL1_HDOMAIN_MASK 0xf +#define DL1_HDOMAIN_MASK_SFT (0xf << 4) +#define DL0_HDOMAIN_SFT 0 +#define DL0_HDOMAIN_MASK 0xf +#define DL0_HDOMAIN_MASK_SFT (0xf << 0) + +/* AFE_SE_DOMAIN_SIDEBAND1 */ +#define DL_48CH_HDOMAIN_SFT 24 +#define DL_48CH_HDOMAIN_MASK 0xf +#define DL_48CH_HDOMAIN_MASK_SFT (0xf << 24) +#define DL_24CH_HDOMAIN_SFT 20 +#define DL_24CH_HDOMAIN_MASK 0xf +#define DL_24CH_HDOMAIN_MASK_SFT (0xf << 20) +#define DL_4CH_HDOMAIN_SFT 16 +#define DL_4CH_HDOMAIN_MASK 0xf +#define DL_4CH_HDOMAIN_MASK_SFT (0xf << 16) +#define HDMI_HDOMAIN_SFT 12 +#define HDMI_HDOMAIN_MASK 0xf +#define HDMI_HDOMAIN_MASK_SFT (0xf << 12) +#define SPDIF2_OUT_HDOMAIN_SFT 8 +#define SPDIF2_OUT_HDOMAIN_MASK 0xf +#define SPDIF2_OUT_HDOMAIN_MASK_SFT (0xf << 8) +#define SPDIF_OUT_HDOMAIN_SFT 4 +#define SPDIF_OUT_HDOMAIN_MASK 0xf +#define SPDIF_OUT_HDOMAIN_MASK_SFT (0xf << 4) +#define DL8_HDOMAIN_SFT 0 +#define DL8_HDOMAIN_MASK 0xf +#define DL8_HDOMAIN_MASK_SFT (0xf << 0) + +/* AFE_SE_DOMAIN_SIDEBAND2 */ +#define DL30_HDOMAIN_SFT 28 +#define DL30_HDOMAIN_MASK 0xf +#define DL30_HDOMAIN_MASK_SFT (0xf << 28) +#define DL29_HDOMAIN_SFT 24 +#define DL29_HDOMAIN_MASK 0xf +#define DL29_HDOMAIN_MASK_SFT (0xf << 24) +#define DL28_HDOMAIN_SFT 20 +#define DL28_HDOMAIN_MASK 0xf +#define DL28_HDOMAIN_MASK_SFT (0xf << 20) +#define DL27_HDOMAIN_SFT 16 +#define DL27_HDOMAIN_MASK 0xf +#define DL27_HDOMAIN_MASK_SFT (0xf << 16) +#define DL26_HDOMAIN_SFT 12 +#define DL26_HDOMAIN_MASK 0xf +#define DL26_HDOMAIN_MASK_SFT (0xf << 12) +#define DL25_HDOMAIN_SFT 8 +#define DL25_HDOMAIN_MASK 0xf +#define DL25_HDOMAIN_MASK_SFT (0xf << 8) +#define DL24_HDOMAIN_SFT 4 +#define DL24_HDOMAIN_MASK 0xf +#define DL24_HDOMAIN_MASK_SFT (0xf << 4) +#define DL23_HDOMAIN_SFT 0 +#define DL23_HDOMAIN_MASK 0xf +#define DL23_HDOMAIN_MASK_SFT (0xf << 0) + +/* AFE_SE_DOMAIN_SIDEBAND3 */ +#define DL38_HDOMAIN_SFT 28 +#define DL38_HDOMAIN_MASK 0xf +#define DL38_HDOMAIN_MASK_SFT (0xf << 28) +#define DL37_HDOMAIN_SFT 24 +#define DL37_HDOMAIN_MASK 0xf +#define DL37_HDOMAIN_MASK_SFT (0xf << 24) +#define DL36_HDOMAIN_SFT 20 +#define DL36_HDOMAIN_MASK 0xf +#define DL36_HDOMAIN_MASK_SFT (0xf << 20) +#define DL35_HDOMAIN_SFT 16 +#define DL35_HDOMAIN_MASK 0xf +#define DL35_HDOMAIN_MASK_SFT (0xf << 16) +#define DL34_HDOMAIN_SFT 12 +#define DL34_HDOMAIN_MASK 0xf +#define DL34_HDOMAIN_MASK_SFT (0xf << 12) +#define DL33_HDOMAIN_SFT 8 +#define DL33_HDOMAIN_MASK 0xf +#define DL33_HDOMAIN_MASK_SFT (0xf << 8) +#define DL32_HDOMAIN_SFT 4 +#define DL32_HDOMAIN_MASK 0xf +#define DL32_HDOMAIN_MASK_SFT (0xf << 4) +#define DL31_HDOMAIN_SFT 0 +#define DL31_HDOMAIN_MASK 0xf +#define DL31_HDOMAIN_MASK_SFT (0xf << 0) + +/* AFE_SE_DOMAIN_SIDEBAND4 */ +#define DL46_HDOMAIN_SFT 28 +#define DL46_HDOMAIN_MASK 0xf +#define DL46_HDOMAIN_MASK_SFT (0xf << 28) +#define DL45_HDOMAIN_SFT 24 +#define DL45_HDOMAIN_MASK 0xf +#define DL45_HDOMAIN_MASK_SFT (0xf << 24) +#define DL44_HDOMAIN_SFT 20 +#define DL44_HDOMAIN_MASK 0xf +#define DL44_HDOMAIN_MASK_SFT (0xf << 20) +#define DL43_HDOMAIN_SFT 16 +#define DL43_HDOMAIN_MASK 0xf +#define DL43_HDOMAIN_MASK_SFT (0xf << 16) +#define DL42_HDOMAIN_SFT 12 +#define DL42_HDOMAIN_MASK 0xf +#define DL42_HDOMAIN_MASK_SFT (0xf << 12) +#define DL41_HDOMAIN_SFT 8 +#define DL41_HDOMAIN_MASK 0xf +#define DL41_HDOMAIN_MASK_SFT (0xf << 8) +#define DL40_HDOMAIN_SFT 4 +#define DL40_HDOMAIN_MASK 0xf +#define DL40_HDOMAIN_MASK_SFT (0xf << 4) +#define DL39_HDOMAIN_SFT 0 +#define DL39_HDOMAIN_MASK 0xf +#define DL39_HDOMAIN_MASK_SFT (0xf << 0) + +/* AFE_SE_DOMAIN_SIDEBAND5 */ +#define VUL7_HDOMAIN_SFT 28 +#define VUL7_HDOMAIN_MASK 0xf +#define VUL7_HDOMAIN_MASK_SFT (0xf << 28) +#define VUL6_HDOMAIN_SFT 24 +#define VUL6_HDOMAIN_MASK 0xf +#define VUL6_HDOMAIN_MASK_SFT (0xf << 24) +#define VUL5_HDOMAIN_SFT 20 +#define VUL5_HDOMAIN_MASK 0xf +#define VUL5_HDOMAIN_MASK_SFT (0xf << 20) +#define VUL4_HDOMAIN_SFT 16 +#define VUL4_HDOMAIN_MASK 0xf +#define VUL4_HDOMAIN_MASK_SFT (0xf << 16) +#define VUL3_HDOMAIN_SFT 12 +#define VUL3_HDOMAIN_MASK 0xf +#define VUL3_HDOMAIN_MASK_SFT (0xf << 12) +#define VUL2_HDOMAIN_SFT 8 +#define VUL2_HDOMAIN_MASK 0xf +#define VUL2_HDOMAIN_MASK_SFT (0xf << 8) +#define VUL1_HDOMAIN_SFT 4 +#define VUL1_HDOMAIN_MASK 0xf +#define VUL1_HDOMAIN_MASK_SFT (0xf << 4) +#define VUL0_HDOMAIN_SFT 0 +#define VUL0_HDOMAIN_MASK 0xf +#define VUL0_HDOMAIN_MASK_SFT (0xf << 0) + +/* AFE_SE_DOMAIN_SIDEBAND6 */ +#define VU25_HDOMAIN_SFT 28 +#define VU25_HDOMAIN_MASK 0xf +#define VU25_HDOMAIN_MASK_SFT (0xf << 28) +#define VUL24_HDOMAIN_SFT 24 +#define VUL24_HDOMAIN_MASK 0xf +#define VUL24_HDOMAIN_MASK_SFT (0xf << 24) +#define VUL_CM2_HDOMAIN_SFT 20 +#define VUL_CM2_HDOMAIN_MASK 0xf +#define VUL_CM2_HDOMAIN_MASK_SFT (0xf << 20) +#define VUL_CM1_HDOMAIN_SFT 16 +#define VUL_CM1_HDOMAIN_MASK 0xf +#define VUL_CM1_HDOMAIN_MASK_SFT (0xf << 16) +#define VUL_CM0_HDOMAIN_SFT 12 +#define VUL_CM0_HDOMAIN_MASK 0xf +#define VUL_CM0_HDOMAIN_MASK_SFT (0xf << 12) +#define VUL10_HDOMAIN_SFT 8 +#define VUL10_HDOMAIN_MASK 0xf +#define VUL10_HDOMAIN_MASK_SFT (0xf << 8) +#define VUL9_HDOMAIN_SFT 4 +#define VUL9_HDOMAIN_MASK 0xf +#define VUL9_HDOMAIN_MASK_SFT (0xf << 4) +#define VUL8_HDOMAIN_SFT 0 +#define VUL8_HDOMAIN_MASK 0xf +#define VUL8_HDOMAIN_MASK_SFT (0xf << 0) + +/* AFE_SE_DOMAIN_SIDEBAND7 */ +#define VUL33_HDOMAIN_SFT 28 +#define VUL33_HDOMAIN_MASK 0xf +#define VUL33_HDOMAIN_MASK_SFT (0xf << 28) +#define VUL32_HDOMAIN_SFT 24 +#define VUL32_HDOMAIN_MASK 0xf +#define VUL32_HDOMAIN_MASK_SFT (0xf << 24) +#define VUL31_HDOMAIN_SFT 20 +#define VUL31_HDOMAIN_MASK 0xf +#define VUL31_HDOMAIN_MASK_SFT (0xf << 20) +#define VUL30_HDOMAIN_SFT 16 +#define VUL30_HDOMAIN_MASK 0xf +#define VUL30_HDOMAIN_MASK_SFT (0xf << 16) +#define VUL29_HDOMAIN_SFT 12 +#define VUL29_HDOMAIN_MASK 0xf +#define VUL29_HDOMAIN_MASK_SFT (0xf << 12) +#define VUL28_HDOMAIN_SFT 8 +#define VUL28_HDOMAIN_MASK 0xf +#define VUL28_HDOMAIN_MASK_SFT (0xf << 8) +#define VUL27_HDOMAIN_SFT 4 +#define VUL27_HDOMAIN_MASK 0xf +#define VUL27_HDOMAIN_MASK_SFT (0xf << 4) +#define VUL26_HDOMAIN_SFT 0 +#define VUL26_HDOMAIN_MASK 0xf +#define VUL26_HDOMAIN_MASK_SFT (0xf << 0) + +/* AFE_SE_DOMAIN_SIDEBAND8 */ +#define ETDM_IN1_HDOMAIN_SFT 24 +#define ETDM_IN1_HDOMAIN_MASK 0xf +#define ETDM_IN1_HDOMAIN_MASK_SFT (0xf << 24) +#define ETDM_IN0_HDOMAIN_SFT 20 +#define ETDM_IN0_HDOMAIN_MASK 0xf +#define ETDM_IN0_HDOMAIN_MASK_SFT (0xf << 20) +#define VUL38_HDOMAIN_SFT 16 +#define VUL38_HDOMAIN_MASK 0xf +#define VUL38_HDOMAIN_MASK_SFT (0xf << 16) +#define VUL37_HDOMAIN_SFT 12 +#define VUL37_HDOMAIN_MASK 0xf +#define VUL37_HDOMAIN_MASK_SFT (0xf << 12) +#define VUL36_HDOMAIN_SFT 8 +#define VUL36_HDOMAIN_MASK 0xf +#define VUL36_HDOMAIN_MASK_SFT (0xf << 8) +#define VUL35_HDOMAIN_SFT 4 +#define VUL35_HDOMAIN_MASK 0xf +#define VUL35_HDOMAIN_MASK_SFT (0xf << 4) +#define VUL34_HDOMAIN_SFT 0 +#define VUL34_HDOMAIN_MASK 0xf +#define VUL34_HDOMAIN_MASK_SFT (0xf << 0) + +/* AFE_SE_DOMAIN_SIDEBAND9 */ +#define MPHONE_EARC_HDOMAIN_SFT 28 +#define MPHONE_EARC_HDOMAIN_MASK 0xf +#define MPHONE_EARC_HDOMAIN_MASK_SFT (0xf << 28) +#define MPHONE_SPDIF_HDOMAIN_SFT 24 +#define MPHONE_SPDIF_HDOMAIN_MASK 0xf +#define MPHONE_SPDIF_HDOMAIN_MASK_SFT (0xf << 24) +#define SPDIFIN_HDOMAIN_SFT 20 +#define SPDIFIN_HDOMAIN_MASK 0xf +#define SPDIFIN_HDOMAIN_MASK_SFT (0xf << 20) +#define TDMIN_HDOMAIN_SFT 16 +#define TDMIN_HDOMAIN_MASK 0xf +#define TDMIN_HDOMAIN_MASK_SFT (0xf << 16) + +/* AFE_PROT_SIDEBAND0_MON */ +#define AFE_DOMAIN_SIDEBAN0_MON_SFT 0 +#define AFE_DOMAIN_SIDEBAN0_MON_MASK 0xffffffff +#define AFE_DOMAIN_SIDEBAN0_MON_MASK_SFT (0xffffffff << 0) + +/* AFE_PROT_SIDEBAND1_MON */ +#define AFE_DOMAIN_SIDEBAN1_MON_SFT 0 +#define AFE_DOMAIN_SIDEBAN1_MON_MASK 0xffffffff +#define AFE_DOMAIN_SIDEBAN1_MON_MASK_SFT (0xffffffff << 0) + +/* AFE_PROT_SIDEBAND2_MON */ +#define AFE_DOMAIN_SIDEBAN2_MON_SFT 0 +#define AFE_DOMAIN_SIDEBAN2_MON_MASK 0xffffffff +#define AFE_DOMAIN_SIDEBAN2_MON_MASK_SFT (0xffffffff << 0) + +/* AFE_PROT_SIDEBAND3_MON */ +#define AFE_DOMAIN_SIDEBAN3_MON_SFT 0 +#define AFE_DOMAIN_SIDEBAN3_MON_MASK 0xffffffff +#define AFE_DOMAIN_SIDEBAN3_MON_MASK_SFT (0xffffffff << 0) + +/* AFE_DOMAIN_SIDEBAND0_MON */ +#define AFE_DOMAIN_SIDEBAN0_MON_SFT 0 +#define AFE_DOMAIN_SIDEBAN0_MON_MASK 0xffffffff +#define AFE_DOMAIN_SIDEBAN0_MON_MASK_SFT (0xffffffff << 0) + +/* AFE_DOMAIN_SIDEBAND1_MON */ +#define AFE_DOMAIN_SIDEBAN1_MON_SFT 0 +#define AFE_DOMAIN_SIDEBAN1_MON_MASK 0xffffffff +#define AFE_DOMAIN_SIDEBAN1_MON_MASK_SFT (0xffffffff << 0) + +/* AFE_DOMAIN_SIDEBAND2_MON */ +#define AFE_DOMAIN_SIDEBAN2_MON_SFT 0 +#define AFE_DOMAIN_SIDEBAN2_MON_MASK 0xffffffff +#define AFE_DOMAIN_SIDEBAN2_MON_MASK_SFT (0xffffffff << 0) + +/* AFE_DOMAIN_SIDEBAND3_MON */ +#define AFE_DOMAIN_SIDEBAN3_MON_SFT 0 +#define AFE_DOMAIN_SIDEBAN3_MON_MASK 0xffffffff +#define AFE_DOMAIN_SIDEBAN3_MON_MASK_SFT (0xffffffff << 0) + +/* AFE_DOMAIN_SIDEBAND4_MON */ +#define AFE_DOMAIN_SIDEBAN0_MON_SFT 0 +#define AFE_DOMAIN_SIDEBAN0_MON_MASK 0xffffffff +#define AFE_DOMAIN_SIDEBAN0_MON_MASK_SFT (0xffffffff << 0) + +/* AFE_DOMAIN_SIDEBAND5_MON */ +#define AFE_DOMAIN_SIDEBAN1_MON_SFT 0 +#define AFE_DOMAIN_SIDEBAN1_MON_MASK 0xffffffff +#define AFE_DOMAIN_SIDEBAN1_MON_MASK_SFT (0xffffffff << 0) + +/* AFE_DOMAIN_SIDEBAND6_MON */ +#define AFE_DOMAIN_SIDEBAN2_MON_SFT 0 +#define AFE_DOMAIN_SIDEBAN2_MON_MASK 0xffffffff +#define AFE_DOMAIN_SIDEBAN2_MON_MASK_SFT (0xffffffff << 0) + +/* AFE_DOMAIN_SIDEBAND7_MON */ +#define AFE_DOMAIN_SIDEBAN3_MON_SFT 0 +#define AFE_DOMAIN_SIDEBAN3_MON_MASK 0xffffffff +#define AFE_DOMAIN_SIDEBAN3_MON_MASK_SFT (0xffffffff << 0) + +/* AFE_DOMAIN_SIDEBAND8_MON */ +#define AFE_DOMAIN_SIDEBAN2_MON_SFT 0 +#define AFE_DOMAIN_SIDEBAN2_MON_MASK 0xffffffff +#define AFE_DOMAIN_SIDEBAN2_MON_MASK_SFT (0xffffffff << 0) + +/* AFE_DOMAIN_SIDEBAND9_MON */ +#define AFE_DOMAIN_SIDEBAN3_MON_SFT 0 +#define AFE_DOMAIN_SIDEBAN3_MON_MASK 0xffffffff +#define AFE_DOMAIN_SIDEBAN3_MON_MASK_SFT (0xffffffff << 0) + +/* AFE_SECURE_CONN0 */ +#define AFE_SPDIFIN_LPBK_CON_MASK_S_SFT 26 +#define AFE_SPDIFIN_LPBK_CON_MASK_S_MASK 0x3 +#define AFE_SPDIFIN_LPBK_CON_MASK_S_MASK_SFT (0x3 << 26) +#define AFE_ADDA_DMIC1_SRC_CON0_MASK_S_SFT 25 +#define AFE_ADDA_DMIC1_SRC_CON0_MASK_S_MASK 0x1 +#define AFE_ADDA_DMIC1_SRC_CON0_MASK_S_MASK_SFT (0x1 << 25) +#define AFE_ADDA_DMIC0_SRC_CON0_MASK_S_SFT 24 +#define AFE_ADDA_DMIC0_SRC_CON0_MASK_S_MASK 0x1 +#define AFE_ADDA_DMIC0_SRC_CON0_MASK_S_MASK_SFT (0x1 << 24) +#define AFE_ADDA_UL3_SRC_CON0_MASK_S_SFT 23 +#define AFE_ADDA_UL3_SRC_CON0_MASK_S_MASK 0x1 +#define AFE_ADDA_UL3_SRC_CON0_MASK_S_MASK_SFT (0x1 << 23) +#define AFE_ADDA_UL2_SRC_CON0_MASK_S_SFT 22 +#define AFE_ADDA_UL2_SRC_CON0_MASK_S_MASK 0x1 +#define AFE_ADDA_UL2_SRC_CON0_MASK_S_MASK_SFT (0x1 << 22) +#define AFE_ADDA_UL1_SRC_CON0_MASK_S_SFT 21 +#define AFE_ADDA_UL1_SRC_CON0_MASK_S_MASK 0x1 +#define AFE_ADDA_UL1_SRC_CON0_MASK_S_MASK_SFT (0x1 << 21) +#define AFE_ADDA_UL0_SRC_CON0_MASK_S_SFT 20 +#define AFE_ADDA_UL0_SRC_CON0_MASK_S_MASK 0x1 +#define AFE_ADDA_UL0_SRC_CON0_MASK_S_MASK_SFT (0x1 << 20) +#define AFE_MRKAIF1_CFG0_MASK_S_SFT 19 +#define AFE_MRKAIF1_CFG0_MASK_S_MASK 0x1 +#define AFE_MRKAIF1_CFG0_MASK_S_MASK_SFT (0x1 << 19) +#define AFE_MRKAIF0_CFG0_MASK_S_SFT 18 +#define AFE_MRKAIF0_CFG0_MASK_S_MASK 0x1 +#define AFE_MRKAIF0_CFG0_MASK_S_MASK_SFT (0x1 << 18) +#define AFE_TDMIN_CON1_MASK_S_SFT 17 +#define AFE_TDMIN_CON1_MASK_S_MASK 0x1 +#define AFE_TDMIN_CON1_MASK_S_MASK_SFT (0x1 << 17) +#define AFE_TDM_CON2_MASK_S_SFT 16 +#define AFE_TDM_CON2_MASK_S_MASK 0x1 +#define AFE_TDM_CON2_MASK_S_MASK_SFT (0x1 << 16) +#define AFE_DAIBT_CON_MASK_S_SFT 14 +#define AFE_DAIBT_CON_MASK_S_MASK 0x3 +#define AFE_DAIBT_CON_MASK_S_MASK_SFT (0x3 << 14) +#define AFE_MRGIF_CON_MASK_S_SFT 12 +#define AFE_MRGIF_CON_MASK_S_MASK 0x3 +#define AFE_MRGIF_CON_MASK_S_MASK_SFT (0x3 << 12) +#define AFE_CONNSYS_I2S_CON_MASK_S_SFT 11 +#define AFE_CONNSYS_I2S_CON_MASK_S_MASK 0x1 +#define AFE_CONNSYS_I2S_CON_MASK_S_MASK_SFT (0x1 << 11) +#define AFE_PCM1_INFT_CON0_MASK_S_SFT 6 +#define AFE_PCM1_INFT_CON0_MASK_S_MASK 0x1f +#define AFE_PCM1_INFT_CON0_MASK_S_MASK_SFT (0x1f << 6) +#define AFE_PCM0_INTF_CON1_MASK_S_SFT 0 +#define AFE_PCM0_INTF_CON1_MASK_S_MASK 0x3f +#define AFE_PCM0_INTF_CON1_MASK_S_MASK_SFT (0x3f << 0) + +/* AFE_SECURE_CONN_ETDM1 */ +#define ETDM1_4_7_COWORK_CON1_MASK_S_0_SFT 24 +#define ETDM1_4_7_COWORK_CON1_MASK_S_0_MASK 0xff +#define ETDM1_4_7_COWORK_CON1_MASK_S_0_MASK_SFT (0xff << 24) +#define ETDM1_4_7_COWORK_CON0_MASK_S_0_SFT 20 +#define ETDM1_4_7_COWORK_CON0_MASK_S_0_MASK 0xf +#define ETDM1_4_7_COWORK_CON0_MASK_S_0_MASK_SFT (0xf << 20) +#define ETDM1_4_7_COWORK_CON0_MASK_S_1_SFT 16 +#define ETDM1_4_7_COWORK_CON0_MASK_S_1_MASK 0xf +#define ETDM1_4_7_COWORK_CON0_MASK_S_1_MASK_SFT (0xf << 16) +#define ETDM1_0_3_COWORK_CON3_MASK_S_0_SFT 8 +#define ETDM1_0_3_COWORK_CON3_MASK_S_0_MASK 0xff +#define ETDM1_0_3_COWORK_CON3_MASK_S_0_MASK_SFT (0xff << 8) +#define ETDM1_0_3_COWORK_CON3_MASK_S_1_SFT 0 +#define ETDM1_0_3_COWORK_CON3_MASK_S_1_MASK 0xff +#define ETDM1_0_3_COWORK_CON3_MASK_S_1_MASK_SFT (0xff << 0) + +/* AFE_SECURE_CONN_ETDM2 */ +#define ETDM2_4_7_COWORK_CON3_MASK_S_0_SFT 24 +#define ETDM2_4_7_COWORK_CON3_MASK_S_0_MASK 0xff +#define ETDM2_4_7_COWORK_CON3_MASK_S_0_MASK_SFT (0xff << 24) +#define ETDM2_4_7_COWORK_CON3_MASK_S_1_SFT 16 +#define ETDM2_4_7_COWORK_CON3_MASK_S_1_MASK 0xff +#define ETDM2_4_7_COWORK_CON3_MASK_S_1_MASK_SFT (0xff << 16) +#define ETDM2_4_7_COWORK_CON2_MASK_S_0_SFT 12 +#define ETDM2_4_7_COWORK_CON2_MASK_S_0_MASK 0xf +#define ETDM2_4_7_COWORK_CON2_MASK_S_0_MASK_SFT (0xf << 12) +#define ETDM2_4_7_COWORK_CON2_MASK_S_1_SFT 8 +#define ETDM2_4_7_COWORK_CON2_MASK_S_1_MASK 0xf +#define ETDM2_4_7_COWORK_CON2_MASK_S_1_MASK_SFT (0xf << 8) +#define ETDM2_4_7_COWORK_CON1_MASK_S_0_SFT 0 +#define ETDM2_4_7_COWORK_CON1_MASK_S_0_MASK 0xff +#define ETDM2_4_7_COWORK_CON1_MASK_S_0_MASK_SFT (0xff << 0) + +/* AFE_SECURE_SRAM_CON0 */ +#define SRAM_READ_EN15_NS_SFT 31 +#define SRAM_READ_EN15_NS_MASK 0x1 +#define SRAM_READ_EN15_NS_MASK_SFT (0x1 << 31) +#define SRAM_WRITE_EN15_NS_SFT 30 +#define SRAM_WRITE_EN15_NS_MASK 0x1 +#define SRAM_WRITE_EN15_NS_MASK_SFT (0x1 << 30) +#define SRAM_READ_EN14_NS_SFT 29 +#define SRAM_READ_EN14_NS_MASK 0x1 +#define SRAM_READ_EN14_NS_MASK_SFT (0x1 << 29) +#define SRAM_WRITE_EN14_NS_SFT 28 +#define SRAM_WRITE_EN14_NS_MASK 0x1 +#define SRAM_WRITE_EN14_NS_MASK_SFT (0x1 << 28) +#define SRAM_READ_EN13_NS_SFT 27 +#define SRAM_READ_EN13_NS_MASK 0x1 +#define SRAM_READ_EN13_NS_MASK_SFT (0x1 << 27) +#define SRAM_WRITE_EN13_NS_SFT 26 +#define SRAM_WRITE_EN13_NS_MASK 0x1 +#define SRAM_WRITE_EN13_NS_MASK_SFT (0x1 << 26) +#define SRAM_READ_EN12_NS_SFT 25 +#define SRAM_READ_EN12_NS_MASK 0x1 +#define SRAM_READ_EN12_NS_MASK_SFT (0x1 << 25) +#define SRAM_WRITE_EN12_NS_SFT 24 +#define SRAM_WRITE_EN12_NS_MASK 0x1 +#define SRAM_WRITE_EN12_NS_MASK_SFT (0x1 << 24) +#define SRAM_READ_EN11_NS_SFT 23 +#define SRAM_READ_EN11_NS_MASK 0x1 +#define SRAM_READ_EN11_NS_MASK_SFT (0x1 << 23) +#define SRAM_WRITE_EN11_NS_SFT 22 +#define SRAM_WRITE_EN11_NS_MASK 0x1 +#define SRAM_WRITE_EN11_NS_MASK_SFT (0x1 << 22) +#define SRAM_READ_EN10_NS_SFT 21 +#define SRAM_READ_EN10_NS_MASK 0x1 +#define SRAM_READ_EN10_NS_MASK_SFT (0x1 << 21) +#define SRAM_WRITE_EN10_NS_SFT 20 +#define SRAM_WRITE_EN10_NS_MASK 0x1 +#define SRAM_WRITE_EN10_NS_MASK_SFT (0x1 << 20) +#define SRAM_READ_EN9_NS_SFT 19 +#define SRAM_READ_EN9_NS_MASK 0x1 +#define SRAM_READ_EN9_NS_MASK_SFT (0x1 << 19) +#define SRAM_WRITE_EN9_NS_SFT 18 +#define SRAM_WRITE_EN9_NS_MASK 0x1 +#define SRAM_WRITE_EN9_NS_MASK_SFT (0x1 << 18) +#define SRAM_READ_EN8_NS_SFT 17 +#define SRAM_READ_EN8_NS_MASK 0x1 +#define SRAM_READ_EN8_NS_MASK_SFT (0x1 << 17) +#define SRAM_WRITE_EN8_NS_SFT 16 +#define SRAM_WRITE_EN8_NS_MASK 0x1 +#define SRAM_WRITE_EN8_NS_MASK_SFT (0x1 << 16) +#define SRAM_READ_EN7_NS_SFT 15 +#define SRAM_READ_EN7_NS_MASK 0x1 +#define SRAM_READ_EN7_NS_MASK_SFT (0x1 << 15) +#define SRAM_WRITE_EN7_NS_SFT 14 +#define SRAM_WRITE_EN7_NS_MASK 0x1 +#define SRAM_WRITE_EN7_NS_MASK_SFT (0x1 << 14) +#define SRAM_READ_EN6_NS_SFT 13 +#define SRAM_READ_EN6_NS_MASK 0x1 +#define SRAM_READ_EN6_NS_MASK_SFT (0x1 << 13) +#define SRAM_WRITE_EN6_NS_SFT 12 +#define SRAM_WRITE_EN6_NS_MASK 0x1 +#define SRAM_WRITE_EN6_NS_MASK_SFT (0x1 << 12) +#define SRAM_READ_EN5_NS_SFT 11 +#define SRAM_READ_EN5_NS_MASK 0x1 +#define SRAM_READ_EN5_NS_MASK_SFT (0x1 << 11) +#define SRAM_WRITE_EN5_NS_SFT 10 +#define SRAM_WRITE_EN5_NS_MASK 0x1 +#define SRAM_WRITE_EN5_NS_MASK_SFT (0x1 << 10) +#define SRAM_READ_EN4_NS_SFT 9 +#define SRAM_READ_EN4_NS_MASK 0x1 +#define SRAM_READ_EN4_NS_MASK_SFT (0x1 << 9) +#define SRAM_WRITE_EN4_NS_SFT 8 +#define SRAM_WRITE_EN4_NS_MASK 0x1 +#define SRAM_WRITE_EN4_NS_MASK_SFT (0x1 << 8) +#define SRAM_READ_EN3_NS_SFT 7 +#define SRAM_READ_EN3_NS_MASK 0x1 +#define SRAM_READ_EN3_NS_MASK_SFT (0x1 << 7) +#define SRAM_WRITE_EN3_NS_SFT 6 +#define SRAM_WRITE_EN3_NS_MASK 0x1 +#define SRAM_WRITE_EN3_NS_MASK_SFT (0x1 << 6) +#define SRAM_READ_EN2_NS_SFT 5 +#define SRAM_READ_EN2_NS_MASK 0x1 +#define SRAM_READ_EN2_NS_MASK_SFT (0x1 << 5) +#define SRAM_WRITE_EN2_NS_SFT 4 +#define SRAM_WRITE_EN2_NS_MASK 0x1 +#define SRAM_WRITE_EN2_NS_MASK_SFT (0x1 << 4) +#define SRAM_READ_EN1_NS_SFT 3 +#define SRAM_READ_EN1_NS_MASK 0x1 +#define SRAM_READ_EN1_NS_MASK_SFT (0x1 << 3) +#define SRAM_WRITE_EN1_NS_SFT 2 +#define SRAM_WRITE_EN1_NS_MASK 0x1 +#define SRAM_WRITE_EN1_NS_MASK_SFT (0x1 << 2) +#define SRAM_READ_EN0_NS_SFT 1 +#define SRAM_READ_EN0_NS_MASK 0x1 +#define SRAM_READ_EN0_NS_MASK_SFT (0x1 << 1) +#define SRAM_WRITE_EN0_NS_SFT 0 +#define SRAM_WRITE_EN0_NS_MASK 0x1 +#define SRAM_WRITE_EN0_NS_MASK_SFT (0x1 << 0) + +/* AFE_SECURE_SRAM_CON1 */ +#define SRAM_READ_EN15_S_SFT 31 +#define SRAM_READ_EN15_S_MASK 0x1 +#define SRAM_READ_EN15_S_MASK_SFT (0x1 << 31) +#define SRAM_WRITE_EN15_S_SFT 30 +#define SRAM_WRITE_EN15_S_MASK 0x1 +#define SRAM_WRITE_EN15_S_MASK_SFT (0x1 << 30) +#define SRAM_READ_EN14_S_SFT 29 +#define SRAM_READ_EN14_S_MASK 0x1 +#define SRAM_READ_EN14_S_MASK_SFT (0x1 << 29) +#define SRAM_WRITE_EN14_S_SFT 28 +#define SRAM_WRITE_EN14_S_MASK 0x1 +#define SRAM_WRITE_EN14_S_MASK_SFT (0x1 << 28) +#define SRAM_READ_EN13_S_SFT 27 +#define SRAM_READ_EN13_S_MASK 0x1 +#define SRAM_READ_EN13_S_MASK_SFT (0x1 << 27) +#define SRAM_WRITE_EN13_S_SFT 26 +#define SRAM_WRITE_EN13_S_MASK 0x1 +#define SRAM_WRITE_EN13_S_MASK_SFT (0x1 << 26) +#define SRAM_READ_EN12_S_SFT 25 +#define SRAM_READ_EN12_S_MASK 0x1 +#define SRAM_READ_EN12_S_MASK_SFT (0x1 << 25) +#define SRAM_WRITE_EN12_S_SFT 24 +#define SRAM_WRITE_EN12_S_MASK 0x1 +#define SRAM_WRITE_EN12_S_MASK_SFT (0x1 << 24) +#define SRAM_READ_EN11_S_SFT 23 +#define SRAM_READ_EN11_S_MASK 0x1 +#define SRAM_READ_EN11_S_MASK_SFT (0x1 << 23) +#define SRAM_WRITE_EN11_S_SFT 22 +#define SRAM_WRITE_EN11_S_MASK 0x1 +#define SRAM_WRITE_EN11_S_MASK_SFT (0x1 << 22) +#define SRAM_READ_EN10_S_SFT 21 +#define SRAM_READ_EN10_S_MASK 0x1 +#define SRAM_READ_EN10_S_MASK_SFT (0x1 << 21) +#define SRAM_WRITE_EN10_S_SFT 20 +#define SRAM_WRITE_EN10_S_MASK 0x1 +#define SRAM_WRITE_EN10_S_MASK_SFT (0x1 << 20) +#define SRAM_READ_EN9_S_SFT 19 +#define SRAM_READ_EN9_S_MASK 0x1 +#define SRAM_READ_EN9_S_MASK_SFT (0x1 << 19) +#define SRAM_WRITE_EN9_S_SFT 18 +#define SRAM_WRITE_EN9_S_MASK 0x1 +#define SRAM_WRITE_EN9_S_MASK_SFT (0x1 << 18) +#define SRAM_READ_EN8_S_SFT 17 +#define SRAM_READ_EN8_S_MASK 0x1 +#define SRAM_READ_EN8_S_MASK_SFT (0x1 << 17) +#define SRAM_WRITE_EN8_S_SFT 16 +#define SRAM_WRITE_EN8_S_MASK 0x1 +#define SRAM_WRITE_EN8_S_MASK_SFT (0x1 << 16) +#define SRAM_READ_EN7_S_SFT 15 +#define SRAM_READ_EN7_S_MASK 0x1 +#define SRAM_READ_EN7_S_MASK_SFT (0x1 << 15) +#define SRAM_WRITE_EN7_S_SFT 14 +#define SRAM_WRITE_EN7_S_MASK 0x1 +#define SRAM_WRITE_EN7_S_MASK_SFT (0x1 << 14) +#define SRAM_READ_EN6_S_SFT 13 +#define SRAM_READ_EN6_S_MASK 0x1 +#define SRAM_READ_EN6_S_MASK_SFT (0x1 << 13) +#define SRAM_WRITE_EN6_S_SFT 12 +#define SRAM_WRITE_EN6_S_MASK 0x1 +#define SRAM_WRITE_EN6_S_MASK_SFT (0x1 << 12) +#define SRAM_READ_EN5_S_SFT 11 +#define SRAM_READ_EN5_S_MASK 0x1 +#define SRAM_READ_EN5_S_MASK_SFT (0x1 << 11) +#define SRAM_WRITE_EN5_S_SFT 10 +#define SRAM_WRITE_EN5_S_MASK 0x1 +#define SRAM_WRITE_EN5_S_MASK_SFT (0x1 << 10) +#define SRAM_READ_EN4_S_SFT 9 +#define SRAM_READ_EN4_S_MASK 0x1 +#define SRAM_READ_EN4_S_MASK_SFT (0x1 << 9) +#define SRAM_WRITE_EN4_S_SFT 8 +#define SRAM_WRITE_EN4_S_MASK 0x1 +#define SRAM_WRITE_EN4_S_MASK_SFT (0x1 << 8) +#define SRAM_READ_EN3_S_SFT 7 +#define SRAM_READ_EN3_S_MASK 0x1 +#define SRAM_READ_EN3_S_MASK_SFT (0x1 << 7) +#define SRAM_WRITE_EN3_S_SFT 6 +#define SRAM_WRITE_EN3_S_MASK 0x1 +#define SRAM_WRITE_EN3_S_MASK_SFT (0x1 << 6) +#define SRAM_READ_EN2_S_SFT 5 +#define SRAM_READ_EN2_S_MASK 0x1 +#define SRAM_READ_EN2_S_MASK_SFT (0x1 << 5) +#define SRAM_WRITE_EN2_S_SFT 4 +#define SRAM_WRITE_EN2_S_MASK 0x1 +#define SRAM_WRITE_EN2_S_MASK_SFT (0x1 << 4) +#define SRAM_READ_EN1_S_SFT 3 +#define SRAM_READ_EN1_S_MASK 0x1 +#define SRAM_READ_EN1_S_MASK_SFT (0x1 << 3) +#define SRAM_WRITE_EN1_S_SFT 2 +#define SRAM_WRITE_EN1_S_MASK 0x1 +#define SRAM_WRITE_EN1_S_MASK_SFT (0x1 << 2) +#define SRAM_READ_EN0_S_SFT 1 +#define SRAM_READ_EN0_S_MASK 0x1 +#define SRAM_READ_EN0_S_MASK_SFT (0x1 << 1) +#define SRAM_WRITE_EN0_S_SFT 0 +#define SRAM_WRITE_EN0_S_MASK 0x1 +#define SRAM_WRITE_EN0_S_MASK_SFT (0x1 << 0) + +/* AFE_SE_CONN_INPUT_MASK0 */ +#define SECURE_INTRCONN_I0_I31_S_SFT 0 +#define SECURE_INTRCONN_I0_I31_S_MASK 0xffffffff +#define SECURE_INTRCONN_I0_I31_S_MASK_SFT (0xffffffff << 0) + +/* AFE_SE_CONN_INPUT_MASK1 */ +#define SECURE_INTRCONN_I32_I63_S_SFT 0 +#define SECURE_INTRCONN_I32_I63_S_MASK 0xffffffff +#define SECURE_INTRCONN_I32_I63_S_MASK_SFT (0xffffffff << 0) + +/* AFE_SE_CONN_INPUT_MASK2 */ +#define SECURE_INTRCONN_I64_I95_S_SFT 0 +#define SECURE_INTRCONN_I64_I95_S_MASK 0xffffffff +#define SECURE_INTRCONN_I64_I95_S_MASK_SFT (0xffffffff << 0) + +/* AFE_SE_CONN_INPUT_MASK3 */ +#define SECURE_INTRCONN_I96_I127_S_SFT 0 +#define SECURE_INTRCONN_I96_I127_S_MASK 0xffffffff +#define SECURE_INTRCONN_I96_I127_S_MASK_SFT (0xffffffff << 0) + +/* AFE_SE_CONN_INPUT_MASK4 */ +#define SECURE_INTRCONN_I128_I159_S_SFT 0 +#define SECURE_INTRCONN_I128_I159_S_MASK 0xffffffff +#define SECURE_INTRCONN_I128_I159_S_MASK_SFT (0xffffffff << 0) + +/* AFE_SE_CONN_INPUT_MASK5 */ +#define SECURE_INTRCONN_I160_I191_S_SFT 0 +#define SECURE_INTRCONN_I160_I191_S_MASK 0xffffffff +#define SECURE_INTRCONN_I160_I191_S_MASK_SFT (0xffffffff << 0) + +/* AFE_SE_CONN_INPUT_MASK6 */ +#define SECURE_INTRCONN_I192_I223_S_SFT 0 +#define SECURE_INTRCONN_I192_I223_S_MASK 0xffffffff +#define SECURE_INTRCONN_I192_I223_S_MASK_SFT (0xffffffff << 0) + +/* AFE_SE_CONN_INPUT_MASK7 */ +#define SECURE_INTRCONN_I224_I256_S_SFT 0 +#define SECURE_INTRCONN_I224_I256_S_MASK 0xffffffff +#define SECURE_INTRCONN_I224_I256_S_MASK_SFT (0xffffffff << 0) + +/* AFE_NON_SE_CONN_INPUT_MASK0 */ +#define NORMAL_INTRCONN_I0_I31_S_SFT 0 +#define NORMAL_INTRCONN_I0_I31_S_MASK 0xffffffff +#define NORMAL_INTRCONN_I0_I31_S_MASK_SFT (0xffffffff << 0) + +/* AFE_NON_SE_CONN_INPUT_MASK1 */ +#define NORMAL_INTRCONN_I32_I63_S_SFT 0 +#define NORMAL_INTRCONN_I32_I63_S_MASK 0xffffffff +#define NORMAL_INTRCONN_I32_I63_S_MASK_SFT (0xffffffff << 0) + +/* AFE_NON_SE_CONN_INPUT_MASK2 */ +#define NORMAL_INTRCONN_I64_I95_S_SFT 0 +#define NORMAL_INTRCONN_I64_I95_S_MASK 0xffffffff +#define NORMAL_INTRCONN_I64_I95_S_MASK_SFT (0xffffffff << 0) + +/* AFE_NON_SE_CONN_INPUT_MASK3 */ +#define NORMAL_INTRCONN_I96_I127_S_SFT 0 +#define NORMAL_INTRCONN_I96_I127_S_MASK 0xffffffff +#define NORMAL_INTRCONN_I96_I127_S_MASK_SFT (0xffffffff << 0) + +/* AFE_NON_SE_CONN_INPUT_MASK4 */ +#define NORMAL_INTRCONN_I128_I159_S_SFT 0 +#define NORMAL_INTRCONN_I128_I159_S_MASK 0xffffffff +#define NORMAL_INTRCONN_I128_I159_S_MASK_SFT (0xffffffff << 0) + +/* AFE_NON_SE_CONN_INPUT_MASK5 */ +#define NORMAL_INTRCONN_I160_I191_S_SFT 0 +#define NORMAL_INTRCONN_I160_I191_S_MASK 0xffffffff +#define NORMAL_INTRCONN_I160_I191_S_MASK_SFT (0xffffffff << 0) + +/* AFE_NON_SE_CONN_INPUT_MASK6 */ +#define NORMAL_INTRCONN_I192_I223_S_SFT 0 +#define NORMAL_INTRCONN_I192_I223_S_MASK 0xffffffff +#define NORMAL_INTRCONN_I192_I223_S_MASK_SFT (0xffffffff << 0) + +/* AFE_NON_SE_CONN_INPUT_MASK7 */ +#define NORMAL_INTRCONN_I224_I256_S_SFT 0 +#define NORMAL_INTRCONN_I224_I256_S_MASK 0xffffffff +#define NORMAL_INTRCONN_I224_I256_S_MASK_SFT (0xffffffff << 0) + +/* AFE_SE_CONN_OUTPUT_SEL0 */ +#define SECURE_INTRCONN_O0_O31_S_SFT 0 +#define SECURE_INTRCONN_O0_O31_S_MASK 0xffffffff +#define SECURE_INTRCONN_O0_O31_S_MASK_SFT (0xffffffff << 0) + +/* AFE_SE_CONN_OUTPUT_SEL1 */ +#define SECURE_INTRCONN_O32_O63_S_SFT 0 +#define SECURE_INTRCONN_O32_O63_S_MASK 0xffffffff +#define SECURE_INTRCONN_O32_O63_S_MASK_SFT (0xffffffff << 0) + +/* AFE_SE_CONN_OUTPUT_SEL2 */ +#define SECURE_INTRCONN_O64_O95_S_SFT 0 +#define SECURE_INTRCONN_O64_O95_S_MASK 0xffffffff +#define SECURE_INTRCONN_O64_O95_S_MASK_SFT (0xffffffff << 0) + +/* AFE_SE_CONN_OUTPUT_SEL3 */ +#define SECURE_INTRCONN_O96_O127_S_SFT 0 +#define SECURE_INTRCONN_O96_O127_S_MASK 0xffffffff +#define SECURE_INTRCONN_O96_O127_S_MASK_SFT (0xffffffff << 0) + +/* AFE_SE_CONN_OUTPUT_SEL4 */ +#define SECURE_INTRCONN_O128_O159_S_SFT 0 +#define SECURE_INTRCONN_O128_O159_S_MASK 0xffffffff +#define SECURE_INTRCONN_O128_O159_S_MASK_SFT (0xffffffff << 0) + +/* AFE_SE_CONN_OUTPUT_SEL5 */ +#define SECURE_INTRCONN_O160_O191_S_SFT 0 +#define SECURE_INTRCONN_O160_O191_S_MASK 0xffffffff +#define SECURE_INTRCONN_O160_O191_S_MASK_SFT (0xffffffff << 0) + +/* AFE_SE_CONN_OUTPUT_SEL6 */ +#define SECURE_INTRCONN_O192_O223_S_SFT 0 +#define SECURE_INTRCONN_O192_O223_S_MASK 0xffffffff +#define SECURE_INTRCONN_O192_O223_S_MASK_SFT (0xffffffff << 0) + +/* AFE_SE_CONN_OUTPUT_SEL7 */ +#define SECURE_INTRCONN_O224_O256_S_SFT 0 +#define SECURE_INTRCONN_O224_O256_S_MASK 0xffffffff +#define SECURE_INTRCONN_O224_O256_S_MASK_SFT (0xffffffff << 0) + +/* AFE_PCM0_INTF_CON1_MASK_MON */ +#define AFE_PCM0_INTF_CON1_MASK_MON_SFT 0 +#define AFE_PCM0_INTF_CON1_MASK_MON_MASK 0xffffffff +#define AFE_PCM0_INTF_CON1_MASK_MON_MASK_SFT (0xffffffff << 0) + +/* AFE_PCM0_INTF_CON0_MASK_MON */ +#define AFE_PCM0_INTF_CON0_MASK_MON_SFT 0 +#define AFE_PCM0_INTF_CON0_MASK_MON_MASK 0xffffffff +#define AFE_PCM0_INTF_CON0_MASK_MON_MASK_SFT (0xffffffff << 0) + +/* AFE_CONNSYS_I2S_CON_MASK_MON */ +#define AFE_CONNSYS_I2S_CON_MASK_MON_SFT 0 +#define AFE_CONNSYS_I2S_CON_MASK_MON_MASK 0xffffffff +#define AFE_CONNSYS_I2S_CON_MASK_MON_MASK_SFT (0xffffffff << 0) + +/* AFE_MTKAIF0_CFG0_MASK_MON */ +#define AFE_MTKAIF0_CFG0_MASK_MON_SFT 0 +#define AFE_MTKAIF0_CFG0_MASK_MON_MASK 0xffffffff +#define AFE_MTKAIF0_CFG0_MASK_MON_MASK_SFT (0xffffffff << 0) + +/* AFE_MTKAIF1_CFG0_MASK_MON */ +#define AFE_MTKAIF1_CFG0_MASK_MON_SFT 0 +#define AFE_MTKAIF1_CFG0_MASK_MON_MASK 0xffffffff +#define AFE_MTKAIF1_CFG0_MASK_MON_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL0_SRC_CON0_MASK_MON */ +#define AFE_ADDA_UL0_SRC_CON0_MASK_MON_SFT 0 +#define AFE_ADDA_UL0_SRC_CON0_MASK_MON_MASK 0xffffffff +#define AFE_ADDA_UL0_SRC_CON0_MASK_MON_MASK_SFT (0xffffffff << 0) + +/* AFE_ADDA_UL1_SRC_CON0_MASK_MON */ +#define AFE_ADDA_UL1_SRC_CON0_MASK_MON_SFT 0 +#define AFE_ADDA_UL1_SRC_CON0_MASK_MON_MASK 0xffffffff +#define AFE_ADDA_UL1_SRC_CON0_MASK_MON_MASK_SFT (0xffffffff << 0) + +/* AFE_GASRC0_NEW_CON0 */ +#define ONE_HEART_SFT 31 +#define ONE_HEART_MASK 0x1 +#define ONE_HEART_MASK_SFT (0x1 << 31) +#define CHSET0_OFS_ONE_HEART_DISABLE_SFT 30 +#define CHSET0_OFS_ONE_HEART_DISABLE_MASK 0x1 +#define CHSET0_OFS_ONE_HEART_DISABLE_MASK_SFT (0x1 << 30) +#define USE_SHORT_DELAY_COEFF_SFT 29 +#define USE_SHORT_DELAY_COEFF_MASK 0x1 +#define USE_SHORT_DELAY_COEFF_MASK_SFT (0x1 << 29) +#define CHSET0_O16BIT_SFT 19 +#define CHSET0_O16BIT_MASK 0x1 +#define CHSET0_O16BIT_MASK_SFT (0x1 << 19) +#define CHSET0_CLR_IIR_HISTORY_SFT 17 +#define CHSET0_CLR_IIR_HISTORY_MASK 0x1 +#define CHSET0_CLR_IIR_HISTORY_MASK_SFT (0x1 << 17) +#define CHSET0_IS_MONO_SFT 16 +#define CHSET0_IS_MONO_MASK 0x1 +#define CHSET0_IS_MONO_MASK_SFT (0x1 << 16) +#define CHSET0_OFS_SEL_SFT 14 +#define CHSET0_OFS_SEL_MASK 0x3 +#define CHSET0_OFS_SEL_MASK_SFT (0x3 << 14) +#define CHSET0_IFS_SEL_SFT 12 +#define CHSET0_IFS_SEL_MASK 0x3 +#define CHSET0_IFS_SEL_MASK_SFT (0x3 << 12) +#define CHSET0_IIR_EN_SFT 11 +#define CHSET0_IIR_EN_MASK 0x1 +#define CHSET0_IIR_EN_MASK_SFT (0x1 << 11) +#define CHSET0_IIR_STAGE_SFT 8 +#define CHSET0_IIR_STAGE_MASK 0x7 +#define CHSET0_IIR_STAGE_MASK_SFT (0x7 << 8) +#define ASM_ON_MOD_SFT 7 +#define ASM_ON_MOD_MASK 0x1 +#define ASM_ON_MOD_MASK_SFT (0x1 << 7) +#define CHSET_STR_CLR_SFT 4 +#define CHSET_STR_CLR_MASK 0x1 +#define CHSET_STR_CLR_MASK_SFT (0x1 << 4) +#define CHSET_ON_SFT 2 +#define CHSET_ON_MASK 0x1 +#define CHSET_ON_MASK_SFT (0x1 << 2) +#define COEFF_SRAM_CTRL_SFT 1 +#define COEFF_SRAM_CTRL_MASK 0x1 +#define COEFF_SRAM_CTRL_MASK_SFT (0x1 << 1) +#define ASM_ON_SFT 0 +#define ASM_ON_MASK 0x1 +#define ASM_ON_MASK_SFT (0x1 << 0) + +/* AFE_GASRC0_NEW_CON1 */ +#define ASM_FREQ_0_SFT 0 +#define ASM_FREQ_0_MASK 0xffffff +#define ASM_FREQ_0_MASK_SFT (0xffffff << 0) + +/* AFE_GASRC0_NEW_CON2 */ +#define ASM_FREQ_1_SFT 0 +#define ASM_FREQ_1_MASK 0xffffff +#define ASM_FREQ_1_MASK_SFT (0xffffff << 0) + +/* AFE_GASRC0_NEW_CON3 */ +#define ASM_FREQ_2_SFT 0 +#define ASM_FREQ_2_MASK 0xffffff +#define ASM_FREQ_2_MASK_SFT (0xffffff << 0) + +/* AFE_GASRC0_NEW_CON4 */ +#define ASM_FREQ_3_SFT 0 +#define ASM_FREQ_3_MASK 0xffffff +#define ASM_FREQ_3_MASK_SFT (0xffffff << 0) + +/* AFE_GASRC0_NEW_CON5 */ +#define OUT_EN_SEL_DOMAIN_SFT 29 +#define OUT_EN_SEL_DOMAIN_MASK 0x7 +#define OUT_EN_SEL_DOMAIN_MASK_SFT (0x7 << 29) +#define OUT_EN_SEL_FS_SFT 24 +#define OUT_EN_SEL_FS_MASK 0x1f +#define OUT_EN_SEL_FS_MASK_SFT (0x1f << 24) +#define IN_EN_SEL_DOMAIN_SFT 21 +#define IN_EN_SEL_DOMAIN_MASK 0x7 +#define IN_EN_SEL_DOMAIN_MASK_SFT (0x7 << 21) +#define IN_EN_SEL_FS_SFT 16 +#define IN_EN_SEL_FS_MASK 0x1f +#define IN_EN_SEL_FS_MASK_SFT (0x1f << 16) +#define RESULT_SEL_SFT 8 +#define RESULT_SEL_MASK 0x7 +#define RESULT_SEL_MASK_SFT (0x7 << 8) +#define CALI_CK_SEL_SFT 4 +#define CALI_CK_SEL_MASK 0x7 +#define CALI_CK_SEL_MASK_SFT (0x7 << 4) +#define CALI_LRCK_SEL_SFT 1 +#define CALI_LRCK_SEL_MASK 0x7 +#define CALI_LRCK_SEL_MASK_SFT (0x7 << 1) +#define SOFT_RESET_SFT 0 +#define SOFT_RESET_MASK 0x1 +#define SOFT_RESET_MASK_SFT (0x1 << 0) + +/* AFE_GASRC0_NEW_CON6 */ +#define FREQ_CALI_CYCLE_SFT 16 +#define FREQ_CALI_CYCLE_MASK 0xffff +#define FREQ_CALI_CYCLE_MASK_SFT (0xffff << 16) +#define FREQ_CALI_AUTORST_EN_SFT 15 +#define FREQ_CALI_AUTORST_EN_MASK 0x1 +#define FREQ_CALI_AUTORST_EN_MASK_SFT (0x1 << 15) +#define CALI_AUTORST_DETECT_SFT 14 +#define CALI_AUTORST_DETECT_MASK 0x1 +#define CALI_AUTORST_DETECT_MASK_SFT (0x1 << 14) +#define FREQ_CALC_RUNNING_SFT 13 +#define FREQ_CALC_RUNNING_MASK 0x1 +#define FREQ_CALC_RUNNING_MASK_SFT (0x1 << 13) +#define AUTO_TUNE_FREQ3_SFT 12 +#define AUTO_TUNE_FREQ3_MASK 0x1 +#define AUTO_TUNE_FREQ3_MASK_SFT (0x1 << 12) +#define COMP_FREQ_RES_EN_SFT 11 +#define COMP_FREQ_RES_EN_MASK 0x1 +#define COMP_FREQ_RES_EN_MASK_SFT (0x1 << 11) +#define FREQ_CALI_SEL_SFT 8 +#define FREQ_CALI_SEL_MASK 0x3 +#define FREQ_CALI_SEL_MASK_SFT (0x3 << 8) +#define FREQ_CALI_BP_DGL_SFT 7 +#define FREQ_CALI_BP_DGL_MASK 0x1 +#define FREQ_CALI_BP_DGL_MASK_SFT (0x1 << 7) +#define FREQ_CALI_MAX_GWIDTH_SFT 4 +#define FREQ_CALI_MAX_GWIDTH_MASK 0x7 +#define FREQ_CALI_MAX_GWIDTH_MASK_SFT (0x7 << 4) +#define AUTO_TUNE_FREQ2_SFT 3 +#define AUTO_TUNE_FREQ2_MASK 0x1 +#define AUTO_TUNE_FREQ2_MASK_SFT (0x1 << 3) +#define FREQ_CALI_AUTO_RESTART_SFT 2 +#define FREQ_CALI_AUTO_RESTART_MASK 0x1 +#define FREQ_CALI_AUTO_RESTART_MASK_SFT (0x1 << 2) +#define CALI_USE_FREQ_OUT_SFT 1 +#define CALI_USE_FREQ_OUT_MASK 0x1 +#define CALI_USE_FREQ_OUT_MASK_SFT (0x1 << 1) +#define CALI_EN_SFT 0 +#define CALI_EN_MASK 0x1 +#define CALI_EN_MASK_SFT (0x1 << 0) + +/* AFE_GASRC0_NEW_CON7 */ +#define FREQ_CALC_DENOMINATOR_SFT 0 +#define FREQ_CALC_DENOMINATOR_MASK 0xffffff +#define FREQ_CALC_DENOMINATOR_MASK_SFT (0xffffff << 0) + +/* AFE_GASRC0_NEW_CON8 */ +#define PRD_CALI_RESULT_RECORD_SFT 0 +#define PRD_CALI_RESULT_RECORD_MASK 0xffffff +#define PRD_CALI_RESULT_RECORD_MASK_SFT (0xffffff << 0) + +/* AFE_GASRC0_NEW_CON9 */ +#define FREQ_CALI_RESULT_SFT 0 +#define FREQ_CALI_RESULT_MASK 0xffffff +#define FREQ_CALI_RESULT_MASK_SFT (0xffffff << 0) + +/* AFE_GASRC0_NEW_CON10 */ +#define COEFF_SRAM_DATA_SFT 0 +#define COEFF_SRAM_DATA_MASK 0xffffffff +#define COEFF_SRAM_DATA_MASK_SFT (0xffffffff << 0) + +/* AFE_GASRC0_NEW_CON11 */ +#define COEFF_SRAM_ADR_SFT 0 +#define COEFF_SRAM_ADR_MASK 0x3f +#define COEFF_SRAM_ADR_MASK_SFT (0x3f << 0) + +/* AFE_GASRC0_NEW_CON12 */ +#define RING_DBG_RD_SFT 0 +#define RING_DBG_RD_MASK 0x3ffffff +#define RING_DBG_RD_MASK_SFT (0x3ffffff << 0) + +/* AFE_GASRC0_NEW_CON13 */ +#define FREQ_CALI_AUTORST_TH_HIGH_SFT 0 +#define FREQ_CALI_AUTORST_TH_HIGH_MASK 0xffffff +#define FREQ_CALI_AUTORST_TH_HIGH_MASK_SFT (0xffffff << 0) + +/* AFE_GASRC0_NEW_CON14 */ +#define FREQ_CALI_AUTORST_TH_LOW_SFT 0 +#define FREQ_CALI_AUTORST_TH_LOW_MASK 0xffffff +#define FREQ_CALI_AUTORST_TH_LOW_MASK_SFT (0xffffff << 0) + +/* AFE_GASRC0_NEW_IP_VERSION */ +#define IP_VERSION_SFT 0 +#define IP_VERSION_MASK 0xffffffff +#define IP_VERSION_MASK_SFT (0xffffffff << 0) + +#define AUDIO_TOP_CON0 0x0 +#define AUDIO_TOP_CON1 0x4 +#define AUDIO_TOP_CON2 0x8 +#define AUDIO_TOP_CON3 0xc +#define AUDIO_TOP_CON4 0x10 +#define AUDIO_ENGEN_CON0 0x14 +#define AUDIO_ENGEN_CON0_USER1 0x18 +#define AUDIO_ENGEN_CON0_USER2 0x1c +#define AFE_SINEGEN_CON0 0x20 +#define AFE_SINEGEN_CON1 0x24 +#define AFE_SINEGEN_CON2 0x28 +#define AFE_SINEGEN_CON3 0x2c +#define AFE_APLL1_TUNER_CFG 0x30 +#define AFE_APLL1_TUNER_MON0 0x34 +#define AFE_APLL2_TUNER_CFG 0x38 +#define AFE_APLL2_TUNER_MON0 0x3c +#define AUDIO_TOP_RG0 0x4c +#define AUDIO_TOP_RG1 0x50 +#define AUDIO_TOP_RG2 0x54 +#define AUDIO_TOP_RG3 0x58 +#define AUDIO_TOP_RG4 0x5c +#define AFE_SPM_CONTROL_REQ 0x60 +#define AFE_SPM_CONTROL_ACK 0x64 +#define AUD_TOP_CFG_VCORE_RG 0x68 +#define AUDIO_TOP_IP_VERSION 0x6c +#define AUDIO_ENGEN_CON0_MON 0x7c +#define AUDIO_PROJECT_MON 0x80 +#define AUD_TOP_CFG_VLP_RG 0x98 +#define AUD_TOP_MON_RG 0x9c +#define AUDIO_USE_DEFAULT_DELSEL0 0xa0 +#define AUDIO_USE_DEFAULT_DELSEL1 0xa4 +#define AUDIO_USE_DEFAULT_DELSEL2 0xa8 +#define AFE_CONNSYS_I2S_IPM_VER_MON 0xb0 +#define AFE_CONNSYS_I2S_MON_SEL 0xb4 +#define AFE_CONNSYS_I2S_MON 0xb8 +#define AFE_CONNSYS_I2S_CON 0xbc +#define AFE_PCM0_INTF_CON0 0xc0 +#define AFE_PCM0_INTF_CON1 0xc4 +#define AFE_PCM_INTF_MON 0xc8 +#define AFE_PCM_TOP_IP_VERSION 0xe8 +#define AFE_GAIN0_CON0 0x400 +#define AFE_GAIN0_CON1_R 0x404 +#define AFE_GAIN0_CON1_L 0x408 +#define AFE_GAIN0_CON2 0x40c +#define AFE_GAIN0_CON3 0x410 +#define AFE_GAIN0_CUR_R 0x414 +#define AFE_GAIN0_CUR_L 0x418 +#define AFE_GAIN1_CON0 0x41c +#define AFE_GAIN1_CON1_R 0x420 +#define AFE_GAIN1_CON1_L 0x424 +#define AFE_GAIN1_CON2 0x428 +#define AFE_GAIN1_CON3 0x42c +#define AFE_GAIN1_CUR_R 0x430 +#define AFE_GAIN1_CUR_L 0x434 +#define AFE_GAIN2_CON0 0x438 +#define AFE_GAIN2_CON1_R 0x43c +#define AFE_GAIN2_CON1_L 0x440 +#define AFE_GAIN2_CON2 0x444 +#define AFE_GAIN2_CON3 0x448 +#define AFE_GAIN2_CUR_R 0x44c +#define AFE_GAIN2_CUR_L 0x450 +#define AFE_GAIN3_CON0 0x454 +#define AFE_GAIN3_CON1_R 0x458 +#define AFE_GAIN3_CON1_L 0x45c +#define AFE_GAIN3_CON2 0x460 +#define AFE_GAIN3_CON3 0x464 +#define AFE_GAIN3_CUR_R 0x468 +#define AFE_GAIN3_CUR_L 0x46c +#define AFE_GAIN_0_1_IP_VERSION 0x474 +#define AFE_GAIN_2_3_IP_VERSION 0x478 +#define AFE_ADDA_DL_IPM_VER_MON 0x4c0 +#define AFE_ADDA_DL_SRC_CON0 0x4d0 +#define AFE_ADDA_DL_SRC_CON1 0x4d4 +#define AFE_ADDA_DL_SRC_DEBUG_MON0 0x4d8 +#define AFE_ADDA_DL_PREDIS_CON0 0x4dc +#define AFE_ADDA_DL_PREDIS_CON1 0x4e0 +#define AFE_ADDA_DL_PREDIS_CON2 0x4e4 +#define AFE_ADDA_DL_PREDIS_CON3 0x4e8 +#define AFE_ADDA_DL_SDM_DCCOMP_CON 0x4ec +#define AFE_ADDA_DL_SDM_TEST 0x4f0 +#define AFE_ADDA_DL_DC_COMP_CFG0 0x4f4 +#define AFE_ADDA_DL_DC_COMP_CFG1 0x4f8 +#define AFE_ADDA_DL_SDM_OUT_MON 0x4fc +#define AFE_ADDA_DL_SRC_LCH_MON 0x500 +#define AFE_ADDA_DL_SRC_RCH_MON 0x504 +#define AFE_ADDA_DL_SRC_DEBUG 0x508 +#define AFE_ADDA_DL_SDM_DITHER_CON 0x50c +#define AFE_ADDA_DL_SDM_AUTO_RESET_CON 0x510 +#define AFE_ADDA_DL_HBF1_SCF1_CONFIG 0x514 +#define AFE_ADDA_DL_HBF1_SCF1_TAP1_TAP2_CONFIG 0x518 +#define AFE_ADDA_DL_HBF1_SCF1_TAP3_TAP4_CONFIG 0x51c +#define AFE_ADDA_DL_HBF1_SCF1_TAP5_TAP6_CONFIG 0x520 +#define AFE_ADDA_DL_HBF1_SCF1_TAP7_TAP8_CONFIG 0x524 +#define AFE_ADDA_DL_HBF1_SCF1_TAP9_TAP10_CONFIG 0x528 +#define AFE_ADDA_DL_HBF1_SCF1_TAP11_TAP12_CONFIG 0x52c +#define AFE_ADDA_DL_HBF1_SCF1_TAP13_TAP14_CONFIG 0x530 +#define AFE_ADDA_DL_HBF1_SCF1_TAP15_TAP16_CONFIG 0x534 +#define AFE_ADDA_DL_HBF1_SCF1_TAP17_TAP18_CONFIG 0x538 +#define AFE_ADDA_DL_HBF1_SCF1_TAP19_TAP20_CONFIG 0x53c +#define AFE_ADDA_DL_HBF1_SCF1_TAP21_TAP22_CONFIG 0x540 +#define AFE_ADDA_DL_HBF1_SCF1_TAP23_TAP24_CONFIG 0x544 +#define AFE_ADDA_DL_HBF1_SCF1_TAP25_TAP26_CONFIG 0x548 +#define AFE_ADDA_DL_HBF1_SCF1_TAP27_TAP28_CONFIG 0x54c +#define AFE_ADDA_DL_HBF1_SCF1_TAP29_TAP30_CONFIG 0x550 +#define AFE_ADDA_DL_HBF1_SCF1_TAP31_TAP32_CONFIG 0x554 +#define AFE_ADDA_DL_HBF1_SCF1_TAP33_TAP34_CONFIG 0x558 +#define AFE_ADDA_DL_HBF1_SCF1_TAP35_TAP36_CONFIG 0x55c +#define AFE_ADDA_DL_HBF1_SCF1_TAP37_TAP38_CONFIG 0x560 +#define AFE_ADDA_DL_HBF1_SCF1_TAP39_TAP40_CONFIG 0x564 +#define AFE_ADDA_DL_HBF1_SCF1_TAP41_TAP42_CONFIG 0x568 +#define AFE_ADDA_DL_HBF1_SCF1_TAP43_TAP44_CONFIG 0x56c +#define AFE_ADDA_DL_HBF1_SCF1_TAP45_TAP46_CONFIG 0x570 +#define AFE_ADDA_DL_HBF1_SCF1_TAP47_TAP48_CONFIG 0x574 +#define AFE_ADDA_DL_HBF1_SCF1_TAP49_TAP50_CONFIG 0x578 +#define AFE_ADDA_DL_HBF1_SCF1_TAP51_TAP52_CONFIG 0x57c +#define AFE_ADDA_DL_HBF1_SCF1_TAP53_TAP54_CONFIG 0x580 +#define AFE_ADDA_DL_HBF1_SCF1_TAP55_TAP56_CONFIG 0x584 +#define AFE_DEM_IDWA_CON0 0xa1c +#define DEM_RECONSTRUCT_MON 0xa20 +#define AFE_CM0_CON0 0xba0 +#define AFE_CM0_MON 0xba4 +#define AFE_CM0_IP_VERSION 0xba8 +#define AFE_CM1_CON0 0xbb0 +#define AFE_CM1_MON 0xbb4 +#define AFE_CM1_IP_VERSION 0xbb8 +#define AFE_ADDA_UL0_SRC_CON0 0xbd0 +#define AFE_ADDA_UL0_SRC_CON1 0xbd4 +#define AFE_ADDA_UL0_SRC_CON2 0xbd8 +#define AFE_ADDA_UL0_SRC_DEBUG 0xbdc +#define AFE_ADDA_UL0_SRC_DEBUG_MON0 0xbe0 +#define AFE_ADDA_UL0_SRC_MON0 0xbe4 +#define AFE_ADDA_UL0_SRC_MON1 0xbe8 +#define AFE_ADDA_UL0_IIR_COEF_02_01 0xbec +#define AFE_ADDA_UL0_IIR_COEF_04_03 0xbf0 +#define AFE_ADDA_UL0_IIR_COEF_06_05 0xbf4 +#define AFE_ADDA_UL0_IIR_COEF_08_07 0xbf8 +#define AFE_ADDA_UL0_IIR_COEF_10_09 0xbfc +#define AFE_ADDA_UL0_ULCF_CFG_02_01 0xc00 +#define AFE_ADDA_UL0_ULCF_CFG_04_03 0xc04 +#define AFE_ADDA_UL0_ULCF_CFG_06_05 0xc08 +#define AFE_ADDA_UL0_ULCF_CFG_08_07 0xc0c +#define AFE_ADDA_UL0_ULCF_CFG_10_09 0xc10 +#define AFE_ADDA_UL0_ULCF_CFG_12_11 0xc14 +#define AFE_ADDA_UL0_ULCF_CFG_14_13 0xc18 +#define AFE_ADDA_UL0_ULCF_CFG_16_15 0xc1c +#define AFE_ADDA_UL0_ULCF_CFG_18_17 0xc20 +#define AFE_ADDA_UL0_ULCF_CFG_20_19 0xc24 +#define AFE_ADDA_UL0_ULCF_CFG_22_21 0xc28 +#define AFE_ADDA_UL0_ULCF_CFG_24_23 0xc2c +#define AFE_ADDA_UL0_ULCF_CFG_26_25 0xc30 +#define AFE_ADDA_UL0_ULCF_CFG_28_27 0xc34 +#define AFE_ADDA_UL0_ULCF_CFG_30_29 0xc38 +#define AFE_ADDA_UL0_ULCF_CFG_32_31 0xc3c +#define AFE_ADDA_UL0_IP_VERSION 0xc4c +#define AFE_ADDA_DMIC0_SRC_CON0 0xdd0 +#define AFE_ADDA_DMIC0_SRC_CON1 0xdd4 +#define AFE_ADDA_DMIC0_SRC_CON2 0xdd8 +#define AFE_ADDA_DMIC0_SRC_DEBUG 0xddc +#define AFE_ADDA_DMIC0_SRC_DEBUG_MON0 0xde0 +#define AFE_ADDA_DMIC0_SRC_MON0 0xde4 +#define AFE_ADDA_DMIC0_SRC_MON1 0xde8 +#define AFE_ADDA_DMIC0_IIR_COEF_02_01 0xdec +#define AFE_ADDA_DMIC0_IIR_COEF_04_03 0xdf0 +#define AFE_ADDA_DMIC0_IIR_COEF_06_05 0xdf4 +#define AFE_ADDA_DMIC0_IIR_COEF_08_07 0xdf8 +#define AFE_ADDA_DMIC0_IIR_COEF_10_09 0xdfc +#define AFE_ADDA_DMIC0_ULCF_CFG_02_01 0xe00 +#define AFE_ADDA_DMIC0_ULCF_CFG_04_03 0xe04 +#define AFE_ADDA_DMIC0_ULCF_CFG_06_05 0xe08 +#define AFE_ADDA_DMIC0_ULCF_CFG_08_07 0xe0c +#define AFE_ADDA_DMIC0_ULCF_CFG_10_09 0xe10 +#define AFE_ADDA_DMIC0_ULCF_CFG_12_11 0xe14 +#define AFE_ADDA_DMIC0_ULCF_CFG_14_13 0xe18 +#define AFE_ADDA_DMIC0_ULCF_CFG_16_15 0xe1c +#define AFE_ADDA_DMIC0_ULCF_CFG_18_17 0xe20 +#define AFE_ADDA_DMIC0_ULCF_CFG_20_19 0xe24 +#define AFE_ADDA_DMIC0_ULCF_CFG_22_21 0xe28 +#define AFE_ADDA_DMIC0_ULCF_CFG_24_23 0xe2c +#define AFE_ADDA_DMIC0_ULCF_CFG_26_25 0xe30 +#define AFE_ADDA_DMIC0_ULCF_CFG_28_27 0xe34 +#define AFE_ADDA_DMIC0_ULCF_CFG_30_29 0xe38 +#define AFE_ADDA_DMIC0_ULCF_CFG_32_31 0xe3c +#define AFE_ADDA_DMIC0_IP_VERSION 0xe4c +#define AFE_ADDA_DMIC1_SRC_CON0 0xe50 +#define AFE_ADDA_DMIC1_SRC_CON1 0xe54 +#define AFE_ADDA_DMIC1_SRC_CON2 0xe58 +#define AFE_ADDA_DMIC1_SRC_DEBUG 0xe5c +#define AFE_ADDA_DMIC1_SRC_DEBUG_MON0 0xe60 +#define AFE_ADDA_DMIC1_SRC_MON0 0xe64 +#define AFE_ADDA_DMIC1_SRC_MON1 0xe68 +#define AFE_ADDA_DMIC1_IIR_COEF_02_01 0xe6c +#define AFE_ADDA_DMIC1_IIR_COEF_04_03 0xe70 +#define AFE_ADDA_DMIC1_IIR_COEF_06_05 0xe74 +#define AFE_ADDA_DMIC1_IIR_COEF_08_07 0xe78 +#define AFE_ADDA_DMIC1_IIR_COEF_10_09 0xe7c +#define AFE_ADDA_DMIC1_ULCF_CFG_02_01 0xe80 +#define AFE_ADDA_DMIC1_ULCF_CFG_04_03 0xe84 +#define AFE_ADDA_DMIC1_ULCF_CFG_06_05 0xe88 +#define AFE_ADDA_DMIC1_ULCF_CFG_08_07 0xe8c +#define AFE_ADDA_DMIC1_ULCF_CFG_10_09 0xe90 +#define AFE_ADDA_DMIC1_ULCF_CFG_12_11 0xe94 +#define AFE_ADDA_DMIC1_ULCF_CFG_14_13 0xe98 +#define AFE_ADDA_DMIC1_ULCF_CFG_16_15 0xe9c +#define AFE_ADDA_DMIC1_ULCF_CFG_18_17 0xea0 +#define AFE_ADDA_DMIC1_ULCF_CFG_20_19 0xea4 +#define AFE_ADDA_DMIC1_ULCF_CFG_22_21 0xea8 +#define AFE_ADDA_DMIC1_ULCF_CFG_24_23 0xeac +#define AFE_ADDA_DMIC1_ULCF_CFG_26_25 0xeb0 +#define AFE_ADDA_DMIC1_ULCF_CFG_28_27 0xeb4 +#define AFE_ADDA_DMIC1_ULCF_CFG_30_29 0xeb8 +#define AFE_ADDA_DMIC1_ULCF_CFG_32_31 0xebc +#define AFE_ADDA_DMIC1_IP_VERSION 0xecc +#define AFE_ADDA_ULSRC_PHASE_CLK_CON0 0xf00 +#define AFE_ADDA_ULSRC_PHASE_CLK_CON1 0xf04 +#define AFE_ADDA_ULSRC_PHASE_CLK_CON2 0xf08 +#define AFE_ADDA_ULSRC_PHASE_CLK_CON3 0xf0c +#define AFE_ADDA_ULSRC_PHASE_CLK_CON4 0xf10 +#define AFE_ADDA_ULSRC_PHASE_ENGEN_CON0 0xf14 +#define AFE_ADDA_ULSRC_PHASE_ENGEN_CON1 0xf18 +#define AFE_ADDA_ULSRC_PHASE_RST_CON0 0xf1c +#define AFE_MTKAIF_IPM_VER_MON 0x1180 +#define AFE_MTKAIF_MON_SEL 0x1184 +#define AFE_MTKAIF_MON 0x1188 +#define AFE_MTKAIF0_CFG0 0x1190 +#define AFE_MTKAIF0_TX_CFG0 0x1194 +#define AFE_MTKAIF0_RX_CFG0 0x1198 +#define AFE_MTKAIF0_RX_CFG1 0x119c +#define AFE_MTKAIF0_RX_CFG2 0x11a0 +#define AFE_MTKAIF1_CFG0 0x11f0 +#define AFE_MTKAIF1_TX_CFG0 0x11f4 +#define AFE_MTKAIF1_RX_CFG0 0x11f8 +#define AFE_MTKAIF1_RX_CFG1 0x11fc +#define AFE_MTKAIF1_RX_CFG2 0x1200 +#define AFE_AUD_PAD_TOP_CFG0 0x1204 +#define AFE_AUD_PAD_TOP_MON 0x1208 +#define AFE_ADDA_MTKAIFV4_TX_CFG0 0x1280 +#define AFE_ADDA6_MTKAIFV4_TX_CFG0 0x1284 +#define AFE_ADDA_MTKAIFV4_RX_CFG0 0x1288 +#define AFE_ADDA_MTKAIFV4_RX_CFG1 0x128c +#define AFE_ADDA6_MTKAIFV4_RX_CFG0 0x1290 +#define AFE_ADDA6_MTKAIFV4_RX_CFG1 0x1294 +#define AFE_ADDA_MTKAIFV4_TX_SYNCWORD_CFG 0x1298 +#define AFE_ADDA_MTKAIFV4_RX_SYNCWORD_CFG 0x129c +#define AFE_ADDA_MTKAIFV4_MON0 0x12a0 +#define AFE_ADDA_MTKAIFV4_MON1 0x12a4 +#define AFE_ADDA6_MTKAIFV4_MON0 0x12a8 +#define ETDM_IN0_CON0 0x1300 +#define ETDM_IN0_CON1 0x1304 +#define ETDM_IN0_CON2 0x1308 +#define ETDM_IN0_CON3 0x130c +#define ETDM_IN0_CON4 0x1310 +#define ETDM_IN0_CON5 0x1314 +#define ETDM_IN0_CON6 0x1318 +#define ETDM_IN0_CON7 0x131c +#define ETDM_IN0_CON8 0x1320 +#define ETDM_IN0_CON9 0x1324 +#define ETDM_IN0_MON 0x1328 +#define ETDM_IN1_CON0 0x1330 +#define ETDM_IN1_CON1 0x1334 +#define ETDM_IN1_CON2 0x1338 +#define ETDM_IN1_CON3 0x133c +#define ETDM_IN1_CON4 0x1340 +#define ETDM_IN1_CON5 0x1344 +#define ETDM_IN1_CON6 0x1348 +#define ETDM_IN1_CON7 0x134c +#define ETDM_IN1_CON8 0x1350 +#define ETDM_IN1_CON9 0x1354 +#define ETDM_IN1_MON 0x1358 +#define ETDM_OUT0_CON0 0x1480 +#define ETDM_OUT0_CON1 0x1484 +#define ETDM_OUT0_CON2 0x1488 +#define ETDM_OUT0_CON3 0x148c +#define ETDM_OUT0_CON4 0x1490 +#define ETDM_OUT0_CON5 0x1494 +#define ETDM_OUT0_CON6 0x1498 +#define ETDM_OUT0_CON7 0x149c +#define ETDM_OUT0_CON8 0x14a0 +#define ETDM_OUT0_CON9 0x14a4 +#define ETDM_OUT0_MON 0x14a8 +#define ETDM_OUT1_CON0 0x14c0 +#define ETDM_OUT1_CON1 0x14c4 +#define ETDM_OUT1_CON2 0x14c8 +#define ETDM_OUT1_CON3 0x14cc +#define ETDM_OUT1_CON4 0x14d0 +#define ETDM_OUT1_CON5 0x14d4 +#define ETDM_OUT1_CON6 0x14d8 +#define ETDM_OUT1_CON7 0x14dc +#define ETDM_OUT1_CON8 0x14e0 +#define ETDM_OUT1_CON9 0x14e4 +#define ETDM_OUT1_MON 0x14e8 +#define ETDM_OUT4_CON0 0x1580 +#define ETDM_OUT4_CON1 0x1584 +#define ETDM_OUT4_CON2 0x1588 +#define ETDM_OUT4_CON3 0x158c +#define ETDM_OUT4_CON4 0x1590 +#define ETDM_OUT4_CON5 0x1594 +#define ETDM_OUT4_CON6 0x1598 +#define ETDM_OUT4_CON7 0x159c +#define ETDM_OUT4_CON8 0x15a0 +#define ETDM_OUT4_CON9 0x15a4 +#define ETDM_OUT4_MON 0x15a8 +#define ETDM_0_3_COWORK_CON0 0x1680 +#define ETDM_0_3_COWORK_CON1 0x1684 +#define ETDM_0_3_COWORK_CON2 0x1688 +#define ETDM_0_3_COWORK_CON3 0x168c +#define ETDM_4_7_COWORK_CON0 0x1690 +#define ETDM_4_7_COWORK_CON1 0x1694 +#define ETDM_4_7_COWORK_CON2 0x1698 +#define ETDM_4_7_COWORK_CON3 0x169c +#define ETDM_IP_VERSION 0x1c4c +#define AFE_DPTX_CON 0x2040 +#define AFE_DPTX_MON 0x2044 +#define AFE_TDM_CON1 0x2048 +#define AFE_TDM_CON2 0x204c +#define AFE_TDM_CON3 0x2050 +#define AFE_TDM_OUT_MON 0x2054 +#define AFE_HDMI_CONN0 0x2078 +#define AFE_TDM_TOP_IP_VERSION 0x207c +#define AFE_CONN004_0 0x2100 +#define AFE_CONN004_1 0x2104 +#define AFE_CONN004_2 0x2108 +#define AFE_CONN004_4 0x2110 +#define AFE_CONN004_6 0x2118 +#define AFE_CONN005_0 0x2120 +#define AFE_CONN005_1 0x2124 +#define AFE_CONN005_2 0x2128 +#define AFE_CONN005_4 0x2130 +#define AFE_CONN005_6 0x2138 +#define AFE_CONN006_0 0x2140 +#define AFE_CONN006_1 0x2144 +#define AFE_CONN006_2 0x2148 +#define AFE_CONN006_4 0x2150 +#define AFE_CONN006_6 0x2158 +#define AFE_CONN007_0 0x2160 +#define AFE_CONN007_1 0x2164 +#define AFE_CONN007_2 0x2168 +#define AFE_CONN007_4 0x2170 +#define AFE_CONN007_6 0x2178 +#define AFE_CONN008_0 0x2180 +#define AFE_CONN008_1 0x2184 +#define AFE_CONN008_2 0x2188 +#define AFE_CONN008_4 0x2190 +#define AFE_CONN008_6 0x2198 +#define AFE_CONN009_0 0x21a0 +#define AFE_CONN009_1 0x21a4 +#define AFE_CONN009_2 0x21a8 +#define AFE_CONN009_4 0x21b0 +#define AFE_CONN009_6 0x21b8 +#define AFE_CONN010_0 0x21c0 +#define AFE_CONN010_1 0x21c4 +#define AFE_CONN010_2 0x21c8 +#define AFE_CONN010_4 0x21d0 +#define AFE_CONN010_6 0x21d8 +#define AFE_CONN011_0 0x21e0 +#define AFE_CONN011_1 0x21e4 +#define AFE_CONN011_2 0x21e8 +#define AFE_CONN011_4 0x21f0 +#define AFE_CONN011_6 0x21f8 +#define AFE_CONN014_0 0x2240 +#define AFE_CONN014_1 0x2244 +#define AFE_CONN014_2 0x2248 +#define AFE_CONN014_4 0x2250 +#define AFE_CONN014_6 0x2258 +#define AFE_CONN015_0 0x2260 +#define AFE_CONN015_1 0x2264 +#define AFE_CONN015_2 0x2268 +#define AFE_CONN015_4 0x2270 +#define AFE_CONN015_6 0x2278 +#define AFE_CONN016_0 0x2280 +#define AFE_CONN016_1 0x2284 +#define AFE_CONN016_2 0x2288 +#define AFE_CONN016_4 0x2290 +#define AFE_CONN016_6 0x2298 +#define AFE_CONN017_0 0x22a0 +#define AFE_CONN017_1 0x22a4 +#define AFE_CONN017_2 0x22a8 +#define AFE_CONN017_4 0x22b0 +#define AFE_CONN017_6 0x22b8 +#define AFE_CONN018_0 0x22c0 +#define AFE_CONN018_1 0x22c4 +#define AFE_CONN018_2 0x22c8 +#define AFE_CONN018_4 0x22d0 +#define AFE_CONN018_6 0x22d8 +#define AFE_CONN019_0 0x22e0 +#define AFE_CONN019_1 0x22e4 +#define AFE_CONN019_2 0x22e8 +#define AFE_CONN019_4 0x22f0 +#define AFE_CONN019_6 0x22f8 +#define AFE_CONN020_0 0x2300 +#define AFE_CONN020_1 0x2304 +#define AFE_CONN020_2 0x2308 +#define AFE_CONN020_4 0x2310 +#define AFE_CONN020_6 0x2318 +#define AFE_CONN021_0 0x2320 +#define AFE_CONN021_1 0x2324 +#define AFE_CONN021_2 0x2328 +#define AFE_CONN021_4 0x2330 +#define AFE_CONN021_6 0x2338 +#define AFE_CONN022_0 0x2340 +#define AFE_CONN022_1 0x2344 +#define AFE_CONN022_2 0x2348 +#define AFE_CONN022_4 0x2350 +#define AFE_CONN022_6 0x2358 +#define AFE_CONN023_0 0x2360 +#define AFE_CONN023_1 0x2364 +#define AFE_CONN023_2 0x2368 +#define AFE_CONN023_4 0x2370 +#define AFE_CONN023_6 0x2378 +#define AFE_CONN024_0 0x2380 +#define AFE_CONN024_1 0x2384 +#define AFE_CONN024_2 0x2388 +#define AFE_CONN024_4 0x2390 +#define AFE_CONN024_6 0x2398 +#define AFE_CONN025_0 0x23a0 +#define AFE_CONN025_1 0x23a4 +#define AFE_CONN025_2 0x23a8 +#define AFE_CONN025_4 0x23b0 +#define AFE_CONN025_6 0x23b8 +#define AFE_CONN026_0 0x23c0 +#define AFE_CONN026_1 0x23c4 +#define AFE_CONN026_2 0x23c8 +#define AFE_CONN026_4 0x23d0 +#define AFE_CONN026_6 0x23d8 +#define AFE_CONN027_0 0x23e0 +#define AFE_CONN027_1 0x23e4 +#define AFE_CONN027_2 0x23e8 +#define AFE_CONN027_4 0x23f0 +#define AFE_CONN027_6 0x23f8 +#define AFE_CONN028_0 0x2400 +#define AFE_CONN028_1 0x2404 +#define AFE_CONN028_2 0x2408 +#define AFE_CONN028_4 0x2410 +#define AFE_CONN028_6 0x2418 +#define AFE_CONN029_0 0x2420 +#define AFE_CONN029_1 0x2424 +#define AFE_CONN029_2 0x2428 +#define AFE_CONN029_4 0x2430 +#define AFE_CONN029_6 0x2438 +#define AFE_CONN030_0 0x2440 +#define AFE_CONN030_1 0x2444 +#define AFE_CONN030_2 0x2448 +#define AFE_CONN030_4 0x2450 +#define AFE_CONN030_6 0x2458 +#define AFE_CONN031_0 0x2460 +#define AFE_CONN031_1 0x2464 +#define AFE_CONN031_2 0x2468 +#define AFE_CONN031_4 0x2470 +#define AFE_CONN031_6 0x2478 +#define AFE_CONN032_0 0x2480 +#define AFE_CONN032_1 0x2484 +#define AFE_CONN032_2 0x2488 +#define AFE_CONN032_4 0x2490 +#define AFE_CONN032_6 0x2498 +#define AFE_CONN033_0 0x24a0 +#define AFE_CONN033_1 0x24a4 +#define AFE_CONN033_2 0x24a8 +#define AFE_CONN033_4 0x24b0 +#define AFE_CONN033_6 0x24b8 +#define AFE_CONN034_0 0x24c0 +#define AFE_CONN034_1 0x24c4 +#define AFE_CONN034_2 0x24c8 +#define AFE_CONN034_4 0x24d0 +#define AFE_CONN034_6 0x24d8 +#define AFE_CONN035_0 0x24e0 +#define AFE_CONN035_1 0x24e4 +#define AFE_CONN035_2 0x24e8 +#define AFE_CONN035_4 0x24f0 +#define AFE_CONN035_6 0x24f8 +#define AFE_CONN036_0 0x2500 +#define AFE_CONN036_1 0x2504 +#define AFE_CONN036_2 0x2508 +#define AFE_CONN036_4 0x2510 +#define AFE_CONN036_6 0x2518 +#define AFE_CONN037_0 0x2520 +#define AFE_CONN037_1 0x2524 +#define AFE_CONN037_2 0x2528 +#define AFE_CONN037_4 0x2530 +#define AFE_CONN037_6 0x2538 +#define AFE_CONN038_0 0x2540 +#define AFE_CONN038_1 0x2544 +#define AFE_CONN038_2 0x2548 +#define AFE_CONN038_4 0x2550 +#define AFE_CONN038_6 0x2558 +#define AFE_CONN039_0 0x2560 +#define AFE_CONN039_1 0x2564 +#define AFE_CONN039_2 0x2568 +#define AFE_CONN039_4 0x2570 +#define AFE_CONN039_6 0x2578 +#define AFE_CONN040_0 0x2580 +#define AFE_CONN040_1 0x2584 +#define AFE_CONN040_2 0x2588 +#define AFE_CONN040_4 0x2590 +#define AFE_CONN040_6 0x2598 +#define AFE_CONN041_0 0x25a0 +#define AFE_CONN041_1 0x25a4 +#define AFE_CONN041_2 0x25a8 +#define AFE_CONN041_4 0x25b0 +#define AFE_CONN041_6 0x25b8 +#define AFE_CONN042_0 0x25c0 +#define AFE_CONN042_1 0x25c4 +#define AFE_CONN042_2 0x25c8 +#define AFE_CONN042_4 0x25d0 +#define AFE_CONN042_6 0x25d8 +#define AFE_CONN043_0 0x25e0 +#define AFE_CONN043_1 0x25e4 +#define AFE_CONN043_2 0x25e8 +#define AFE_CONN043_4 0x25f0 +#define AFE_CONN043_6 0x25f8 +#define AFE_CONN044_0 0x2600 +#define AFE_CONN044_1 0x2604 +#define AFE_CONN044_2 0x2608 +#define AFE_CONN044_4 0x2610 +#define AFE_CONN044_6 0x2618 +#define AFE_CONN045_0 0x2620 +#define AFE_CONN045_1 0x2624 +#define AFE_CONN045_2 0x2628 +#define AFE_CONN045_4 0x2630 +#define AFE_CONN045_6 0x2638 +#define AFE_CONN046_0 0x2640 +#define AFE_CONN046_1 0x2644 +#define AFE_CONN046_2 0x2648 +#define AFE_CONN046_4 0x2650 +#define AFE_CONN046_6 0x2658 +#define AFE_CONN047_0 0x2660 +#define AFE_CONN047_1 0x2664 +#define AFE_CONN047_2 0x2668 +#define AFE_CONN047_4 0x2670 +#define AFE_CONN047_6 0x2678 +#define AFE_CONN048_0 0x2680 +#define AFE_CONN048_1 0x2684 +#define AFE_CONN048_2 0x2688 +#define AFE_CONN048_4 0x2690 +#define AFE_CONN048_6 0x2698 +#define AFE_CONN049_0 0x26a0 +#define AFE_CONN049_1 0x26a4 +#define AFE_CONN049_2 0x26a8 +#define AFE_CONN049_4 0x26b0 +#define AFE_CONN049_6 0x26b8 +#define AFE_CONN050_0 0x26c0 +#define AFE_CONN050_1 0x26c4 +#define AFE_CONN050_2 0x26c8 +#define AFE_CONN050_4 0x26d0 +#define AFE_CONN050_6 0x26d8 +#define AFE_CONN051_0 0x26e0 +#define AFE_CONN051_1 0x26e4 +#define AFE_CONN051_2 0x26e8 +#define AFE_CONN051_4 0x26f0 +#define AFE_CONN051_6 0x26f8 +#define AFE_CONN052_0 0x2700 +#define AFE_CONN052_1 0x2704 +#define AFE_CONN052_2 0x2708 +#define AFE_CONN052_4 0x2710 +#define AFE_CONN052_6 0x2718 +#define AFE_CONN053_0 0x2720 +#define AFE_CONN053_1 0x2724 +#define AFE_CONN053_2 0x2728 +#define AFE_CONN053_4 0x2730 +#define AFE_CONN053_6 0x2738 +#define AFE_CONN054_0 0x2740 +#define AFE_CONN054_1 0x2744 +#define AFE_CONN054_2 0x2748 +#define AFE_CONN054_4 0x2750 +#define AFE_CONN054_6 0x2758 +#define AFE_CONN055_0 0x2760 +#define AFE_CONN055_1 0x2764 +#define AFE_CONN055_2 0x2768 +#define AFE_CONN055_4 0x2770 +#define AFE_CONN055_6 0x2778 +#define AFE_CONN056_0 0x2780 +#define AFE_CONN056_1 0x2784 +#define AFE_CONN056_2 0x2788 +#define AFE_CONN056_4 0x2790 +#define AFE_CONN056_6 0x2798 +#define AFE_CONN057_0 0x27a0 +#define AFE_CONN057_1 0x27a4 +#define AFE_CONN057_2 0x27a8 +#define AFE_CONN057_4 0x27b0 +#define AFE_CONN057_6 0x27b8 +#define AFE_CONN058_0 0x27c0 +#define AFE_CONN058_1 0x27c4 +#define AFE_CONN058_2 0x27c8 +#define AFE_CONN058_4 0x27d0 +#define AFE_CONN058_6 0x27d8 +#define AFE_CONN059_0 0x27e0 +#define AFE_CONN059_1 0x27e4 +#define AFE_CONN059_2 0x27e8 +#define AFE_CONN059_4 0x27f0 +#define AFE_CONN059_6 0x27f8 +#define AFE_CONN060_0 0x2800 +#define AFE_CONN060_1 0x2804 +#define AFE_CONN060_2 0x2808 +#define AFE_CONN060_4 0x2810 +#define AFE_CONN060_6 0x2818 +#define AFE_CONN061_0 0x2820 +#define AFE_CONN061_1 0x2824 +#define AFE_CONN061_2 0x2828 +#define AFE_CONN061_4 0x2830 +#define AFE_CONN061_6 0x2838 +#define AFE_CONN062_0 0x2840 +#define AFE_CONN062_1 0x2844 +#define AFE_CONN062_2 0x2848 +#define AFE_CONN062_4 0x2850 +#define AFE_CONN062_6 0x2858 +#define AFE_CONN063_0 0x2860 +#define AFE_CONN063_1 0x2864 +#define AFE_CONN063_2 0x2868 +#define AFE_CONN063_4 0x2870 +#define AFE_CONN063_6 0x2878 +#define AFE_CONN066_0 0x28c0 +#define AFE_CONN066_1 0x28c4 +#define AFE_CONN066_2 0x28c8 +#define AFE_CONN066_4 0x28d0 +#define AFE_CONN066_6 0x28d8 +#define AFE_CONN067_0 0x28e0 +#define AFE_CONN067_1 0x28e4 +#define AFE_CONN067_2 0x28e8 +#define AFE_CONN067_4 0x28f0 +#define AFE_CONN067_6 0x28f8 +#define AFE_CONN068_0 0x2900 +#define AFE_CONN068_1 0x2904 +#define AFE_CONN068_2 0x2908 +#define AFE_CONN068_4 0x2910 +#define AFE_CONN068_6 0x2918 +#define AFE_CONN069_0 0x2920 +#define AFE_CONN069_1 0x2924 +#define AFE_CONN069_2 0x2928 +#define AFE_CONN069_4 0x2930 +#define AFE_CONN069_6 0x2938 +#define AFE_CONN096_0 0x2c80 +#define AFE_CONN096_1 0x2c84 +#define AFE_CONN096_2 0x2c88 +#define AFE_CONN096_4 0x2c90 +#define AFE_CONN096_6 0x2c98 +#define AFE_CONN097_0 0x2ca0 +#define AFE_CONN097_1 0x2ca4 +#define AFE_CONN097_2 0x2ca8 +#define AFE_CONN097_4 0x2cb0 +#define AFE_CONN097_6 0x2cb8 +#define AFE_CONN098_0 0x2cc0 +#define AFE_CONN098_1 0x2cc4 +#define AFE_CONN098_2 0x2cc8 +#define AFE_CONN098_4 0x2cd0 +#define AFE_CONN098_6 0x2cd8 +#define AFE_CONN099_0 0x2ce0 +#define AFE_CONN099_1 0x2ce4 +#define AFE_CONN099_2 0x2ce8 +#define AFE_CONN099_4 0x2cf0 +#define AFE_CONN099_6 0x2cf8 +#define AFE_CONN100_0 0x2d00 +#define AFE_CONN100_1 0x2d04 +#define AFE_CONN100_2 0x2d08 +#define AFE_CONN100_4 0x2d10 +#define AFE_CONN100_6 0x2d18 +#define AFE_CONN108_0 0x2e00 +#define AFE_CONN108_1 0x2e04 +#define AFE_CONN108_2 0x2e08 +#define AFE_CONN108_4 0x2e10 +#define AFE_CONN108_6 0x2e18 +#define AFE_CONN109_0 0x2e20 +#define AFE_CONN109_1 0x2e24 +#define AFE_CONN109_2 0x2e28 +#define AFE_CONN109_4 0x2e30 +#define AFE_CONN109_6 0x2e38 +#define AFE_CONN110_0 0x2e40 +#define AFE_CONN110_1 0x2e44 +#define AFE_CONN110_2 0x2e48 +#define AFE_CONN110_4 0x2e50 +#define AFE_CONN110_6 0x2e58 +#define AFE_CONN111_0 0x2e60 +#define AFE_CONN111_1 0x2e64 +#define AFE_CONN111_2 0x2e68 +#define AFE_CONN111_4 0x2e70 +#define AFE_CONN111_6 0x2e78 +#define AFE_CONN116_0 0x2f00 +#define AFE_CONN116_1 0x2f04 +#define AFE_CONN116_2 0x2f08 +#define AFE_CONN116_4 0x2f10 +#define AFE_CONN116_6 0x2f18 +#define AFE_CONN117_0 0x2f20 +#define AFE_CONN117_1 0x2f24 +#define AFE_CONN117_2 0x2f28 +#define AFE_CONN117_4 0x2f30 +#define AFE_CONN117_6 0x2f38 +#define AFE_CONN118_0 0x2f40 +#define AFE_CONN118_1 0x2f44 +#define AFE_CONN118_2 0x2f48 +#define AFE_CONN118_4 0x2f50 +#define AFE_CONN118_6 0x2f58 +#define AFE_CONN119_0 0x2f60 +#define AFE_CONN119_1 0x2f64 +#define AFE_CONN119_2 0x2f68 +#define AFE_CONN119_4 0x2f70 +#define AFE_CONN119_6 0x2f78 +#define AFE_CONN120_0 0x2f80 +#define AFE_CONN120_1 0x2f84 +#define AFE_CONN120_2 0x2f88 +#define AFE_CONN120_4 0x2f90 +#define AFE_CONN120_6 0x2f98 +#define AFE_CONN121_0 0x2fa0 +#define AFE_CONN121_1 0x2fa4 +#define AFE_CONN121_2 0x2fa8 +#define AFE_CONN121_4 0x2fb0 +#define AFE_CONN121_6 0x2fb8 +#define AFE_CONN122_0 0x2fc0 +#define AFE_CONN122_1 0x2fc4 +#define AFE_CONN122_2 0x2fc8 +#define AFE_CONN122_4 0x2fd0 +#define AFE_CONN122_6 0x2fd8 +#define AFE_CONN123_0 0x2fe0 +#define AFE_CONN123_1 0x2fe4 +#define AFE_CONN123_2 0x2fe8 +#define AFE_CONN123_4 0x2ff0 +#define AFE_CONN123_6 0x2ff8 +#define AFE_CONN180_0 0x3700 +#define AFE_CONN180_1 0x3704 +#define AFE_CONN180_2 0x3708 +#define AFE_CONN180_4 0x3710 +#define AFE_CONN180_6 0x3718 +#define AFE_CONN181_0 0x3720 +#define AFE_CONN181_1 0x3724 +#define AFE_CONN181_2 0x3728 +#define AFE_CONN181_4 0x3730 +#define AFE_CONN181_6 0x3738 +#define AFE_CONN182_0 0x3740 +#define AFE_CONN182_1 0x3744 +#define AFE_CONN182_2 0x3748 +#define AFE_CONN182_4 0x3750 +#define AFE_CONN182_6 0x3758 +#define AFE_CONN183_0 0x3760 +#define AFE_CONN183_1 0x3764 +#define AFE_CONN183_2 0x3768 +#define AFE_CONN183_4 0x3770 +#define AFE_CONN183_6 0x3778 +#define AFE_CONN184_0 0x3780 +#define AFE_CONN184_1 0x3784 +#define AFE_CONN184_2 0x3788 +#define AFE_CONN184_4 0x3790 +#define AFE_CONN184_6 0x3798 +#define AFE_CONN185_0 0x37a0 +#define AFE_CONN185_1 0x37a4 +#define AFE_CONN185_2 0x37a8 +#define AFE_CONN185_4 0x37b0 +#define AFE_CONN185_6 0x37b8 +#define AFE_CONN186_0 0x37c0 +#define AFE_CONN186_1 0x37c4 +#define AFE_CONN186_2 0x37c8 +#define AFE_CONN186_4 0x37d0 +#define AFE_CONN186_6 0x37d8 +#define AFE_CONN187_0 0x37e0 +#define AFE_CONN187_1 0x37e4 +#define AFE_CONN187_2 0x37e8 +#define AFE_CONN187_4 0x37f0 +#define AFE_CONN187_6 0x37f8 +#define AFE_CONN188_0 0x3800 +#define AFE_CONN188_1 0x3804 +#define AFE_CONN188_2 0x3808 +#define AFE_CONN188_4 0x3810 +#define AFE_CONN188_6 0x3818 +#define AFE_CONN189_0 0x3820 +#define AFE_CONN189_1 0x3824 +#define AFE_CONN189_2 0x3828 +#define AFE_CONN189_4 0x3830 +#define AFE_CONN189_6 0x3838 +#define AFE_CONN_MON_CFG 0x4080 +#define AFE_CONN_MON0 0x4084 +#define AFE_CONN_MON1 0x4088 +#define AFE_CONN_MON2 0x408c +#define AFE_CONN_MON3 0x4090 +#define AFE_CONN_MON4 0x4094 +#define AFE_CONN_MON5 0x4098 +#define AFE_CONN_RS_0 0x40a0 +#define AFE_CONN_RS_1 0x40a4 +#define AFE_CONN_RS_2 0x40a8 +#define AFE_CONN_RS_3 0x40ac +#define AFE_CONN_RS_5 0x40b4 +#define AFE_CONN_DI_0 0x40c0 +#define AFE_CONN_DI_1 0x40c4 +#define AFE_CONN_DI_2 0x40c8 +#define AFE_CONN_DI_3 0x40cc +#define AFE_CONN_DI_5 0x40d4 +#define AFE_CONN_16BIT_0 0x40e0 +#define AFE_CONN_16BIT_1 0x40e4 +#define AFE_CONN_16BIT_2 0x40e8 +#define AFE_CONN_16BIT_3 0x40ec +#define AFE_CONN_16BIT_5 0x40f4 +#define AFE_CONN_24BIT_0 0x4100 +#define AFE_CONN_24BIT_1 0x4104 +#define AFE_CONN_24BIT_2 0x4108 +#define AFE_CONN_24BIT_3 0x410c +#define AFE_CONN_24BIT_5 0x4114 +#define AFE_CONN_TOP_IP_VERSION 0x4120 +#define AFE_CBIP_CFG0 0x4380 +#define AFE_CBIP_SLV_DECODER_MON0 0x4384 +#define AFE_CBIP_SLV_DECODER_MON1 0x4388 +#define AFE_CBIP_SLV_MUX_MON_CFG 0x438c +#define AFE_CBIP_SLV_MUX_MON0 0x4390 +#define AFE_CBIP_SLV_MUX_MON1 0x4394 +#define AFE_MEMIF_IP_VERSION 0x4398 +#define AFE_MEMIF_CON0 0x4400 +#define AFE_MEMIF_RD_MON 0x4408 +#define AFE_MEMIF_WR_MON 0x440c +#define AFE_MEMIF_CFG_MON0 0x4410 +#define AFE_BUS_CFG0 0x4414 +#define AFE_BUS_MON1 0x4418 +#define AFE_BUS_MON2 0x441c +#define AFE_MEMIF_ONE_HEART 0x4420 +#define AFE_DL0_BASE_MSB 0x4440 +#define AFE_DL0_BASE 0x4444 +#define AFE_DL0_CUR_MSB 0x4448 +#define AFE_DL0_CUR 0x444c +#define AFE_DL0_END_MSB 0x4450 +#define AFE_DL0_END 0x4454 +#define AFE_DL0_RCH_MON 0x4458 +#define AFE_DL0_LCH_MON 0x445c +#define AFE_DL0_CON0 0x4460 +#define AFE_DL0_MON0 0x4464 +#define AFE_DL0_MEM_UP_MSB 0x4468 +#define AFE_DL0_MEM_UP 0x446c +#define AFE_DL1_BASE_MSB 0x4470 +#define AFE_DL1_BASE 0x4474 +#define AFE_DL1_CUR_MSB 0x4478 +#define AFE_DL1_CUR 0x447c +#define AFE_DL1_END_MSB 0x4480 +#define AFE_DL1_END 0x4484 +#define AFE_DL1_RCH_MON 0x4488 +#define AFE_DL1_LCH_MON 0x448c +#define AFE_DL1_CON0 0x4490 +#define AFE_DL1_MON0 0x4494 +#define AFE_DL1_MEM_UP_MSB 0x4498 +#define AFE_DL1_MEM_UP 0x449c +#define AFE_DL2_BASE_MSB 0x44a0 +#define AFE_DL2_BASE 0x44a4 +#define AFE_DL2_CUR_MSB 0x44a8 +#define AFE_DL2_CUR 0x44ac +#define AFE_DL2_END_MSB 0x44b0 +#define AFE_DL2_END 0x44b4 +#define AFE_DL2_RCH_MON 0x44b8 +#define AFE_DL2_LCH_MON 0x44bc +#define AFE_DL2_CON0 0x44c0 +#define AFE_DL2_MON0 0x44c4 +#define AFE_DL2_MEM_UP_MSB 0x44c8 +#define AFE_DL2_MEM_UP 0x44cc +#define AFE_DL3_BASE_MSB 0x44d0 +#define AFE_DL3_BASE 0x44d4 +#define AFE_DL3_CUR_MSB 0x44d8 +#define AFE_DL3_CUR 0x44dc +#define AFE_DL3_END_MSB 0x44e0 +#define AFE_DL3_END 0x44e4 +#define AFE_DL3_RCH_MON 0x44e8 +#define AFE_DL3_LCH_MON 0x44ec +#define AFE_DL3_CON0 0x44f0 +#define AFE_DL3_MON0 0x44f4 +#define AFE_DL3_MEM_UP_MSB 0x44f8 +#define AFE_DL3_MEM_UP 0x44fc +#define AFE_DL4_BASE_MSB 0x4500 +#define AFE_DL4_BASE 0x4504 +#define AFE_DL4_CUR_MSB 0x4508 +#define AFE_DL4_CUR 0x450c +#define AFE_DL4_END_MSB 0x4510 +#define AFE_DL4_END 0x4514 +#define AFE_DL4_RCH_MON 0x4518 +#define AFE_DL4_LCH_MON 0x451c +#define AFE_DL4_CON0 0x4520 +#define AFE_DL4_MON0 0x4524 +#define AFE_DL4_MEM_UP_MSB 0x4528 +#define AFE_DL4_MEM_UP 0x452c +#define AFE_DL5_BASE_MSB 0x4530 +#define AFE_DL5_BASE 0x4534 +#define AFE_DL5_CUR_MSB 0x4538 +#define AFE_DL5_CUR 0x453c +#define AFE_DL5_END_MSB 0x4540 +#define AFE_DL5_END 0x4544 +#define AFE_DL5_RCH_MON 0x4548 +#define AFE_DL5_LCH_MON 0x454c +#define AFE_DL5_CON0 0x4550 +#define AFE_DL5_MON0 0x4554 +#define AFE_DL5_MEM_UP_MSB 0x4558 +#define AFE_DL5_MEM_UP 0x455c +#define AFE_DL6_BASE_MSB 0x4560 +#define AFE_DL6_BASE 0x4564 +#define AFE_DL6_CUR_MSB 0x4568 +#define AFE_DL6_CUR 0x456c +#define AFE_DL6_END_MSB 0x4570 +#define AFE_DL6_END 0x4574 +#define AFE_DL6_RCH_MON 0x4578 +#define AFE_DL6_LCH_MON 0x457c +#define AFE_DL6_CON0 0x4580 +#define AFE_DL6_MON0 0x4584 +#define AFE_DL6_MEM_UP_MSB 0x4588 +#define AFE_DL6_MEM_UP 0x458c +#define AFE_DL7_BASE_MSB 0x4590 +#define AFE_DL7_BASE 0x4594 +#define AFE_DL7_CUR_MSB 0x4598 +#define AFE_DL7_CUR 0x459c +#define AFE_DL7_END_MSB 0x45a0 +#define AFE_DL7_END 0x45a4 +#define AFE_DL7_RCH_MON 0x45a8 +#define AFE_DL7_LCH_MON 0x45ac +#define AFE_DL7_CON0 0x45b0 +#define AFE_DL7_MON0 0x45b4 +#define AFE_DL7_MEM_UP_MSB 0x45b8 +#define AFE_DL7_MEM_UP 0x45bc +#define AFE_DL8_BASE_MSB 0x45c0 +#define AFE_DL8_BASE 0x45c4 +#define AFE_DL8_CUR_MSB 0x45c8 +#define AFE_DL8_CUR 0x45cc +#define AFE_DL8_END_MSB 0x45d0 +#define AFE_DL8_END 0x45d4 +#define AFE_DL8_RCH_MON 0x45d8 +#define AFE_DL8_LCH_MON 0x45dc +#define AFE_DL8_CON0 0x45e0 +#define AFE_DL8_MON0 0x45e4 +#define AFE_DL8_MEM_UP_MSB 0x45e8 +#define AFE_DL8_MEM_UP 0x45ec +#define AFE_DL_24CH_BASE_MSB 0x4620 +#define AFE_DL_24CH_BASE 0x4624 +#define AFE_DL_24CH_CUR_MSB 0x4628 +#define AFE_DL_24CH_CUR 0x462c +#define AFE_DL_24CH_END_MSB 0x4630 +#define AFE_DL_24CH_END 0x4634 +#define AFE_DL_24CH_CON0 0x4640 +#define AFE_DL_24CH_MON0 0x4644 +#define AFE_DL_24CH_MEM_UP_MSB 0x4648 +#define AFE_DL_24CH_MEM_UP 0x464c +#define AFE_DL23_BASE_MSB 0x4680 +#define AFE_DL23_BASE 0x4684 +#define AFE_DL23_CUR_MSB 0x4688 +#define AFE_DL23_CUR 0x468c +#define AFE_DL23_END_MSB 0x4690 +#define AFE_DL23_END 0x4694 +#define AFE_DL23_RCH_MON 0x4698 +#define AFE_DL23_LCH_MON 0x469c +#define AFE_DL23_CON0 0x46a0 +#define AFE_DL23_MON0 0x46a4 +#define AFE_DL23_MEM_UP_MSB 0x46a8 +#define AFE_DL23_MEM_UP 0x46ac +#define AFE_DL24_BASE_MSB 0x46b0 +#define AFE_DL24_BASE 0x46b4 +#define AFE_DL24_CUR_MSB 0x46b8 +#define AFE_DL24_CUR 0x46bc +#define AFE_DL24_END_MSB 0x46c0 +#define AFE_DL24_END 0x46c4 +#define AFE_DL24_RCH_MON 0x46c8 +#define AFE_DL24_LCH_MON 0x46cc +#define AFE_DL24_CON0 0x46d0 +#define AFE_DL24_MON0 0x46d4 +#define AFE_DL24_MEM_UP_MSB 0x46d8 +#define AFE_DL24_MEM_UP 0x46dc +#define AFE_DL25_BASE_MSB 0x46e0 +#define AFE_DL25_BASE 0x46e4 +#define AFE_DL25_CUR_MSB 0x46e8 +#define AFE_DL25_CUR 0x46ec +#define AFE_DL25_END_MSB 0x46f0 +#define AFE_DL25_END 0x46f4 +#define AFE_DL25_RCH_MON 0x46f8 +#define AFE_DL25_LCH_MON 0x46fc +#define AFE_DL25_CON0 0x4700 +#define AFE_DL25_MON0 0x4704 +#define AFE_DL25_MEM_UP_MSB 0x4708 +#define AFE_DL25_MEM_UP 0x470c +#define AFE_VUL0_BASE_MSB 0x4d60 +#define AFE_VUL0_BASE 0x4d64 +#define AFE_VUL0_CUR_MSB 0x4d68 +#define AFE_VUL0_CUR 0x4d6c +#define AFE_VUL0_END_MSB 0x4d70 +#define AFE_VUL0_END 0x4d74 +#define AFE_VUL0_RCH_MON 0x4d78 +#define AFE_VUL0_LCH_MON 0x4d7c +#define AFE_VUL0_CON0 0x4d80 +#define AFE_VUL0_MON0 0x4d84 +#define AFE_VUL1_BASE_MSB 0x4d90 +#define AFE_VUL1_BASE 0x4d94 +#define AFE_VUL1_CUR_MSB 0x4d98 +#define AFE_VUL1_CUR 0x4d9c +#define AFE_VUL1_END_MSB 0x4da0 +#define AFE_VUL1_END 0x4da4 +#define AFE_VUL1_RCH_MON 0x4da8 +#define AFE_VUL1_LCH_MON 0x4dac +#define AFE_VUL1_CON0 0x4db0 +#define AFE_VUL1_MON0 0x4db4 +#define AFE_VUL2_BASE_MSB 0x4dc0 +#define AFE_VUL2_BASE 0x4dc4 +#define AFE_VUL2_CUR_MSB 0x4dc8 +#define AFE_VUL2_CUR 0x4dcc +#define AFE_VUL2_END_MSB 0x4dd0 +#define AFE_VUL2_END 0x4dd4 +#define AFE_VUL2_RCH_MON 0x4dd8 +#define AFE_VUL2_LCH_MON 0x4ddc +#define AFE_VUL2_CON0 0x4de0 +#define AFE_VUL2_MON0 0x4de4 +#define AFE_VUL3_BASE_MSB 0x4df0 +#define AFE_VUL3_BASE 0x4df4 +#define AFE_VUL3_CUR_MSB 0x4df8 +#define AFE_VUL3_CUR 0x4dfc +#define AFE_VUL3_END_MSB 0x4e00 +#define AFE_VUL3_END 0x4e04 +#define AFE_VUL3_RCH_MON 0x4e08 +#define AFE_VUL3_LCH_MON 0x4e0c +#define AFE_VUL3_CON0 0x4e10 +#define AFE_VUL3_MON0 0x4e14 +#define AFE_VUL4_BASE_MSB 0x4e20 +#define AFE_VUL4_BASE 0x4e24 +#define AFE_VUL4_CUR_MSB 0x4e28 +#define AFE_VUL4_CUR 0x4e2c +#define AFE_VUL4_END_MSB 0x4e30 +#define AFE_VUL4_END 0x4e34 +#define AFE_VUL4_RCH_MON 0x4e38 +#define AFE_VUL4_LCH_MON 0x4e3c +#define AFE_VUL4_CON0 0x4e40 +#define AFE_VUL4_MON0 0x4e44 +#define AFE_VUL5_BASE_MSB 0x4e50 +#define AFE_VUL5_BASE 0x4e54 +#define AFE_VUL5_CUR_MSB 0x4e58 +#define AFE_VUL5_CUR 0x4e5c +#define AFE_VUL5_END_MSB 0x4e60 +#define AFE_VUL5_END 0x4e64 +#define AFE_VUL5_RCH_MON 0x4e68 +#define AFE_VUL5_LCH_MON 0x4e6c +#define AFE_VUL5_CON0 0x4e70 +#define AFE_VUL5_MON0 0x4e74 +#define AFE_VUL6_BASE_MSB 0x4e80 +#define AFE_VUL6_BASE 0x4e84 +#define AFE_VUL6_CUR_MSB 0x4e88 +#define AFE_VUL6_CUR 0x4e8c +#define AFE_VUL6_END_MSB 0x4e90 +#define AFE_VUL6_END 0x4e94 +#define AFE_VUL6_RCH_MON 0x4e98 +#define AFE_VUL6_LCH_MON 0x4e9c +#define AFE_VUL6_CON0 0x4ea0 +#define AFE_VUL6_MON0 0x4ea4 +#define AFE_VUL7_BASE_MSB 0x4eb0 +#define AFE_VUL7_BASE 0x4eb4 +#define AFE_VUL7_CUR_MSB 0x4eb8 +#define AFE_VUL7_CUR 0x4ebc +#define AFE_VUL7_END_MSB 0x4ec0 +#define AFE_VUL7_END 0x4ec4 +#define AFE_VUL7_RCH_MON 0x4ec8 +#define AFE_VUL7_LCH_MON 0x4ecc +#define AFE_VUL7_CON0 0x4ed0 +#define AFE_VUL7_MON0 0x4ed4 +#define AFE_VUL8_BASE_MSB 0x4ee0 +#define AFE_VUL8_BASE 0x4ee4 +#define AFE_VUL8_CUR_MSB 0x4ee8 +#define AFE_VUL8_CUR 0x4eec +#define AFE_VUL8_END_MSB 0x4ef0 +#define AFE_VUL8_END 0x4ef4 +#define AFE_VUL8_RCH_MON 0x4ef8 +#define AFE_VUL8_LCH_MON 0x4efc +#define AFE_VUL8_CON0 0x4f00 +#define AFE_VUL8_MON0 0x4f04 +#define AFE_VUL9_BASE_MSB 0x4f10 +#define AFE_VUL9_BASE 0x4f14 +#define AFE_VUL9_CUR_MSB 0x4f18 +#define AFE_VUL9_CUR 0x4f1c +#define AFE_VUL9_END_MSB 0x4f20 +#define AFE_VUL9_END 0x4f24 +#define AFE_VUL9_RCH_MON 0x4f28 +#define AFE_VUL9_LCH_MON 0x4f2c +#define AFE_VUL9_CON0 0x4f30 +#define AFE_VUL9_MON0 0x4f34 +#define AFE_VUL10_BASE_MSB 0x4f40 +#define AFE_VUL10_BASE 0x4f44 +#define AFE_VUL10_CUR_MSB 0x4f48 +#define AFE_VUL10_CUR 0x4f4c +#define AFE_VUL10_END_MSB 0x4f50 +#define AFE_VUL10_END 0x4f54 +#define AFE_VUL10_RCH_MON 0x4f58 +#define AFE_VUL10_LCH_MON 0x4f5c +#define AFE_VUL10_CON0 0x4f60 +#define AFE_VUL10_MON0 0x4f64 +#define AFE_VUL24_BASE_MSB 0x4fa0 +#define AFE_VUL24_BASE 0x4fa4 +#define AFE_VUL24_CUR_MSB 0x4fa8 +#define AFE_VUL24_CUR 0x4fac +#define AFE_VUL24_END_MSB 0x4fb0 +#define AFE_VUL24_END 0x4fb4 +#define AFE_VUL24_CON0 0x4fb8 +#define AFE_VUL24_MON0 0x4fbc +#define AFE_VUL25_BASE_MSB 0x4fc0 +#define AFE_VUL25_BASE 0x4fc4 +#define AFE_VUL25_CUR_MSB 0x4fc8 +#define AFE_VUL25_CUR 0x4fcc +#define AFE_VUL25_END_MSB 0x4fd0 +#define AFE_VUL25_END 0x4fd4 +#define AFE_VUL25_CON0 0x4fd8 +#define AFE_VUL25_MON0 0x4fdc +#define AFE_VUL_CM0_BASE_MSB 0x51c0 +#define AFE_VUL_CM0_BASE 0x51c4 +#define AFE_VUL_CM0_CUR_MSB 0x51c8 +#define AFE_VUL_CM0_CUR 0x51cc +#define AFE_VUL_CM0_END_MSB 0x51d0 +#define AFE_VUL_CM0_END 0x51d4 +#define AFE_VUL_CM0_CON0 0x51d8 +#define AFE_VUL_CM0_MON0 0x51dc +#define AFE_VUL_CM1_BASE_MSB 0x51e0 +#define AFE_VUL_CM1_BASE 0x51e4 +#define AFE_VUL_CM1_CUR_MSB 0x51e8 +#define AFE_VUL_CM1_CUR 0x51ec +#define AFE_VUL_CM1_END_MSB 0x51f0 +#define AFE_VUL_CM1_END 0x51f4 +#define AFE_VUL_CM1_CON0 0x51f8 +#define AFE_VUL_CM1_MON0 0x51fc +#define AFE_ETDM_IN0_BASE_MSB 0x5220 +#define AFE_ETDM_IN0_BASE 0x5224 +#define AFE_ETDM_IN0_CUR_MSB 0x5228 +#define AFE_ETDM_IN0_CUR 0x522c +#define AFE_ETDM_IN0_END_MSB 0x5230 +#define AFE_ETDM_IN0_END 0x5234 +#define AFE_ETDM_IN0_CON0 0x5238 +#define AFE_ETDM_IN1_BASE_MSB 0x5240 +#define AFE_ETDM_IN1_BASE 0x5244 +#define AFE_ETDM_IN1_CUR_MSB 0x5248 +#define AFE_ETDM_IN1_CUR 0x524c +#define AFE_ETDM_IN1_END_MSB 0x5250 +#define AFE_ETDM_IN1_END 0x5254 +#define AFE_ETDM_IN1_CON0 0x5258 +#define AFE_HDMI_OUT_BASE_MSB 0x5360 +#define AFE_HDMI_OUT_BASE 0x5364 +#define AFE_HDMI_OUT_CUR_MSB 0x5368 +#define AFE_HDMI_OUT_CUR 0x536c +#define AFE_HDMI_OUT_END_MSB 0x5370 +#define AFE_HDMI_OUT_END 0x5374 +#define AFE_HDMI_OUT_CON0 0x5378 +#define AFE_HDMI_OUT_MON0 0x537c +#define AFE_VUL24_RCH_MON 0x53e0 +#define AFE_VUL24_LCH_MON 0x53e4 +#define AFE_VUL25_RCH_MON 0x53e8 +#define AFE_VUL25_LCH_MON 0x53ec +#define AFE_VUL_CM0_RCH_MON 0x5458 +#define AFE_VUL_CM0_LCH_MON 0x545c +#define AFE_VUL_CM1_RCH_MON 0x5460 +#define AFE_VUL_CM1_LCH_MON 0x5464 +#define AFE_DL_24CH_CH0_MON 0x5504 +#define AFE_DL_24CH_CH1_MON 0x5508 +#define AFE_DL_24CH_CH2_MON 0x550c +#define AFE_DL_24CH_CH3_MON 0x5510 +#define AFE_DL_24CH_CH4_MON 0x5514 +#define AFE_DL_24CH_CH5_MON 0x5518 +#define AFE_DL_24CH_CH6_MON 0x551c +#define AFE_DL_24CH_CH7_MON 0x5520 +#define AFE_HDMI_OUT_MEM_UP_MSB 0x55b0 +#define AFE_HDMI_OUT_MEM_UP 0x55b4 +#define AFE_SRAM_BOUND 0x5620 +#define AFE_SECURE_CON0 0x5624 +#define AFE_SECURE_CON1 0x5628 +#define AFE_SE_SECURE_CON0 0x5630 +#define AFE_SE_SECURE_CON1 0x5634 +#define AFE_SE_SECURE_CON2 0x5638 +#define AFE_SE_SECURE_CON3 0x563c +#define AFE_SE_PROT_SIDEBAND0 0x5640 +#define AFE_SE_PROT_SIDEBAND1 0x5644 +#define AFE_SE_PROT_SIDEBAND2 0x5648 +#define AFE_SE_PROT_SIDEBAND3 0x564c +#define AFE_SE_DOMAIN_SIDEBAND0 0x5650 +#define AFE_SE_DOMAIN_SIDEBAND1 0x5654 +#define AFE_SE_DOMAIN_SIDEBAND2 0x5658 +#define AFE_SE_DOMAIN_SIDEBAND3 0x565c +#define AFE_SE_DOMAIN_SIDEBAND4 0x5660 +#define AFE_SE_DOMAIN_SIDEBAND5 0x5664 +#define AFE_SE_DOMAIN_SIDEBAND6 0x5668 +#define AFE_SE_DOMAIN_SIDEBAND7 0x566c +#define AFE_SE_DOMAIN_SIDEBAND8 0x5670 +#define AFE_SE_DOMAIN_SIDEBAND9 0x5674 +#define AFE_PROT_SIDEBAND0_MON 0x5678 +#define AFE_PROT_SIDEBAND1_MON 0x567c +#define AFE_PROT_SIDEBAND2_MON 0x5680 +#define AFE_PROT_SIDEBAND3_MON 0x5684 +#define AFE_DOMAIN_SIDEBAND0_MON 0x5688 +#define AFE_DOMAIN_SIDEBAND1_MON 0x568c +#define AFE_DOMAIN_SIDEBAND2_MON 0x5690 +#define AFE_DOMAIN_SIDEBAND3_MON 0x5694 +#define AFE_DOMAIN_SIDEBAND4_MON 0x5698 +#define AFE_DOMAIN_SIDEBAND5_MON 0x569c +#define AFE_DOMAIN_SIDEBAND6_MON 0x56a0 +#define AFE_DOMAIN_SIDEBAND7_MON 0x56a4 +#define AFE_DOMAIN_SIDEBAND8_MON 0x56a8 +#define AFE_DOMAIN_SIDEBAND9_MON 0x56ac +#define AFE_SECURE_CONN0 0x56b0 +#define AFE_SECURE_CONN_ETDM0 0x56b4 +#define AFE_SECURE_CONN_ETDM1 0x56b8 +#define AFE_SECURE_CONN_ETDM2 0x56bc +#define AFE_SECURE_SRAM_CON0 0x56c0 +#define AFE_SECURE_SRAM_CON1 0x56c4 +#define AFE_SE_CONN_INPUT_MASK0 0x56d0 +#define AFE_SE_CONN_INPUT_MASK1 0x56d4 +#define AFE_SE_CONN_INPUT_MASK2 0x56d8 +#define AFE_SE_CONN_INPUT_MASK3 0x56dc +#define AFE_SE_CONN_INPUT_MASK4 0x56e0 +#define AFE_SE_CONN_INPUT_MASK5 0x56e4 +#define AFE_SE_CONN_INPUT_MASK6 0x56e8 +#define AFE_SE_CONN_INPUT_MASK7 0x56ec +#define AFE_NON_SE_CONN_INPUT_MASK0 0x56f0 +#define AFE_NON_SE_CONN_INPUT_MASK1 0x56f4 +#define AFE_NON_SE_CONN_INPUT_MASK2 0x56f8 +#define AFE_NON_SE_CONN_INPUT_MASK3 0x56fc +#define AFE_NON_SE_CONN_INPUT_MASK4 0x5700 +#define AFE_NON_SE_CONN_INPUT_MASK5 0x5704 +#define AFE_NON_SE_CONN_INPUT_MASK6 0x5708 +#define AFE_NON_SE_CONN_INPUT_MASK7 0x570c +#define AFE_SE_CONN_OUTPUT_SEL0 0x5710 +#define AFE_SE_CONN_OUTPUT_SEL1 0x5714 +#define AFE_SE_CONN_OUTPUT_SEL2 0x5718 +#define AFE_SE_CONN_OUTPUT_SEL3 0x571c +#define AFE_SE_CONN_OUTPUT_SEL4 0x5720 +#define AFE_SE_CONN_OUTPUT_SEL5 0x5724 +#define AFE_SE_CONN_OUTPUT_SEL6 0x5728 +#define AFE_SE_CONN_OUTPUT_SEL7 0x572c +#define AFE_PCM0_INTF_CON1_MASK_MON 0x5730 +#define AFE_CONNSYS_I2S_CON_MASK_MON 0x5738 +#define AFE_TDM_CON2_MASK_MON 0x5744 +#define AFE_MTKAIF0_CFG0_MASK_MON 0x574c +#define AFE_MTKAIF1_CFG0_MASK_MON 0x5750 +#define AFE_ADDA_UL0_SRC_CON0_MASK_MON 0x5754 +#define AFE_ADDA_DMIC0_SRC_CON0_MASK_MON 0x5764 +#define AFE_ADDA_DMIC1_SRC_CON0_MASK_MON 0x5768 +#define AFE_MON_SECURE_CON0 0x5840 +#define AFE_SECURE_CONN_ETDM3 0x5850 +#define AFE_ASRC_NEW_CON0 0x7800 +#define AFE_ASRC_NEW_CON1 0x7804 +#define AFE_ASRC_NEW_CON2 0x7808 +#define AFE_ASRC_NEW_CON3 0x780c +#define AFE_ASRC_NEW_CON4 0x7810 +#define AFE_ASRC_NEW_CON5 0x7814 +#define AFE_ASRC_NEW_CON6 0x7818 +#define AFE_ASRC_NEW_CON7 0x781c +#define AFE_ASRC_NEW_CON8 0x7820 +#define AFE_ASRC_NEW_CON9 0x7824 +#define AFE_ASRC_NEW_CON10 0x7828 +#define AFE_ASRC_NEW_CON11 0x782c +#define AFE_ASRC_NEW_CON12 0x7830 +#define AFE_ASRC_NEW_CON13 0x7834 +#define AFE_ASRC_NEW_CON14 0x7838 +#define AFE_ASRC_NEW_IP_VERSION 0x783c +#define AFE_GASRC0_NEW_CON0 0x7840 +#define AFE_GASRC0_NEW_CON1 0x7844 +#define AFE_GASRC0_NEW_CON2 0x7848 +#define AFE_GASRC0_NEW_CON3 0x784c +#define AFE_GASRC0_NEW_CON4 0x7850 +#define AFE_GASRC0_NEW_CON5 0x7854 +#define AFE_GASRC0_NEW_CON6 0x7858 +#define AFE_GASRC0_NEW_CON7 0x785c +#define AFE_GASRC0_NEW_CON8 0x7860 +#define AFE_GASRC0_NEW_CON9 0x7864 +#define AFE_GASRC0_NEW_CON10 0x7868 +#define AFE_GASRC0_NEW_CON11 0x786c +#define AFE_GASRC0_NEW_CON12 0x7870 +#define AFE_GASRC0_NEW_CON13 0x7874 +#define AFE_GASRC0_NEW_CON14 0x7878 +#define AFE_GASRC0_NEW_IP_VERSION 0x787c +#define AFE_GASRC1_NEW_CON0 0x7880 +#define AFE_GASRC1_NEW_CON1 0x7884 +#define AFE_GASRC1_NEW_CON2 0x7888 +#define AFE_GASRC1_NEW_CON3 0x788c +#define AFE_GASRC1_NEW_CON4 0x7890 +#define AFE_GASRC1_NEW_CON5 0x7894 +#define AFE_GASRC1_NEW_CON6 0x7898 +#define AFE_GASRC1_NEW_CON7 0x789c +#define AFE_GASRC1_NEW_CON8 0x78a0 +#define AFE_GASRC1_NEW_CON9 0x78a4 +#define AFE_GASRC1_NEW_CON10 0x78a8 +#define AFE_GASRC1_NEW_CON11 0x78ac +#define AFE_GASRC1_NEW_CON12 0x78b0 +#define AFE_GASRC1_NEW_CON13 0x78b4 +#define AFE_GASRC1_NEW_CON14 0x78b8 +#define AFE_GASRC1_NEW_IP_VERSION 0x78bc +#define AFE_GASRC2_NEW_CON0 0x78c0 +#define AFE_GASRC2_NEW_CON1 0x78c4 +#define AFE_GASRC2_NEW_CON2 0x78c8 +#define AFE_GASRC2_NEW_CON3 0x78cc +#define AFE_GASRC2_NEW_CON4 0x78d0 +#define AFE_GASRC2_NEW_CON5 0x78d4 +#define AFE_GASRC2_NEW_CON6 0x78d8 +#define AFE_GASRC2_NEW_CON7 0x78dc +#define AFE_GASRC2_NEW_CON8 0x78e0 +#define AFE_GASRC2_NEW_CON9 0x78e4 +#define AFE_GASRC2_NEW_CON10 0x78e8 +#define AFE_GASRC2_NEW_CON11 0x78ec +#define AFE_GASRC2_NEW_CON12 0x78f0 +#define AFE_GASRC2_NEW_CON13 0x78f4 +#define AFE_GASRC2_NEW_CON14 0x78f8 +#define AFE_GASRC2_NEW_IP_VERSION 0x78fc +#define AFE_GASRC3_NEW_CON0 0x7900 +#define AFE_GASRC3_NEW_CON1 0x7904 +#define AFE_GASRC3_NEW_CON2 0x7908 +#define AFE_GASRC3_NEW_CON3 0x790c +#define AFE_GASRC3_NEW_CON4 0x7910 +#define AFE_GASRC3_NEW_CON5 0x7914 +#define AFE_GASRC3_NEW_CON6 0x7918 +#define AFE_GASRC3_NEW_CON7 0x791c +#define AFE_GASRC3_NEW_CON8 0x7920 +#define AFE_GASRC3_NEW_CON9 0x7924 +#define AFE_GASRC3_NEW_CON10 0x7928 +#define AFE_GASRC3_NEW_CON11 0x792c +#define AFE_GASRC3_NEW_CON12 0x7930 +#define AFE_GASRC3_NEW_CON13 0x7934 +#define AFE_GASRC3_NEW_CON14 0x7938 +#define AFE_GASRC3_NEW_IP_VERSION 0x793c +#define AFE_GASRC4_NEW_CON0 0x7940 +#define AFE_GASRC4_NEW_CON1 0x7944 +#define AFE_GASRC4_NEW_CON2 0x7948 +#define AFE_GASRC4_NEW_CON3 0x794c +#define AFE_GASRC4_NEW_CON4 0x7950 +#define AFE_GASRC4_NEW_CON5 0x7954 +#define AFE_GASRC4_NEW_CON6 0x7958 +#define AFE_GASRC4_NEW_CON7 0x795c +#define AFE_GASRC4_NEW_CON8 0x7960 +#define AFE_GASRC4_NEW_CON9 0x7964 +#define AFE_GASRC4_NEW_CON10 0x7968 +#define AFE_GASRC4_NEW_CON11 0x796c +#define AFE_GASRC4_NEW_CON12 0x7970 +#define AFE_GASRC4_NEW_CON13 0x7974 +#define AFE_GASRC4_NEW_CON14 0x7978 +#define AFE_GASRC4_NEW_IP_VERSION 0x797c +#define AFE_SOUNDWIRE_ULSRC_PHASE_CLK_CON0 0x9400 +#define AFE_SOUNDWIRE_ULSRC_PHASE_CLK_CON1 0x9404 +#define AFE_SOUNDWIRE_ULSRC_PHASE_CLK_CON2 0x9408 +#define AFE_SOUNDWIRE_ULSRC_PHASE_CLK_CON3 0x940c +#define AFE_SOUNDWIRE_ULSRC_PHASE_CLK_CON4 0x9410 +#define AFE_SOUNDWIRE_ULSRC_PHASE_ENGEN_CON0 0x9414 +#define AFE_SOUNDWIRE_ULSRC_PHASE_ENGEN_CON1 0x9418 +#define AFE_SOUNDWIRE_ULSRC_PHASE_RST_CON0 0x941c +#define AFE_IRQ_MCU_EN 0x9d00 +#define AFE_IRQ_MCU_DSP_EN 0x9d04 +#define AFE_IRQ_MCU_DSP2_EN 0x9d08 +#define AFE_IRQ_MCU_SCP_EN 0x9d0c +#define AFE_CUSTOM_IRQ_MCU_EN 0x9d10 +#define AFE_CUSTOM_IRQ_MCU_DSP_EN 0x9d14 +#define AFE_CUSTOM_IRQ_MCU_DSP2_EN 0x9d18 +#define AFE_CUSTOM_IRQ_MCU_SCP_EN 0x9d1c +#define AFE_IRQ_MCU_STATUS 0x9d20 +#define AFE_CUSTOM_IRQ_MCU_STATUS 0x9d24 +#define AFE_IRQ0_MCU_CFG0 0x9d40 +#define AFE_IRQ0_MCU_CFG1 0x9d44 +#define AFE_IRQ1_MCU_CFG0 0x9d48 +#define AFE_IRQ1_MCU_CFG1 0x9d4c +#define AFE_IRQ2_MCU_CFG0 0x9d50 +#define AFE_IRQ2_MCU_CFG1 0x9d54 +#define AFE_IRQ3_MCU_CFG0 0x9d58 +#define AFE_IRQ3_MCU_CFG1 0x9d5c +#define AFE_IRQ4_MCU_CFG0 0x9d60 +#define AFE_IRQ4_MCU_CFG1 0x9d64 +#define AFE_IRQ5_MCU_CFG0 0x9d68 +#define AFE_IRQ5_MCU_CFG1 0x9d6c +#define AFE_IRQ6_MCU_CFG0 0x9d70 +#define AFE_IRQ6_MCU_CFG1 0x9d74 +#define AFE_IRQ7_MCU_CFG0 0x9d78 +#define AFE_IRQ7_MCU_CFG1 0x9d7c +#define AFE_IRQ8_MCU_CFG0 0x9d80 +#define AFE_IRQ8_MCU_CFG1 0x9d84 +#define AFE_IRQ9_MCU_CFG0 0x9d88 +#define AFE_IRQ9_MCU_CFG1 0x9d8c +#define AFE_IRQ10_MCU_CFG0 0x9d90 +#define AFE_IRQ10_MCU_CFG1 0x9d94 +#define AFE_IRQ11_MCU_CFG0 0x9d98 +#define AFE_IRQ11_MCU_CFG1 0x9d9c +#define AFE_IRQ12_MCU_CFG0 0x9da0 +#define AFE_IRQ12_MCU_CFG1 0x9da4 +#define AFE_IRQ13_MCU_CFG0 0x9da8 +#define AFE_IRQ13_MCU_CFG1 0x9dac +#define AFE_IRQ14_MCU_CFG0 0x9db0 +#define AFE_IRQ14_MCU_CFG1 0x9db4 +#define AFE_IRQ15_MCU_CFG0 0x9db8 +#define AFE_IRQ15_MCU_CFG1 0x9dbc +#define AFE_IRQ16_MCU_CFG0 0x9dc0 +#define AFE_IRQ16_MCU_CFG1 0x9dc4 +#define AFE_IRQ17_MCU_CFG0 0x9dc8 +#define AFE_IRQ17_MCU_CFG1 0x9dcc +#define AFE_IRQ18_MCU_CFG0 0x9dd0 +#define AFE_IRQ18_MCU_CFG1 0x9dd4 +#define AFE_IRQ19_MCU_CFG0 0x9dd8 +#define AFE_IRQ19_MCU_CFG1 0x9ddc +#define AFE_IRQ20_MCU_CFG0 0x9de0 +#define AFE_IRQ20_MCU_CFG1 0x9de4 +#define AFE_IRQ21_MCU_CFG0 0x9de8 +#define AFE_IRQ21_MCU_CFG1 0x9dec +#define AFE_IRQ22_MCU_CFG0 0x9df0 +#define AFE_IRQ22_MCU_CFG1 0x9df4 +#define AFE_IRQ23_MCU_CFG0 0x9df8 +#define AFE_IRQ23_MCU_CFG1 0x9dfc +#define AFE_IRQ24_MCU_CFG0 0x9e00 +#define AFE_IRQ24_MCU_CFG1 0x9e04 +#define AFE_IRQ25_MCU_CFG0 0x9e08 +#define AFE_IRQ25_MCU_CFG1 0x9e0c +#define AFE_IRQ26_MCU_CFG0 0x9e10 +#define AFE_IRQ26_MCU_CFG1 0x9e14 +#define AFE_CUSTOM_IRQ0_MCU_CFG0 0x9e68 +#define AFE_CUSTOM_IRQ22_MCU_CFG0 0x9ec8 +#define AFE_CUSTOM_IRQ22_MCU_CFG1 0x9ecc +#define AFE_CUSTOM_IRQ23_MCU_CFG0 0x9ed0 +#define AFE_CUSTOM_IRQ23_MCU_CFG1 0x9ed4 +#define AFE_IRQ0_CNT_MON 0x9f10 +#define AFE_IRQ1_CNT_MON 0x9f14 +#define AFE_IRQ2_CNT_MON 0x9f18 +#define AFE_IRQ3_CNT_MON 0x9f1c +#define AFE_IRQ4_CNT_MON 0x9f20 +#define AFE_IRQ5_CNT_MON 0x9f24 +#define AFE_IRQ6_CNT_MON 0x9f28 +#define AFE_IRQ7_CNT_MON 0x9f2c +#define AFE_IRQ8_CNT_MON 0x9f30 +#define AFE_IRQ9_CNT_MON 0x9f34 +#define AFE_IRQ10_CNT_MON 0x9f38 +#define AFE_IRQ11_CNT_MON 0x9f3c +#define AFE_IRQ12_CNT_MON 0x9f40 +#define AFE_IRQ13_CNT_MON 0x9f44 +#define AFE_IRQ14_CNT_MON 0x9f48 +#define AFE_IRQ15_CNT_MON 0x9f4c +#define AFE_IRQ16_CNT_MON 0x9f50 +#define AFE_IRQ17_CNT_MON 0x9f54 +#define AFE_IRQ18_CNT_MON 0x9f58 +#define AFE_IRQ19_CNT_MON 0x9f5c +#define AFE_IRQ20_CNT_MON 0x9f60 +#define AFE_IRQ21_CNT_MON 0x9f64 +#define AFE_IRQ22_CNT_MON 0x9f68 +#define AFE_IRQ23_CNT_MON 0x9f6c +#define AFE_IRQ24_CNT_MON 0x9f70 +#define AFE_IRQ25_CNT_MON 0x9f74 +#define AFE_IRQ26_CNT_MON 0x9f78 +#define AFE_CUSTOM_IRQ0_CNT_MON 0x9f90 +#define AFE_CUSTOM_IRQ0_MCU_CFG1 0x9fdc +#define AFE_IRQ_MCU_DSP3_EN 0xa000 +#define AFE_CUSTOM_IRQ_MCU_DSP3_EN 0xa004 +#define AFE_CUSTOM2_IRQ_MCU_EN 0xa008 +#define AFE_CUSTOM2_IRQ_MCU_DSP_EN 0xa00c +#define AFE_CUSTOM2_IRQ_MCU_DSP2_EN 0xa010 +#define AFE_CUSTOM2_IRQ_MCU_DSP3_EN 0xa014 +#define AFE_CUSTOM2_IRQ_MCU_SCP_EN 0xa018 +#define AFE_IRQ_MCU_MON3 0xa01c +#define AFE_IRQ_MCU_MON0 0xa024 +#define AFE_IRQ_MCU_MON1 0xa028 +#define AFE_IRQ_MCU_MON2 0xa02c +#define AFE_CUSTOM2_IRQ_MISS_FLAG_MCU_MON 0xa034 +#define AFE_CUSTOM2_IRQ_DELAY_EN 0xa038 +#define AFE_CUSTOM2_IRQ_MCU_STATUS 0xa03c +#define AFE_CUSTOM2_IRQ0_MCU_CFG0 0xa040 +#define AFE_CUSTOM2_IRQ0_MCU_CFG1 0xa044 +#define AFE_CUSTOM2_IRQ0_CNT_MON 0xa048 +#define AFE_CUSTOM2_IRQ0_MCU_DELAY_CNT_CFG0 0xa04c +#define AFE_CUSTOM2_IRQ1_MCU_CFG0 0xa050 +#define AFE_CUSTOM2_IRQ1_MCU_CFG1 0xa054 +#define AFE_CUSTOM2_IRQ1_CNT_MON 0xa058 +#define AFE_CUSTOM2_IRQ1_MCU_DELAY_CNT_CFG0 0xa05c +#define AFE_CUSTOM2_IRQ2_MCU_CFG0 0xa060 +#define AFE_CUSTOM2_IRQ2_MCU_CFG1 0xa064 +#define AFE_CUSTOM2_IRQ2_CNT_MON 0xa068 +#define AFE_CUSTOM2_IRQ2_MCU_DELAY_CNT_CFG0 0xa06c +#define AFE_CUSTOM2_IRQ3_MCU_CFG0 0xa070 +#define AFE_CUSTOM2_IRQ3_MCU_CFG1 0xa074 +#define AFE_CUSTOM2_IRQ3_CNT_MON 0xa078 +#define AFE_CUSTOM2_IRQ3_MCU_DELAY_CNT_CFG0 0xa07c +#define AFE_CUSTOM2_IRQ4_MCU_CFG0 0xa080 +#define AFE_CUSTOM2_IRQ4_MCU_CFG1 0xa084 +#define AFE_CUSTOM2_IRQ4_CNT_MON 0xa088 +#define AFE_CUSTOM2_IRQ4_MCU_DELAY_CNT_CFG0 0xa08c +#define AFE_CUSTOM2_IRQ5_MCU_CFG0 0xa090 +#define AFE_CUSTOM2_IRQ5_MCU_CFG1 0xa094 +#define AFE_CUSTOM2_IRQ5_CNT_MON 0xa098 +#define AFE_CUSTOM2_IRQ5_MCU_DELAY_CNT_CFG0 0xa09c +#define AFE_CUSTOM2_IRQ6_MCU_CFG0 0xa0a0 +#define AFE_CUSTOM2_IRQ6_MCU_CFG1 0xa0a4 +#define AFE_CUSTOM2_IRQ6_CNT_MON 0xa0a8 +#define AFE_CUSTOM2_IRQ6_MCU_DELAY_CNT_CFG0 0xa0ac +#define AFE_CUSTOM2_IRQ7_MCU_CFG0 0xa0b0 +#define AFE_CUSTOM2_IRQ7_MCU_CFG1 0xa0b4 +#define AFE_CUSTOM2_IRQ7_CNT_MON 0xa0b8 +#define AFE_CUSTOM2_IRQ7_MCU_DELAY_CNT_CFG0 0xa0bc +#define AFE_CUSTOM2_IRQ8_MCU_CFG0 0xa0c0 +#define AFE_CUSTOM2_IRQ8_MCU_CFG1 0xa0c4 +#define AFE_CUSTOM2_IRQ8_CNT_MON 0xa0c8 +#define AFE_CUSTOM2_IRQ8_MCU_DELAY_CNT_CFG0 0xa0cc +#define AFE_CUSTOM2_IRQ9_MCU_CFG0 0xa0d0 +#define AFE_CUSTOM2_IRQ9_MCU_CFG1 0xa0d4 +#define AFE_CUSTOM2_IRQ9_CNT_MON 0xa0d8 +#define AFE_CUSTOM2_IRQ9_MCU_DELAY_CNT_CFG0 0xa0dc +#define AFE_CUSTOM2_IRQ10_MCU_CFG0 0xa0e0 +#define AFE_CUSTOM2_IRQ10_MCU_CFG1 0xa0e4 +#define AFE_CUSTOM2_IRQ10_CNT_MON 0xa0e8 +#define AFE_CUSTOM2_IRQ10_MCU_DELAY_CNT_CFG0 0xa0ec +#define AFE_CUSTOM2_IRQ11_MCU_CFG0 0xa0f0 +#define AFE_CUSTOM2_IRQ11_MCU_CFG1 0xa0f4 +#define AFE_CUSTOM2_IRQ11_CNT_MON 0xa0f8 +#define AFE_CUSTOM2_IRQ11_MCU_DELAY_CNT_CFG0 0xa0fc +#define AFE_CUSTOM2_IRQ12_MCU_CFG0 0xa100 +#define AFE_CUSTOM2_IRQ12_MCU_CFG1 0xa104 +#define AFE_CUSTOM2_IRQ12_CNT_MON 0xa108 +#define AFE_CUSTOM2_IRQ12_MCU_DELAY_CNT_CFG0 0xa10c +#define AFE_CUSTOM2_IRQ30_MCU_CFG0 0xa220 +#define AFE_CUSTOM2_IRQ30_MCU_CFG1 0xa224 +#define AFE_CUSTOM2_IRQ30_CNT_MON 0xa228 +#define AFE_CUSTOM2_IRQ30_MCU_DELAY_CNT_CFG0 0xa22c +#define AFE_CUSTOM2_IRQ31_MCU_CFG0 0xa230 +#define AFE_CUSTOM2_IRQ31_MCU_CFG1 0xa234 +#define AFE_CUSTOM2_IRQ31_CNT_MON 0xa238 +#define AFE_CUSTOM2_IRQ31_MCU_DELAY_CNT_CFG0 0xa23c +#define AFE_CUSTOM3_IRQ8_MCU_CFG0 0xa2c0 +#define AFE_CUSTOM3_IRQ8_MCU_CFG1 0xa2c4 +#define AFE_CUSTOM3_IRQ8_CNT_MON 0xa2c8 +#define AFE_CUSTOM3_IRQ8_MCU_DELAY_CNT_CFG0 0xa2cc +#define AFE_CUSTOM3_IRQ9_MCU_CFG0 0xa2d0 +#define AFE_CUSTOM3_IRQ9_MCU_CFG1 0xa2d4 +#define AFE_CUSTOM3_IRQ9_CNT_MON 0xa2d8 +#define AFE_CUSTOM3_IRQ9_MCU_DELAY_CNT_CFG0 0xa2dc +#define AFE_CUSTOM3_IRQ_MISS_FLAG_MCU_MON 0xa440 +#define AFE_CUSTOM3_IRQ_DELAY_EN 0xa444 +#define AFE_CUSTOM3_IRQ_MCU_STATUS 0xa448 +#define AFE_CUSTOM3_IRQ_MCU_EN 0xa44c +#define AFE_CUSTOM3_IRQ_MCU_DSP_EN 0xa450 +#define AFE_CUSTOM3_IRQ_MCU_DSP2_EN 0xa454 +#define AFE_CUSTOM3_IRQ_MCU_DSP3_EN 0xa458 +#define AFE_CUSTOM3_IRQ_MCU_DSP_WLA_EN 0xa45c +#define AFE_CUSTOM3_IRQ_MCU_SCP_EN 0xa460 +#define AFE_CUSTOM2_IRQ_MCU_DSP_WLA_EN 0xa464 +#define AFE_IRQ_MCU_DSP_WLA_EN 0xa468 +#define AFE_COMMON2_IRQ_MCU_STATUS 0xa46c +#define AFE_COMMON2_IRQ_MCU_EN 0xa470 +#define AFE_COMMON2_IRQ_MCU_DSP_EN 0xa474 +#define AFE_COMMON2_IRQ_MCU_DSP2_EN 0xa478 +#define AFE_COMMON2_IRQ_MCU_DSP3_EN 0xa47c +#define AFE_COMMON2_IRQ_MCU_DSP_WLA_EN 0xa480 +#define AFE_COMMON2_IRQ_MCU_SCP_EN 0xa484 +#define AFE_CUSTOM_IRQ_MCU_DSP_WLA_EN 0xa508 + +#define AFE_MAX_REGISTER AFE_CUSTOM_IRQ_MCU_DSP_WLA_EN + +#define AFE_IRQ_STATUS_BITS 0x7FFFFFF +#define AFE_IRQ_CNT_SHIFT 0 +#define AFE_IRQ_CNT_MASK 0xffffff + +#endif diff --git a/sound/soc/mediatek/mt8195/mt8195-mt6359.c b/sound/soc/mediatek/mt8195/mt8195-mt6359.c index 7b96c843a14a5b..4d62bc654a587b 100644 --- a/sound/soc/mediatek/mt8195/mt8195-mt6359.c +++ b/sound/soc/mediatek/mt8195/mt8195-mt6359.c @@ -451,6 +451,7 @@ static int mt8195_rt5682_init(struct snd_soc_pcm_runtime *rtd) struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt_afe); struct mt8195_afe_private *afe_priv = afe->platform_priv; struct snd_soc_card *card = rtd->card; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); int ret; priv->i2so1_mclk = afe_priv->clk[MT8195_CLK_TOP_APLL12_DIV2]; @@ -477,7 +478,7 @@ static int mt8195_rt5682_init(struct snd_soc_pcm_runtime *rtd) return ret; } - ret = snd_soc_dapm_add_routes(&card->dapm, mt8195_rt5682_routes, + ret = snd_soc_dapm_add_routes(dapm, mt8195_rt5682_routes, ARRAY_SIZE(mt8195_rt5682_routes)); if (ret) dev_err(rtd->dev, "unable to add dapm routes, ret %d\n", ret); @@ -547,9 +548,10 @@ static const struct snd_soc_ops mt8195_sof_be_ops = { static int mt8195_rt1011_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_card *card = rtd->card; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); int ret; - ret = snd_soc_dapm_new_controls(&card->dapm, mt8195_dual_speaker_widgets, + ret = snd_soc_dapm_new_controls(dapm, mt8195_dual_speaker_widgets, ARRAY_SIZE(mt8195_dual_speaker_widgets)); if (ret) { dev_err(rtd->dev, "unable to add dapm controls, ret %d\n", ret); @@ -564,7 +566,7 @@ static int mt8195_rt1011_init(struct snd_soc_pcm_runtime *rtd) return ret; } - ret = snd_soc_dapm_add_routes(&card->dapm, mt8195_rt1011_routes, + ret = snd_soc_dapm_add_routes(dapm, mt8195_rt1011_routes, ARRAY_SIZE(mt8195_rt1011_routes)); if (ret) dev_err(rtd->dev, "unable to add dapm routes, ret %d\n", ret); @@ -575,9 +577,10 @@ static int mt8195_rt1011_init(struct snd_soc_pcm_runtime *rtd) static int mt8195_dumb_amp_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_card *card = rtd->card; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); int ret; - ret = snd_soc_dapm_new_controls(&card->dapm, mt8195_speaker_widgets, + ret = snd_soc_dapm_new_controls(dapm, mt8195_speaker_widgets, ARRAY_SIZE(mt8195_speaker_widgets)); if (ret) { dev_err(rtd->dev, "unable to add dapm controls, ret %d\n", ret); @@ -598,13 +601,14 @@ static int mt8195_dumb_amp_init(struct snd_soc_pcm_runtime *rtd) static int mt8195_rt1019_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_card *card = rtd->card; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); int ret; ret = mt8195_dumb_amp_init(rtd); if (ret) return ret; - ret = snd_soc_dapm_add_routes(&card->dapm, mt8195_rt1019_routes, + ret = snd_soc_dapm_add_routes(dapm, mt8195_rt1019_routes, ARRAY_SIZE(mt8195_rt1019_routes)); if (ret) dev_err(rtd->dev, "unable to add dapm routes, ret %d\n", ret); @@ -615,9 +619,10 @@ static int mt8195_rt1019_init(struct snd_soc_pcm_runtime *rtd) static int mt8195_max98390_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_card *card = rtd->card; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); int ret; - ret = snd_soc_dapm_new_controls(&card->dapm, mt8195_dual_speaker_widgets, + ret = snd_soc_dapm_new_controls(dapm, mt8195_dual_speaker_widgets, ARRAY_SIZE(mt8195_dual_speaker_widgets)); if (ret) { dev_err(rtd->dev, "unable to add dapm controls, ret %d\n", ret); @@ -632,7 +637,7 @@ static int mt8195_max98390_init(struct snd_soc_pcm_runtime *rtd) return ret; } - ret = snd_soc_dapm_add_routes(&card->dapm, mt8195_max98390_routes, + ret = snd_soc_dapm_add_routes(dapm, mt8195_max98390_routes, ARRAY_SIZE(mt8195_max98390_routes)); if (ret) dev_err(rtd->dev, "unable to add dapm routes, ret %d\n", ret); @@ -655,7 +660,7 @@ static int mt8195_etdm_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, static int mt8195_set_bias_level_post(struct snd_soc_card *card, struct snd_soc_dapm_context *dapm, enum snd_soc_bias_level level) { - struct snd_soc_component *component = dapm->component; + struct snd_soc_component *component = snd_soc_dapm_to_component(dapm); struct mtk_soc_card_data *soc_card_data = snd_soc_card_get_drvdata(card); struct mt8195_mt6359_priv *priv = soc_card_data->mach_priv; int ret; diff --git a/sound/soc/mediatek/mt8365/mt8365-afe-pcm.c b/sound/soc/mediatek/mt8365/mt8365-afe-pcm.c index d48252cd96ac4c..d01793394f2254 100644 --- a/sound/soc/mediatek/mt8365/mt8365-afe-pcm.c +++ b/sound/soc/mediatek/mt8365/mt8365-afe-pcm.c @@ -1256,8 +1256,7 @@ static int mt8365_afe_cm2_io_input_mux_get(struct snd_kcontrol *kcontrol, static int mt8365_afe_cm2_io_input_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_context *dapm = - snd_soc_dapm_kcontrol_dapm(kcontrol); + struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kcontrol); struct snd_soc_component *comp = snd_soc_dapm_to_component(dapm); struct mtk_base_afe *afe = snd_soc_component_get_drvdata(comp); struct mt8365_afe_private *afe_priv = afe->platform_priv; diff --git a/sound/soc/meson/aiu-acodec-ctrl.c b/sound/soc/meson/aiu-acodec-ctrl.c index 7b04b97f7b41c8..483772ba69cd7c 100644 --- a/sound/soc/meson/aiu-acodec-ctrl.c +++ b/sound/soc/meson/aiu-acodec-ctrl.c @@ -31,10 +31,8 @@ static const char * const aiu_acodec_ctrl_mux_texts[] = { static int aiu_acodec_ctrl_mux_put_enum(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_component *component = - snd_soc_dapm_kcontrol_component(kcontrol); - struct snd_soc_dapm_context *dapm = - snd_soc_dapm_kcontrol_dapm(kcontrol); + struct snd_soc_component *component = snd_soc_dapm_kcontrol_to_component(kcontrol); + struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kcontrol); struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; unsigned int mux, changed; diff --git a/sound/soc/meson/aiu-codec-ctrl.c b/sound/soc/meson/aiu-codec-ctrl.c index ee0ef6301010c9..396f815077e291 100644 --- a/sound/soc/meson/aiu-codec-ctrl.c +++ b/sound/soc/meson/aiu-codec-ctrl.c @@ -23,10 +23,8 @@ static const char * const aiu_codec_ctrl_mux_texts[] = { static int aiu_codec_ctrl_mux_put_enum(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_component *component = - snd_soc_dapm_kcontrol_component(kcontrol); - struct snd_soc_dapm_context *dapm = - snd_soc_dapm_kcontrol_dapm(kcontrol); + struct snd_soc_component *component = snd_soc_dapm_kcontrol_to_component(kcontrol); + struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kcontrol); struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; unsigned int mux, changed; diff --git a/sound/soc/meson/axg-spdifout.c b/sound/soc/meson/axg-spdifout.c index e8a12f15f3b4a8..84868fe574e0aa 100644 --- a/sound/soc/meson/axg-spdifout.c +++ b/sound/soc/meson/axg-spdifout.c @@ -352,8 +352,8 @@ static int axg_spdifout_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { struct axg_spdifout *priv = snd_soc_component_get_drvdata(component); - enum snd_soc_bias_level now = - snd_soc_component_get_bias_level(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); + enum snd_soc_bias_level now = snd_soc_dapm_get_bias_level(dapm); int ret = 0; switch (level) { diff --git a/sound/soc/meson/axg-tdm-interface.c b/sound/soc/meson/axg-tdm-interface.c index 421b5d719fb3db..d5287d78f53b87 100644 --- a/sound/soc/meson/axg-tdm-interface.c +++ b/sound/soc/meson/axg-tdm-interface.c @@ -479,8 +479,8 @@ static int axg_tdm_iface_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { struct axg_tdm_iface *iface = snd_soc_component_get_drvdata(component); - enum snd_soc_bias_level now = - snd_soc_component_get_bias_level(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); + enum snd_soc_bias_level now = snd_soc_dapm_get_bias_level(dapm); int ret = 0; switch (level) { diff --git a/sound/soc/meson/g12a-toacodec.c b/sound/soc/meson/g12a-toacodec.c index 531bb8707a3ec4..a95375b53f0a3d 100644 --- a/sound/soc/meson/g12a-toacodec.c +++ b/sound/soc/meson/g12a-toacodec.c @@ -63,11 +63,9 @@ static const char * const g12a_toacodec_mux_texts[] = { static int g12a_toacodec_mux_put_enum(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_component *component = - snd_soc_dapm_kcontrol_component(kcontrol); + struct snd_soc_component *component = snd_soc_dapm_kcontrol_to_component(kcontrol); struct g12a_toacodec *priv = snd_soc_component_get_drvdata(component); - struct snd_soc_dapm_context *dapm = - snd_soc_dapm_kcontrol_dapm(kcontrol); + struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kcontrol); struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; unsigned int mux, reg; diff --git a/sound/soc/meson/g12a-tohdmitx.c b/sound/soc/meson/g12a-tohdmitx.c index b92434125face1..d541ca4acfaf3c 100644 --- a/sound/soc/meson/g12a-tohdmitx.c +++ b/sound/soc/meson/g12a-tohdmitx.c @@ -38,10 +38,8 @@ static const char * const g12a_tohdmitx_i2s_mux_texts[] = { static int g12a_tohdmitx_i2s_mux_put_enum(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_component *component = - snd_soc_dapm_kcontrol_component(kcontrol); - struct snd_soc_dapm_context *dapm = - snd_soc_dapm_kcontrol_dapm(kcontrol); + struct snd_soc_component *component = snd_soc_dapm_kcontrol_to_component(kcontrol); + struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kcontrol); struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; unsigned int mux, changed; @@ -89,10 +87,8 @@ static const char * const g12a_tohdmitx_spdif_mux_texts[] = { static int g12a_tohdmitx_spdif_mux_put_enum(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_component *component = - snd_soc_dapm_kcontrol_component(kcontrol); - struct snd_soc_dapm_context *dapm = - snd_soc_dapm_kcontrol_dapm(kcontrol); + struct snd_soc_component *component = snd_soc_dapm_kcontrol_to_component(kcontrol); + struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kcontrol); struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; unsigned int mux, changed; diff --git a/sound/soc/meson/t9015.c b/sound/soc/meson/t9015.c index a80e9c9d6288be..da1a93946d6790 100644 --- a/sound/soc/meson/t9015.c +++ b/sound/soc/meson/t9015.c @@ -177,8 +177,8 @@ static int t9015_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { struct t9015 *priv = snd_soc_component_get_drvdata(component); - enum snd_soc_bias_level now = - snd_soc_component_get_bias_level(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); + enum snd_soc_bias_level now = snd_soc_dapm_get_bias_level(dapm); int ret; switch (level) { diff --git a/sound/soc/pxa/spitz.c b/sound/soc/pxa/spitz.c index 6ca0a6bcd34cd7..2ea21a2091ee1e 100644 --- a/sound/soc/pxa/spitz.c +++ b/sound/soc/pxa/spitz.c @@ -105,9 +105,10 @@ static void spitz_ext_control(struct snd_soc_dapm_context *dapm) static int spitz_startup(struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(rtd->card); /* check the jack status at stream startup */ - spitz_ext_control(&rtd->card->dapm); + spitz_ext_control(dapm); return 0; } @@ -166,12 +167,13 @@ static int spitz_set_jack(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_card *card = snd_kcontrol_chip(kcontrol); + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); if (spitz_jack_func == ucontrol->value.enumerated.item[0]) return 0; spitz_jack_func = ucontrol->value.enumerated.item[0]; - spitz_ext_control(&card->dapm); + spitz_ext_control(dapm); return 1; } @@ -186,12 +188,13 @@ static int spitz_set_spk(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_card *card = snd_kcontrol_chip(kcontrol); + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); if (spitz_spk_func == ucontrol->value.enumerated.item[0]) return 0; spitz_spk_func = ucontrol->value.enumerated.item[0]; - spitz_ext_control(&card->dapm); + spitz_ext_control(dapm); return 1; } diff --git a/sound/soc/qcom/qdsp6/q6routing.c b/sound/soc/qcom/qdsp6/q6routing.c index f49243daa517f2..aaa3af9f199361 100644 --- a/sound/soc/qcom/qdsp6/q6routing.c +++ b/sound/soc/qcom/qdsp6/q6routing.c @@ -468,8 +468,7 @@ EXPORT_SYMBOL_GPL(q6routing_stream_close); static int msm_routing_get_audio_mixer(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_context *dapm = - snd_soc_dapm_kcontrol_dapm(kcontrol); + struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kcontrol); struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; int session_id = mc->shift; @@ -488,8 +487,7 @@ static int msm_routing_get_audio_mixer(struct snd_kcontrol *kcontrol, static int msm_routing_put_audio_mixer(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_context *dapm = - snd_soc_dapm_kcontrol_dapm(kcontrol); + struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kcontrol); struct snd_soc_component *c = snd_soc_dapm_to_component(dapm); struct msm_routing_data *data = dev_get_drvdata(c->dev); struct soc_mixer_control *mc = diff --git a/sound/soc/qcom/qdsp6/q6usb.c b/sound/soc/qcom/qdsp6/q6usb.c index ebe0c242592779..6381b289c55cf2 100644 --- a/sound/soc/qcom/qdsp6/q6usb.c +++ b/sound/soc/qcom/qdsp6/q6usb.c @@ -138,10 +138,11 @@ static int q6usb_audio_ports_of_xlate_dai_name(struct snd_soc_component *compone static int q6usb_get_pcm_id_from_widget(struct snd_soc_dapm_widget *w) { + struct snd_soc_card *card = snd_soc_dapm_to_card(w->dapm); struct snd_soc_pcm_runtime *rtd; struct snd_soc_dai *dai; - for_each_card_rtds(w->dapm->card, rtd) { + for_each_card_rtds(card, rtd) { dai = snd_soc_rtd_to_cpu(rtd, 0); /* * Only look for playback widget. RTD number carries the assigned diff --git a/sound/soc/qcom/qdsp6/topology.c b/sound/soc/qcom/qdsp6/topology.c index f61285e7dcf209..5ce6edf3305ea1 100644 --- a/sound/soc/qcom/qdsp6/topology.c +++ b/sound/soc/qcom/qdsp6/topology.c @@ -1143,8 +1143,8 @@ static int audioreach_get_audio_mixer(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; - struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol); - struct snd_soc_dapm_widget *dw = snd_soc_dapm_kcontrol_widget(kcontrol); + struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kcontrol); + struct snd_soc_dapm_widget *dw = snd_soc_dapm_kcontrol_to_widget(kcontrol); struct snd_soc_component *c = snd_soc_dapm_to_component(dapm); struct snd_ar_control *dapm_scontrol = dw->dobj.private; struct snd_ar_control *scontrol = mc->dobj.private; @@ -1164,8 +1164,8 @@ static int audioreach_put_audio_mixer(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; - struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol); - struct snd_soc_dapm_widget *dw = snd_soc_dapm_kcontrol_widget(kcontrol); + struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kcontrol); + struct snd_soc_dapm_widget *dw = snd_soc_dapm_kcontrol_to_widget(kcontrol); struct snd_soc_component *c = snd_soc_dapm_to_component(dapm); struct snd_ar_control *dapm_scontrol = dw->dobj.private; struct snd_ar_control *scontrol = mc->dobj.private; @@ -1184,7 +1184,7 @@ static int audioreach_put_audio_mixer(struct snd_kcontrol *kcontrol, static int audioreach_get_vol_ctrl_audio_mixer(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_widget *dw = snd_soc_dapm_kcontrol_widget(kcontrol); + struct snd_soc_dapm_widget *dw = snd_soc_dapm_kcontrol_to_widget(kcontrol); struct audioreach_module *mod = dw->dobj.private; ucontrol->value.integer.value[0] = mod->gain; @@ -1195,7 +1195,7 @@ static int audioreach_get_vol_ctrl_audio_mixer(struct snd_kcontrol *kcontrol, static int audioreach_put_vol_ctrl_audio_mixer(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_widget *dw = snd_soc_dapm_kcontrol_widget(kcontrol); + struct snd_soc_dapm_widget *dw = snd_soc_dapm_kcontrol_to_widget(kcontrol); struct audioreach_module *mod = dw->dobj.private; mod->gain = ucontrol->value.integer.value[0]; diff --git a/sound/soc/qcom/sc7180.c b/sound/soc/qcom/sc7180.c index 84b6ac5d2a2052..bc5a1888347931 100644 --- a/sound/soc/qcom/sc7180.c +++ b/sound/soc/qcom/sc7180.c @@ -287,8 +287,9 @@ static int sc7180_qdsp_snd_startup(struct snd_pcm_substream *substream) static int dmic_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol); - struct sc7180_snd_data *data = snd_soc_card_get_drvdata(dapm->card); + struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kcontrol); + struct snd_soc_card *card = snd_soc_dapm_to_card(dapm); + struct sc7180_snd_data *data = snd_soc_card_get_drvdata(card); ucontrol->value.integer.value[0] = data->dmic_switch; return 0; @@ -297,8 +298,9 @@ static int dmic_get(struct snd_kcontrol *kcontrol, static int dmic_set(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol); - struct sc7180_snd_data *data = snd_soc_card_get_drvdata(dapm->card); + struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kcontrol); + struct snd_soc_card *card = snd_soc_dapm_to_card(dapm); + struct sc7180_snd_data *data = snd_soc_card_get_drvdata(card); data->dmic_switch = ucontrol->value.integer.value[0]; gpiod_set_value(data->dmic_sel, data->dmic_switch); diff --git a/sound/soc/renesas/rcar/ssiu.c b/sound/soc/renesas/rcar/ssiu.c index faf351126d5744..244fb833292a74 100644 --- a/sound/soc/renesas/rcar/ssiu.c +++ b/sound/soc/renesas/rcar/ssiu.c @@ -509,7 +509,7 @@ void rsnd_parse_connect_ssiu(struct rsnd_dai *rdai, int rsnd_ssiu_probe(struct rsnd_priv *priv) { struct device *dev = rsnd_priv_to_dev(priv); - struct device_node *node; + struct device_node *node __free(device_node) = rsnd_ssiu_of_node(priv); struct rsnd_ssiu *ssiu; struct rsnd_mod_ops *ops; const int *list = NULL; @@ -522,7 +522,6 @@ int rsnd_ssiu_probe(struct rsnd_priv *priv) * see * rsnd_ssiu_bufsif_to_id() */ - node = rsnd_ssiu_of_node(priv); if (node) nr = rsnd_node_count(priv, node, SSIU_NAME); else diff --git a/sound/soc/renesas/rz-ssi.c b/sound/soc/renesas/rz-ssi.c index 81b883e8ac92aa..f4dc2f68deadac 100644 --- a/sound/soc/renesas/rz-ssi.c +++ b/sound/soc/renesas/rz-ssi.c @@ -13,6 +13,7 @@ #include #include #include +#include #include /* REGISTER OFFSET */ @@ -87,7 +88,6 @@ struct rz_ssi_stream { int dma_buffer_pos; /* The address for the next DMA descriptor */ int completed_dma_buf_pos; /* The address of the last completed DMA descriptor. */ int period_counter; /* for keeping track of periods transferred */ - int sample_width; int buffer_pos; /* current frame position in the buffer */ int running; /* 0=stopped, 1=running */ @@ -133,6 +133,12 @@ struct rz_ssi_priv { bool bckp_rise; /* Bit clock polarity (SSICR.BCKP) */ bool dma_rt; + struct { + bool tx_active; + bool rx_active; + bool one_stream_triggered; + } dup; + /* Full duplex communication support */ struct { unsigned int rate; @@ -211,10 +217,7 @@ static inline bool rz_ssi_is_stream_running(struct rz_ssi_stream *strm) static void rz_ssi_stream_init(struct rz_ssi_stream *strm, struct snd_pcm_substream *substream) { - struct snd_pcm_runtime *runtime = substream->runtime; - rz_ssi_set_substream(strm, substream); - strm->sample_width = samples_to_bytes(runtime, 1); strm->dma_buffer_pos = 0; strm->completed_dma_buf_pos = 0; strm->period_counter = 0; @@ -332,13 +335,12 @@ static int rz_ssi_start(struct rz_ssi_priv *ssi, struct rz_ssi_stream *strm) bool is_full_duplex; u32 ssicr, ssifcr; - is_full_duplex = rz_ssi_is_stream_running(&ssi->playback) || - rz_ssi_is_stream_running(&ssi->capture); + is_full_duplex = ssi->dup.tx_active && ssi->dup.rx_active; ssicr = rz_ssi_reg_readl(ssi, SSICR); ssifcr = rz_ssi_reg_readl(ssi, SSIFCR); if (!is_full_duplex) { ssifcr &= ~0xF; - } else { + } else if (ssi->dup.one_stream_triggered) { rz_ssi_reg_mask_setl(ssi, SSICR, SSICR_TEN | SSICR_REN, 0); rz_ssi_set_idle(ssi); ssifcr &= ~SSIFCR_FIFO_RST; @@ -374,12 +376,16 @@ static int rz_ssi_start(struct rz_ssi_priv *ssi, struct rz_ssi_stream *strm) SSISR_RUIRQ), 0); strm->running = 1; - if (is_full_duplex) - ssicr |= SSICR_TEN | SSICR_REN; - else + if (!is_full_duplex) { ssicr |= is_play ? SSICR_TEN : SSICR_REN; - - rz_ssi_reg_writel(ssi, SSICR, ssicr); + rz_ssi_reg_writel(ssi, SSICR, ssicr); + } else if (ssi->dup.one_stream_triggered) { + ssicr |= SSICR_TEN | SSICR_REN; + rz_ssi_reg_writel(ssi, SSICR, ssicr); + ssi->dup.one_stream_triggered = false; + } else { + ssi->dup.one_stream_triggered = true; + } return 0; } @@ -915,6 +921,30 @@ static int rz_ssi_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) return 0; } +static int rz_ssi_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct rz_ssi_priv *ssi = snd_soc_dai_get_drvdata(dai); + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + ssi->dup.tx_active = true; + else + ssi->dup.rx_active = true; + + return 0; +} + +static void rz_ssi_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct rz_ssi_priv *ssi = snd_soc_dai_get_drvdata(dai); + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + ssi->dup.tx_active = false; + else + ssi->dup.rx_active = false; +} + static bool rz_ssi_is_valid_hw_params(struct rz_ssi_priv *ssi, unsigned int rate, unsigned int channels, unsigned int sample_width, @@ -945,9 +975,9 @@ static int rz_ssi_dai_hw_params(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct rz_ssi_priv *ssi = snd_soc_dai_get_drvdata(dai); - struct rz_ssi_stream *strm = rz_ssi_stream_get(ssi, substream); unsigned int sample_bits = hw_param_interval(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS)->min; + unsigned int sample_width = params_width(params); unsigned int channels = params_channels(params); unsigned int rate = params_rate(params); int ret; @@ -966,16 +996,14 @@ static int rz_ssi_dai_hw_params(struct snd_pcm_substream *substream, if (rz_ssi_is_stream_running(&ssi->playback) || rz_ssi_is_stream_running(&ssi->capture)) { - if (rz_ssi_is_valid_hw_params(ssi, rate, channels, - strm->sample_width, sample_bits)) + if (rz_ssi_is_valid_hw_params(ssi, rate, channels, sample_width, sample_bits)) return 0; dev_err(ssi->dev, "Full duplex needs same HW params\n"); return -EINVAL; } - rz_ssi_cache_hw_params(ssi, rate, channels, strm->sample_width, - sample_bits); + rz_ssi_cache_hw_params(ssi, rate, channels, sample_width, sample_bits); ret = rz_ssi_swreset(ssi); if (ret) @@ -985,6 +1013,8 @@ static int rz_ssi_dai_hw_params(struct snd_pcm_substream *substream, } static const struct snd_soc_dai_ops rz_ssi_dai_ops = { + .startup = rz_ssi_startup, + .shutdown = rz_ssi_shutdown, .trigger = rz_ssi_dai_trigger, .set_fmt = rz_ssi_dai_set_fmt, .hw_params = rz_ssi_dai_hw_params, diff --git a/sound/soc/rockchip/rk3288_hdmi_analog.c b/sound/soc/rockchip/rk3288_hdmi_analog.c index ffbc5a39b493f1..cf642a23c38ad0 100644 --- a/sound/soc/rockchip/rk3288_hdmi_analog.c +++ b/sound/soc/rockchip/rk3288_hdmi_analog.c @@ -31,7 +31,8 @@ struct rk_drvdata { static int rk_hp_power(struct snd_soc_dapm_widget *w, struct snd_kcontrol *k, int event) { - struct rk_drvdata *machine = snd_soc_card_get_drvdata(w->dapm->card); + struct snd_soc_card *card = snd_soc_dapm_to_card(w->dapm); + struct rk_drvdata *machine = snd_soc_card_get_drvdata(card); gpiod_set_value_cansleep(machine->gpio_hp_en, SND_SOC_DAPM_EVENT_ON(event)); diff --git a/sound/soc/rockchip/rockchip_max98090.c b/sound/soc/rockchip/rockchip_max98090.c index b8326e9143b6c0..075d0990a12660 100644 --- a/sound/soc/rockchip/rockchip_max98090.c +++ b/sound/soc/rockchip/rockchip_max98090.c @@ -108,7 +108,7 @@ static int rk_jack_event(struct notifier_block *nb, unsigned long event, void *data) { struct snd_soc_jack *jack = (struct snd_soc_jack *)data; - struct snd_soc_dapm_context *dapm = &jack->card->dapm; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(jack->card); if (event & SND_JACK_MICROPHONE) { snd_soc_dapm_force_enable_pin(dapm, "MICBIAS"); diff --git a/sound/soc/samsung/aries_wm8994.c b/sound/soc/samsung/aries_wm8994.c index 3723329b266dde..48ccc1d1854bc6 100644 --- a/sound/soc/samsung/aries_wm8994.c +++ b/sound/soc/samsung/aries_wm8994.c @@ -159,7 +159,7 @@ static struct snd_soc_jack_gpio headset_button_gpio[] = { static int aries_spk_cfg(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_card *card = w->dapm->card; + struct snd_soc_card *card = snd_soc_dapm_to_card(w->dapm); struct snd_soc_pcm_runtime *rtd; struct snd_soc_component *component; int ret = 0; @@ -194,7 +194,7 @@ static int aries_spk_cfg(struct snd_soc_dapm_widget *w, static int aries_main_bias(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_card *card = w->dapm->card; + struct snd_soc_card *card = snd_soc_dapm_to_card(w->dapm); struct aries_wm8994_data *priv = snd_soc_card_get_drvdata(card); int ret = 0; @@ -213,7 +213,7 @@ static int aries_main_bias(struct snd_soc_dapm_widget *w, static int aries_headset_bias(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_card *card = w->dapm->card; + struct snd_soc_card *card = snd_soc_dapm_to_card(w->dapm); struct aries_wm8994_data *priv = snd_soc_card_get_drvdata(card); int ret = 0; diff --git a/sound/soc/samsung/bells.c b/sound/soc/samsung/bells.c index 61ed5e69391a47..fc4963d3b99bfe 100644 --- a/sound/soc/samsung/bells.c +++ b/sound/soc/samsung/bells.c @@ -62,12 +62,12 @@ static int bells_set_bias_level(struct snd_soc_card *card, codec_dai = snd_soc_rtd_to_codec(rtd, 0); component = codec_dai->component; - if (dapm->dev != codec_dai->dev) + if (snd_soc_dapm_to_dev(dapm) != codec_dai->dev) return 0; switch (level) { case SND_SOC_BIAS_PREPARE: - if (dapm->bias_level != SND_SOC_BIAS_STANDBY) + if (snd_soc_dapm_get_bias_level(dapm) != SND_SOC_BIAS_STANDBY) break; ret = snd_soc_component_set_pll(component, WM5102_FLL1, @@ -108,7 +108,7 @@ static int bells_set_bias_level_post(struct snd_soc_card *card, codec_dai = snd_soc_rtd_to_codec(rtd, 0); component = codec_dai->component; - if (dapm->dev != codec_dai->dev) + if (snd_soc_dapm_to_dev(dapm) != codec_dai->dev) return 0; switch (level) { diff --git a/sound/soc/samsung/littlemill.c b/sound/soc/samsung/littlemill.c index c8b06894ac88cd..d0d1b1ee326ead 100644 --- a/sound/soc/samsung/littlemill.c +++ b/sound/soc/samsung/littlemill.c @@ -24,7 +24,7 @@ static int littlemill_set_bias_level(struct snd_soc_card *card, rtd = snd_soc_get_pcm_runtime(card, &card->dai_link[0]); aif1_dai = snd_soc_rtd_to_codec(rtd, 0); - if (dapm->dev != aif1_dai->dev) + if (snd_soc_dapm_to_dev(dapm) != aif1_dai->dev) return 0; switch (level) { @@ -33,7 +33,7 @@ static int littlemill_set_bias_level(struct snd_soc_card *card, * If we've not already clocked things via hw_params() * then do so now, otherwise these are noops. */ - if (dapm->bias_level == SND_SOC_BIAS_STANDBY) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_STANDBY) { ret = snd_soc_dai_set_pll(aif1_dai, WM8994_FLL1, WM8994_FLL_SRC_MCLK2, 32768, sample_rate * 512); @@ -71,7 +71,7 @@ static int littlemill_set_bias_level_post(struct snd_soc_card *card, rtd = snd_soc_get_pcm_runtime(card, &card->dai_link[0]); aif1_dai = snd_soc_rtd_to_codec(rtd, 0); - if (dapm->dev != aif1_dai->dev) + if (snd_soc_dapm_to_dev(dapm) != aif1_dai->dev) return 0; switch (level) { @@ -173,7 +173,7 @@ static struct snd_soc_dai_link littlemill_dai[] = { static int bbclk_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_card *card = w->dapm->card; + struct snd_soc_card *card = snd_soc_dapm_to_card(w->dapm); struct snd_soc_pcm_runtime *rtd; struct snd_soc_dai *aif2_dai; int ret; diff --git a/sound/soc/samsung/lowland.c b/sound/soc/samsung/lowland.c index 1e95a2a435d49d..ca9b78007dfe71 100644 --- a/sound/soc/samsung/lowland.c +++ b/sound/soc/samsung/lowland.c @@ -70,8 +70,9 @@ static int lowland_wm5100_init(struct snd_soc_pcm_runtime *rtd) static int lowland_wm9081_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(rtd->card); - snd_soc_dapm_nc_pin(&rtd->card->dapm, "LINEOUT"); + snd_soc_dapm_disable_pin(dapm, "LINEOUT"); /* At any time the WM9081 is active it will have this clock */ return snd_soc_component_set_sysclk(component, WM9081_SYSCLK_MCLK, 0, diff --git a/sound/soc/samsung/midas_wm1811.c b/sound/soc/samsung/midas_wm1811.c index 239e958b88d3fb..bc34dbbb50c91a 100644 --- a/sound/soc/samsung/midas_wm1811.c +++ b/sound/soc/samsung/midas_wm1811.c @@ -73,7 +73,7 @@ static struct snd_soc_jack_zone headset_key_zones[] = { static int headset_jack_check(void *data) { struct snd_soc_component *codec = data; - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(codec); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(codec); struct midas_priv *priv = snd_soc_card_get_drvdata(codec->card); int adc, ret; int jack_type = 0; @@ -285,7 +285,7 @@ static int midas_ext_spkmode(struct snd_soc_dapm_widget *w, static int midas_fm_set(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_card *card = w->dapm->card; + struct snd_soc_card *card = snd_soc_dapm_to_card(w->dapm); struct midas_priv *priv = snd_soc_card_get_drvdata(card); if (!priv->gpio_fm_sel) @@ -306,7 +306,7 @@ static int midas_fm_set(struct snd_soc_dapm_widget *w, static int midas_line_set(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_card *card = w->dapm->card; + struct snd_soc_card *card = snd_soc_dapm_to_card(w->dapm); struct midas_priv *priv = snd_soc_card_get_drvdata(card); if (!priv->gpio_lineout_sel) @@ -376,7 +376,7 @@ static int midas_set_bias_level(struct snd_soc_card *card, &card->dai_link[0]); struct snd_soc_dai *aif1_dai = snd_soc_rtd_to_codec(rtd, 0); - if (dapm->dev != aif1_dai->dev) + if (snd_soc_dapm_to_dev(dapm) != aif1_dai->dev) return 0; switch (level) { diff --git a/sound/soc/samsung/smdk_wm8994.c b/sound/soc/samsung/smdk_wm8994.c index acb29cd785a90d..911f56b12f0a83 100644 --- a/sound/soc/samsung/smdk_wm8994.c +++ b/sound/soc/samsung/smdk_wm8994.c @@ -69,23 +69,23 @@ static const struct snd_soc_ops smdk_ops = { static int smdk_wm8994_init_paiftx(struct snd_soc_pcm_runtime *rtd) { - struct snd_soc_dapm_context *dapm = &rtd->card->dapm; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(rtd->card); /* Other pins NC */ - snd_soc_dapm_nc_pin(dapm, "HPOUT2P"); - snd_soc_dapm_nc_pin(dapm, "HPOUT2N"); - snd_soc_dapm_nc_pin(dapm, "SPKOUTLN"); - snd_soc_dapm_nc_pin(dapm, "SPKOUTLP"); - snd_soc_dapm_nc_pin(dapm, "SPKOUTRP"); - snd_soc_dapm_nc_pin(dapm, "SPKOUTRN"); - snd_soc_dapm_nc_pin(dapm, "LINEOUT1N"); - snd_soc_dapm_nc_pin(dapm, "LINEOUT1P"); - snd_soc_dapm_nc_pin(dapm, "LINEOUT2N"); - snd_soc_dapm_nc_pin(dapm, "LINEOUT2P"); - snd_soc_dapm_nc_pin(dapm, "IN1LP"); - snd_soc_dapm_nc_pin(dapm, "IN2LP:VXRN"); - snd_soc_dapm_nc_pin(dapm, "IN1RP"); - snd_soc_dapm_nc_pin(dapm, "IN2RP:VXRP"); + snd_soc_dapm_disable_pin(dapm, "HPOUT2P"); + snd_soc_dapm_disable_pin(dapm, "HPOUT2N"); + snd_soc_dapm_disable_pin(dapm, "SPKOUTLN"); + snd_soc_dapm_disable_pin(dapm, "SPKOUTLP"); + snd_soc_dapm_disable_pin(dapm, "SPKOUTRP"); + snd_soc_dapm_disable_pin(dapm, "SPKOUTRN"); + snd_soc_dapm_disable_pin(dapm, "LINEOUT1N"); + snd_soc_dapm_disable_pin(dapm, "LINEOUT1P"); + snd_soc_dapm_disable_pin(dapm, "LINEOUT2N"); + snd_soc_dapm_disable_pin(dapm, "LINEOUT2P"); + snd_soc_dapm_disable_pin(dapm, "IN1LP"); + snd_soc_dapm_disable_pin(dapm, "IN2LP:VXRN"); + snd_soc_dapm_disable_pin(dapm, "IN1RP"); + snd_soc_dapm_disable_pin(dapm, "IN2RP:VXRP"); return 0; } diff --git a/sound/soc/samsung/speyside.c b/sound/soc/samsung/speyside.c index f4cc5684ef0ab8..26701a55fe0af0 100644 --- a/sound/soc/samsung/speyside.c +++ b/sound/soc/samsung/speyside.c @@ -27,7 +27,7 @@ static int speyside_set_bias_level(struct snd_soc_card *card, rtd = snd_soc_get_pcm_runtime(card, &card->dai_link[1]); codec_dai = snd_soc_rtd_to_codec(rtd, 0); - if (dapm->dev != codec_dai->dev) + if (snd_soc_dapm_to_dev(dapm) != codec_dai->dev) return 0; switch (level) { @@ -63,12 +63,12 @@ static int speyside_set_bias_level_post(struct snd_soc_card *card, rtd = snd_soc_get_pcm_runtime(card, &card->dai_link[1]); codec_dai = snd_soc_rtd_to_codec(rtd, 0); - if (dapm->dev != codec_dai->dev) + if (snd_soc_dapm_to_dev(dapm) != codec_dai->dev) return 0; switch (level) { case SND_SOC_BIAS_PREPARE: - if (card->dapm.bias_level == SND_SOC_BIAS_STANDBY) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_STANDBY) { ret = snd_soc_dai_set_pll(codec_dai, 0, WM8996_FLL_MCLK2, 32768, MCLK_AUDIO_RATE); @@ -125,7 +125,7 @@ static void speyside_set_polarity(struct snd_soc_component *component, gpiod_direction_output(speyside_hpsel_gpio, speyside_jack_polarity); /* Re-run DAPM to make sure we're using the correct mic bias */ - snd_soc_dapm_sync(snd_soc_component_get_dapm(component)); + snd_soc_dapm_sync(snd_soc_component_to_dapm(component)); } static int speyside_wm0010_init(struct snd_soc_pcm_runtime *rtd) @@ -177,13 +177,15 @@ static int speyside_wm8996_init(struct snd_soc_pcm_runtime *rtd) static int speyside_late_probe(struct snd_soc_card *card) { - snd_soc_dapm_ignore_suspend(&card->dapm, "Headphone"); - snd_soc_dapm_ignore_suspend(&card->dapm, "Headset Mic"); - snd_soc_dapm_ignore_suspend(&card->dapm, "Main AMIC"); - snd_soc_dapm_ignore_suspend(&card->dapm, "Main DMIC"); - snd_soc_dapm_ignore_suspend(&card->dapm, "Main Speaker"); - snd_soc_dapm_ignore_suspend(&card->dapm, "WM1250 Output"); - snd_soc_dapm_ignore_suspend(&card->dapm, "WM1250 Input"); + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); + + snd_soc_dapm_ignore_suspend(dapm, "Headphone"); + snd_soc_dapm_ignore_suspend(dapm, "Headset Mic"); + snd_soc_dapm_ignore_suspend(dapm, "Main AMIC"); + snd_soc_dapm_ignore_suspend(dapm, "Main DMIC"); + snd_soc_dapm_ignore_suspend(dapm, "Main Speaker"); + snd_soc_dapm_ignore_suspend(dapm, "WM1250 Output"); + snd_soc_dapm_ignore_suspend(dapm, "WM1250 Input"); return 0; } diff --git a/sound/soc/samsung/tm2_wm5110.c b/sound/soc/samsung/tm2_wm5110.c index b68ce7bd44ef17..f1f59e059f5da8 100644 --- a/sound/soc/samsung/tm2_wm5110.c +++ b/sound/soc/samsung/tm2_wm5110.c @@ -260,7 +260,7 @@ static const struct snd_soc_ops tm2_hdmi_ops = { static int tm2_mic_bias(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_card *card = w->dapm->card; + struct snd_soc_card *card = snd_soc_dapm_to_card(w->dapm); struct tm2_machine_priv *priv = snd_soc_card_get_drvdata(card); switch (event) { @@ -279,16 +279,17 @@ static int tm2_set_bias_level(struct snd_soc_card *card, struct snd_soc_dapm_context *dapm, enum snd_soc_bias_level level) { + struct snd_soc_dapm_context *card_dapm = snd_soc_card_to_dapm(card); struct snd_soc_pcm_runtime *rtd; rtd = snd_soc_get_pcm_runtime(card, &card->dai_link[0]); - if (dapm->dev != snd_soc_rtd_to_codec(rtd, 0)->dev) + if (snd_soc_dapm_to_dev(dapm) != snd_soc_rtd_to_codec(rtd, 0)->dev) return 0; switch (level) { case SND_SOC_BIAS_STANDBY: - if (card->dapm.bias_level == SND_SOC_BIAS_OFF) + if (snd_soc_dapm_get_bias_level(card_dapm) == SND_SOC_BIAS_OFF) tm2_start_sysclk(card); break; case SND_SOC_BIAS_OFF: diff --git a/sound/soc/samsung/tobermory.c b/sound/soc/samsung/tobermory.c index 1d0a782402f031..5448c16199bd2e 100644 --- a/sound/soc/samsung/tobermory.c +++ b/sound/soc/samsung/tobermory.c @@ -24,12 +24,12 @@ static int tobermory_set_bias_level(struct snd_soc_card *card, rtd = snd_soc_get_pcm_runtime(card, &card->dai_link[0]); codec_dai = snd_soc_rtd_to_codec(rtd, 0); - if (dapm->dev != codec_dai->dev) + if (snd_soc_dapm_to_dev(dapm) != codec_dai->dev) return 0; switch (level) { case SND_SOC_BIAS_PREPARE: - if (dapm->bias_level == SND_SOC_BIAS_STANDBY) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_STANDBY) { ret = snd_soc_dai_set_pll(codec_dai, WM8962_FLL, WM8962_FLL_MCLK, 32768, sample_rate * 512); @@ -67,7 +67,7 @@ static int tobermory_set_bias_level_post(struct snd_soc_card *card, rtd = snd_soc_get_pcm_runtime(card, &card->dai_link[0]); codec_dai = snd_soc_rtd_to_codec(rtd, 0); - if (dapm->dev != codec_dai->dev) + if (snd_soc_dapm_to_dev(dapm) != codec_dai->dev) return 0; switch (level) { diff --git a/sound/soc/sdca/Kconfig b/sound/soc/sdca/Kconfig index a73920d07073ea..fabb69a3450d3b 100644 --- a/sound/soc/sdca/Kconfig +++ b/sound/soc/sdca/Kconfig @@ -4,6 +4,7 @@ menu "SoundWire (SDCA)" config SND_SOC_SDCA tristate depends on ACPI + select AUXILIARY_BUS help This option enables support for the MIPI SoundWire Device Class for Audio (SDCA). @@ -36,4 +37,23 @@ config SND_SOC_SDCA_FDL config SND_SOC_SDCA_OPTIONAL def_tristate SND_SOC_SDCA || !SND_SOC_SDCA +config SND_SOC_SDCA_CLASS + tristate "SDCA Class Driver" + depends on SOUNDWIRE + depends on HID=y || HID=SND_SOC_SDCA + depends on SND_SOC_SDCA + select SND_SOC_SDCA_CLASS_FUNCTION + select SND_SOC_SDCA_FDL + select SND_SOC_SDCA_HID + select SND_SOC_SDCA_IRQ + help + This option enables support for the SDCA Class driver which should + support any class compliant SDCA part. + +config SND_SOC_SDCA_CLASS_FUNCTION + tristate + help + This option enables support for the SDCA Class Function drivers, + these implement the individual functions of the SDCA Class driver. + endmenu diff --git a/sound/soc/sdca/Makefile b/sound/soc/sdca/Makefile index be911c399bbded..f6b73275d96493 100644 --- a/sound/soc/sdca/Makefile +++ b/sound/soc/sdca/Makefile @@ -1,9 +1,15 @@ # SPDX-License-Identifier: GPL-2.0-only -snd-soc-sdca-y := sdca_functions.o sdca_device.o sdca_regmap.o sdca_asoc.o \ - sdca_ump.o +snd-soc-sdca-y := sdca_functions.o sdca_device.o sdca_function_device.o \ + sdca_regmap.o sdca_asoc.o sdca_ump.o snd-soc-sdca-$(CONFIG_SND_SOC_SDCA_HID) += sdca_hid.o snd-soc-sdca-$(CONFIG_SND_SOC_SDCA_IRQ) += sdca_interrupts.o snd-soc-sdca-$(CONFIG_SND_SOC_SDCA_FDL) += sdca_fdl.o +snd-soc-sdca-class-y := sdca_class.o +snd-soc-sdca-class-function-y := sdca_class_function.o + obj-$(CONFIG_SND_SOC_SDCA) += snd-soc-sdca.o + +obj-$(CONFIG_SND_SOC_SDCA_CLASS) += snd-soc-sdca-class.o +obj-$(CONFIG_SND_SOC_SDCA_CLASS_FUNCTION) += snd-soc-sdca-class-function.o diff --git a/sound/soc/sdca/sdca_asoc.c b/sound/soc/sdca/sdca_asoc.c index 892b7c028faea8..2d328bbb95b945 100644 --- a/sound/soc/sdca/sdca_asoc.c +++ b/sound/soc/sdca/sdca_asoc.c @@ -115,50 +115,6 @@ int sdca_asoc_count_component(struct device *dev, struct sdca_function_data *fun } EXPORT_SYMBOL_NS(sdca_asoc_count_component, "SND_SOC_SDCA"); -static const char *get_terminal_name(enum sdca_terminal_type type) -{ - switch (type) { - case SDCA_TERM_TYPE_LINEIN_STEREO: - return SDCA_TERM_TYPE_LINEIN_STEREO_NAME; - case SDCA_TERM_TYPE_LINEIN_FRONT_LR: - return SDCA_TERM_TYPE_LINEIN_FRONT_LR_NAME; - case SDCA_TERM_TYPE_LINEIN_CENTER_LFE: - return SDCA_TERM_TYPE_LINEIN_CENTER_LFE_NAME; - case SDCA_TERM_TYPE_LINEIN_SURROUND_LR: - return SDCA_TERM_TYPE_LINEIN_SURROUND_LR_NAME; - case SDCA_TERM_TYPE_LINEIN_REAR_LR: - return SDCA_TERM_TYPE_LINEIN_REAR_LR_NAME; - case SDCA_TERM_TYPE_LINEOUT_STEREO: - return SDCA_TERM_TYPE_LINEOUT_STEREO_NAME; - case SDCA_TERM_TYPE_LINEOUT_FRONT_LR: - return SDCA_TERM_TYPE_LINEOUT_FRONT_LR_NAME; - case SDCA_TERM_TYPE_LINEOUT_CENTER_LFE: - return SDCA_TERM_TYPE_LINEOUT_CENTER_LFE_NAME; - case SDCA_TERM_TYPE_LINEOUT_SURROUND_LR: - return SDCA_TERM_TYPE_LINEOUT_SURROUND_LR_NAME; - case SDCA_TERM_TYPE_LINEOUT_REAR_LR: - return SDCA_TERM_TYPE_LINEOUT_REAR_LR_NAME; - case SDCA_TERM_TYPE_MIC_JACK: - return SDCA_TERM_TYPE_MIC_JACK_NAME; - case SDCA_TERM_TYPE_STEREO_JACK: - return SDCA_TERM_TYPE_STEREO_JACK_NAME; - case SDCA_TERM_TYPE_FRONT_LR_JACK: - return SDCA_TERM_TYPE_FRONT_LR_JACK_NAME; - case SDCA_TERM_TYPE_CENTER_LFE_JACK: - return SDCA_TERM_TYPE_CENTER_LFE_JACK_NAME; - case SDCA_TERM_TYPE_SURROUND_LR_JACK: - return SDCA_TERM_TYPE_SURROUND_LR_JACK_NAME; - case SDCA_TERM_TYPE_REAR_LR_JACK: - return SDCA_TERM_TYPE_REAR_LR_JACK_NAME; - case SDCA_TERM_TYPE_HEADPHONE_JACK: - return SDCA_TERM_TYPE_HEADPHONE_JACK_NAME; - case SDCA_TERM_TYPE_HEADSET_JACK: - return SDCA_TERM_TYPE_HEADSET_JACK_NAME; - default: - return NULL; - } -} - static int entity_early_parse_ge(struct device *dev, struct sdca_function_data *function, struct sdca_entity *entity) @@ -217,7 +173,7 @@ static int entity_early_parse_ge(struct device *dev, type = sdca_range(range, SDCA_SELECTED_MODE_TERM_TYPE, i); values[i + 3] = sdca_range(range, SDCA_SELECTED_MODE_INDEX, i); - texts[i + 3] = get_terminal_name(type); + texts[i + 3] = sdca_find_terminal_name(type); if (!texts[i + 3]) { dev_err(dev, "%s: unrecognised terminal type: %#x\n", entity->label, type); @@ -337,7 +293,7 @@ static int entity_parse_ot(struct device *dev, static int entity_pde_event(struct snd_soc_dapm_widget *widget, struct snd_kcontrol *kctl, int event) { - struct snd_soc_component *component = widget->dapm->component; + struct snd_soc_component *component = snd_soc_dapm_to_component(widget->dapm); struct sdca_entity *entity = widget->priv; static const int polls = 100; unsigned int reg, val; @@ -499,7 +455,7 @@ static int entity_parse_su_device(struct device *dev, return -EINVAL; } - add_route(route, entity->label, get_terminal_name(term), + add_route(route, entity->label, sdca_find_terminal_name(term), entity->sources[affected->val - 1]->label); } } @@ -655,7 +611,7 @@ static int entity_parse_mu(struct device *dev, static int entity_cs_event(struct snd_soc_dapm_widget *widget, struct snd_kcontrol *kctl, int event) { - struct snd_soc_component *component = widget->dapm->component; + struct snd_soc_component *component = snd_soc_dapm_to_component(widget->dapm); struct sdca_entity *entity = widget->priv; if (!component) @@ -886,6 +842,9 @@ static int populate_control(struct device *dev, mc->min = 0; mc->max = clamp((0x1ull << control->nbits) - 1, 0, type_max(mc->max)); + if (SDCA_CTL_TYPE(entity->type, control->sel) == SDCA_CTL_TYPE_S(FU, MUTE)) + mc->invert = true; + (*kctl)->name = control_name; (*kctl)->private_value = (unsigned long)mc; (*kctl)->iface = SNDRV_CTL_ELEM_IFACE_MIXER; diff --git a/sound/soc/sdca/sdca_class.c b/sound/soc/sdca/sdca_class.c new file mode 100644 index 00000000000000..349d32933ba85b --- /dev/null +++ b/sound/soc/sdca/sdca_class.c @@ -0,0 +1,304 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2025 Cirrus Logic, Inc. and +// Cirrus Logic International Semiconductor Ltd. + +/* + * The MIPI SDCA specification is available for public downloads at + * https://www.mipi.org/mipi-sdca-v1-0-download + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "sdca_class.h" + +#define CLASS_SDW_ATTACH_TIMEOUT_MS 5000 + +static int class_read_prop(struct sdw_slave *sdw) +{ + struct sdw_slave_prop *prop = &sdw->prop; + + sdw_slave_read_prop(sdw); + + prop->use_domain_irq = true; + prop->scp_int1_mask = SDW_SCP_INT1_BUS_CLASH | SDW_SCP_INT1_PARITY | + SDW_SCP_INT1_IMPL_DEF; + + return 0; +} + +static int class_sdw_update_status(struct sdw_slave *sdw, enum sdw_slave_status status) +{ + struct sdca_class_drv *drv = dev_get_drvdata(&sdw->dev); + + switch (status) { + case SDW_SLAVE_ATTACHED: + dev_dbg(drv->dev, "device attach\n"); + + drv->attached = true; + + complete(&drv->device_attach); + break; + case SDW_SLAVE_UNATTACHED: + dev_dbg(drv->dev, "device detach\n"); + + drv->attached = false; + + reinit_completion(&drv->device_attach); + break; + default: + break; + } + + return 0; +} + +static const struct sdw_slave_ops class_sdw_ops = { + .read_prop = class_read_prop, + .update_status = class_sdw_update_status, +}; + +static void class_regmap_lock(void *data) +{ + struct mutex *lock = data; + + mutex_lock(lock); +} + +static void class_regmap_unlock(void *data) +{ + struct mutex *lock = data; + + mutex_unlock(lock); +} + +static int class_wait_for_attach(struct sdca_class_drv *drv) +{ + if (!drv->attached) { + unsigned long timeout = msecs_to_jiffies(CLASS_SDW_ATTACH_TIMEOUT_MS); + unsigned long time; + + time = wait_for_completion_timeout(&drv->device_attach, timeout); + if (!time) { + dev_err(drv->dev, "timed out waiting for device re-attach\n"); + return -ETIMEDOUT; + } + } + + regcache_cache_only(drv->dev_regmap, false); + + return 0; +} + +static bool class_dev_regmap_volatile(struct device *dev, unsigned int reg) +{ + switch (reg) { + case SDW_SCP_SDCA_INTMASK1 ... SDW_SCP_SDCA_INTMASK4: + return false; + default: + return true; + } +} + +static bool class_dev_regmap_precious(struct device *dev, unsigned int reg) +{ + switch (reg) { + case SDW_SCP_SDCA_INT1 ... SDW_SCP_SDCA_INT4: + case SDW_SCP_SDCA_INTMASK1 ... SDW_SCP_SDCA_INTMASK4: + return false; + default: + return true; + } +} + +static const struct regmap_config class_dev_regmap_config = { + .name = "sdca-device", + .reg_bits = 32, + .val_bits = 8, + + .max_register = SDW_SDCA_MAX_REGISTER, + .volatile_reg = class_dev_regmap_volatile, + .precious_reg = class_dev_regmap_precious, + + .cache_type = REGCACHE_MAPLE, + + .lock = class_regmap_lock, + .unlock = class_regmap_unlock, +}; + +static void class_boot_work(struct work_struct *work) +{ + struct sdca_class_drv *drv = container_of(work, + struct sdca_class_drv, + boot_work); + int ret; + + ret = class_wait_for_attach(drv); + if (ret) + goto err; + + drv->irq_info = sdca_irq_allocate(drv->dev, drv->dev_regmap, + drv->sdw->irq); + if (IS_ERR(drv->irq_info)) + goto err; + + ret = sdca_dev_register_functions(drv->sdw); + if (ret) + goto err; + + dev_dbg(drv->dev, "boot work complete\n"); + + pm_runtime_mark_last_busy(drv->dev); + pm_runtime_put_autosuspend(drv->dev); + + return; + +err: + pm_runtime_put_sync(drv->dev); +} + +static void class_dev_remove(void *data) +{ + struct sdca_class_drv *drv = data; + + cancel_work_sync(&drv->boot_work); + + sdca_dev_unregister_functions(drv->sdw); +} + +static int class_sdw_probe(struct sdw_slave *sdw, const struct sdw_device_id *id) +{ + struct device *dev = &sdw->dev; + struct sdca_device_data *data = &sdw->sdca_data; + struct regmap_config *dev_config; + struct sdca_class_drv *drv; + int ret; + + sdca_lookup_swft(sdw); + + drv = devm_kzalloc(dev, sizeof(*drv), GFP_KERNEL); + if (!drv) + return -ENOMEM; + + dev_config = devm_kmemdup(dev, &class_dev_regmap_config, + sizeof(*dev_config), GFP_KERNEL); + if (!dev_config) + return -ENOMEM; + + drv->functions = devm_kcalloc(dev, data->num_functions, + sizeof(*drv->functions), + GFP_KERNEL); + if (!drv->functions) + return -ENOMEM; + + drv->dev = dev; + drv->sdw = sdw; + mutex_init(&drv->regmap_lock); + + dev_set_drvdata(drv->dev, drv); + + INIT_WORK(&drv->boot_work, class_boot_work); + init_completion(&drv->device_attach); + + dev_config->lock_arg = &drv->regmap_lock; + + drv->dev_regmap = devm_regmap_init_sdw(sdw, dev_config); + if (IS_ERR(drv->dev_regmap)) + return dev_err_probe(drv->dev, PTR_ERR(drv->dev_regmap), + "failed to create device regmap\n"); + + regcache_cache_only(drv->dev_regmap, true); + + pm_runtime_set_autosuspend_delay(dev, 250); + pm_runtime_use_autosuspend(dev); + pm_runtime_set_active(dev); + pm_runtime_get_noresume(dev); + + ret = devm_pm_runtime_enable(dev); + if (ret) + return ret; + + ret = devm_add_action_or_reset(dev, class_dev_remove, drv); + if (ret) + return ret; + + queue_work(system_long_wq, &drv->boot_work); + + return 0; +} + +static int class_runtime_suspend(struct device *dev) +{ + struct sdca_class_drv *drv = dev_get_drvdata(dev); + + /* + * Whilst the driver doesn't power the chip down here, going into runtime + * suspend lets the SoundWire bus power down, which means the driver + * can't communicate with the device any more. + */ + regcache_cache_only(drv->dev_regmap, true); + + return 0; +} + +static int class_runtime_resume(struct device *dev) +{ + struct sdca_class_drv *drv = dev_get_drvdata(dev); + int ret; + + ret = class_wait_for_attach(drv); + if (ret) + goto err; + + regcache_mark_dirty(drv->dev_regmap); + + ret = regcache_sync(drv->dev_regmap); + if (ret) { + dev_err(drv->dev, "failed to restore cache: %d\n", ret); + goto err; + } + + return 0; + +err: + regcache_cache_only(drv->dev_regmap, true); + + return ret; +} + +static const struct dev_pm_ops class_pm_ops = { + RUNTIME_PM_OPS(class_runtime_suspend, class_runtime_resume, NULL) +}; + +static const struct sdw_device_id class_sdw_id[] = { + SDW_SLAVE_ENTRY(0x01FA, 0x4245, 0), + {} +}; +MODULE_DEVICE_TABLE(sdw, class_sdw_id); + +static struct sdw_driver class_sdw_driver = { + .driver = { + .name = "sdca_class", + .pm = pm_ptr(&class_pm_ops), + }, + + .probe = class_sdw_probe, + .id_table = class_sdw_id, + .ops = &class_sdw_ops, +}; +module_sdw_driver(class_sdw_driver); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("SDCA Class Driver"); +MODULE_IMPORT_NS("SND_SOC_SDCA"); diff --git a/sound/soc/sdca/sdca_class.h b/sound/soc/sdca/sdca_class.h new file mode 100644 index 00000000000000..bb4c9dd1242961 --- /dev/null +++ b/sound/soc/sdca/sdca_class.h @@ -0,0 +1,37 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * The MIPI SDCA specification is available for public downloads at + * https://www.mipi.org/mipi-sdca-v1-0-download + * + * Copyright (C) 2025 Cirrus Logic, Inc. and + * Cirrus Logic International Semiconductor Ltd. + */ + +#ifndef __SDCA_CLASS_H__ +#define __SDCA_CLASS_H__ + +#include +#include +#include + +struct device; +struct regmap; +struct sdw_slave; +struct sdca_function_data; + +struct sdca_class_drv { + struct device *dev; + struct regmap *dev_regmap; + struct sdw_slave *sdw; + + struct sdca_function_data *functions; + struct sdca_interrupt_info *irq_info; + + struct mutex regmap_lock; + struct work_struct boot_work; + struct completion device_attach; + + bool attached; +}; + +#endif /* __SDCA_CLASS_H__ */ diff --git a/sound/soc/sdca/sdca_class_function.c b/sound/soc/sdca/sdca_class_function.c new file mode 100644 index 00000000000000..0028482a1e7520 --- /dev/null +++ b/sound/soc/sdca/sdca_class_function.c @@ -0,0 +1,460 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2025 Cirrus Logic, Inc. and +// Cirrus Logic International Semiconductor Ltd. + +/* + * The MIPI SDCA specification is available for public downloads at + * https://www.mipi.org/mipi-sdca-v1-0-download + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "sdca_class.h" + +struct class_function_drv { + struct device *dev; + struct regmap *regmap; + struct sdca_class_drv *core; + + struct sdca_function_data *function; +}; + +static void class_function_regmap_lock(void *data) +{ + struct mutex *lock = data; + + mutex_lock(lock); +} + +static void class_function_regmap_unlock(void *data) +{ + struct mutex *lock = data; + + mutex_unlock(lock); +} + +static bool class_function_regmap_writeable(struct device *dev, unsigned int reg) +{ + struct auxiliary_device *auxdev = to_auxiliary_dev(dev); + struct class_function_drv *drv = auxiliary_get_drvdata(auxdev); + + return sdca_regmap_writeable(drv->function, reg); +} + +static bool class_function_regmap_readable(struct device *dev, unsigned int reg) +{ + struct auxiliary_device *auxdev = to_auxiliary_dev(dev); + struct class_function_drv *drv = auxiliary_get_drvdata(auxdev); + + return sdca_regmap_readable(drv->function, reg); +} + +static bool class_function_regmap_volatile(struct device *dev, unsigned int reg) +{ + struct auxiliary_device *auxdev = to_auxiliary_dev(dev); + struct class_function_drv *drv = auxiliary_get_drvdata(auxdev); + + return sdca_regmap_volatile(drv->function, reg); +} + +static const struct regmap_config class_function_regmap_config = { + .name = "sdca", + .reg_bits = 32, + .val_bits = 32, + .reg_format_endian = REGMAP_ENDIAN_LITTLE, + .val_format_endian = REGMAP_ENDIAN_LITTLE, + + .max_register = SDW_SDCA_MAX_REGISTER, + .readable_reg = class_function_regmap_readable, + .writeable_reg = class_function_regmap_writeable, + .volatile_reg = class_function_regmap_volatile, + + .cache_type = REGCACHE_MAPLE, + + .lock = class_function_regmap_lock, + .unlock = class_function_regmap_unlock, +}; + +static int class_function_regmap_mbq_size(struct device *dev, unsigned int reg) +{ + struct auxiliary_device *auxdev = to_auxiliary_dev(dev); + struct class_function_drv *drv = auxiliary_get_drvdata(auxdev); + + return sdca_regmap_mbq_size(drv->function, reg); +} + +static bool class_function_regmap_deferrable(struct device *dev, unsigned int reg) +{ + struct auxiliary_device *auxdev = to_auxiliary_dev(dev); + struct class_function_drv *drv = auxiliary_get_drvdata(auxdev); + + return sdca_regmap_deferrable(drv->function, reg); +} + +static const struct regmap_sdw_mbq_cfg class_function_mbq_config = { + .mbq_size = class_function_regmap_mbq_size, + .deferrable = class_function_regmap_deferrable, + .retry_us = 1000, + .timeout_us = 10000, +}; + +static int class_function_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct class_function_drv *drv = snd_soc_component_get_drvdata(dai->component); + + return sdca_asoc_set_constraints(drv->dev, drv->regmap, drv->function, + substream, dai); +} + +static int class_function_sdw_add_peripheral(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct class_function_drv *drv = snd_soc_component_get_drvdata(dai->component); + struct sdw_stream_runtime *sdw_stream = snd_soc_dai_get_dma_data(dai, substream); + struct sdw_slave *sdw = dev_to_sdw_dev(drv->dev->parent); + struct sdw_stream_config sconfig = {0}; + struct sdw_port_config pconfig = {0}; + int ret; + + if (!sdw_stream) + return -EINVAL; + + snd_sdw_params_to_config(substream, params, &sconfig, &pconfig); + + /* + * FIXME: As also noted in sdca_asoc_get_port(), currently only + * a single unshared port is supported for each DAI. + */ + ret = sdca_asoc_get_port(drv->dev, drv->regmap, drv->function, dai); + if (ret < 0) + return ret; + + pconfig.num = ret; + + ret = sdw_stream_add_slave(sdw, &sconfig, &pconfig, 1, sdw_stream); + if (ret) { + dev_err(drv->dev, "failed to add sdw stream: %d\n", ret); + return ret; + } + + return sdca_asoc_hw_params(drv->dev, drv->regmap, drv->function, + substream, params, dai); +} + +static int class_function_sdw_remove_peripheral(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct class_function_drv *drv = snd_soc_component_get_drvdata(dai->component); + struct sdw_stream_runtime *sdw_stream = snd_soc_dai_get_dma_data(dai, substream); + struct sdw_slave *sdw = dev_to_sdw_dev(drv->dev->parent); + + if (!sdw_stream) + return -EINVAL; + + return sdw_stream_remove_slave(sdw, sdw_stream); +} + +static int class_function_sdw_set_stream(struct snd_soc_dai *dai, void *sdw_stream, + int direction) +{ + snd_soc_dai_dma_data_set(dai, direction, sdw_stream); + + return 0; +} + +static const struct snd_soc_dai_ops class_function_sdw_ops = { + .startup = class_function_startup, + .shutdown = sdca_asoc_free_constraints, + .set_stream = class_function_sdw_set_stream, + .hw_params = class_function_sdw_add_peripheral, + .hw_free = class_function_sdw_remove_peripheral, +}; + +static int class_function_component_probe(struct snd_soc_component *component) +{ + struct class_function_drv *drv = snd_soc_component_get_drvdata(component); + struct sdca_class_drv *core = drv->core; + + return sdca_irq_populate(drv->function, component, core->irq_info); +} + +static const struct snd_soc_component_driver class_function_component_drv = { + .probe = class_function_component_probe, + .endianness = 1, +}; + +static int class_function_boot(struct class_function_drv *drv) +{ + unsigned int reg = SDW_SDCA_CTL(drv->function->desc->adr, + SDCA_ENTITY_TYPE_ENTITY_0, + SDCA_CTL_ENTITY_0_FUNCTION_STATUS, 0); + unsigned int val; + int ret; + + ret = regmap_read(drv->regmap, reg, &val); + if (ret < 0) { + dev_err(drv->dev, "failed to read function status: %d\n", ret); + return ret; + } + + if (!(val & SDCA_CTL_ENTITY_0_FUNCTION_HAS_BEEN_RESET)) { + dev_dbg(drv->dev, "reset function device\n"); + + ret = sdca_reset_function(drv->dev, drv->function, drv->regmap); + if (ret) + return ret; + } + + if (val & SDCA_CTL_ENTITY_0_FUNCTION_NEEDS_INITIALIZATION) { + dev_dbg(drv->dev, "write initialisation\n"); + + ret = sdca_regmap_write_init(drv->dev, drv->core->dev_regmap, + drv->function); + if (ret) + return ret; + + ret = regmap_write(drv->regmap, reg, + SDCA_CTL_ENTITY_0_FUNCTION_NEEDS_INITIALIZATION); + if (ret < 0) { + dev_err(drv->dev, + "failed to clear function init status: %d\n", + ret); + return ret; + } + } + + /* Start FDL process */ + ret = sdca_irq_populate_early(drv->dev, drv->regmap, drv->function, + drv->core->irq_info); + if (ret) + return ret; + + ret = sdca_fdl_sync(drv->dev, drv->function, drv->core->irq_info); + if (ret) + return ret; + + ret = sdca_regmap_write_defaults(drv->dev, drv->regmap, drv->function); + if (ret) + return ret; + + ret = regmap_write(drv->regmap, reg, 0xFF); + if (ret < 0) { + dev_err(drv->dev, "failed to clear function status: %d\n", ret); + return ret; + } + + return 0; +} + +static int class_function_probe(struct auxiliary_device *auxdev, + const struct auxiliary_device_id *aux_dev_id) +{ + struct device *dev = &auxdev->dev; + struct sdca_class_drv *core = dev_get_drvdata(dev->parent); + struct sdca_device_data *data = &core->sdw->sdca_data; + struct sdca_function_desc *desc; + struct snd_soc_component_driver *cmp_drv; + struct snd_soc_dai_driver *dais; + struct class_function_drv *drv; + struct regmap_sdw_mbq_cfg *mbq_config; + struct regmap_config *config; + struct reg_default *defaults; + int ndefaults; + int num_dais; + int ret; + int i; + + drv = devm_kzalloc(dev, sizeof(*drv), GFP_KERNEL); + if (!drv) + return -ENOMEM; + + cmp_drv = devm_kmemdup(dev, &class_function_component_drv, sizeof(*cmp_drv), + GFP_KERNEL); + if (!cmp_drv) + return -ENOMEM; + + config = devm_kmemdup(dev, &class_function_regmap_config, sizeof(*config), + GFP_KERNEL); + if (!config) + return -ENOMEM; + + mbq_config = devm_kmemdup(dev, &class_function_mbq_config, sizeof(*mbq_config), + GFP_KERNEL); + if (!mbq_config) + return -ENOMEM; + + drv->dev = dev; + drv->core = core; + + for (i = 0; i < data->num_functions; i++) { + desc = &data->function[i]; + + if (desc->type == aux_dev_id->driver_data) + break; + } + if (i == core->sdw->sdca_data.num_functions) { + dev_err(dev, "failed to locate function\n"); + return -EINVAL; + } + + drv->function = &core->functions[i]; + + ret = sdca_parse_function(dev, core->sdw, desc, drv->function); + if (ret) + return ret; + + ndefaults = sdca_regmap_count_constants(dev, drv->function); + if (ndefaults < 0) + return ndefaults; + + defaults = devm_kcalloc(dev, ndefaults, sizeof(*defaults), GFP_KERNEL); + if (!defaults) + return -ENOMEM; + + ret = sdca_regmap_populate_constants(dev, drv->function, defaults); + if (ret < 0) + return ret; + + regcache_sort_defaults(defaults, ndefaults); + + auxiliary_set_drvdata(auxdev, drv); + + config->reg_defaults = defaults; + config->num_reg_defaults = ndefaults; + config->lock_arg = &core->regmap_lock; + + if (drv->function->busy_max_delay) { + mbq_config->timeout_us = drv->function->busy_max_delay; + mbq_config->retry_us = umax(drv->function->busy_max_delay / 10, + mbq_config->retry_us); + } + + drv->regmap = devm_regmap_init_sdw_mbq_cfg(dev, core->sdw, config, mbq_config); + if (IS_ERR(drv->regmap)) + return dev_err_probe(dev, PTR_ERR(drv->regmap), + "failed to create regmap"); + + ret = sdca_asoc_populate_component(dev, drv->function, cmp_drv, + &dais, &num_dais, + &class_function_sdw_ops); + if (ret) + return ret; + + pm_runtime_set_autosuspend_delay(dev, 200); + pm_runtime_use_autosuspend(dev); + pm_runtime_set_active(dev); + pm_runtime_get_noresume(dev); + + ret = devm_pm_runtime_enable(dev); + if (ret) + return ret; + + ret = class_function_boot(drv); + if (ret) + return ret; + + ret = devm_snd_soc_register_component(dev, cmp_drv, dais, num_dais); + if (ret) + return dev_err_probe(dev, ret, "failed to register component\n"); + + pm_runtime_mark_last_busy(dev); + pm_runtime_put_autosuspend(dev); + + return 0; +} + +static int class_function_runtime_suspend(struct device *dev) +{ + struct auxiliary_device *auxdev = to_auxiliary_dev(dev); + struct class_function_drv *drv = auxiliary_get_drvdata(auxdev); + + /* + * Whilst the driver doesn't power the chip down here, going into + * runtime suspend means the driver can't be sure the bus won't + * power down which would prevent communication with the device. + */ + regcache_cache_only(drv->regmap, true); + + return 0; +} + +static int class_function_runtime_resume(struct device *dev) +{ + struct auxiliary_device *auxdev = to_auxiliary_dev(dev); + struct class_function_drv *drv = auxiliary_get_drvdata(auxdev); + int ret; + + regcache_mark_dirty(drv->regmap); + regcache_cache_only(drv->regmap, false); + + ret = regcache_sync(drv->regmap); + if (ret) { + dev_err(drv->dev, "failed to restore register cache: %d\n", ret); + goto err; + } + + return 0; + +err: + regcache_cache_only(drv->regmap, true); + + return ret; +} + +static const struct dev_pm_ops class_function_pm_ops = { + RUNTIME_PM_OPS(class_function_runtime_suspend, + class_function_runtime_resume, NULL) +}; + +static const struct auxiliary_device_id class_function_id_table[] = { + { + .name = "snd_soc_sdca." SDCA_FUNCTION_TYPE_SMART_AMP_NAME, + .driver_data = SDCA_FUNCTION_TYPE_SMART_AMP, + }, + { + .name = "snd_soc_sdca." SDCA_FUNCTION_TYPE_SMART_MIC_NAME, + .driver_data = SDCA_FUNCTION_TYPE_SMART_MIC, + }, + { + .name = "snd_soc_sdca." SDCA_FUNCTION_TYPE_UAJ_NAME, + .driver_data = SDCA_FUNCTION_TYPE_UAJ, + }, + { + .name = "snd_soc_sdca." SDCA_FUNCTION_TYPE_HID_NAME, + .driver_data = SDCA_FUNCTION_TYPE_HID, + }, + {}, +}; +MODULE_DEVICE_TABLE(auxiliary, class_function_id_table); + +static struct auxiliary_driver class_function_drv = { + .driver = { + .name = "sdca_function", + .pm = pm_ptr(&class_function_pm_ops), + }, + + .probe = class_function_probe, + .id_table = class_function_id_table +}; +module_auxiliary_driver(class_function_drv); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("SDCA Class Function Driver"); +MODULE_IMPORT_NS("SND_SOC_SDCA"); diff --git a/sound/soc/sdca/sdca_fdl.c b/sound/soc/sdca/sdca_fdl.c index cb79dc3131b82f..3180ebd07c4007 100644 --- a/sound/soc/sdca/sdca_fdl.c +++ b/sound/soc/sdca/sdca_fdl.c @@ -51,6 +51,10 @@ int sdca_reset_function(struct device *dev, struct sdca_function_data *function, return -EINVAL; } + /* + * Poll up to 16 times but no more than once per ms, these are just + * arbitrarily selected values, so may be fine tuned in future. + */ poll_us = umin(function->reset_max_delay >> 4, 1000); ret = regmap_read_poll_timeout(regmap, reg, val, !val, poll_us, @@ -402,8 +406,6 @@ int sdca_fdl_process(struct sdca_interrupt *interrupt) unsigned int reg, status; int response, ret; - guard(mutex)(&fdl_state->lock); - ret = sdca_ump_get_owner_host(dev, interrupt->function_regmap, interrupt->function, interrupt->entity, interrupt->control); @@ -412,56 +414,59 @@ int sdca_fdl_process(struct sdca_interrupt *interrupt) sdca_ump_cancel_timeout(&fdl_state->timeout); - reg = SDW_SDCA_CTL(interrupt->function->desc->adr, interrupt->entity->id, - SDCA_CTL_XU_FDL_STATUS, 0); - ret = regmap_read(interrupt->function_regmap, reg, &status); - if (ret < 0) { - dev_err(dev, "failed to read FDL status: %d\n", ret); - return ret; - } - - dev_dbg(dev, "FDL status: %#x\n", status); + scoped_guard(mutex, &fdl_state->lock) { + reg = SDW_SDCA_CTL(interrupt->function->desc->adr, + interrupt->entity->id, SDCA_CTL_XU_FDL_STATUS, 0); + ret = regmap_read(interrupt->function_regmap, reg, &status); + if (ret < 0) { + dev_err(dev, "failed to read FDL status: %d\n", ret); + return ret; + } - ret = fdl_status_process(interrupt, status); - if (ret < 0) - goto reset_function; + dev_dbg(dev, "FDL status: %#x\n", status); - response = ret; + ret = fdl_status_process(interrupt, status); + if (ret < 0) + goto reset_function; - dev_dbg(dev, "FDL response: %#x\n", response); + response = ret; - ret = regmap_write(interrupt->function_regmap, reg, - response | (status & ~SDCA_CTL_XU_FDLH_MASK)); - if (ret < 0) { - dev_err(dev, "failed to set FDL status signal: %d\n", ret); - return ret; - } + dev_dbg(dev, "FDL response: %#x\n", response); - ret = sdca_ump_set_owner_device(dev, interrupt->function_regmap, - interrupt->function, interrupt->entity, - interrupt->control); - if (ret) - return ret; - - switch (response) { - case SDCA_CTL_XU_FDLH_RESET_ACK: - dev_dbg(dev, "FDL request reset\n"); + ret = regmap_write(interrupt->function_regmap, reg, + response | (status & ~SDCA_CTL_XU_FDLH_MASK)); + if (ret < 0) { + dev_err(dev, "failed to set FDL status signal: %d\n", ret); + return ret; + } - switch (xu->reset_mechanism) { - default: - dev_warn(dev, "Requested reset mechanism not implemented\n"); + ret = sdca_ump_set_owner_device(dev, interrupt->function_regmap, + interrupt->function, + interrupt->entity, + interrupt->control); + if (ret) + return ret; + + switch (response) { + case SDCA_CTL_XU_FDLH_RESET_ACK: + dev_dbg(dev, "FDL request reset\n"); + + switch (xu->reset_mechanism) { + default: + dev_warn(dev, "Requested reset mechanism not implemented\n"); + fallthrough; + case SDCA_XU_RESET_FUNCTION: + goto reset_function; + } + case SDCA_CTL_XU_FDLH_COMPLETE: + if (status & SDCA_CTL_XU_FDLD_REQ_ABORT || + status == SDCA_CTL_XU_FDLD_COMPLETE) + return 0; fallthrough; - case SDCA_XU_RESET_FUNCTION: - goto reset_function; - } - case SDCA_CTL_XU_FDLH_COMPLETE: - if (status & SDCA_CTL_XU_FDLD_REQ_ABORT || - status == SDCA_CTL_XU_FDLD_COMPLETE) + default: + sdca_ump_schedule_timeout(&fdl_state->timeout, xu->max_delay); return 0; - fallthrough; - default: - sdca_ump_schedule_timeout(&fdl_state->timeout, xu->max_delay); - return 0; + } } reset_function: diff --git a/sound/soc/sdca/sdca_function_device.c b/sound/soc/sdca/sdca_function_device.c new file mode 100644 index 00000000000000..c6cc880a150ebe --- /dev/null +++ b/sound/soc/sdca/sdca_function_device.c @@ -0,0 +1,117 @@ +// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) +// Copyright(c) 2024 Intel Corporation. + +/* + * SDCA Function Device management + */ + +#include +#include +#include +#include +#include +#include +#include "sdca_function_device.h" + +/* + * A SoundWire device can have multiple SDCA functions identified by + * their type and ADR. there can be multiple SoundWire devices per + * link, or multiple devices spread across multiple links. An IDA is + * required to identify each instance. + */ +static DEFINE_IDA(sdca_function_ida); + +static void sdca_dev_release(struct device *dev) +{ + struct auxiliary_device *auxdev = to_auxiliary_dev(dev); + struct sdca_dev *sdev = auxiliary_dev_to_sdca_dev(auxdev); + + ida_free(&sdca_function_ida, auxdev->id); + kfree(sdev); +} + +/* alloc, init and add link devices */ +static struct sdca_dev *sdca_dev_register(struct device *parent, + struct sdca_function_desc *function_desc) +{ + struct sdca_dev *sdev; + struct auxiliary_device *auxdev; + int ret; + int rc; + + sdev = kzalloc(sizeof(*sdev), GFP_KERNEL); + if (!sdev) + return ERR_PTR(-ENOMEM); + + auxdev = &sdev->auxdev; + auxdev->name = function_desc->name; + auxdev->dev.parent = parent; + auxdev->dev.fwnode = function_desc->node; + auxdev->dev.release = sdca_dev_release; + + sdev->function.desc = function_desc; + + rc = ida_alloc(&sdca_function_ida, GFP_KERNEL); + if (rc < 0) { + kfree(sdev); + return ERR_PTR(rc); + } + auxdev->id = rc; + + /* now follow the two-step init/add sequence */ + ret = auxiliary_device_init(auxdev); + if (ret < 0) { + dev_err(parent, "failed to initialize SDCA function dev %s\n", + function_desc->name); + ida_free(&sdca_function_ida, auxdev->id); + kfree(sdev); + return ERR_PTR(ret); + } + + ret = auxiliary_device_add(auxdev); + if (ret < 0) { + dev_err(parent, "failed to add SDCA function dev %s\n", + sdev->auxdev.name); + /* sdev will be freed with the put_device() and .release sequence */ + auxiliary_device_uninit(&sdev->auxdev); + return ERR_PTR(ret); + } + + return sdev; +} + +static void sdca_dev_unregister(struct sdca_dev *sdev) +{ + auxiliary_device_delete(&sdev->auxdev); + auxiliary_device_uninit(&sdev->auxdev); +} + +int sdca_dev_register_functions(struct sdw_slave *slave) +{ + struct sdca_device_data *sdca_data = &slave->sdca_data; + int i; + + for (i = 0; i < sdca_data->num_functions; i++) { + struct sdca_dev *func_dev; + + func_dev = sdca_dev_register(&slave->dev, + &sdca_data->function[i]); + if (IS_ERR(func_dev)) + return PTR_ERR(func_dev); + + sdca_data->function[i].func_dev = func_dev; + } + + return 0; +} +EXPORT_SYMBOL_NS(sdca_dev_register_functions, "SND_SOC_SDCA"); + +void sdca_dev_unregister_functions(struct sdw_slave *slave) +{ + struct sdca_device_data *sdca_data = &slave->sdca_data; + int i; + + for (i = 0; i < sdca_data->num_functions; i++) + sdca_dev_unregister(sdca_data->function[i].func_dev); +} +EXPORT_SYMBOL_NS(sdca_dev_unregister_functions, "SND_SOC_SDCA"); diff --git a/sound/soc/sdca/sdca_function_device.h b/sound/soc/sdca/sdca_function_device.h new file mode 100644 index 00000000000000..5adf7551d3a448 --- /dev/null +++ b/sound/soc/sdca/sdca_function_device.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */ +/* Copyright(c) 2024 Intel Corporation. */ + +#ifndef __SDCA_FUNCTION_DEVICE_H +#define __SDCA_FUNCTION_DEVICE_H + +struct sdca_dev { + struct auxiliary_device auxdev; + struct sdca_function_data function; +}; + +#define auxiliary_dev_to_sdca_dev(auxiliary_dev) \ + container_of(auxiliary_dev, struct sdca_dev, auxdev) + +#endif diff --git a/sound/soc/sdca/sdca_functions.c b/sound/soc/sdca/sdca_functions.c index 49b98fe2d85438..5a1f120487ef05 100644 --- a/sound/soc/sdca/sdca_functions.c +++ b/sound/soc/sdca/sdca_functions.c @@ -6,8 +6,6 @@ * https://www.mipi.org/mipi-sdca-v1-0-download */ -#define dev_fmt(fmt) "%s: " fmt, __func__ - #include #include #include @@ -16,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -79,6 +78,8 @@ static const char *get_sdca_function_name(u32 function_type) return SDCA_FUNCTION_TYPE_SPEAKER_MIC_NAME; case SDCA_FUNCTION_TYPE_RJ: return SDCA_FUNCTION_TYPE_RJ_NAME; + case SDCA_FUNCTION_TYPE_COMPANION_AMP: + return SDCA_FUNCTION_TYPE_COMPANION_AMP_NAME; case SDCA_FUNCTION_TYPE_IMP_DEF: return SDCA_FUNCTION_TYPE_IMP_DEF_NAME; default: @@ -1011,10 +1012,10 @@ static int find_sdca_entity_control(struct device *dev, struct sdca_entity *enti control->type = find_sdca_control_datatype(entity, control); control->nbits = find_sdca_control_bits(entity, control); - dev_info(dev, "%s: %s: control %#x mode %#x layers %#x cn %#llx int %d %s\n", - entity->label, control->label, control->sel, - control->mode, control->layers, control->cn_list, - control->interrupt_position, control->deferrable ? "deferrable" : ""); + dev_dbg(dev, "%s: %s: control %#x mode %#x layers %#x cn %#llx int %d %s\n", + entity->label, control->label, control->sel, + control->mode, control->layers, control->cn_list, + control->interrupt_position, control->deferrable ? "deferrable" : ""); return 0; } @@ -1120,6 +1121,14 @@ static int find_sdca_entity_iot(struct device *dev, terminal->type = tmp; terminal->is_dataport = find_sdca_iot_dataport(terminal); + if (!terminal->is_dataport) { + const char *type_name = sdca_find_terminal_name(terminal->type); + + if (type_name) + entity->label = devm_kasprintf(dev, GFP_KERNEL, "%s %s", + entity->label, type_name); + } + ret = fwnode_property_read_u32(entity_node, "mipi-sdca-terminal-reference-number", &tmp); if (!ret) @@ -1135,9 +1144,9 @@ static int find_sdca_entity_iot(struct device *dev, if (!ret) terminal->num_transducer = tmp; - dev_info(dev, "%s: terminal type %#x ref %#x conn %#x count %d\n", - entity->label, terminal->type, terminal->reference, - terminal->connector, terminal->num_transducer); + dev_dbg(dev, "%s: terminal type %#x ref %#x conn %#x count %d\n", + entity->label, terminal->type, terminal->reference, + terminal->connector, terminal->num_transducer); return 0; } @@ -1163,8 +1172,8 @@ static int find_sdca_entity_cs(struct device *dev, if (!ret) clock->max_delay = tmp; - dev_info(dev, "%s: clock type %#x delay %d\n", entity->label, - clock->type, clock->max_delay); + dev_dbg(dev, "%s: clock type %#x delay %d\n", entity->label, + clock->type, clock->max_delay); return 0; } @@ -1215,8 +1224,8 @@ static int find_sdca_entity_pde(struct device *dev, delays[i].to_ps = delay_list[j++]; delays[i].us = delay_list[j++]; - dev_info(dev, "%s: from %#x to %#x delay %dus\n", entity->label, - delays[i].from_ps, delays[i].to_ps, delays[i].us); + dev_dbg(dev, "%s: from %#x to %#x delay %dus\n", entity->label, + delays[i].from_ps, delays[i].to_ps, delays[i].us); } power->num_max_delay = num_delays; @@ -1322,7 +1331,7 @@ find_sdca_entity_hide(struct device *dev, struct sdw_slave *sdw, unsigned char *report_desc = NULL; ret = fwnode_property_read_u32(entity_node, - "mipi-sdca-RxUMP-ownership-transition-maxdelay", &delay); + "mipi-sdca-RxUMP-ownership-transition-max-delay", &delay); if (!ret) hide->max_delay = delay; @@ -1445,8 +1454,8 @@ static int find_sdca_entity(struct device *dev, struct sdw_slave *sdw, entity->type = tmp; - dev_info(dev, "%s: entity %#x type %#x\n", - entity->label, entity->id, entity->type); + dev_dbg(dev, "%s: entity %#x type %#x\n", + entity->label, entity->id, entity->type); switch (entity->type) { case SDCA_ENTITY_TYPE_IT: @@ -1565,7 +1574,7 @@ static struct sdca_entity *find_sdca_entity_by_label(struct sdca_function_data * for (i = 0; i < function->num_entities; i++) { struct sdca_entity *entity = &function->entities[i]; - if (!strcmp(entity->label, entity_label)) + if (!strncmp(entity->label, entity_label, strlen(entity_label))) return entity; } @@ -1621,7 +1630,7 @@ static int find_sdca_entity_connection_iot(struct device *dev, terminal->clock = clock_entity; - dev_info(dev, "%s -> %s\n", clock_entity->label, entity->label); + dev_dbg(dev, "%s -> %s\n", clock_entity->label, entity->label); fwnode_handle_put(clock_node); return 0; @@ -1671,7 +1680,7 @@ static int find_sdca_entity_connection_pde(struct device *dev, return -EINVAL; } - dev_info(dev, "%s -> %s\n", managed[i]->label, entity->label); + dev_dbg(dev, "%s -> %s\n", managed[i]->label, entity->label); } power->num_managed = num_managed; @@ -1806,7 +1815,7 @@ static int find_sdca_entity_connection(struct device *dev, pins[i] = connected_entity; - dev_info(dev, "%s -> %s\n", connected_entity->label, entity->label); + dev_dbg(dev, "%s -> %s\n", connected_entity->label, entity->label); i++; fwnode_handle_put(connected_node); @@ -1891,8 +1900,8 @@ static int find_sdca_cluster_channel(struct device *dev, channel->relationship = tmp; - dev_info(dev, "cluster %#x: channel id %#x purpose %#x relationship %#x\n", - cluster->id, channel->id, channel->purpose, channel->relationship); + dev_dbg(dev, "cluster %#x: channel id %#x purpose %#x relationship %#x\n", + cluster->id, channel->id, channel->purpose, channel->relationship); return 0; } @@ -2063,7 +2072,7 @@ static int find_sdca_filesets(struct device *dev, struct sdw_slave *sdw, return -EINVAL; } - dev_info(dev, "fileset: %#x\n", filesets_list[i]); + dev_dbg(dev, "fileset: %#x\n", filesets_list[i]); files = devm_kcalloc(dev, num_entries / mult_fileset, sizeof(struct sdca_fdl_file), GFP_KERNEL); @@ -2084,8 +2093,8 @@ static int find_sdca_filesets(struct device *dev, struct sdw_slave *sdw, file->file_id = fileset_entries[j++]; file->fdl_offset = fileset_entries[j++]; - dev_info(dev, "file: %#x, vendor: %#x, offset: %#x\n", - file->file_id, file->vendor_id, file->fdl_offset); + dev_dbg(dev, "file: %#x, vendor: %#x, offset: %#x\n", + file->file_id, file->vendor_id, file->fdl_offset); } set->id = filesets_list[i]; @@ -2128,9 +2137,9 @@ int sdca_parse_function(struct device *dev, struct sdw_slave *sdw, if (!ret) function->reset_max_delay = tmp; - dev_info(dev, "%pfwP: name %s busy delay %dus reset delay %dus\n", - function->desc->node, function->desc->name, - function->busy_max_delay, function->reset_max_delay); + dev_dbg(dev, "%pfwP: name %s busy delay %dus reset delay %dus\n", + function->desc->node, function->desc->name, + function->busy_max_delay, function->reset_max_delay); ret = find_sdca_init_table(dev, function_desc->node, function); if (ret) @@ -2156,6 +2165,51 @@ int sdca_parse_function(struct device *dev, struct sdw_slave *sdw, } EXPORT_SYMBOL_NS(sdca_parse_function, "SND_SOC_SDCA"); +const char *sdca_find_terminal_name(enum sdca_terminal_type type) +{ + switch (type) { + case SDCA_TERM_TYPE_LINEIN_STEREO: + return SDCA_TERM_TYPE_LINEIN_STEREO_NAME; + case SDCA_TERM_TYPE_LINEIN_FRONT_LR: + return SDCA_TERM_TYPE_LINEIN_FRONT_LR_NAME; + case SDCA_TERM_TYPE_LINEIN_CENTER_LFE: + return SDCA_TERM_TYPE_LINEIN_CENTER_LFE_NAME; + case SDCA_TERM_TYPE_LINEIN_SURROUND_LR: + return SDCA_TERM_TYPE_LINEIN_SURROUND_LR_NAME; + case SDCA_TERM_TYPE_LINEIN_REAR_LR: + return SDCA_TERM_TYPE_LINEIN_REAR_LR_NAME; + case SDCA_TERM_TYPE_LINEOUT_STEREO: + return SDCA_TERM_TYPE_LINEOUT_STEREO_NAME; + case SDCA_TERM_TYPE_LINEOUT_FRONT_LR: + return SDCA_TERM_TYPE_LINEOUT_FRONT_LR_NAME; + case SDCA_TERM_TYPE_LINEOUT_CENTER_LFE: + return SDCA_TERM_TYPE_LINEOUT_CENTER_LFE_NAME; + case SDCA_TERM_TYPE_LINEOUT_SURROUND_LR: + return SDCA_TERM_TYPE_LINEOUT_SURROUND_LR_NAME; + case SDCA_TERM_TYPE_LINEOUT_REAR_LR: + return SDCA_TERM_TYPE_LINEOUT_REAR_LR_NAME; + case SDCA_TERM_TYPE_MIC_JACK: + return SDCA_TERM_TYPE_MIC_JACK_NAME; + case SDCA_TERM_TYPE_STEREO_JACK: + return SDCA_TERM_TYPE_STEREO_JACK_NAME; + case SDCA_TERM_TYPE_FRONT_LR_JACK: + return SDCA_TERM_TYPE_FRONT_LR_JACK_NAME; + case SDCA_TERM_TYPE_CENTER_LFE_JACK: + return SDCA_TERM_TYPE_CENTER_LFE_JACK_NAME; + case SDCA_TERM_TYPE_SURROUND_LR_JACK: + return SDCA_TERM_TYPE_SURROUND_LR_JACK_NAME; + case SDCA_TERM_TYPE_REAR_LR_JACK: + return SDCA_TERM_TYPE_REAR_LR_JACK_NAME; + case SDCA_TERM_TYPE_HEADPHONE_JACK: + return SDCA_TERM_TYPE_HEADPHONE_JACK_NAME; + case SDCA_TERM_TYPE_HEADSET_JACK: + return SDCA_TERM_TYPE_HEADSET_JACK_NAME; + default: + return NULL; + } +} +EXPORT_SYMBOL_NS(sdca_find_terminal_name, "SND_SOC_SDCA"); + struct sdca_control *sdca_selector_find_control(struct device *dev, struct sdca_entity *entity, const int sel) diff --git a/sound/soc/sdca/sdca_hid.c b/sound/soc/sdca/sdca_hid.c index ad53207b0d62b7..abbd56a3d29716 100644 --- a/sound/soc/sdca/sdca_hid.c +++ b/sound/soc/sdca/sdca_hid.c @@ -166,6 +166,3 @@ int sdca_hid_process_report(struct sdca_interrupt *interrupt) return 0; } EXPORT_SYMBOL_NS(sdca_hid_process_report, "SND_SOC_SDCA"); - -MODULE_LICENSE("Dual BSD/GPL"); -MODULE_DESCRIPTION("SDCA HID library"); diff --git a/sound/soc/sdca/sdca_interrupts.c b/sound/soc/sdca/sdca_interrupts.c index 5176460416bbe8..8f6a2adfb6fbea 100644 --- a/sound/soc/sdca/sdca_interrupts.c +++ b/sound/soc/sdca/sdca_interrupts.c @@ -456,11 +456,8 @@ int sdca_irq_populate_early(struct device *dev, struct regmap *regmap, else if (!interrupt) continue; - switch (entity->type) { - case SDCA_ENTITY_TYPE_XU: - if (control->sel != SDCA_CTL_XU_FDL_CURRENTOWNER) - break; - + switch (SDCA_CTL_TYPE(entity->type, control->sel)) { + case SDCA_CTL_TYPE_S(XU, FDL_CURRENTOWNER): ret = sdca_irq_data_populate(dev, regmap, NULL, function, entity, control, interrupt); @@ -534,27 +531,22 @@ int sdca_irq_populate(struct sdca_function_data *function, handler = base_handler; - switch (entity->type) { - case SDCA_ENTITY_TYPE_ENTITY_0: - if (control->sel == SDCA_CTL_ENTITY_0_FUNCTION_STATUS) - handler = function_status_handler; + switch (SDCA_CTL_TYPE(entity->type, control->sel)) { + case SDCA_CTL_TYPE_S(ENTITY_0, FUNCTION_STATUS): + handler = function_status_handler; break; - case SDCA_ENTITY_TYPE_GE: - if (control->sel == SDCA_CTL_GE_DETECTED_MODE) - handler = detected_mode_handler; + case SDCA_CTL_TYPE_S(GE, DETECTED_MODE): + handler = detected_mode_handler; break; - case SDCA_ENTITY_TYPE_XU: - if (control->sel == SDCA_CTL_XU_FDL_CURRENTOWNER) { - ret = sdca_fdl_alloc_state(interrupt); - if (ret) - return ret; + case SDCA_CTL_TYPE_S(XU, FDL_CURRENTOWNER): + ret = sdca_fdl_alloc_state(interrupt); + if (ret) + return ret; - handler = fdl_owner_handler; - } + handler = fdl_owner_handler; break; - case SDCA_ENTITY_TYPE_HIDE: - if (control->sel == SDCA_CTL_HIDE_HIDTX_CURRENTOWNER) - handler = hid_handler; + case SDCA_CTL_TYPE_S(HIDE, HIDTX_CURRENTOWNER): + handler = hid_handler; break; default: break; @@ -618,6 +610,3 @@ struct sdca_interrupt_info *sdca_irq_allocate(struct device *sdev, return info; } EXPORT_SYMBOL_NS_GPL(sdca_irq_allocate, "SND_SOC_SDCA"); - -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("SDCA IRQ library"); diff --git a/sound/soc/sdca/sdca_regmap.c b/sound/soc/sdca/sdca_regmap.c index 8fa138fca00ffb..2cca9a9c71ea90 100644 --- a/sound/soc/sdca/sdca_regmap.c +++ b/sound/soc/sdca/sdca_regmap.c @@ -275,6 +275,49 @@ int sdca_regmap_populate_constants(struct device *dev, } EXPORT_SYMBOL_NS(sdca_regmap_populate_constants, "SND_SOC_SDCA"); +static int populate_control_defaults(struct device *dev, struct regmap *regmap, + struct sdca_function_data *function, + struct sdca_entity *entity, + struct sdca_control *control) +{ + int i, ret; + int cn; + + if (control->mode == SDCA_ACCESS_MODE_DC) + return 0; + + if (control->layers & SDCA_ACCESS_LAYER_DEVICE) + return 0; + + i = 0; + for_each_set_bit(cn, (unsigned long *)&control->cn_list, + BITS_PER_TYPE(control->cn_list)) { + unsigned int reg, val; + + reg = SDW_SDCA_CTL(function->desc->adr, entity->id, control->sel, cn); + + if (control->has_default || control->has_fixed) { + ret = regmap_write(regmap, reg, control->values[i]); + if (ret) { + dev_err(dev, "Failed to write default %#x: %d\n", + reg, ret); + return ret; + } + + i++; + } else if (!control->is_volatile) { + ret = regmap_read(regmap, reg, &val); + if (ret) { + dev_err(dev, "Failed to read initial %#x: %d\n", + reg, ret); + return ret; + } + } + } + + return 0; +} + /** * sdca_regmap_write_defaults - write out DisCo defaults to device * @dev: Pointer to the device. @@ -283,14 +326,17 @@ EXPORT_SYMBOL_NS(sdca_regmap_populate_constants, "SND_SOC_SDCA"); * * This function will write out to the hardware all the DisCo default and * fixed value controls. This will cause them to be populated into the cache, - * and subsequent handling can be done through a cache sync. + * and subsequent handling can be done through a cache sync. It will also + * read any non-volatile registers that don't have defaults/fixed values to + * populate those into the cache, this ensures they are available for reads + * even when the device is runtime suspended. * * Return: Returns zero on success, and a negative error code on failure. */ int sdca_regmap_write_defaults(struct device *dev, struct regmap *regmap, struct sdca_function_data *function) { - int i, j, k; + int i, j; int ret; for (i = 0; i < function->num_entities; i++) { @@ -298,31 +344,30 @@ int sdca_regmap_write_defaults(struct device *dev, struct regmap *regmap, for (j = 0; j < entity->num_controls; j++) { struct sdca_control *control = &entity->controls[j]; - int cn; - if (control->mode == SDCA_ACCESS_MODE_DC) - continue; - - if (!control->has_default && !control->has_fixed) - continue; - - k = 0; - for_each_set_bit(cn, (unsigned long *)&control->cn_list, - BITS_PER_TYPE(control->cn_list)) { - unsigned int reg; + ret = populate_control_defaults(dev, regmap, function, + entity, control); + if (ret) + return ret; + } + } - reg = SDW_SDCA_CTL(function->desc->adr, entity->id, - control->sel, cn); + return 0; +} +EXPORT_SYMBOL_NS(sdca_regmap_write_defaults, "SND_SOC_SDCA"); - ret = regmap_write(regmap, reg, control->values[k]); - if (ret) - return ret; +int sdca_regmap_write_init(struct device *dev, struct regmap *regmap, + struct sdca_function_data *function) +{ + struct sdca_init_write *init = function->init_table; + int ret, i; - k++; - } - } + for (i = 0; i < function->num_init_table; i++) { + ret = regmap_write(regmap, init[i].addr, init[i].val); + if (ret) + return ret; } return 0; } -EXPORT_SYMBOL_NS(sdca_regmap_write_defaults, "SND_SOC_SDCA"); +EXPORT_SYMBOL_NS(sdca_regmap_write_init, "SND_SOC_SDCA"); diff --git a/sound/soc/sdw_utils/Makefile b/sound/soc/sdw_utils/Makefile index a87c53e1a2c18e..e8bd5ffb1a6ade 100644 --- a/sound/soc/sdw_utils/Makefile +++ b/sound/soc/sdw_utils/Makefile @@ -5,6 +5,7 @@ snd-soc-sdw-utils-y := soc_sdw_utils.o soc_sdw_dmic.o soc_sdw_rt_dmic.o \ soc_sdw_rt_amp.o soc_sdw_rt_mf_sdca.o \ soc_sdw_bridge_cs35l56.o \ soc_sdw_cs42l42.o soc_sdw_cs42l43.o \ + soc_sdw_cs42l45.o \ soc_sdw_cs_amp.o \ soc_sdw_maxim.o \ soc_sdw_ti_amp.o diff --git a/sound/soc/sdw_utils/soc_sdw_bridge_cs35l56.c b/sound/soc/sdw_utils/soc_sdw_bridge_cs35l56.c index c7e55f4433514c..2a7109d53cbe3a 100644 --- a/sound/soc/sdw_utils/soc_sdw_bridge_cs35l56.c +++ b/sound/soc/sdw_utils/soc_sdw_bridge_cs35l56.c @@ -33,6 +33,7 @@ static const char * const bridge_cs35l56_name_prefixes[] = { static int asoc_sdw_bridge_cs35l56_asp_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_card *card = rtd->card; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); int i, ret; unsigned int rx_mask = 3; // ASP RX1, RX2 unsigned int tx_mask = 3; // ASP TX1, TX2 @@ -45,14 +46,14 @@ static int asoc_sdw_bridge_cs35l56_asp_init(struct snd_soc_pcm_runtime *rtd) if (!card->components) return -ENOMEM; - ret = snd_soc_dapm_new_controls(&card->dapm, bridge_widgets, + ret = snd_soc_dapm_new_controls(dapm, bridge_widgets, ARRAY_SIZE(bridge_widgets)); if (ret) { dev_err(card->dev, "widgets addition failed: %d\n", ret); return ret; } - ret = snd_soc_dapm_add_routes(&card->dapm, bridge_map, ARRAY_SIZE(bridge_map)); + ret = snd_soc_dapm_add_routes(dapm, bridge_map, ARRAY_SIZE(bridge_map)); if (ret) { dev_err(card->dev, "map addition failed: %d\n", ret); return ret; diff --git a/sound/soc/sdw_utils/soc_sdw_cs42l42.c b/sound/soc/sdw_utils/soc_sdw_cs42l42.c index f37c1793991a4c..ff1bdf52d483ee 100644 --- a/sound/soc/sdw_utils/soc_sdw_cs42l42.c +++ b/sound/soc/sdw_utils/soc_sdw_cs42l42.c @@ -40,6 +40,7 @@ static struct snd_soc_jack_pin cs42l42_jack_pins[] = { int asoc_sdw_cs42l42_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai) { struct snd_soc_card *card = rtd->card; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); struct asoc_sdw_mc_private *ctx = snd_soc_card_get_drvdata(card); struct snd_soc_component *component; struct snd_soc_jack *jack; @@ -52,7 +53,7 @@ int asoc_sdw_cs42l42_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_da if (!card->components) return -ENOMEM; - ret = snd_soc_dapm_add_routes(&card->dapm, cs42l42_map, + ret = snd_soc_dapm_add_routes(dapm, cs42l42_map, ARRAY_SIZE(cs42l42_map)); if (ret) { diff --git a/sound/soc/sdw_utils/soc_sdw_cs42l43.c b/sound/soc/sdw_utils/soc_sdw_cs42l43.c index b415d45d520d0c..4c954501e50023 100644 --- a/sound/soc/sdw_utils/soc_sdw_cs42l43.c +++ b/sound/soc/sdw_utils/soc_sdw_cs42l43.c @@ -58,6 +58,7 @@ int asoc_sdw_cs42l43_hs_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc struct asoc_sdw_mc_private *ctx = snd_soc_card_get_drvdata(rtd->card); struct snd_soc_jack *jack = &ctx->sdw_headset; struct snd_soc_card *card = rtd->card; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); int ret; card->components = devm_kasprintf(card->dev, GFP_KERNEL, "%s hs:cs42l43", @@ -65,7 +66,7 @@ int asoc_sdw_cs42l43_hs_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc if (!card->components) return -ENOMEM; - ret = snd_soc_dapm_add_routes(&card->dapm, cs42l43_hs_map, + ret = snd_soc_dapm_add_routes(dapm, cs42l43_hs_map, ARRAY_SIZE(cs42l43_hs_map)); if (ret) { dev_err(card->dev, "cs42l43 hs map addition failed: %d\n", ret); @@ -107,6 +108,7 @@ EXPORT_SYMBOL_NS(asoc_sdw_cs42l43_hs_rtd_init, "SND_SOC_SDW_UTILS"); int asoc_sdw_cs42l43_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai) { struct snd_soc_card *card = rtd->card; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); struct asoc_sdw_mc_private *ctx = snd_soc_card_get_drvdata(card); int ret; @@ -127,7 +129,7 @@ int asoc_sdw_cs42l43_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_so dev_info(card->dev, "Setting CS42L43 Speaker volume limit to %d\n", CS42L43_SPK_VOLUME_0DB); - ret = snd_soc_dapm_add_routes(&card->dapm, cs42l43_spk_map, + ret = snd_soc_dapm_add_routes(dapm, cs42l43_spk_map, ARRAY_SIZE(cs42l43_spk_map)); if (ret) dev_err(card->dev, "cs42l43 speaker map addition failed: %d\n", ret); @@ -154,6 +156,7 @@ EXPORT_SYMBOL_NS(asoc_sdw_cs42l43_spk_init, "SND_SOC_SDW_UTILS"); int asoc_sdw_cs42l43_dmic_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai) { struct snd_soc_card *card = rtd->card; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); int ret; card->components = devm_kasprintf(card->dev, GFP_KERNEL, "%s mic:cs42l43-dmic", @@ -161,7 +164,7 @@ int asoc_sdw_cs42l43_dmic_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_s if (!card->components) return -ENOMEM; - ret = snd_soc_dapm_add_routes(&card->dapm, cs42l43_dmic_map, + ret = snd_soc_dapm_add_routes(dapm, cs42l43_dmic_map, ARRAY_SIZE(cs42l43_dmic_map)); if (ret) dev_err(card->dev, "cs42l43 dmic map addition failed: %d\n", ret); diff --git a/sound/soc/sdw_utils/soc_sdw_cs42l45.c b/sound/soc/sdw_utils/soc_sdw_cs42l45.c new file mode 100644 index 00000000000000..647923d9669fd3 --- /dev/null +++ b/sound/soc/sdw_utils/soc_sdw_cs42l45.c @@ -0,0 +1,80 @@ +// SPDX-License-Identifier: GPL-2.0-only +// Based on sof_sdw_rt5682.c +// This file incorporates work covered by the following copyright notice: +// Copyright (c) 2023 Intel Corporation +// Copyright (c) 2024 Advanced Micro Devices, Inc. + +/* + * soc_sdw_cs42l45 - Helpers to handle CS42L45 from generic machine driver + */ +#include +#include +#include +#include +#include +#include +#include +#include + +static struct snd_soc_jack_pin soc_jack_pins[] = { + { + .pin = "cs42l45 OT 43 Headphone", + .mask = SND_JACK_HEADPHONE, + }, + { + .pin = "cs42l45 OT 45 Headset", + .mask = SND_JACK_HEADPHONE, + }, + { + .pin = "cs42l45 IT 31 Microphone", + .mask = SND_JACK_MICROPHONE, + }, + { + .pin = "cs42l45 IT 33 Headset", + .mask = SND_JACK_MICROPHONE, + }, +}; + +int asoc_sdw_cs42l45_hs_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai) +{ + struct snd_soc_card *card = rtd->card; + struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component; + struct asoc_sdw_mc_private *ctx = snd_soc_card_get_drvdata(card); + struct snd_soc_jack *jack = &ctx->sdw_headset; + int ret; + + card->components = devm_kasprintf(card->dev, GFP_KERNEL, "%s hs:cs42l45", + card->components); + if (!card->components) + return -ENOMEM; + + ret = snd_soc_card_jack_new_pins(card, "Jack", SND_JACK_MECHANICAL | + SND_JACK_HEADSET | SND_JACK_LINEOUT, jack, + soc_jack_pins, ARRAY_SIZE(soc_jack_pins)); + if (ret) { + dev_err(card->dev, "Failed to create jack: %d\n", ret); + return ret; + } + + ret = snd_soc_component_set_jack(component, jack, NULL); + if (ret) { + dev_err(card->dev, "Failed to register jack: %d\n", ret); + return ret; + } + + return 0; +} +EXPORT_SYMBOL_NS(asoc_sdw_cs42l45_hs_rtd_init, "SND_SOC_SDW_UTILS"); + +int asoc_sdw_cs42l45_dmic_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai) +{ + struct snd_soc_card *card = rtd->card; + + card->components = devm_kasprintf(card->dev, GFP_KERNEL, "%s mic:cs42l45-dmic", + card->components); + if (!card->components) + return -ENOMEM; + + return 0; +} +EXPORT_SYMBOL_NS(asoc_sdw_cs42l45_dmic_rtd_init, "SND_SOC_SDW_UTILS"); diff --git a/sound/soc/sdw_utils/soc_sdw_cs_amp.c b/sound/soc/sdw_utils/soc_sdw_cs_amp.c index 520ea36c63eee9..325ab723048172 100644 --- a/sound/soc/sdw_utils/soc_sdw_cs_amp.c +++ b/sound/soc/sdw_utils/soc_sdw_cs_amp.c @@ -38,6 +38,7 @@ EXPORT_SYMBOL_NS(asoc_sdw_cs35l56_volume_limit, "SND_SOC_SDW_UTILS"); int asoc_sdw_cs_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai) { struct snd_soc_card *card = rtd->card; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); char widget_name[16]; struct snd_soc_dapm_route route = { "Speaker", NULL, widget_name }; struct snd_soc_dai *codec_dai; @@ -54,7 +55,7 @@ int asoc_sdw_cs_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai if (ret) return ret; - ret = snd_soc_dapm_add_routes(&card->dapm, &route, 1); + ret = snd_soc_dapm_add_routes(dapm, &route, 1); if (ret) return ret; } diff --git a/sound/soc/sdw_utils/soc_sdw_dmic.c b/sound/soc/sdw_utils/soc_sdw_dmic.c index 0d8fce7234a737..6075cd23545219 100644 --- a/sound/soc/sdw_utils/soc_sdw_dmic.c +++ b/sound/soc/sdw_utils/soc_sdw_dmic.c @@ -24,9 +24,10 @@ static const struct snd_soc_dapm_route dmic_map[] = { int asoc_sdw_dmic_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_card *card = rtd->card; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); int ret; - ret = snd_soc_dapm_new_controls(&card->dapm, dmic_widgets, + ret = snd_soc_dapm_new_controls(dapm, dmic_widgets, ARRAY_SIZE(dmic_widgets)); if (ret) { dev_err(card->dev, "DMic widget addition failed: %d\n", ret); @@ -34,7 +35,7 @@ int asoc_sdw_dmic_init(struct snd_soc_pcm_runtime *rtd) return ret; } - ret = snd_soc_dapm_add_routes(&card->dapm, dmic_map, + ret = snd_soc_dapm_add_routes(dapm, dmic_map, ARRAY_SIZE(dmic_map)); if (ret) diff --git a/sound/soc/sdw_utils/soc_sdw_maxim.c b/sound/soc/sdw_utils/soc_sdw_maxim.c index 8f9d1ed0725bdb..14090b032cb655 100644 --- a/sound/soc/sdw_utils/soc_sdw_maxim.c +++ b/sound/soc/sdw_utils/soc_sdw_maxim.c @@ -26,9 +26,10 @@ static const struct snd_soc_dapm_route max_98373_dapm_routes[] = { int asoc_sdw_maxim_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai) { struct snd_soc_card *card = rtd->card; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); int ret; - ret = snd_soc_dapm_add_routes(&card->dapm, max_98373_dapm_routes, 2); + ret = snd_soc_dapm_add_routes(dapm, max_98373_dapm_routes, 2); if (ret) dev_err(rtd->dev, "failed to add first SPK map: %d\n", ret); @@ -50,8 +51,7 @@ static int asoc_sdw_mx8373_enable_spk_pin(struct snd_pcm_substream *substream, b cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); for_each_rtd_codec_dais(rtd, j, codec_dai) { - struct snd_soc_dapm_context *dapm = - snd_soc_component_get_dapm(cpu_dai->component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(cpu_dai->component); char pin_name[16]; snprintf(pin_name, ARRAY_SIZE(pin_name), "%s Spk", @@ -104,7 +104,7 @@ static const struct snd_soc_ops max_98373_sdw_ops = { static int asoc_sdw_mx8373_sdw_late_probe(struct snd_soc_card *card) { - struct snd_soc_dapm_context *dapm = &card->dapm; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); /* Disable Left and Right Spk pin after boot */ snd_soc_dapm_disable_pin(dapm, "Left Spk"); diff --git a/sound/soc/sdw_utils/soc_sdw_rt5682.c b/sound/soc/sdw_utils/soc_sdw_rt5682.c index 8c86254cbaf640..641362835b4eb6 100644 --- a/sound/soc/sdw_utils/soc_sdw_rt5682.c +++ b/sound/soc/sdw_utils/soc_sdw_rt5682.c @@ -40,6 +40,7 @@ static struct snd_soc_jack_pin rt5682_jack_pins[] = { int asoc_sdw_rt5682_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai) { struct snd_soc_card *card = rtd->card; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); struct asoc_sdw_mc_private *ctx = snd_soc_card_get_drvdata(card); struct snd_soc_component *component; struct snd_soc_jack *jack; @@ -52,7 +53,7 @@ int asoc_sdw_rt5682_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai if (!card->components) return -ENOMEM; - ret = snd_soc_dapm_add_routes(&card->dapm, rt5682_map, + ret = snd_soc_dapm_add_routes(dapm, rt5682_map, ARRAY_SIZE(rt5682_map)); if (ret) { diff --git a/sound/soc/sdw_utils/soc_sdw_rt700.c b/sound/soc/sdw_utils/soc_sdw_rt700.c index e6468e4ac6e726..ffedfde955d03c 100644 --- a/sound/soc/sdw_utils/soc_sdw_rt700.c +++ b/sound/soc/sdw_utils/soc_sdw_rt700.c @@ -38,6 +38,7 @@ static struct snd_soc_jack_pin rt700_jack_pins[] = { int asoc_sdw_rt700_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai) { struct snd_soc_card *card = rtd->card; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); struct asoc_sdw_mc_private *ctx = snd_soc_card_get_drvdata(card); struct snd_soc_component *component; struct snd_soc_jack *jack; @@ -50,7 +51,7 @@ int asoc_sdw_rt700_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai if (!card->components) return -ENOMEM; - ret = snd_soc_dapm_add_routes(&card->dapm, rt700_map, + ret = snd_soc_dapm_add_routes(dapm, rt700_map, ARRAY_SIZE(rt700_map)); if (ret) { diff --git a/sound/soc/sdw_utils/soc_sdw_rt711.c b/sound/soc/sdw_utils/soc_sdw_rt711.c index 4aa93fdefef63a..3a3a66b4b7372f 100644 --- a/sound/soc/sdw_utils/soc_sdw_rt711.c +++ b/sound/soc/sdw_utils/soc_sdw_rt711.c @@ -64,6 +64,7 @@ static struct snd_soc_jack_pin rt711_jack_pins[] = { int asoc_sdw_rt711_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai) { struct snd_soc_card *card = rtd->card; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); struct asoc_sdw_mc_private *ctx = snd_soc_card_get_drvdata(card); struct snd_soc_component *component; struct snd_soc_jack *jack; @@ -76,7 +77,7 @@ int asoc_sdw_rt711_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai if (!card->components) return -ENOMEM; - ret = snd_soc_dapm_add_routes(&card->dapm, rt711_map, + ret = snd_soc_dapm_add_routes(dapm, rt711_map, ARRAY_SIZE(rt711_map)); if (ret) { diff --git a/sound/soc/sdw_utils/soc_sdw_rt_amp.c b/sound/soc/sdw_utils/soc_sdw_rt_amp.c index 76ee24b8eee4a2..4e9b08cb653d14 100644 --- a/sound/soc/sdw_utils/soc_sdw_rt_amp.c +++ b/sound/soc/sdw_utils/soc_sdw_rt_amp.c @@ -187,6 +187,7 @@ static const struct snd_soc_dapm_route *get_codec_name_and_route(struct snd_soc_ int asoc_sdw_rt_amp_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai) { struct snd_soc_card *card = rtd->card; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); const struct snd_soc_dapm_route *rt_amp_map; char codec_name[CODEC_NAME_SIZE]; struct snd_soc_dai *codec_dai; @@ -197,9 +198,9 @@ int asoc_sdw_rt_amp_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc for_each_rtd_codec_dais(rtd, i, codec_dai) { if (strstr(codec_dai->component->name_prefix, "-1")) - ret = snd_soc_dapm_add_routes(&card->dapm, rt_amp_map, 2); + ret = snd_soc_dapm_add_routes(dapm, rt_amp_map, 2); else if (strstr(codec_dai->component->name_prefix, "-2")) - ret = snd_soc_dapm_add_routes(&card->dapm, rt_amp_map + 2, 2); + ret = snd_soc_dapm_add_routes(dapm, rt_amp_map + 2, 2); } return ret; diff --git a/sound/soc/sdw_utils/soc_sdw_rt_mf_sdca.c b/sound/soc/sdw_utils/soc_sdw_rt_mf_sdca.c index 224b58de908491..5bf3627a97a00d 100644 --- a/sound/soc/sdw_utils/soc_sdw_rt_mf_sdca.c +++ b/sound/soc/sdw_utils/soc_sdw_rt_mf_sdca.c @@ -59,6 +59,7 @@ static const struct codec_route_map *get_codec_route_map(const char *codec_name) int asoc_sdw_rt_mf_sdca_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai) { struct snd_soc_card *card = rtd->card; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); char codec_name[CODEC_NAME_SIZE]; int ret; @@ -74,7 +75,7 @@ int asoc_sdw_rt_mf_sdca_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd } /* Add routes */ - ret = snd_soc_dapm_add_routes(&card->dapm, route_map->route_map, route_map->route_size); + ret = snd_soc_dapm_add_routes(dapm, route_map->route_map, route_map->route_size); if (ret) dev_err(rtd->dev, "failed to add rt sdca spk map: %d\n", ret); diff --git a/sound/soc/sdw_utils/soc_sdw_rt_sdca_jack_common.c b/sound/soc/sdw_utils/soc_sdw_rt_sdca_jack_common.c index 6279faf6edd488..2547b5b3fdd795 100644 --- a/sound/soc/sdw_utils/soc_sdw_rt_sdca_jack_common.c +++ b/sound/soc/sdw_utils/soc_sdw_rt_sdca_jack_common.c @@ -93,6 +93,7 @@ static const char * const need_sdca_suffix[] = { int asoc_sdw_rt_sdca_jack_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai) { struct snd_soc_card *card = rtd->card; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); struct asoc_sdw_mc_private *ctx = snd_soc_card_get_drvdata(card); struct snd_soc_component *component; struct snd_soc_jack *jack; @@ -118,19 +119,19 @@ int asoc_sdw_rt_sdca_jack_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_s } if (strstr(component->name_prefix, "rt711")) { - ret = snd_soc_dapm_add_routes(&card->dapm, rt711_sdca_map, + ret = snd_soc_dapm_add_routes(dapm, rt711_sdca_map, ARRAY_SIZE(rt711_sdca_map)); } else if (strstr(component->name_prefix, "rt712")) { - ret = snd_soc_dapm_add_routes(&card->dapm, rt712_sdca_map, + ret = snd_soc_dapm_add_routes(dapm, rt712_sdca_map, ARRAY_SIZE(rt712_sdca_map)); } else if (strstr(component->name_prefix, "rt713")) { - ret = snd_soc_dapm_add_routes(&card->dapm, rt713_sdca_map, + ret = snd_soc_dapm_add_routes(dapm, rt713_sdca_map, ARRAY_SIZE(rt713_sdca_map)); } else if (strstr(component->name_prefix, "rt721")) { - ret = snd_soc_dapm_add_routes(&card->dapm, rt721_sdca_map, + ret = snd_soc_dapm_add_routes(dapm, rt721_sdca_map, ARRAY_SIZE(rt721_sdca_map)); } else if (strstr(component->name_prefix, "rt722")) { - ret = snd_soc_dapm_add_routes(&card->dapm, rt722_sdca_map, + ret = snd_soc_dapm_add_routes(dapm, rt722_sdca_map, ARRAY_SIZE(rt722_sdca_map)); } else { dev_err(card->dev, "%s is not supported\n", component->name_prefix); diff --git a/sound/soc/sdw_utils/soc_sdw_ti_amp.c b/sound/soc/sdw_utils/soc_sdw_ti_amp.c index f0011360ae9b6c..cbd60faecd0981 100644 --- a/sound/soc/sdw_utils/soc_sdw_ti_amp.c +++ b/sound/soc/sdw_utils/soc_sdw_ti_amp.c @@ -41,6 +41,7 @@ int asoc_sdw_ti_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai) { struct snd_soc_card *card = rtd->card; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); char widget_name[16]; char speaker[16]; struct snd_soc_dapm_route route = {speaker, NULL, widget_name}; @@ -68,7 +69,7 @@ int asoc_sdw_ti_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, if (ret) return ret; - ret = snd_soc_dapm_add_routes(&card->dapm, &route, 1); + ret = snd_soc_dapm_add_routes(dapm, &route, 1); if (ret) return ret; } diff --git a/sound/soc/sdw_utils/soc_sdw_utils.c b/sound/soc/sdw_utils/soc_sdw_utils.c index d79e6d1dc06459..6c656b2f7f3ae5 100644 --- a/sound/soc/sdw_utils/soc_sdw_utils.c +++ b/sound/soc/sdw_utils/soc_sdw_utils.c @@ -656,12 +656,12 @@ struct asoc_sdw_codec_info codec_info_list[] = { { .part_id = 0x4243, .name_prefix = "cs42l43", - .codec_name = "cs42l43-codec", .count_sidecar = asoc_sdw_bridge_cs35l56_count_sidecar, .add_sidecar = asoc_sdw_bridge_cs35l56_add_sidecar, .dais = { { .direction = {true, false}, + .codec_name = "cs42l43-codec", .dai_name = "cs42l43-dp5", .dai_type = SOC_SDW_DAI_TYPE_JACK, .dailink = {SOC_SDW_JACK_OUT_DAI_ID, SOC_SDW_UNUSED_DAI_ID}, @@ -673,6 +673,7 @@ struct asoc_sdw_codec_info codec_info_list[] = { }, { .direction = {false, true}, + .codec_name = "cs42l43-codec", .dai_name = "cs42l43-dp1", .dai_type = SOC_SDW_DAI_TYPE_MIC, .dailink = {SOC_SDW_UNUSED_DAI_ID, SOC_SDW_DMIC_DAI_ID}, @@ -684,12 +685,14 @@ struct asoc_sdw_codec_info codec_info_list[] = { }, { .direction = {false, true}, + .codec_name = "cs42l43-codec", .dai_name = "cs42l43-dp2", .dai_type = SOC_SDW_DAI_TYPE_JACK, .dailink = {SOC_SDW_UNUSED_DAI_ID, SOC_SDW_JACK_IN_DAI_ID}, }, { .direction = {true, false}, + .codec_name = "cs42l43-codec", .dai_name = "cs42l43-dp6", .dai_type = SOC_SDW_DAI_TYPE_AMP, .dailink = {SOC_SDW_AMP_OUT_DAI_ID, SOC_SDW_UNUSED_DAI_ID}, @@ -704,6 +707,42 @@ struct asoc_sdw_codec_info codec_info_list[] = { }, .dai_num = 4, }, + { + .part_id = 0x4245, + .name_prefix = "cs42l45", + .dais = { + { + .direction = {true, false}, + .codec_name = "snd_soc_sdca.UAJ.1", + .dai_name = "IT 41", + .dai_type = SOC_SDW_DAI_TYPE_JACK, + .dailink = {SOC_SDW_JACK_OUT_DAI_ID, SOC_SDW_UNUSED_DAI_ID}, + .rtd_init = asoc_sdw_cs42l45_hs_rtd_init, + }, + { + .direction = {false, true}, + .codec_name = "snd_soc_sdca.SmartMic.0", + .dai_name = "OT 113", + .dai_type = SOC_SDW_DAI_TYPE_MIC, + .dailink = {SOC_SDW_UNUSED_DAI_ID, SOC_SDW_DMIC_DAI_ID}, + .rtd_init = asoc_sdw_cs42l45_dmic_rtd_init, + }, + { + .direction = {false, true}, + .codec_name = "snd_soc_sdca.UAJ.1", + .dai_name = "OT 36", + .dai_type = SOC_SDW_DAI_TYPE_JACK, + .dailink = {SOC_SDW_UNUSED_DAI_ID, SOC_SDW_JACK_IN_DAI_ID}, + }, + }, + .dai_num = 3, + .auxs = { + { + .codec_name = "snd_soc_sdca.HID.2", + }, + }, + .aux_num = 1, + }, { .part_id = 0xaaaa, /* generic codec mockup */ .name_prefix = "sdw_mockup_mmulti-function", @@ -837,6 +876,7 @@ EXPORT_SYMBOL_NS(asoc_sdw_find_codec_info_dai, "SND_SOC_SDW_UTILS"); int asoc_sdw_rtd_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_card *card = rtd->card; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); struct asoc_sdw_codec_info *codec_info; struct snd_soc_dai *dai; const char *spk_components=""; @@ -876,7 +916,7 @@ int asoc_sdw_rtd_init(struct snd_soc_pcm_runtime *rtd) } } if (codec_info->dais[dai_index].widgets) { - ret = snd_soc_dapm_new_controls(&card->dapm, + ret = snd_soc_dapm_new_controls(dapm, codec_info->dais[dai_index].widgets, codec_info->dais[dai_index].num_widgets); if (ret) { @@ -1093,7 +1133,6 @@ static bool asoc_sdw_is_unique_device(const struct snd_soc_acpi_link_adr *adr_li } static const char *_asoc_sdw_get_codec_name(struct device *dev, - const struct asoc_sdw_codec_info *codec_info, const struct snd_soc_acpi_link_adr *adr_link, int adr_index) { @@ -1115,14 +1154,14 @@ static const char *_asoc_sdw_get_codec_name(struct device *dev, } const char *asoc_sdw_get_codec_name(struct device *dev, - const struct asoc_sdw_codec_info *codec_info, + const struct asoc_sdw_dai_info *dai_info, const struct snd_soc_acpi_link_adr *adr_link, int adr_index) { - if (codec_info->codec_name) - return devm_kstrdup(dev, codec_info->codec_name, GFP_KERNEL); + if (dai_info->codec_name) + return devm_kstrdup(dev, dai_info->codec_name, GFP_KERNEL); - return _asoc_sdw_get_codec_name(dev, codec_info, adr_link, adr_index); + return _asoc_sdw_get_codec_name(dev, adr_link, adr_index); } EXPORT_SYMBOL_NS(asoc_sdw_get_codec_name, "SND_SOC_SDW_UTILS"); @@ -1249,7 +1288,8 @@ int asoc_sdw_init_simple_dai_link(struct device *dev, struct snd_soc_dai_link *d } EXPORT_SYMBOL_NS(asoc_sdw_init_simple_dai_link, "SND_SOC_SDW_UTILS"); -int asoc_sdw_count_sdw_endpoints(struct snd_soc_card *card, int *num_devs, int *num_ends) +int asoc_sdw_count_sdw_endpoints(struct snd_soc_card *card, + int *num_devs, int *num_ends, int *num_aux) { struct device *dev = card->dev; struct snd_soc_acpi_mach *mach = dev_get_platdata(dev); @@ -1260,8 +1300,18 @@ int asoc_sdw_count_sdw_endpoints(struct snd_soc_card *card, int *num_devs, int * for (adr_link = mach_params->links; adr_link->num_adr; adr_link++) { *num_devs += adr_link->num_adr; - for (i = 0; i < adr_link->num_adr; i++) - *num_ends += adr_link->adr_d[i].num_endpoints; + for (i = 0; i < adr_link->num_adr; i++) { + const struct snd_soc_acpi_adr_device *adr_dev = &adr_link->adr_d[i]; + struct asoc_sdw_codec_info *codec_info; + + *num_ends += adr_dev->num_endpoints; + + codec_info = asoc_sdw_find_codec_info_part(adr_dev->adr); + if (!codec_info) + return -EINVAL; + + *num_aux += codec_info->aux_num; + } } dev_dbg(dev, "Found %d devices with %d endpoints\n", *num_devs, *num_ends); @@ -1353,8 +1403,7 @@ static int is_sdca_endpoint_present(struct device *dev, } kfree(dlc); - sdw_codec_name = _asoc_sdw_get_codec_name(dev, codec_info, - adr_link, adr_index); + sdw_codec_name = _asoc_sdw_get_codec_name(dev, adr_link, adr_index); if (!sdw_codec_name) return -ENOMEM; @@ -1400,6 +1449,7 @@ static int is_sdca_endpoint_present(struct device *dev, } int asoc_sdw_parse_sdw_endpoints(struct snd_soc_card *card, + struct snd_soc_aux_dev *soc_aux, struct asoc_sdw_dailink *soc_dais, struct asoc_sdw_endpoint *soc_ends, int *num_devs) @@ -1439,16 +1489,12 @@ int asoc_sdw_parse_sdw_endpoints(struct snd_soc_card *card, if (!codec_info) return -EINVAL; - ctx->ignore_internal_dmic |= codec_info->ignore_internal_dmic; - - codec_name = asoc_sdw_get_codec_name(dev, codec_info, adr_link, i); - if (!codec_name) - return -ENOMEM; - - dev_dbg(dev, "Adding prefix %s for %s\n", - adr_dev->name_prefix, codec_name); + for (j = 0; j < codec_info->aux_num; j++) { + soc_aux->dlc.name = codec_info->auxs[j].codec_name; + soc_aux++; + } - soc_end->name_prefix = adr_dev->name_prefix; + ctx->ignore_internal_dmic |= codec_info->ignore_internal_dmic; if (codec_info->count_sidecar && codec_info->add_sidecar) { ret = codec_info->count_sidecar(card, &num_dais, num_devs); @@ -1537,6 +1583,16 @@ int asoc_sdw_parse_sdw_endpoints(struct snd_soc_card *card, num_link_dailinks += !!list_empty(&soc_dai->endpoints); list_add_tail(&soc_end->list, &soc_dai->endpoints); + codec_name = asoc_sdw_get_codec_name(dev, dai_info, + adr_link, i); + if (!codec_name) + return -ENOMEM; + + dev_dbg(dev, "Adding prefix %s for %s\n", + adr_dev->name_prefix, codec_name); + + soc_end->name_prefix = adr_dev->name_prefix; + soc_end->link_mask = adr_link->mask; soc_end->codec_name = codec_name; soc_end->codec_info = codec_info; diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 9f323bfafbe836..096048faf335c2 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -151,7 +151,7 @@ static void soc_init_component_debugfs(struct snd_soc_component *component) component->card->debugfs_card_root); } - snd_soc_dapm_debugfs_init(snd_soc_component_get_dapm(component), + snd_soc_dapm_debugfs_init(snd_soc_component_to_dapm(component), component->debugfs_root); } @@ -203,7 +203,7 @@ static void soc_init_card_debugfs(struct snd_soc_card *card) debugfs_create_u32("dapm_pop_time", 0644, card->debugfs_card_root, &card->pop_time); - snd_soc_dapm_debugfs_init(&card->dapm, card->debugfs_card_root); + snd_soc_dapm_debugfs_init(snd_soc_card_to_dapm(card), card->debugfs_card_root); } static void soc_cleanup_card_debugfs(struct snd_soc_card *card) @@ -545,6 +545,11 @@ static struct snd_soc_pcm_runtime *soc_new_pcm_runtime( dev_set_drvdata(dev, rtd); INIT_DELAYED_WORK(&rtd->delayed_work, close_delayed_work); + if ((dai_link->num_cpus + dai_link->num_codecs) == 0) { + dev_err(dev, "ASoC: it has no CPU or codec DAIs\n"); + goto free_rtd; + } + /* * for rtd->dais */ @@ -687,7 +692,7 @@ int snd_soc_suspend(struct device *dev) /* Recheck all endpoints too, their state is affected by suspend */ snd_soc_dapm_mark_endpoints_dirty(card); - snd_soc_dapm_sync(&card->dapm); + snd_soc_dapm_sync(snd_soc_card_to_dapm(card)); /* suspend all COMPONENTs */ for_each_card_rtds(card, rtd) { @@ -696,8 +701,7 @@ int snd_soc_suspend(struct device *dev) continue; for_each_rtd_components(rtd, i, component) { - struct snd_soc_dapm_context *dapm = - snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); /* * ignore if component was already suspended @@ -717,7 +721,7 @@ int snd_soc_suspend(struct device *dev) * means it's doing something, * otherwise fall through. */ - if (!dapm->idle_bias) { + if (!snd_soc_dapm_get_idle_bias(dapm)) { dev_dbg(component->dev, "ASoC: idle_bias_off CODEC on over suspend\n"); break; @@ -784,7 +788,7 @@ static void soc_resume_deferred(struct work_struct *work) /* Recheck all endpoints too, their state is affected by suspend */ snd_soc_dapm_mark_endpoints_dirty(card); - snd_soc_dapm_sync(&card->dapm); + snd_soc_dapm_sync(snd_soc_card_to_dapm(card)); /* userspace can access us now we are back as we were before */ snd_power_change_state(card->snd_card, SNDRV_CTL_POWER_D0); @@ -1590,7 +1594,7 @@ static void soc_remove_component(struct snd_soc_component *component, snd_soc_component_remove(component); list_del_init(&component->card_list); - snd_soc_dapm_free(snd_soc_component_get_dapm(component)); + snd_soc_dapm_free(snd_soc_component_to_dapm(component)); soc_cleanup_component_debugfs(component); component->card = NULL; snd_soc_component_module_put_when_remove(component); @@ -1599,8 +1603,7 @@ static void soc_remove_component(struct snd_soc_component *component, static int soc_probe_component(struct snd_soc_card *card, struct snd_soc_component *component) { - struct snd_soc_dapm_context *dapm = - snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct snd_soc_dai *dai; int probed = 0; int ret; @@ -1652,8 +1655,8 @@ static int soc_probe_component(struct snd_soc_card *card, if (ret < 0) goto err_probe; - WARN(!dapm->idle_bias && - dapm->bias_level != SND_SOC_BIAS_OFF, + WARN(!snd_soc_dapm_get_idle_bias(dapm) && + snd_soc_dapm_get_bias_level(dapm) != SND_SOC_BIAS_OFF, "codec %s can not start from non-off bias with idle_bias_off==1\n", component->name); probed = 1; @@ -2121,7 +2124,7 @@ static void soc_cleanup_card_resources(struct snd_soc_card *card) soc_remove_aux_devices(card); soc_unbind_aux_dev(card); - snd_soc_dapm_free(&card->dapm); + snd_soc_dapm_free(snd_soc_card_to_dapm(card)); soc_cleanup_card_debugfs(card); /* remove the card */ @@ -2147,12 +2150,13 @@ static int snd_soc_bind_card(struct snd_soc_card *card) { struct snd_soc_pcm_runtime *rtd; struct snd_soc_component *component; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); int ret; snd_soc_card_mutex_lock_root(card); snd_soc_fill_dummy_dai(card); - snd_soc_dapm_init(&card->dapm, card, NULL); + snd_soc_dapm_init(dapm, card, NULL); /* check whether any platform is ignore machine FE and using topology */ soc_check_tplg_fes(card); @@ -2182,12 +2186,12 @@ static int snd_soc_bind_card(struct snd_soc_card *card) soc_resume_init(card); - ret = snd_soc_dapm_new_controls(&card->dapm, card->dapm_widgets, + ret = snd_soc_dapm_new_controls(dapm, card->dapm_widgets, card->num_dapm_widgets); if (ret < 0) goto probe_end; - ret = snd_soc_dapm_new_controls(&card->dapm, card->of_dapm_widgets, + ret = snd_soc_dapm_new_controls(dapm, card->of_dapm_widgets, card->num_of_dapm_widgets); if (ret < 0) goto probe_end; @@ -2237,12 +2241,12 @@ static int snd_soc_bind_card(struct snd_soc_card *card) if (ret < 0) goto probe_end; - ret = snd_soc_dapm_add_routes(&card->dapm, card->dapm_routes, + ret = snd_soc_dapm_add_routes(dapm, card->dapm_routes, card->num_dapm_routes); if (ret < 0) goto probe_end; - ret = snd_soc_dapm_add_routes(&card->dapm, card->of_dapm_routes, + ret = snd_soc_dapm_add_routes(dapm, card->of_dapm_routes, card->num_of_dapm_routes); if (ret < 0) goto probe_end; @@ -2286,7 +2290,7 @@ static int snd_soc_bind_card(struct snd_soc_card *card) card->instantiated = 1; snd_soc_dapm_mark_endpoints_dirty(card); - snd_soc_dapm_sync(&card->dapm); + snd_soc_dapm_sync(dapm); /* deactivate pins to sleep state */ for_each_card_components(card, component) diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 51fb09d56c5a17..4d920a59da3c49 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -193,10 +193,12 @@ static bool dapm_dirty_widget(struct snd_soc_dapm_widget *w) static void dapm_mark_dirty(struct snd_soc_dapm_widget *w, const char *reason) { + struct device *dev = snd_soc_dapm_to_dev(w->dapm); + dapm_assert_locked(w->dapm); if (!dapm_dirty_widget(w)) { - dev_vdbg(w->dapm->dev, "Marking %s dirty due to %s\n", + dev_vdbg(dev, "Marking %s dirty due to %s\n", w->name, reason); list_add_tail(&w->dirty, &w->dapm->card->dapm_dirty); } @@ -532,6 +534,7 @@ static int snd_soc_dapm_check_dynamic_path( struct snd_soc_dapm_widget *source, struct snd_soc_dapm_widget *sink, const char *control) { + struct device *dev = snd_soc_dapm_to_dev(dapm); bool dynamic_source = false; bool dynamic_sink = false; @@ -558,12 +561,12 @@ static int snd_soc_dapm_check_dynamic_path( } if (dynamic_source && dynamic_sink) { - dev_err(dapm->dev, + dev_err(dev, "Direct connection between demux and mixer/mux not supported for path %s -> [%s] -> %s\n", source->name, control, sink->name); return -EINVAL; } else if (!dynamic_source && !dynamic_sink) { - dev_err(dapm->dev, + dev_err(dev, "Control not supported for path %s -> [%s] -> %s\n", source->name, control, sink->name); return -EINVAL; @@ -579,26 +582,27 @@ static int snd_soc_dapm_add_path( int (*connected)(struct snd_soc_dapm_widget *source, struct snd_soc_dapm_widget *sink)) { + struct device *dev = snd_soc_dapm_to_dev(dapm); enum snd_soc_dapm_direction dir; struct snd_soc_dapm_path *path; int ret; if (wsink->is_supply && !wsource->is_supply) { - dev_err(dapm->dev, + dev_err(dev, "Connecting non-supply widget to supply widget is not supported (%s -> %s)\n", wsource->name, wsink->name); return -EINVAL; } if (connected && !wsource->is_supply) { - dev_err(dapm->dev, + dev_err(dev, "connected() callback only supported for supply widgets (%s -> %s)\n", wsource->name, wsink->name); return -EINVAL; } if (wsource->is_supply && control) { - dev_err(dapm->dev, + dev_err(dev, "Conditional paths are not supported for supply widgets (%s -> [%s] -> %s)\n", wsource->name, control, wsink->name); return -EINVAL; @@ -676,6 +680,7 @@ static int snd_soc_dapm_add_path( static int dapm_kcontrol_data_alloc(struct snd_soc_dapm_widget *widget, struct snd_kcontrol *kcontrol, const char *ctrl_name) { + struct device *dev = snd_soc_dapm_to_dev(widget->dapm); struct dapm_kcontrol_data *data; struct soc_mixer_control *mc; struct soc_enum *e; @@ -698,7 +703,7 @@ static int dapm_kcontrol_data_alloc(struct snd_soc_dapm_widget *widget, struct snd_soc_dapm_widget template; if (snd_soc_volsw_is_stereo(mc)) - dev_warn(widget->dapm->dev, + dev_warn(dev, "ASoC: Unsupported stereo autodisable control '%s'\n", ctrl_name); @@ -1133,6 +1138,7 @@ static int dapm_create_or_share_kcontrol(struct snd_soc_dapm_widget *w, int kci) { struct snd_soc_dapm_context *dapm = w->dapm; + struct device *dev = snd_soc_dapm_to_dev(dapm); struct snd_card *card = dapm->card->snd_card; const char *prefix; size_t prefix_len; @@ -1221,7 +1227,7 @@ static int dapm_create_or_share_kcontrol(struct snd_soc_dapm_widget *w, ret = snd_ctl_add(card, kcontrol); if (ret < 0) { - dev_err(dapm->dev, + dev_err(dev, "ASoC: failed to add widget %s dapm kcontrol %s: %d\n", w->name, name, ret); goto exit_free; @@ -1277,6 +1283,7 @@ static int dapm_new_mixer(struct snd_soc_dapm_widget *w) static int dapm_new_mux(struct snd_soc_dapm_widget *w) { struct snd_soc_dapm_context *dapm = w->dapm; + struct device *dev = snd_soc_dapm_to_dev(dapm); enum snd_soc_dapm_direction dir; struct snd_soc_dapm_path *path; const char *type; @@ -1296,14 +1303,14 @@ static int dapm_new_mux(struct snd_soc_dapm_widget *w) } if (w->num_kcontrols != 1) { - dev_err(dapm->dev, + dev_err(dev, "ASoC: %s %s has incorrect number of controls\n", type, w->name); return -EINVAL; } if (list_empty(&w->edges[dir])) { - dev_err(dapm->dev, "ASoC: %s %s has no paths\n", type, w->name); + dev_err(dev, "ASoC: %s %s has no paths\n", type, w->name); return -EINVAL; } @@ -1346,13 +1353,14 @@ static int dapm_new_dai_link(struct snd_soc_dapm_widget *w) /* add kcontrol */ for (i = 0; i < w->num_kcontrols; i++) { struct snd_soc_dapm_context *dapm = w->dapm; + struct device *dev = snd_soc_dapm_to_dev(dapm); struct snd_card *card = dapm->card->snd_card; struct snd_kcontrol *kcontrol = snd_soc_cnew(&w->kcontrol_news[i], w, w->name, NULL); int ret = snd_ctl_add(card, kcontrol); if (ret < 0) { - dev_err(dapm->dev, + dev_err(dev, "ASoC: failed to add widget %s dapm kcontrol %s: %d\n", w->name, w->kcontrol_news[i].name, ret); return ret; @@ -1370,13 +1378,14 @@ static int dapm_new_dai_link(struct snd_soc_dapm_widget *w) */ static int snd_soc_dapm_suspend_check(struct snd_soc_dapm_widget *widget) { + struct device *dev = snd_soc_dapm_to_dev(widget->dapm); int level = snd_power_get_state(widget->dapm->card->snd_card); switch (level) { case SNDRV_CTL_POWER_D3hot: case SNDRV_CTL_POWER_D3cold: if (widget->ignore_suspend) - dev_dbg(widget->dapm->dev, "ASoC: %s ignoring suspend\n", + dev_dbg(dev, "ASoC: %s ignoring suspend\n", widget->name); return widget->ignore_suspend; default: @@ -1607,6 +1616,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_dai_free_widgets); int snd_soc_dapm_regulator_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { + struct device *dev = snd_soc_dapm_to_dev(w->dapm); int ret; soc_dapm_async_complete(w->dapm); @@ -1615,7 +1625,7 @@ int snd_soc_dapm_regulator_event(struct snd_soc_dapm_widget *w, if (w->on_val & SND_SOC_DAPM_REGULATOR_BYPASS) { ret = regulator_allow_bypass(w->regulator, false); if (ret != 0) - dev_warn(w->dapm->dev, + dev_warn(dev, "ASoC: Failed to unbypass %s: %d\n", w->name, ret); } @@ -1625,7 +1635,7 @@ int snd_soc_dapm_regulator_event(struct snd_soc_dapm_widget *w, if (w->on_val & SND_SOC_DAPM_REGULATOR_BYPASS) { ret = regulator_allow_bypass(w->regulator, true); if (ret != 0) - dev_warn(w->dapm->dev, + dev_warn(dev, "ASoC: Failed to bypass %s: %d\n", w->name, ret); } @@ -1788,6 +1798,7 @@ static void dapm_seq_insert(struct snd_soc_dapm_widget *new_widget, static void dapm_seq_check_event(struct snd_soc_card *card, struct snd_soc_dapm_widget *w, int event) { + struct device *dev = card->dev; const char *ev_name; int power; @@ -1827,14 +1838,14 @@ static void dapm_seq_check_event(struct snd_soc_card *card, if (w->event && (w->event_flags & event)) { int ret; - pop_dbg(w->dapm->dev, card->pop_time, "pop test : %s %s\n", + pop_dbg(dev, card->pop_time, "pop test : %s %s\n", w->name, ev_name); soc_dapm_async_complete(w->dapm); trace_snd_soc_dapm_widget_event_start(w, event); ret = w->event(w, NULL, event); trace_snd_soc_dapm_widget_event_done(w, event); if (ret < 0) - dev_err(w->dapm->dev, "ASoC: %s: %s event failed: %d\n", + dev_err(dev, "ASoC: %s: %s event failed: %d\n", ev_name, w->name, ret); } } @@ -1843,6 +1854,7 @@ static void dapm_seq_check_event(struct snd_soc_card *card, static void dapm_seq_run_coalesced(struct snd_soc_card *card, struct list_head *pending) { + struct device *dev = card->dev; struct snd_soc_dapm_context *dapm; struct snd_soc_dapm_widget *w; int reg; @@ -1863,7 +1875,7 @@ static void dapm_seq_run_coalesced(struct snd_soc_card *card, else value |= w->off_val << w->shift; - pop_dbg(dapm->dev, card->pop_time, + pop_dbg(dev, card->pop_time, "pop test : Queue %s: reg=0x%x, 0x%x/0x%x\n", w->name, reg, value, mask); @@ -1877,7 +1889,7 @@ static void dapm_seq_run_coalesced(struct snd_soc_card *card, * same register. */ - pop_dbg(dapm->dev, card->pop_time, + pop_dbg(dev, card->pop_time, "pop test : Applying 0x%x/0x%x to %x in %dms\n", value, mask, reg, card->pop_time); pop_wait(card->pop_time); @@ -1901,6 +1913,7 @@ static void dapm_seq_run_coalesced(struct snd_soc_card *card, static void dapm_seq_run(struct snd_soc_card *card, struct list_head *list, int event, bool power_up) { + struct device *dev = card->dev; struct snd_soc_dapm_widget *w, *n; struct snd_soc_dapm_context *d; LIST_HEAD(pending); @@ -1979,7 +1992,7 @@ static void dapm_seq_run(struct snd_soc_card *card, } if (ret < 0) - dev_err(w->dapm->dev, + dev_err(dev, "ASoC: Failed to apply widget power: %d\n", ret); } @@ -2000,6 +2013,7 @@ static void dapm_seq_run(struct snd_soc_card *card, static void dapm_widget_update(struct snd_soc_card *card, struct snd_soc_dapm_update *update) { + struct device *dev = card->dev; struct snd_soc_dapm_widget_list *wlist; struct snd_soc_dapm_widget *w = NULL; unsigned int wi; @@ -2014,7 +2028,7 @@ static void dapm_widget_update(struct snd_soc_card *card, struct snd_soc_dapm_up if (w->event && (w->event_flags & SND_SOC_DAPM_PRE_REG)) { ret = w->event(w, update->kcontrol, SND_SOC_DAPM_PRE_REG); if (ret != 0) - dev_err(w->dapm->dev, "ASoC: %s DAPM pre-event failed: %d\n", + dev_err(dev, "ASoC: %s DAPM pre-event failed: %d\n", w->name, ret); } } @@ -2025,14 +2039,14 @@ static void dapm_widget_update(struct snd_soc_card *card, struct snd_soc_dapm_up ret = soc_dapm_update_bits(w->dapm, update->reg, update->mask, update->val); if (ret < 0) - dev_err(w->dapm->dev, "ASoC: %s DAPM update failed: %d\n", + dev_err(dev, "ASoC: %s DAPM update failed: %d\n", w->name, ret); if (update->has_second_set) { ret = soc_dapm_update_bits(w->dapm, update->reg2, update->mask2, update->val2); if (ret < 0) - dev_err(w->dapm->dev, + dev_err(dev, "ASoC: %s DAPM update failed: %d\n", w->name, ret); } @@ -2041,7 +2055,7 @@ static void dapm_widget_update(struct snd_soc_card *card, struct snd_soc_dapm_up if (w->event && (w->event_flags & SND_SOC_DAPM_POST_REG)) { ret = w->event(w, update->kcontrol, SND_SOC_DAPM_POST_REG); if (ret != 0) - dev_err(w->dapm->dev, "ASoC: %s DAPM post-event failed: %d\n", + dev_err(dev, "ASoC: %s DAPM post-event failed: %d\n", w->name, ret); } } @@ -2053,17 +2067,18 @@ static void dapm_widget_update(struct snd_soc_card *card, struct snd_soc_dapm_up static void dapm_pre_sequence_async(void *data, async_cookie_t cookie) { struct snd_soc_dapm_context *dapm = data; + struct device *dev = snd_soc_dapm_to_dev(dapm); int ret; /* If we're off and we're not supposed to go into STANDBY */ if (dapm->bias_level == SND_SOC_BIAS_OFF && dapm->target_bias_level != SND_SOC_BIAS_OFF) { - if (dapm->dev && cookie) - pm_runtime_get_sync(dapm->dev); + if (dev && cookie) + pm_runtime_get_sync(dev); ret = snd_soc_dapm_set_bias_level(dapm, SND_SOC_BIAS_STANDBY); if (ret != 0) - dev_err(dapm->dev, + dev_err(dev, "ASoC: Failed to turn on bias: %d\n", ret); } @@ -2074,7 +2089,7 @@ static void dapm_pre_sequence_async(void *data, async_cookie_t cookie) dapm->bias_level == SND_SOC_BIAS_ON)) { ret = snd_soc_dapm_set_bias_level(dapm, SND_SOC_BIAS_PREPARE); if (ret != 0) - dev_err(dapm->dev, + dev_err(dev, "ASoC: Failed to prepare bias: %d\n", ret); } } @@ -2085,6 +2100,7 @@ static void dapm_pre_sequence_async(void *data, async_cookie_t cookie) static void dapm_post_sequence_async(void *data, async_cookie_t cookie) { struct snd_soc_dapm_context *dapm = data; + struct device *dev = snd_soc_dapm_to_dev(dapm); int ret; /* If we just powered the last thing off drop to standby bias */ @@ -2093,8 +2109,7 @@ static void dapm_post_sequence_async(void *data, async_cookie_t cookie) dapm->target_bias_level == SND_SOC_BIAS_OFF)) { ret = snd_soc_dapm_set_bias_level(dapm, SND_SOC_BIAS_STANDBY); if (ret != 0) - dev_err(dapm->dev, "ASoC: Failed to apply standby bias: %d\n", - ret); + dev_err(dev, "ASoC: Failed to apply standby bias: %d\n", ret); } /* If we're in standby and can support bias off then do that */ @@ -2102,11 +2117,10 @@ static void dapm_post_sequence_async(void *data, async_cookie_t cookie) dapm->target_bias_level == SND_SOC_BIAS_OFF) { ret = snd_soc_dapm_set_bias_level(dapm, SND_SOC_BIAS_OFF); if (ret != 0) - dev_err(dapm->dev, "ASoC: Failed to turn off bias: %d\n", - ret); + dev_err(dev, "ASoC: Failed to turn off bias: %d\n", ret); - if (dapm->dev && cookie) - pm_runtime_put(dapm->dev); + if (dev && cookie) + pm_runtime_put(dev); } /* If we just powered up then move to active bias */ @@ -2114,8 +2128,7 @@ static void dapm_post_sequence_async(void *data, async_cookie_t cookie) dapm->target_bias_level == SND_SOC_BIAS_ON) { ret = snd_soc_dapm_set_bias_level(dapm, SND_SOC_BIAS_ON); if (ret != 0) - dev_err(dapm->dev, "ASoC: Failed to apply active bias: %d\n", - ret); + dev_err(dev, "ASoC: Failed to apply active bias: %d\n", ret); } } @@ -2213,6 +2226,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_set_idle_bias); static int dapm_power_widgets(struct snd_soc_card *card, int event, struct snd_soc_dapm_update *update) { + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); struct snd_soc_dapm_widget *w; struct snd_soc_dapm_context *d; LIST_HEAD(up_list); @@ -2299,10 +2313,10 @@ static int dapm_power_widgets(struct snd_soc_card *card, int event, trace_snd_soc_dapm_walk_done(card); /* Run card bias changes at first */ - dapm_pre_sequence_async(&card->dapm, 0); + dapm_pre_sequence_async(dapm, 0); /* Run other bias changes in parallel */ for_each_card_dapms(card, d) { - if (d != &card->dapm && d->bias_level != d->target_bias_level) + if (d != dapm && d->bias_level != d->target_bias_level) async_schedule_domain(dapm_pre_sequence_async, d, &async_domain); } @@ -2326,13 +2340,13 @@ static int dapm_power_widgets(struct snd_soc_card *card, int event, /* Run all the bias changes in parallel */ for_each_card_dapms(card, d) { - if (d != &card->dapm && d->bias_level != d->target_bias_level) + if (d != dapm && d->bias_level != d->target_bias_level) async_schedule_domain(dapm_post_sequence_async, d, &async_domain); } async_synchronize_full_domain(&async_domain); /* Run card bias changes at last */ - dapm_post_sequence_async(&card->dapm, 0); + dapm_post_sequence_async(dapm, 0); /* do we need to notify any clients that DAPM event is complete */ for_each_card_dapms(card, d) { @@ -2703,7 +2717,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_mixer_update_power); static ssize_t dapm_widget_show_component(struct snd_soc_component *component, char *buf, int count) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct snd_soc_dapm_widget *w; char *state = "not set"; @@ -2893,12 +2907,13 @@ static int __snd_soc_dapm_set_pin(struct snd_soc_dapm_context *dapm, const char *pin, int status) { struct snd_soc_dapm_widget *w = dapm_find_widget(dapm, pin, true); + struct device *dev = snd_soc_dapm_to_dev(dapm); int ret = 0; dapm_assert_locked(dapm); if (!w) { - dev_err(dapm->dev, "ASoC: DAPM unknown pin %s\n", pin); + dev_err(dev, "ASoC: DAPM unknown pin %s\n", pin); return -EINVAL; } @@ -2976,6 +2991,8 @@ static int dapm_update_dai_chan(struct snd_soc_dapm_path *p, struct snd_soc_dapm_widget *w, int channels) { + struct device *dev = snd_soc_dapm_to_dev(w->dapm); + switch (w->id) { case snd_soc_dapm_aif_out: case snd_soc_dapm_aif_in: @@ -2984,7 +3001,7 @@ static int dapm_update_dai_chan(struct snd_soc_dapm_path *p, return 0; } - dev_dbg(w->dapm->dev, "%s DAI route %s -> %s\n", + dev_dbg(dev, "%s DAI route %s -> %s\n", w->channel < channels ? "Connecting" : "Disconnecting", p->source->name, p->sink->name); @@ -3059,6 +3076,7 @@ static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm, { struct snd_soc_dapm_widget *wsource = NULL, *wsink = NULL, *w; struct snd_soc_dapm_widget *wtsource = NULL, *wtsink = NULL; + struct device *dev = snd_soc_dapm_to_dev(dapm); const char *sink; const char *source; char prefixed_sink[80]; @@ -3101,7 +3119,7 @@ static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm, } sink_ref++; if (sink_ref > 1) - dev_warn(dapm->dev, + dev_warn(dev, "ASoC: sink widget %s overwritten\n", w->name); continue; @@ -3115,7 +3133,7 @@ static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm, } source_ref++; if (source_ref > 1) - dev_warn(dapm->dev, + dev_warn(dev, "ASoC: source widget %s overwritten\n", w->name); } @@ -3141,7 +3159,7 @@ static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm, route->connected); err: if (ret) - dev_err(dapm->dev, "ASoC: Failed to add route %s%s -%s%s%s> %s%s\n", + dev_err(dev, "ASoC: Failed to add route %s%s -%s%s%s> %s%s\n", source, !wsource ? "(*)" : "", !route->control ? "" : "> [", !route->control ? "" : route->control, @@ -3153,6 +3171,7 @@ static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm, static int snd_soc_dapm_del_route(struct snd_soc_dapm_context *dapm, const struct snd_soc_dapm_route *route) { + struct device *dev = snd_soc_dapm_to_dev(dapm); struct snd_soc_dapm_path *path, *p; const char *sink; const char *source; @@ -3161,7 +3180,7 @@ static int snd_soc_dapm_del_route(struct snd_soc_dapm_context *dapm, const char *prefix; if (route->control) { - dev_err(dapm->dev, + dev_err(dev, "ASoC: Removal of routes with controls not supported\n"); return -EINVAL; } @@ -3204,7 +3223,7 @@ static int snd_soc_dapm_del_route(struct snd_soc_dapm_context *dapm, dapm_update_widget_flags(wsource); dapm_update_widget_flags(wsink); } else { - dev_warn(dapm->dev, "ASoC: Route %s->%s does not exist\n", + dev_warn(dev, "ASoC: Route %s->%s does not exist\n", source, sink); } @@ -3351,7 +3370,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_new_widgets); int snd_soc_dapm_get_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol); + struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kcontrol); struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; int reg = mc->reg; @@ -3373,7 +3392,7 @@ int snd_soc_dapm_get_volsw(struct snd_kcontrol *kcontrol, if (snd_soc_volsw_is_stereo(mc)) rval = (reg_val >> mc->rshift) & mask; } else { - reg_val = dapm_kcontrol_get_value(kcontrol); + reg_val = snd_soc_dapm_kcontrol_get_value(kcontrol); val = reg_val & mask; if (snd_soc_volsw_is_stereo(mc)) @@ -3409,7 +3428,8 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_get_volsw); int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol); + struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kcontrol); + struct device *dev = snd_soc_dapm_to_dev(dapm); struct snd_soc_card *card = dapm->card; struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; @@ -3442,7 +3462,7 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol, /* This assumes field width < (bits in unsigned int / 2) */ if (width > sizeof(unsigned int) * 8 / 2) - dev_warn(dapm->dev, + dev_warn(dev, "ASoC: control %s field width limit exceeded\n", kcontrol->id.name); change = dapm_kcontrol_set_value(kcontrol, val | (rval << width)); @@ -3497,7 +3517,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_put_volsw); int snd_soc_dapm_get_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol); + struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kcontrol); struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; unsigned int reg_val, val; @@ -3505,7 +3525,7 @@ int snd_soc_dapm_get_enum_double(struct snd_kcontrol *kcontrol, if (e->reg != SND_SOC_NOPM && dapm_kcontrol_is_powered(kcontrol)) { reg_val = soc_dapm_read(dapm, e->reg); } else { - reg_val = dapm_kcontrol_get_value(kcontrol); + reg_val = snd_soc_dapm_kcontrol_get_value(kcontrol); } snd_soc_dapm_mutex_unlock(dapm); @@ -3533,7 +3553,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_get_enum_double); int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol); + struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kcontrol); struct snd_soc_card *card = dapm->card; struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; unsigned int *item = ucontrol->value.enumerated.item; @@ -3626,9 +3646,10 @@ int snd_soc_dapm_get_pin_switch(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_card *card = snd_kcontrol_chip(kcontrol); + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); const char *pin = (const char *)kcontrol->private_value; - return __snd_soc_dapm_get_pin_switch(&card->dapm, pin, ucontrol); + return __snd_soc_dapm_get_pin_switch(dapm, pin, ucontrol); } EXPORT_SYMBOL_GPL(snd_soc_dapm_get_pin_switch); @@ -3645,9 +3666,10 @@ int snd_soc_dapm_get_component_pin_switch(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); const char *pin = (const char *)kcontrol->private_value; - return __snd_soc_dapm_get_pin_switch(&component->dapm, pin, ucontrol); + return __snd_soc_dapm_get_pin_switch(dapm, pin, ucontrol); } EXPORT_SYMBOL_GPL(snd_soc_dapm_get_component_pin_switch); @@ -3679,9 +3701,10 @@ int snd_soc_dapm_put_pin_switch(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_card *card = snd_kcontrol_chip(kcontrol); + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); const char *pin = (const char *)kcontrol->private_value; - return __snd_soc_dapm_put_pin_switch(&card->dapm, pin, ucontrol); + return __snd_soc_dapm_put_pin_switch(dapm, pin, ucontrol); } EXPORT_SYMBOL_GPL(snd_soc_dapm_put_pin_switch); @@ -3698,9 +3721,10 @@ int snd_soc_dapm_put_component_pin_switch(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); const char *pin = (const char *)kcontrol->private_value; - return __snd_soc_dapm_put_pin_switch(&component->dapm, pin, ucontrol); + return __snd_soc_dapm_put_pin_switch(dapm, pin, ucontrol); } EXPORT_SYMBOL_GPL(snd_soc_dapm_put_component_pin_switch); @@ -3708,6 +3732,7 @@ struct snd_soc_dapm_widget * snd_soc_dapm_new_control_unlocked(struct snd_soc_dapm_context *dapm, const struct snd_soc_dapm_widget *widget) { + struct device *dev = snd_soc_dapm_to_dev(dapm); enum snd_soc_dapm_direction dir; struct snd_soc_dapm_widget *w; int ret = -ENOMEM; @@ -3718,7 +3743,7 @@ snd_soc_dapm_new_control_unlocked(struct snd_soc_dapm_context *dapm, switch (w->id) { case snd_soc_dapm_regulator_supply: - w->regulator = devm_regulator_get(dapm->dev, widget->name); + w->regulator = devm_regulator_get(dev, widget->name); if (IS_ERR(w->regulator)) { ret = PTR_ERR(w->regulator); goto request_failed; @@ -3727,13 +3752,13 @@ snd_soc_dapm_new_control_unlocked(struct snd_soc_dapm_context *dapm, if (w->on_val & SND_SOC_DAPM_REGULATOR_BYPASS) { ret = regulator_allow_bypass(w->regulator, true); if (ret != 0) - dev_warn(dapm->dev, + dev_warn(dev, "ASoC: Failed to bypass %s: %d\n", w->name, ret); } break; case snd_soc_dapm_pinctrl: - w->pinctrl = devm_pinctrl_get(dapm->dev); + w->pinctrl = devm_pinctrl_get(dev); if (IS_ERR(w->pinctrl)) { ret = PTR_ERR(w->pinctrl); goto request_failed; @@ -3743,7 +3768,7 @@ snd_soc_dapm_new_control_unlocked(struct snd_soc_dapm_context *dapm, snd_soc_dapm_pinctrl_event(w, NULL, SND_SOC_DAPM_POST_PMD); break; case snd_soc_dapm_clock_supply: - w->clk = devm_clk_get(dapm->dev, widget->name); + w->clk = devm_clk_get(dev, widget->name); if (IS_ERR(w->clk)) { ret = PTR_ERR(w->clk); goto request_failed; @@ -3837,7 +3862,7 @@ snd_soc_dapm_new_control_unlocked(struct snd_soc_dapm_context *dapm, return w; request_failed: - dev_err_probe(dapm->dev, ret, "ASoC: Failed to request %s\n", + dev_err_probe(dev, ret, "ASoC: Failed to request %s\n", w->name); kfree_const(w->name); kfree_const(w->sname); @@ -3904,6 +3929,7 @@ static int snd_soc_dai_link_event_pre_pmu(struct snd_soc_dapm_widget *w, struct snd_pcm_substream *substream) { + struct device *dev = snd_soc_dapm_to_dev(w->dapm); struct snd_soc_dapm_path *path; struct snd_soc_dai *source, *sink; struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); @@ -3963,13 +3989,13 @@ snd_soc_dai_link_event_pre_pmu(struct snd_soc_dapm_widget *w, */ config = rtd->dai_link->c2c_params + rtd->c2c_params_select; if (!config) { - dev_err(w->dapm->dev, "ASoC: link config missing\n"); + dev_err(dev, "ASoC: link config missing\n"); return -EINVAL; } /* Be a little careful as we don't want to overflow the mask array */ if (!config->formats) { - dev_warn(w->dapm->dev, "ASoC: Invalid format was specified\n"); + dev_warn(dev, "ASoC: Invalid format was specified\n"); return -EINVAL; } @@ -4179,7 +4205,7 @@ snd_soc_dapm_alloc_kcontrol(struct snd_soc_card *card, for (count = 0 ; count < num_c2c_params; count++) { if (!config->stream_name) { - dev_warn(card->dapm.dev, + dev_warn(card->dev, "ASoC: anonymous config %d for dai link %s\n", count, link_name); w_param_text[count] = @@ -4231,6 +4257,7 @@ snd_soc_dapm_new_dai(struct snd_soc_card *card, struct snd_pcm_substream *substream, char *id) { + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct snd_soc_dapm_widget template; struct snd_soc_dapm_widget *w; @@ -4278,7 +4305,7 @@ snd_soc_dapm_new_dai(struct snd_soc_card *card, dev_dbg(card->dev, "ASoC: adding %s widget\n", link_name); - w = snd_soc_dapm_new_control_unlocked(&card->dapm, &template); + w = snd_soc_dapm_new_control_unlocked(dapm, &template); if (IS_ERR(w)) { ret = PTR_ERR(w); goto outfree_kcontrol_news; @@ -4310,10 +4337,11 @@ snd_soc_dapm_new_dai(struct snd_soc_card *card, int snd_soc_dapm_new_dai_widgets(struct snd_soc_dapm_context *dapm, struct snd_soc_dai *dai) { + struct device *dev = snd_soc_dapm_to_dev(dapm); struct snd_soc_dapm_widget template; struct snd_soc_dapm_widget *w; - WARN_ON(dapm->dev != dai->dev); + WARN_ON(dev != dai->dev); memset(&template, 0, sizeof(template)); template.reg = SND_SOC_NOPM; @@ -4417,7 +4445,9 @@ static void dapm_connect_dai_routes(struct snd_soc_dapm_context *dapm, struct snd_soc_dai *sink_dai, struct snd_soc_dapm_widget *sink) { - dev_dbg(dapm->dev, "connected DAI link %s:%s -> %s:%s\n", + struct device *dev = snd_soc_dapm_to_dev(dapm); + + dev_dbg(dev, "connected DAI link %s:%s -> %s:%s\n", src_dai->component->name, src->name, sink_dai->component->name, sink->name); @@ -4434,6 +4464,7 @@ static void dapm_connect_dai_pair(struct snd_soc_card *card, struct snd_soc_dai *codec_dai, struct snd_soc_dai *cpu_dai) { + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); struct snd_soc_dai_link *dai_link = rtd->dai_link; struct snd_soc_dapm_widget *codec, *cpu; struct snd_soc_dai *src_dai[] = { cpu_dai, codec_dai }; @@ -4468,7 +4499,7 @@ static void dapm_connect_dai_pair(struct snd_soc_card *card, rtd->c2c_widget[stream] = dai; } - dapm_connect_dai_routes(&card->dapm, src_dai[stream], *src[stream], + dapm_connect_dai_routes(dapm, src_dai[stream], *src[stream], rtd->c2c_widget[stream], sink_dai[stream], *sink[stream]); } @@ -4661,14 +4692,19 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_enable_pin); int snd_soc_dapm_force_enable_pin_unlocked(struct snd_soc_dapm_context *dapm, const char *pin) { + struct device *dev; struct snd_soc_dapm_widget *w = dapm_find_widget(dapm, pin, true); if (!w) { - dev_err(dapm->dev, "ASoC: unknown pin %s\n", pin); + dev = snd_soc_dapm_to_dev(dapm); + + dev_err(dev, "ASoC: unknown pin %s\n", pin); return -EINVAL; } - dev_dbg(w->dapm->dev, "ASoC: force enable pin %s\n", pin); + dev = snd_soc_dapm_to_dev(w->dapm); + + dev_dbg(dev, "ASoC: force enable pin %s\n", pin); if (!w->connected) { /* * w->force does not affect the number of input or output paths, @@ -4791,10 +4827,11 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_get_pin_status); int snd_soc_dapm_ignore_suspend(struct snd_soc_dapm_context *dapm, const char *pin) { + struct device *dev = snd_soc_dapm_to_dev(dapm); struct snd_soc_dapm_widget *w = dapm_find_widget(dapm, pin, false); if (!w) { - dev_err(dapm->dev, "ASoC: unknown pin %s\n", pin); + dev_err(dev, "ASoC: unknown pin %s\n", pin); return -EINVAL; } @@ -4877,21 +4914,20 @@ static void soc_dapm_shutdown_dapm(struct snd_soc_dapm_context *dapm) */ void snd_soc_dapm_shutdown(struct snd_soc_card *card) { + struct snd_soc_dapm_context *card_dapm = snd_soc_card_to_dapm(card); struct snd_soc_dapm_context *dapm; for_each_card_dapms(card, dapm) { - if (dapm != &card->dapm) { + if (dapm != card_dapm) { soc_dapm_shutdown_dapm(dapm); if (dapm->bias_level == SND_SOC_BIAS_STANDBY) - snd_soc_dapm_set_bias_level(dapm, - SND_SOC_BIAS_OFF); + snd_soc_dapm_set_bias_level(dapm, SND_SOC_BIAS_OFF); } } - soc_dapm_shutdown_dapm(&card->dapm); - if (card->dapm.bias_level == SND_SOC_BIAS_STANDBY) - snd_soc_dapm_set_bias_level(&card->dapm, - SND_SOC_BIAS_OFF); + soc_dapm_shutdown_dapm(card_dapm); + if (card_dapm->bias_level == SND_SOC_BIAS_STANDBY) + snd_soc_dapm_set_bias_level(card_dapm, SND_SOC_BIAS_OFF); } /* Module information */ diff --git a/sound/soc/soc-jack.c b/sound/soc/soc-jack.c index 63971396b708bc..05985ccec571af 100644 --- a/sound/soc/soc-jack.c +++ b/sound/soc/soc-jack.c @@ -40,7 +40,7 @@ void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask) return; trace_snd_soc_jack_report(jack, mask, status); - dapm = &jack->card->dapm; + dapm = snd_soc_card_to_dapm(jack->card); mutex_lock(&jack->mutex); diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index c82b10578ba608..6b134962c71c75 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -1463,7 +1463,7 @@ EXPORT_SYMBOL_GPL(widget_in_list); bool dpcm_end_walk_at_be(struct snd_soc_dapm_widget *widget, enum snd_soc_dapm_direction dir) { - struct snd_soc_card *card = widget->dapm->card; + struct snd_soc_card *card = snd_soc_dapm_to_card(widget->dapm); struct snd_soc_pcm_runtime *rtd; int stream; diff --git a/sound/soc/soc-topology.c b/sound/soc/soc-topology.c index 44b60324eaa2e9..064b8d76b95505 100644 --- a/sound/soc/soc-topology.c +++ b/sound/soc/soc-topology.c @@ -1026,7 +1026,7 @@ static int soc_tplg_add_route(struct soc_tplg *tplg, static int soc_tplg_dapm_graph_elems_load(struct soc_tplg *tplg, struct snd_soc_tplg_hdr *hdr) { - struct snd_soc_dapm_context *dapm = &tplg->comp->dapm; + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(tplg->comp); const size_t maxlen = SNDRV_CTL_ELEM_ID_NAME_MAXLEN; struct snd_soc_tplg_dapm_graph_elem *elem; struct snd_soc_dapm_route *route; @@ -1097,7 +1097,7 @@ static int soc_tplg_dapm_graph_elems_load(struct soc_tplg *tplg, static int soc_tplg_dapm_widget_create(struct soc_tplg *tplg, struct snd_soc_tplg_dapm_widget *w) { - struct snd_soc_dapm_context *dapm = &tplg->comp->dapm; + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(tplg->comp); struct snd_soc_dapm_widget template, *widget; struct snd_soc_tplg_ctl_hdr *control_hdr; struct snd_soc_card *card = tplg->comp->card; @@ -1245,7 +1245,8 @@ static int soc_tplg_dapm_widget_create(struct soc_tplg *tplg, return 0; ready_err: - soc_tplg_remove_widget(widget->dapm->component, &widget->dobj, SOC_TPLG_PASS_WIDGET); + soc_tplg_remove_widget(snd_soc_dapm_to_component(widget->dapm), + &widget->dobj, SOC_TPLG_PASS_WIDGET); snd_soc_dapm_free_widget(widget); hdr_err: kfree(template.sname); @@ -1367,8 +1368,7 @@ static int soc_tplg_dai_create(struct soc_tplg *tplg, struct snd_soc_pcm_stream *stream; struct snd_soc_tplg_stream_caps *caps; struct snd_soc_dai *dai; - struct snd_soc_dapm_context *dapm = - snd_soc_component_get_dapm(tplg->comp); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(tplg->comp); int ret; dai_drv = devm_kzalloc(tplg->dev, sizeof(struct snd_soc_dai_driver), GFP_KERNEL); diff --git a/sound/soc/sof/imx/Kconfig b/sound/soc/sof/imx/Kconfig index 327e2df94a5878..09d88ce5b9e6e5 100644 --- a/sound/soc/sof/imx/Kconfig +++ b/sound/soc/sof/imx/Kconfig @@ -35,6 +35,7 @@ config SND_SOC_SOF_IMX8 config SND_SOC_SOF_IMX9 tristate "SOF support for i.MX9" depends on IMX_DSP + depends on IMX_SCMI_LMM_DRV select SND_SOC_SOF_IMX_COMMON help This adds support for Sound Open Firmware for NXP i.MX9 platforms. diff --git a/sound/soc/sof/imx/imx9.c b/sound/soc/sof/imx/imx9.c index 853155d5990a36..e56e8a1c80222e 100644 --- a/sound/soc/sof/imx/imx9.c +++ b/sound/soc/sof/imx/imx9.c @@ -3,19 +3,11 @@ * Copyright 2025 NXP */ -#include +#include #include "imx-common.h" -#define IMX_SIP_SRC 0xC2000005 -#define IMX_SIP_SRC_M_RESET_ADDR_SET 0x03 - -#define IMX95_CPU_VEC_FLAGS_BOOT BIT(29) - -#define IMX_SIP_LMM 0xC200000F -#define IMX_SIP_LMM_BOOT 0x0 -#define IMX_SIP_LMM_SHUTDOWN 0x1 - +#define IMX95_M7_CPU_ID 0x1 #define IMX95_M7_LM_ID 0x1 static struct snd_soc_dai_driver imx95_dai[] = { @@ -38,7 +30,6 @@ static int imx95_ops_init(struct snd_sof_dev *sdev) static int imx95_chip_probe(struct snd_sof_dev *sdev) { - struct arm_smccc_res smc_res; struct platform_device *pdev; struct resource *res; @@ -49,31 +40,20 @@ static int imx95_chip_probe(struct snd_sof_dev *sdev) return dev_err_probe(sdev->dev, -ENODEV, "failed to fetch SRAM region\n"); - /* set core boot reset address */ - arm_smccc_smc(IMX_SIP_SRC, IMX_SIP_SRC_M_RESET_ADDR_SET, res->start, - IMX95_CPU_VEC_FLAGS_BOOT, 0, 0, 0, 0, &smc_res); - - return smc_res.a0; + return scmi_imx_lmm_reset_vector_set(IMX95_M7_LM_ID, IMX95_M7_CPU_ID, + 0, res->start); } static int imx95_core_kick(struct snd_sof_dev *sdev) { - struct arm_smccc_res smc_res; - - arm_smccc_smc(IMX_SIP_LMM, IMX_SIP_LMM_BOOT, - IMX95_M7_LM_ID, 0, 0, 0, 0, 0, &smc_res); - - return smc_res.a0; + return scmi_imx_lmm_operation(IMX95_M7_LM_ID, SCMI_IMX_LMM_BOOT, 0); } static int imx95_core_shutdown(struct snd_sof_dev *sdev) { - struct arm_smccc_res smc_res; - - arm_smccc_smc(IMX_SIP_LMM, IMX_SIP_LMM_SHUTDOWN, - IMX95_M7_LM_ID, 0, 0, 0, 0, 0, &smc_res); - - return smc_res.a0; + return scmi_imx_lmm_operation(IMX95_M7_LM_ID, + SCMI_IMX_LMM_SHUTDOWN, + SCMI_IMX_LMM_OP_FORCEFUL); } static const struct imx_chip_ops imx95_chip_ops = { diff --git a/sound/soc/sof/sof-client-probes-ipc4.c b/sound/soc/sof/sof-client-probes-ipc4.c index 758a56d271d77a..d3fa37106b6481 100644 --- a/sound/soc/sof/sof-client-probes-ipc4.c +++ b/sound/soc/sof/sof-client-probes-ipc4.c @@ -289,7 +289,7 @@ static int ipc4_probes_point_print(struct sof_client_dev *cdev, char *buf, size_ __func__, SOF_IPC4_MOD_ID_GET(desc->buffer_id), SOF_IPC4_MOD_INSTANCE_GET(desc->buffer_id)); - ret = snprintf(buf, size, "%#x,%#x,%#x\t%s %s buf idx %lu %s\n", + ret = scnprintf(buf, size, "%#x,%#x,%#x\t%s %s buf idx %lu %s\n", desc->buffer_id, desc->purpose, desc->stream_tag, swidget ? swidget->widget->name : "", sof_probe_ipc4_type_string(SOF_IPC4_PROBE_TYPE_GET(desc->buffer_id)), diff --git a/sound/soc/sof/sof-client-probes.c b/sound/soc/sof/sof-client-probes.c index fc7975fb6e6f1c..124f5550815927 100644 --- a/sound/soc/sof/sof-client-probes.c +++ b/sound/soc/sof/sof-client-probes.c @@ -538,9 +538,6 @@ static int sof_probes_client_probe(struct auxiliary_device *auxdev, card->num_links = SOF_PROBES_NUM_DAI_LINKS; card->dai_link = links; - /* set idle_bias_off to prevent the core from resuming the card->dev */ - card->dapm.idle_bias = false; - snd_soc_card_set_drvdata(card, cdev); ret = devm_snd_soc_register_card(dev, card); @@ -551,6 +548,14 @@ static int sof_probes_client_probe(struct auxiliary_device *auxdev, return ret; } + /* + * set idle_bias_off to prevent the core from resuming the card->dev + * call it after snd_soc_register_card() + */ + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); + + snd_soc_dapm_set_idle_bias(dapm, false); + /* enable runtime PM */ pm_runtime_set_autosuspend_delay(dev, SOF_PROBES_SUSPEND_DELAY_MS); pm_runtime_use_autosuspend(dev); diff --git a/sound/soc/stm/stm32_sai.c b/sound/soc/stm/stm32_sai.c index fa821e3fb427e3..00cf24ceca2d4a 100644 --- a/sound/soc/stm/stm32_sai.c +++ b/sound/soc/stm/stm32_sai.c @@ -138,30 +138,24 @@ static int stm32_sai_set_sync(struct stm32_sai_data *sai_client, if (!pdev) { dev_err(&sai_client->pdev->dev, "Device not found for node %pOFn\n", np_provider); - of_node_put(np_provider); return -ENODEV; } sai_provider = platform_get_drvdata(pdev); + put_device(&pdev->dev); if (!sai_provider) { dev_err(&sai_client->pdev->dev, "SAI sync provider data not found\n"); - ret = -EINVAL; - goto error; + return -EINVAL; } /* Configure sync client */ ret = stm32_sai_sync_conf_client(sai_client, synci); if (ret < 0) - goto error; + return ret; /* Configure sync provider */ - ret = stm32_sai_sync_conf_provider(sai_provider, synco); - -error: - put_device(&pdev->dev); - of_node_put(np_provider); - return ret; + return stm32_sai_sync_conf_provider(sai_provider, synco); } static int stm32_sai_get_parent_clk(struct stm32_sai_data *sai) diff --git a/sound/soc/stm/stm32_sai_sub.c b/sound/soc/stm/stm32_sai_sub.c index 0ae1eae2a59e2f..450e1585edeee0 100644 --- a/sound/soc/stm/stm32_sai_sub.c +++ b/sound/soc/stm/stm32_sai_sub.c @@ -1586,7 +1586,8 @@ static int stm32_sai_sub_parse_of(struct platform_device *pdev, dev_err(&pdev->dev, "External synchro not supported\n"); of_node_put(args.np); - return -EINVAL; + ret = -EINVAL; + goto err_put_sync_provider; } sai->sync = SAI_SYNC_EXTERNAL; @@ -1595,7 +1596,8 @@ static int stm32_sai_sub_parse_of(struct platform_device *pdev, (sai->synci > (SAI_GCR_SYNCIN_MAX + 1))) { dev_err(&pdev->dev, "Wrong SAI index\n"); of_node_put(args.np); - return -EINVAL; + ret = -EINVAL; + goto err_put_sync_provider; } if (of_property_match_string(args.np, "compatible", @@ -1609,7 +1611,8 @@ static int stm32_sai_sub_parse_of(struct platform_device *pdev, if (!sai->synco) { dev_err(&pdev->dev, "Unknown SAI sub-block\n"); of_node_put(args.np); - return -EINVAL; + ret = -EINVAL; + goto err_put_sync_provider; } } @@ -1619,13 +1622,15 @@ static int stm32_sai_sub_parse_of(struct platform_device *pdev, of_node_put(args.np); sai->sai_ck = devm_clk_get(&pdev->dev, "sai_ck"); - if (IS_ERR(sai->sai_ck)) - return dev_err_probe(&pdev->dev, PTR_ERR(sai->sai_ck), - "Missing kernel clock sai_ck\n"); + if (IS_ERR(sai->sai_ck)) { + ret = dev_err_probe(&pdev->dev, PTR_ERR(sai->sai_ck), + "Missing kernel clock sai_ck\n"); + goto err_put_sync_provider; + } ret = clk_prepare(sai->pdata->pclk); if (ret < 0) - return ret; + goto err_put_sync_provider; if (STM_SAI_IS_F4(sai->pdata)) return 0; @@ -1634,14 +1639,23 @@ static int stm32_sai_sub_parse_of(struct platform_device *pdev, if (of_property_present(np, "#clock-cells")) { ret = stm32_sai_add_mclk_provider(sai); if (ret < 0) - return ret; + goto err_unprepare_pclk; } else { sai->sai_mclk = devm_clk_get_optional(&pdev->dev, "MCLK"); - if (IS_ERR(sai->sai_mclk)) - return PTR_ERR(sai->sai_mclk); + if (IS_ERR(sai->sai_mclk)) { + ret = PTR_ERR(sai->sai_mclk); + goto err_unprepare_pclk; + } } return 0; + +err_unprepare_pclk: + clk_unprepare(sai->pdata->pclk); +err_put_sync_provider: + of_node_put(sai->np_sync_provider); + + return ret; } static int stm32_sai_sub_probe(struct platform_device *pdev) @@ -1688,26 +1702,34 @@ static int stm32_sai_sub_probe(struct platform_device *pdev) IRQF_SHARED, dev_name(&pdev->dev), sai); if (ret) { dev_err(&pdev->dev, "IRQ request returned %d\n", ret); - return ret; + goto err_unprepare_pclk; } if (STM_SAI_PROTOCOL_IS_SPDIF(sai)) conf = &stm32_sai_pcm_config_spdif; ret = snd_dmaengine_pcm_register(&pdev->dev, conf, 0); - if (ret) - return dev_err_probe(&pdev->dev, ret, "Could not register pcm dma\n"); + if (ret) { + ret = dev_err_probe(&pdev->dev, ret, "Could not register pcm dma\n"); + goto err_unprepare_pclk; + } ret = snd_soc_register_component(&pdev->dev, &stm32_component, &sai->cpu_dai_drv, 1); - if (ret) { - snd_dmaengine_pcm_unregister(&pdev->dev); - return ret; - } + if (ret) + goto err_deregister_pcm_dma; pm_runtime_enable(&pdev->dev); return 0; + +err_deregister_pcm_dma: + snd_dmaengine_pcm_unregister(&pdev->dev); +err_unprepare_pclk: + clk_unprepare(sai->pdata->pclk); + of_node_put(sai->np_sync_provider); + + return ret; } static void stm32_sai_sub_remove(struct platform_device *pdev) @@ -1718,6 +1740,7 @@ static void stm32_sai_sub_remove(struct platform_device *pdev) snd_dmaengine_pcm_unregister(&pdev->dev); snd_soc_unregister_component(&pdev->dev); pm_runtime_disable(&pdev->dev); + of_node_put(sai->np_sync_provider); } static int stm32_sai_sub_suspend(struct device *dev) diff --git a/sound/soc/sunxi/sun4i-codec.c b/sound/soc/sunxi/sun4i-codec.c index 93733ff2e32a03..f4e22af594fa35 100644 --- a/sound/soc/sunxi/sun4i-codec.c +++ b/sound/soc/sunxi/sun4i-codec.c @@ -1663,7 +1663,8 @@ static struct snd_soc_dai_link *sun4i_codec_create_link(struct device *dev, static int sun4i_codec_spk_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *k, int event) { - struct sun4i_codec *scodec = snd_soc_card_get_drvdata(w->dapm->card); + struct snd_soc_card *card = snd_soc_dapm_to_card(w->dapm); + struct sun4i_codec *scodec = snd_soc_card_get_drvdata(card); gpiod_set_value_cansleep(scodec->gpio_pa, !!SND_SOC_DAPM_EVENT_ON(event)); diff --git a/sound/soc/sunxi/sun50i-codec-analog.c b/sound/soc/sunxi/sun50i-codec-analog.c index 2dcdf113b66e5d..a19f8aaaf1c407 100644 --- a/sound/soc/sunxi/sun50i-codec-analog.c +++ b/sound/soc/sunxi/sun50i-codec-analog.c @@ -495,7 +495,7 @@ static const struct snd_soc_dapm_route sun50i_a64_codec_routes[] = { static int sun50i_a64_codec_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); int hbias; switch (level) { diff --git a/sound/soc/sunxi/sun8i-codec-analog.c b/sound/soc/sunxi/sun8i-codec-analog.c index 445b341418964d..2024e2b2553ed2 100644 --- a/sound/soc/sunxi/sun8i-codec-analog.c +++ b/sound/soc/sunxi/sun8i-codec-analog.c @@ -390,7 +390,7 @@ static const struct snd_soc_dapm_route sun8i_codec_headphone_routes[] = { static int sun8i_codec_add_headphone(struct snd_soc_component *cmpnt) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(cmpnt); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(cmpnt); struct device *dev = cmpnt->dev; int ret; @@ -428,7 +428,7 @@ static const struct snd_soc_dapm_widget sun8i_codec_mbias_widgets[] = { static int sun8i_codec_add_mbias(struct snd_soc_component *cmpnt) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(cmpnt); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(cmpnt); struct device *dev = cmpnt->dev; int ret; @@ -449,7 +449,7 @@ static const struct snd_soc_dapm_widget sun8i_codec_hmic_widgets[] = { static int sun8i_codec_add_hmic(struct snd_soc_component *cmpnt) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(cmpnt); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(cmpnt); struct device *dev = cmpnt->dev; int ret; @@ -486,7 +486,7 @@ static const struct snd_soc_dapm_route sun8i_codec_linein_routes[] = { static int sun8i_codec_add_linein(struct snd_soc_component *cmpnt) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(cmpnt); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(cmpnt); struct device *dev = cmpnt->dev; int ret; @@ -567,7 +567,7 @@ static const struct snd_soc_dapm_route sun8i_codec_lineout_routes[] = { static int sun8i_codec_add_lineout(struct snd_soc_component *cmpnt) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(cmpnt); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(cmpnt); struct device *dev = cmpnt->dev; int ret; @@ -632,7 +632,7 @@ static const struct snd_soc_dapm_route sun8i_codec_mic2_routes[] = { static int sun8i_codec_add_mic2(struct snd_soc_component *cmpnt) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(cmpnt); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(cmpnt); struct device *dev = cmpnt->dev; int ret; @@ -688,7 +688,7 @@ static const struct sun8i_codec_analog_quirks sun8i_h3_quirks = { static int sun8i_codec_analog_add_mixer(struct snd_soc_component *cmpnt, const struct sun8i_codec_analog_quirks *quirks) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(cmpnt); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(cmpnt); struct device *dev = cmpnt->dev; int ret; diff --git a/sound/soc/sunxi/sun8i-codec.c b/sound/soc/sunxi/sun8i-codec.c index 7b3496caa31ecb..6bd42da57ac01b 100644 --- a/sound/soc/sunxi/sun8i-codec.c +++ b/sound/soc/sunxi/sun8i-codec.c @@ -1287,7 +1287,7 @@ static const struct snd_soc_dapm_route sun8i_codec_legacy_routes[] = { static int sun8i_codec_component_probe(struct snd_soc_component *component) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct sun8i_codec *scodec = snd_soc_component_get_drvdata(component); int ret; @@ -1331,7 +1331,7 @@ static int sun8i_codec_component_probe(struct snd_soc_component *component) static void sun8i_codec_set_hmic_bias(struct sun8i_codec *scodec, bool enable) { - struct snd_soc_dapm_context *dapm = &scodec->component->card->dapm; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(scodec->component->card); int irq_mask = BIT(SUN8I_HMIC_CTRL1_HMIC_DATA_IRQ_EN); if (enable) diff --git a/sound/soc/tegra/Kconfig b/sound/soc/tegra/Kconfig index 71203a9197ede5..9dbd589879fb81 100644 --- a/sound/soc/tegra/Kconfig +++ b/sound/soc/tegra/Kconfig @@ -3,7 +3,7 @@ menu "Tegra" config SND_SOC_TEGRA tristate "SoC Audio for the Tegra System-on-Chip" - depends on (ARCH_TEGRA && TEGRA20_APB_DMA) || COMPILE_TEST + depends on ARCH_TEGRA || COMPILE_TEST depends on COMMON_CLK depends on RESET_CONTROLLER select REGMAP_MMIO diff --git a/sound/soc/tegra/tegra210_ahub.c b/sound/soc/tegra/tegra210_ahub.c index 21aeaeba0b1079..e795907a3963af 100644 --- a/sound/soc/tegra/tegra210_ahub.c +++ b/sound/soc/tegra/tegra210_ahub.c @@ -17,7 +17,7 @@ static int tegra_ahub_get_value_enum(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *uctl) { - struct snd_soc_component *cmpnt = snd_soc_dapm_kcontrol_component(kctl); + struct snd_soc_component *cmpnt = snd_soc_dapm_kcontrol_to_component(kctl); struct tegra_ahub *ahub = snd_soc_component_get_drvdata(cmpnt); struct soc_enum *e = (struct soc_enum *)kctl->private_value; unsigned int reg, i, bit_pos = 0; @@ -54,9 +54,9 @@ static int tegra_ahub_get_value_enum(struct snd_kcontrol *kctl, static int tegra_ahub_put_value_enum(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *uctl) { - struct snd_soc_component *cmpnt = snd_soc_dapm_kcontrol_component(kctl); + struct snd_soc_component *cmpnt = snd_soc_dapm_kcontrol_to_component(kctl); struct tegra_ahub *ahub = snd_soc_component_get_drvdata(cmpnt); - struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kctl); + struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kctl); struct soc_enum *e = (struct soc_enum *)kctl->private_value; struct snd_soc_dapm_update update[TEGRA_XBAR_UPDATE_MAX_REG] = { }; unsigned int *item = uctl->value.enumerated.item; diff --git a/sound/soc/tegra/tegra_asoc_machine.c b/sound/soc/tegra/tegra_asoc_machine.c index 62f89677273193..d48463ac16fc2a 100644 --- a/sound/soc/tegra/tegra_asoc_machine.c +++ b/sound/soc/tegra/tegra_asoc_machine.c @@ -78,8 +78,8 @@ static struct snd_soc_jack_gpio tegra_machine_mic_jack_gpio = { static int tegra_machine_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *k, int event) { - struct snd_soc_dapm_context *dapm = w->dapm; - struct tegra_machine *machine = snd_soc_card_get_drvdata(dapm->card); + struct snd_soc_card *card = snd_soc_dapm_to_card(w->dapm); + struct tegra_machine *machine = snd_soc_card_get_drvdata(card); if (!snd_soc_dapm_widget_name_cmp(w, "Int Spk") || !snd_soc_dapm_widget_name_cmp(w, "Speakers")) @@ -659,7 +659,9 @@ static const struct tegra_asoc_data tegra_wm8753_data = { static int tegra_wm9712_init(struct snd_soc_pcm_runtime *rtd) { - return snd_soc_dapm_force_enable_pin(&rtd->card->dapm, "Mic Bias"); + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(rtd->card); + + return snd_soc_dapm_force_enable_pin(dapm, "Mic Bias"); } SND_SOC_DAILINK_DEFS(wm9712_hifi, @@ -839,13 +841,14 @@ static const struct tegra_asoc_data tegra_trimslice_data = { static int tegra_rt5677_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_card *card = rtd->card; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); int err; err = tegra_asoc_machine_init(rtd); if (err) return err; - snd_soc_dapm_force_enable_pin(&card->dapm, "MICBIAS1"); + snd_soc_dapm_force_enable_pin(dapm, "MICBIAS1"); return 0; } diff --git a/sound/soc/tegra/tegra_wm8903.c b/sound/soc/tegra/tegra_wm8903.c index 78b02c64d95c43..91180f4cfe1789 100644 --- a/sound/soc/tegra/tegra_wm8903.c +++ b/sound/soc/tegra/tegra_wm8903.c @@ -56,6 +56,7 @@ static int tegra_wm8903_init(struct snd_soc_pcm_runtime *rtd) { struct tegra_machine *machine = snd_soc_card_get_drvdata(rtd->card); struct snd_soc_card *card = rtd->card; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); int err; /* @@ -96,7 +97,7 @@ static int tegra_wm8903_init(struct snd_soc_pcm_runtime *rtd) SND_JACK_MICROPHONE, shrt); } - snd_soc_dapm_force_enable_pin(&card->dapm, "MICBIAS"); + snd_soc_dapm_force_enable_pin(dapm, "MICBIAS"); return 0; } diff --git a/sound/soc/ti/ams-delta.c b/sound/soc/ti/ams-delta.c index 9b8cb80ec81aab..ba173d9fcba91d 100644 --- a/sound/soc/ti/ams-delta.c +++ b/sound/soc/ti/ams-delta.c @@ -99,7 +99,7 @@ static int ams_delta_set_audio_mode(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_card *card = snd_kcontrol_chip(kcontrol); - struct snd_soc_dapm_context *dapm = &card->dapm; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); struct soc_enum *control = (struct soc_enum *)kcontrol->private_value; unsigned short pins; int pin, changed = 0; @@ -172,7 +172,7 @@ static int ams_delta_get_audio_mode(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_card *card = snd_kcontrol_chip(kcontrol); - struct snd_soc_dapm_context *dapm = &card->dapm; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); unsigned short pins, mode; pins = ((snd_soc_dapm_get_pin_status(dapm, "Mouthpiece") << @@ -313,7 +313,7 @@ static void cx81801_close(struct tty_struct *tty) v253_ops.close(tty); - dapm = &component->card->dapm; + dapm = snd_soc_card_to_dapm(component->card); /* Revert back to default audio input/output constellation */ snd_soc_dapm_mutex_lock(dapm); @@ -462,7 +462,7 @@ static int ams_delta_cx20442_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); struct snd_soc_card *card = rtd->card; - struct snd_soc_dapm_context *dapm = &card->dapm; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); int ret; /* Codec is ready, now add/activate board specific controls */ diff --git a/sound/soc/ti/davinci-evm.c b/sound/soc/ti/davinci-evm.c index 2a2f5bc95576ea..3848766d96c3e3 100644 --- a/sound/soc/ti/davinci-evm.c +++ b/sound/soc/ti/davinci-evm.c @@ -113,11 +113,12 @@ static const struct snd_soc_dapm_route audio_map[] = { static int evm_aic3x_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_card *card = rtd->card; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(rtd->card); struct device_node *np = card->dev->of_node; int ret; /* Add davinci-evm specific widgets */ - snd_soc_dapm_new_controls(&card->dapm, aic3x_dapm_widgets, + snd_soc_dapm_new_controls(dapm, aic3x_dapm_widgets, ARRAY_SIZE(aic3x_dapm_widgets)); if (np) { @@ -126,14 +127,14 @@ static int evm_aic3x_init(struct snd_soc_pcm_runtime *rtd) return ret; } else { /* Set up davinci-evm specific audio path audio_map */ - snd_soc_dapm_add_routes(&card->dapm, audio_map, + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); } /* not connected */ - snd_soc_dapm_nc_pin(&card->dapm, "MONO_LOUT"); - snd_soc_dapm_nc_pin(&card->dapm, "HPLCOM"); - snd_soc_dapm_nc_pin(&card->dapm, "HPRCOM"); + snd_soc_dapm_disable_pin(dapm, "MONO_LOUT"); + snd_soc_dapm_disable_pin(dapm, "HPLCOM"); + snd_soc_dapm_disable_pin(dapm, "HPRCOM"); return 0; } diff --git a/sound/soc/ti/j721e-evm.c b/sound/soc/ti/j721e-evm.c index 0e7e4ff950b548..faa62c1a9b8e12 100644 --- a/sound/soc/ti/j721e-evm.c +++ b/sound/soc/ti/j721e-evm.c @@ -444,7 +444,7 @@ static int j721e_audio_init(struct snd_soc_pcm_runtime *rtd) static int j721e_audio_init_ivi(struct snd_soc_pcm_runtime *rtd) { - struct snd_soc_dapm_context *dapm = &rtd->card->dapm; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(rtd->card); snd_soc_dapm_new_controls(dapm, j721e_ivi_codec_a_dapm_widgets, ARRAY_SIZE(j721e_ivi_codec_a_dapm_widgets)); diff --git a/sound/soc/ti/n810.c b/sound/soc/ti/n810.c index 345c987653809c..242b07034816d7 100644 --- a/sound/soc/ti/n810.c +++ b/sound/soc/ti/n810.c @@ -85,10 +85,11 @@ static int n810_startup(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(rtd->card); snd_pcm_hw_constraint_single(runtime, SNDRV_PCM_HW_PARAM_CHANNELS, 2); - n810_ext_control(&rtd->card->dapm); + n810_ext_control(dapm); return clk_prepare_enable(sys_clkout2); } @@ -129,12 +130,13 @@ static int n810_set_spk(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_card *card = snd_kcontrol_chip(kcontrol); + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); if (n810_spk_func == ucontrol->value.enumerated.item[0]) return 0; n810_spk_func = ucontrol->value.enumerated.item[0]; - n810_ext_control(&card->dapm); + n810_ext_control(dapm); return 1; } @@ -151,12 +153,13 @@ static int n810_set_jack(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_card *card = snd_kcontrol_chip(kcontrol); + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); if (n810_jack_func == ucontrol->value.enumerated.item[0]) return 0; n810_jack_func = ucontrol->value.enumerated.item[0]; - n810_ext_control(&card->dapm); + n810_ext_control(dapm); return 1; } @@ -173,12 +176,13 @@ static int n810_set_input(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_card *card = snd_kcontrol_chip(kcontrol); + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); if (n810_dmic_func == ucontrol->value.enumerated.item[0]) return 0; n810_dmic_func = ucontrol->value.enumerated.item[0]; - n810_ext_control(&card->dapm); + n810_ext_control(dapm); return 1; } diff --git a/sound/soc/ti/omap-abe-twl6040.c b/sound/soc/ti/omap-abe-twl6040.c index fb8727a7443629..56aa4b22083bbf 100644 --- a/sound/soc/ti/omap-abe-twl6040.c +++ b/sound/soc/ti/omap-abe-twl6040.c @@ -202,7 +202,7 @@ static const struct snd_soc_dapm_route dmic_audio_map[] = { static int omap_abe_dmic_init(struct snd_soc_pcm_runtime *rtd) { - struct snd_soc_dapm_context *dapm = &rtd->card->dapm; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(rtd->card); return snd_soc_dapm_add_routes(dapm, dmic_audio_map, ARRAY_SIZE(dmic_audio_map)); diff --git a/sound/soc/ti/omap-twl4030.c b/sound/soc/ti/omap-twl4030.c index 3548b58002c462..4d80f8a7a94779 100644 --- a/sound/soc/ti/omap-twl4030.c +++ b/sound/soc/ti/omap-twl4030.c @@ -143,7 +143,7 @@ static inline void twl4030_disconnect_pin(struct snd_soc_dapm_context *dapm, static int omap_twl4030_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_card *card = rtd->card; - struct snd_soc_dapm_context *dapm = &card->dapm; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); struct omap_tw4030_pdata *pdata = dev_get_platdata(card->dev); struct omap_twl4030 *priv = snd_soc_card_get_drvdata(card); int ret = 0; diff --git a/sound/soc/ti/omap3pandora.c b/sound/soc/ti/omap3pandora.c index 808fb6765c05fc..f11b1d8a1306c0 100644 --- a/sound/soc/ti/omap3pandora.c +++ b/sound/soc/ti/omap3pandora.c @@ -71,9 +71,11 @@ static int omap3pandora_dac_event(struct snd_soc_dapm_widget *w, * VCC power on/off and /PD pin high/low */ if (SND_SOC_DAPM_EVENT_ON(event)) { + struct device *dev = snd_soc_dapm_to_dev(w->dapm); + ret = regulator_enable(omap3pandora_dac_reg); if (ret) { - dev_err(w->dapm->dev, "Failed to power DAC: %d\n", ret); + dev_err(dev, "Failed to power DAC: %d\n", ret); return ret; } mdelay(1); @@ -139,32 +141,32 @@ static const struct snd_soc_dapm_route omap3pandora_map[] = { static int omap3pandora_out_init(struct snd_soc_pcm_runtime *rtd) { - struct snd_soc_dapm_context *dapm = &rtd->card->dapm; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(rtd->card); /* All TWL4030 output pins are floating */ - snd_soc_dapm_nc_pin(dapm, "EARPIECE"); - snd_soc_dapm_nc_pin(dapm, "PREDRIVEL"); - snd_soc_dapm_nc_pin(dapm, "PREDRIVER"); - snd_soc_dapm_nc_pin(dapm, "HSOL"); - snd_soc_dapm_nc_pin(dapm, "HSOR"); - snd_soc_dapm_nc_pin(dapm, "CARKITL"); - snd_soc_dapm_nc_pin(dapm, "CARKITR"); - snd_soc_dapm_nc_pin(dapm, "HFL"); - snd_soc_dapm_nc_pin(dapm, "HFR"); - snd_soc_dapm_nc_pin(dapm, "VIBRA"); + snd_soc_dapm_disable_pin(dapm, "EARPIECE"); + snd_soc_dapm_disable_pin(dapm, "PREDRIVEL"); + snd_soc_dapm_disable_pin(dapm, "PREDRIVER"); + snd_soc_dapm_disable_pin(dapm, "HSOL"); + snd_soc_dapm_disable_pin(dapm, "HSOR"); + snd_soc_dapm_disable_pin(dapm, "CARKITL"); + snd_soc_dapm_disable_pin(dapm, "CARKITR"); + snd_soc_dapm_disable_pin(dapm, "HFL"); + snd_soc_dapm_disable_pin(dapm, "HFR"); + snd_soc_dapm_disable_pin(dapm, "VIBRA"); return 0; } static int omap3pandora_in_init(struct snd_soc_pcm_runtime *rtd) { - struct snd_soc_dapm_context *dapm = &rtd->card->dapm; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(rtd->card); /* Not comnnected */ - snd_soc_dapm_nc_pin(dapm, "HSMIC"); - snd_soc_dapm_nc_pin(dapm, "CARKITMIC"); - snd_soc_dapm_nc_pin(dapm, "DIGIMIC0"); - snd_soc_dapm_nc_pin(dapm, "DIGIMIC1"); + snd_soc_dapm_disable_pin(dapm, "HSMIC"); + snd_soc_dapm_disable_pin(dapm, "CARKITMIC"); + snd_soc_dapm_disable_pin(dapm, "DIGIMIC0"); + snd_soc_dapm_disable_pin(dapm, "DIGIMIC1"); return 0; } diff --git a/sound/soc/ti/rx51.c b/sound/soc/ti/rx51.c index e969031657e9aa..7eeb12e5066c4a 100644 --- a/sound/soc/ti/rx51.c +++ b/sound/soc/ti/rx51.c @@ -42,7 +42,7 @@ static int rx51_jack_func; static void rx51_ext_control(struct snd_soc_dapm_context *dapm) { - struct snd_soc_card *card = dapm->card; + struct snd_soc_card *card = snd_soc_dapm_to_card(dapm); struct rx51_audio_pdata *pdata = snd_soc_card_get_drvdata(card); int hp = 0, hs = 0, tvout = 0; @@ -89,10 +89,10 @@ static int rx51_startup(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); - struct snd_soc_card *card = rtd->card; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(rtd->card); snd_pcm_hw_constraint_single(runtime, SNDRV_PCM_HW_PARAM_CHANNELS, 2); - rx51_ext_control(&card->dapm); + rx51_ext_control(dapm); return 0; } @@ -125,12 +125,13 @@ static int rx51_set_spk(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_card *card = snd_kcontrol_chip(kcontrol); + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); if (rx51_spk_func == ucontrol->value.enumerated.item[0]) return 0; rx51_spk_func = ucontrol->value.enumerated.item[0]; - rx51_ext_control(&card->dapm); + rx51_ext_control(dapm); return 1; } @@ -139,7 +140,7 @@ static int rx51_spk_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *k, int event) { struct snd_soc_dapm_context *dapm = w->dapm; - struct snd_soc_card *card = dapm->card; + struct snd_soc_card *card = snd_soc_dapm_to_card(dapm); struct rx51_audio_pdata *pdata = snd_soc_card_get_drvdata(card); gpiod_set_raw_value_cansleep(pdata->speaker_amp_gpio, @@ -160,12 +161,13 @@ static int rx51_set_input(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_card *card = snd_kcontrol_chip(kcontrol); + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); if (rx51_dmic_func == ucontrol->value.enumerated.item[0]) return 0; rx51_dmic_func = ucontrol->value.enumerated.item[0]; - rx51_ext_control(&card->dapm); + rx51_ext_control(dapm); return 1; } @@ -182,12 +184,13 @@ static int rx51_set_jack(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_card *card = snd_kcontrol_chip(kcontrol); + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); if (rx51_jack_func == ucontrol->value.enumerated.item[0]) return 0; rx51_jack_func = ucontrol->value.enumerated.item[0]; - rx51_ext_control(&card->dapm); + rx51_ext_control(dapm); return 1; } diff --git a/sound/soc/ux500/mop500_ab8500.c b/sound/soc/ux500/mop500_ab8500.c index 5246f73ef12e12..2e6ed19a18cdd4 100644 --- a/sound/soc/ux500/mop500_ab8500.c +++ b/sound/soc/ux500/mop500_ab8500.c @@ -357,7 +357,7 @@ const struct snd_soc_ops mop500_ab8500_ops[] = { int mop500_ab8500_machine_init(struct snd_soc_pcm_runtime *rtd) { - struct snd_soc_dapm_context *dapm = &rtd->card->dapm; + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(rtd->card); struct device *dev = rtd->card->dev; struct mop500_ab8500_drvdata *drvdata; int ret; diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c index 880f5afcce60a7..cc15624ecaffe8 100644 --- a/sound/usb/endpoint.c +++ b/sound/usb/endpoint.c @@ -1362,6 +1362,11 @@ int snd_usb_endpoint_set_params(struct snd_usb_audio *chip, ep->sample_rem = ep->cur_rate % ep->pps; ep->packsize[0] = ep->cur_rate / ep->pps; ep->packsize[1] = (ep->cur_rate + (ep->pps - 1)) / ep->pps; + if (ep->packsize[1] > ep->maxpacksize) { + usb_audio_dbg(chip, "Too small maxpacksize %u for rate %u / pps %u\n", + ep->maxpacksize, ep->cur_rate, ep->pps); + return -EINVAL; + } /* calculate the frequency in 16.16 format */ ep->freqm = ep->freqn; diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c index 6f00e0d5238257..72b900505d2c39 100644 --- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c @@ -3086,6 +3086,8 @@ static int snd_usb_mixer_controls_badd(struct usb_mixer_interface *mixer, int i; assoc = usb_ifnum_to_if(dev, ctrlif)->intf_assoc; + if (!assoc) + return -EINVAL; /* Detect BADD capture/playback channels from AS EP descriptors */ for (i = 0; i < assoc->bInterfaceCount; i++) { diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c index 828af3095b86ee..fe6c2cebc7f0db 100644 --- a/sound/usb/mixer_quirks.c +++ b/sound/usb/mixer_quirks.c @@ -2277,7 +2277,8 @@ static int realtek_resume_jack(struct usb_mixer_elem_list *list) } static int realtek_add_jack(struct usb_mixer_interface *mixer, - char *name, u32 val) + char *name, u32 val, int unitid, + const struct snd_kcontrol_new *kctl_new) { struct usb_mixer_elem_info *cval; struct snd_kcontrol *kctl; @@ -2285,14 +2286,13 @@ static int realtek_add_jack(struct usb_mixer_interface *mixer, cval = kzalloc(sizeof(*cval), GFP_KERNEL); if (!cval) return -ENOMEM; - snd_usb_mixer_elem_init_std(&cval->head, mixer, - REALTEK_JACK_INTERRUPT_NODE); + snd_usb_mixer_elem_init_std(&cval->head, mixer, unitid); cval->head.resume = realtek_resume_jack; cval->val_type = USB_MIXER_BOOLEAN; cval->channels = 1; cval->min = 0; cval->max = 1; - kctl = snd_ctl_new1(&realtek_connector_ctl_ro, cval); + kctl = snd_ctl_new1(kctl_new, cval); if (!kctl) { kfree(cval); return -ENOMEM; @@ -2322,14 +2322,20 @@ static int dell_dock_mixer_create(struct usb_mixer_interface *mixer) USB_RECIP_DEVICE | USB_TYPE_VENDOR | USB_DIR_OUT, 0, 0, NULL, 0); - err = realtek_add_jack(mixer, "Line Out Jack", REALTEK_LINE1); + err = realtek_add_jack(mixer, "Line Out Jack", REALTEK_LINE1, + REALTEK_JACK_INTERRUPT_NODE, + &realtek_connector_ctl_ro); if (err < 0) return err; - err = realtek_add_jack(mixer, "Headphone Jack", REALTEK_HP_OUT); + err = realtek_add_jack(mixer, "Headphone Jack", REALTEK_HP_OUT, + REALTEK_JACK_INTERRUPT_NODE, + &realtek_connector_ctl_ro); if (err < 0) return err; err = realtek_add_jack(mixer, "Headset Mic Jack", - REALTEK_HP_OUT | REALTEK_MIC_FLAG); + REALTEK_HP_OUT | REALTEK_MIC_FLAG, + REALTEK_JACK_INTERRUPT_NODE, + &realtek_connector_ctl_ro); if (err < 0) return err; return 0; @@ -2357,6 +2363,105 @@ static int dell_dock_mixer_init(struct usb_mixer_interface *mixer) return 0; } +/* + * HP Thunderbolt Dock G2 jack detection + * + * Similar to the Dell WD15/WD19, but with different commands. + */ + +#define HP_DOCK_JACK_INTERRUPT_NODE 7 + +#define HP_DOCK_GET 37 + +#define HP_DOCK_JACK_PRESENCE 0xffb8 +#define HP_DOCK_JACK_PRESENCE_BIT BIT(2) + +#define HP_DOCK_MIC_SENSE 0xf753 +#define HP_DOCK_MIC_SENSE_COMPLETE_BIT BIT(4) + +#define HP_DOCK_MIC_SENSE_MASK (BIT(2) | BIT(1) | BIT(0)) +/* #define HP_DOCK_MIC_SENSE_PRESENT 0x2 */ +#define HP_DOCK_MIC_SENSE_NOT_PRESENT 0x4 + +static int hp_dock_ctl_connector_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct usb_mixer_elem_info *cval = snd_kcontrol_chip(kcontrol); + struct snd_usb_audio *chip = cval->head.mixer->chip; + u32 pv = kcontrol->private_value; + bool presence; + int err; + u8 buf; + + CLASS(snd_usb_lock, pm)(chip); + if (pm.err < 0) + return pm.err; + + err = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), + HP_DOCK_GET, + USB_RECIP_DEVICE | USB_TYPE_VENDOR | USB_DIR_IN, + 0, HP_DOCK_JACK_PRESENCE, &buf, sizeof(buf)); + if (err < 0) + return err; + + presence = !(buf & HP_DOCK_JACK_PRESENCE_BIT); + + if (pv && presence) { + for (int i = 0; i < 20; i++) { + err = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), + HP_DOCK_GET, + USB_RECIP_DEVICE | USB_TYPE_VENDOR | USB_DIR_IN, + 0, HP_DOCK_MIC_SENSE, &buf, sizeof(buf)); + if (err < 0) + return err; + + /* Mic sense is complete, we have a result. */ + if (buf & HP_DOCK_MIC_SENSE_COMPLETE_BIT) + break; + + msleep(100); + } + + /* + * If we reach the retry limit without mic sense having + * completed, buf will contain HP_DOCK_MIC_SENSE_PRESENT, + * thus presence remains true even when detection fails. + */ + if ((buf & HP_DOCK_MIC_SENSE_MASK) == HP_DOCK_MIC_SENSE_NOT_PRESENT) + presence = false; + } + ucontrol->value.integer.value[0] = presence; + return 0; +} + +static const struct snd_kcontrol_new hp_dock_connector_ctl_ro = { + .iface = SNDRV_CTL_ELEM_IFACE_CARD, + .name = "", /* will be filled later manually */ + .access = SNDRV_CTL_ELEM_ACCESS_READ, + .info = snd_ctl_boolean_mono_info, + .get = hp_dock_ctl_connector_get, +}; + +static int hp_dock_mixer_create(struct usb_mixer_interface *mixer) +{ + int err; + + err = realtek_add_jack(mixer, "Headsets Playback Jack", 0, + HP_DOCK_JACK_INTERRUPT_NODE, + &hp_dock_connector_ctl_ro); + if (err < 0) + return err; + + err = realtek_add_jack(mixer, "Headset Capture Jack", 1, + HP_DOCK_JACK_INTERRUPT_NODE, + &hp_dock_connector_ctl_ro); + if (err < 0) + return err; + + return 0; +} + + /* RME Class Compliant device quirks */ #define SND_RME_GET_STATUS1 23 @@ -4408,6 +4513,9 @@ int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer) case USB_ID(0x2b73, 0x0034): /* Pioneer DJ DJM-V10 */ err = snd_djm_controls_create(mixer, SND_DJM_V10_IDX); break; + case USB_ID(0x03f0, 0x0269): /* HP TB Dock G2 */ + err = hp_dock_mixer_create(mixer); + break; } return err; diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c index 71638e6dfb204b..61bd61ffb1b230 100644 --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c @@ -2022,12 +2022,15 @@ u64 snd_usb_interface_dsd_format_quirks(struct snd_usb_audio *chip, case USB_ID(0x16d0, 0x09d8): /* NuPrime IDA-8 */ case USB_ID(0x16d0, 0x09db): /* NuPrime Audio DAC-9 */ case USB_ID(0x16d0, 0x09dd): /* Encore mDSD */ + case USB_ID(0x16d0, 0x0ab1): /* PureAudio APA DAC */ + case USB_ID(0x16d0, 0xeca1): /* PureAudio Lotus DAC5, DAC5 SE, DAC5 Pro */ case USB_ID(0x1db5, 0x0003): /* Bryston BDA3 */ case USB_ID(0x20a0, 0x4143): /* WaveIO USB Audio 2.0 */ case USB_ID(0x22e1, 0xca01): /* HDTA Serenade DSD */ case USB_ID(0x249c, 0x9326): /* M2Tech Young MkIII */ case USB_ID(0x2616, 0x0106): /* PS Audio NuWave DAC */ case USB_ID(0x2622, 0x0041): /* Audiolab M-DAC+ */ + case USB_ID(0x2622, 0x0061): /* LEAK Stereo 230 */ case USB_ID(0x278b, 0x5100): /* Rotel RC-1590 */ case USB_ID(0x27f7, 0x3002): /* W4S DAC-2v2SE */ case USB_ID(0x29a2, 0x0086): /* Mutec MC3+ USB */ @@ -2267,6 +2270,8 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = { QUIRK_FLAG_FIXED_RATE), DEVICE_FLG(0x0fd9, 0x0008, /* Hauppauge HVR-950Q */ QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER), + DEVICE_FLG(0x1038, 0x1294, /* SteelSeries Arctis Pro Wireless */ + QUIRK_FLAG_MIXER_PLAYBACK_MIN_MUTE), DEVICE_FLG(0x1101, 0x0003, /* Audioengine D1 */ QUIRK_FLAG_GET_SAMPLE_RATE), DEVICE_FLG(0x12d1, 0x3a07, /* Huawei Technologies Co., Ltd. */ @@ -2297,6 +2302,10 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = { QUIRK_FLAG_IGNORE_CLOCK_SOURCE), DEVICE_FLG(0x1686, 0x00dd, /* Zoom R16/24 */ QUIRK_FLAG_TX_LENGTH | QUIRK_FLAG_CTL_MSG_DELAY_1M), + DEVICE_FLG(0x16d0, 0x0ab1, /* PureAudio APA DAC */ + QUIRK_FLAG_DSD_RAW), + DEVICE_FLG(0x16d0, 0xeca1, /* PureAudio Lotus DAC5, DAC5 SE and DAC5 Pro */ + QUIRK_FLAG_DSD_RAW), DEVICE_FLG(0x17aa, 0x1046, /* Lenovo ThinkStation P620 Rear Line-in, Line-out and Microphone */ QUIRK_FLAG_DISABLE_AUTOSUSPEND), DEVICE_FLG(0x17aa, 0x104d, /* Lenovo ThinkStation P620 Internal Speaker + Front Headset */ @@ -2420,6 +2429,8 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = { QUIRK_FLAG_DSD_RAW), VENDOR_FLG(0x25ce, /* Mytek devices */ QUIRK_FLAG_DSD_RAW), + VENDOR_FLG(0x2622, /* IAG Limited devices */ + QUIRK_FLAG_DSD_RAW), VENDOR_FLG(0x278b, /* Rotel? */ QUIRK_FLAG_DSD_RAW), VENDOR_FLG(0x292b, /* Gustard/Ess based devices */ diff --git a/sound/usb/stream.c b/sound/usb/stream.c index 5c235a5ba7e1b1..074a61215de6b2 100644 --- a/sound/usb/stream.c +++ b/sound/usb/stream.c @@ -684,6 +684,37 @@ snd_usb_find_output_terminal_descriptor(struct usb_host_interface *ctrl_iface, return NULL; } +static unsigned int +snd_usb_max_bytes_per_interval(struct snd_usb_audio *chip, + struct usb_host_interface *alts) +{ + struct usb_host_endpoint *ep = &alts->endpoint[0]; + unsigned int max_bytes = usb_endpoint_maxp(&ep->desc); + + /* SuperSpeed isoc endpoints have up to 16 bursts of up to 3 packets each */ + if (snd_usb_get_speed(chip->dev) >= USB_SPEED_SUPER) { + int burst = 1 + ep->ss_ep_comp.bMaxBurst; + int mult = USB_SS_MULT(ep->ss_ep_comp.bmAttributes); + max_bytes *= burst; + max_bytes *= mult; + } + + if (snd_usb_get_speed(chip->dev) == USB_SPEED_SUPER_PLUS && + USB_SS_SSP_ISOC_COMP(ep->ss_ep_comp.bmAttributes)) { + max_bytes = le32_to_cpu(ep->ssp_isoc_ep_comp.dwBytesPerInterval); + } + + /* High speed, 1-3 packets/uframe, max 6 for eUSB2 double bw */ + if (snd_usb_get_speed(chip->dev) == USB_SPEED_HIGH) { + if (usb_endpoint_is_hs_isoc_double(chip->dev, ep)) + max_bytes = le32_to_cpu(ep->eusb2_isoc_ep_comp.dwBytesPerInterval); + else + max_bytes *= usb_endpoint_maxp_mult(&ep->desc); + } + + return max_bytes; +} + static struct audioformat * audio_format_alloc_init(struct snd_usb_audio *chip, struct usb_host_interface *alts, @@ -703,11 +734,8 @@ audio_format_alloc_init(struct snd_usb_audio *chip, fp->ep_attr = get_endpoint(alts, 0)->bmAttributes; fp->datainterval = snd_usb_parse_datainterval(chip, alts); fp->protocol = protocol; - fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize); + fp->maxpacksize = snd_usb_max_bytes_per_interval(chip, alts); fp->channels = num_channels; - if (snd_usb_get_speed(chip->dev) == USB_SPEED_HIGH) - fp->maxpacksize = (((fp->maxpacksize >> 11) & 3) + 1) - * (fp->maxpacksize & 0x7ff); fp->clock = clock; INIT_LIST_HEAD(&fp->list); diff --git a/tools/arch/riscv/include/asm/csr.h b/tools/arch/riscv/include/asm/csr.h index 56d7367ee344c1..21d8cee046383d 100644 --- a/tools/arch/riscv/include/asm/csr.h +++ b/tools/arch/riscv/include/asm/csr.h @@ -167,7 +167,8 @@ #define VSIP_TO_HVIP_SHIFT (IRQ_VS_SOFT - IRQ_S_SOFT) #define VSIP_VALID_MASK ((_AC(1, UL) << IRQ_S_SOFT) | \ (_AC(1, UL) << IRQ_S_TIMER) | \ - (_AC(1, UL) << IRQ_S_EXT)) + (_AC(1, UL) << IRQ_S_EXT) | \ + (_AC(1, UL) << IRQ_PMU_OVF)) /* AIA CSR bits */ #define TOPI_IID_SHIFT 16 @@ -280,7 +281,7 @@ #define CSR_HPMCOUNTER30H 0xc9e #define CSR_HPMCOUNTER31H 0xc9f -#define CSR_SSCOUNTOVF 0xda0 +#define CSR_SCOUNTOVF 0xda0 #define CSR_SSTATUS 0x100 #define CSR_SIE 0x104 diff --git a/tools/arch/x86/include/asm/cpufeatures.h b/tools/arch/x86/include/asm/cpufeatures.h index 06fc0479a23f01..4091a776e37aae 100644 --- a/tools/arch/x86/include/asm/cpufeatures.h +++ b/tools/arch/x86/include/asm/cpufeatures.h @@ -444,6 +444,7 @@ #define X86_FEATURE_VM_PAGE_FLUSH (19*32+ 2) /* VM Page Flush MSR is supported */ #define X86_FEATURE_SEV_ES (19*32+ 3) /* "sev_es" Secure Encrypted Virtualization - Encrypted State */ #define X86_FEATURE_SEV_SNP (19*32+ 4) /* "sev_snp" Secure Encrypted Virtualization - Secure Nested Paging */ +#define X86_FEATURE_SNP_SECURE_TSC (19*32+ 8) /* SEV-SNP Secure TSC */ #define X86_FEATURE_V_TSC_AUX (19*32+ 9) /* Virtual TSC_AUX */ #define X86_FEATURE_SME_COHERENT (19*32+10) /* hardware-enforced cache coherency */ #define X86_FEATURE_DEBUG_SWAP (19*32+14) /* "debug_swap" SEV-ES full debug state swap support */ @@ -495,6 +496,9 @@ #define X86_FEATURE_TSA_SQ_NO (21*32+11) /* AMD CPU not vulnerable to TSA-SQ */ #define X86_FEATURE_TSA_L1_NO (21*32+12) /* AMD CPU not vulnerable to TSA-L1 */ #define X86_FEATURE_CLEAR_CPU_BUF_VM (21*32+13) /* Clear CPU buffers using VERW before VMRUN */ +#define X86_FEATURE_IBPB_EXIT_TO_USER (21*32+14) /* Use IBPB on exit-to-userspace, see VMSCAPE bug */ +#define X86_FEATURE_ABMC (21*32+15) /* Assignable Bandwidth Monitoring Counters */ +#define X86_FEATURE_MSR_IMM (21*32+16) /* MSR immediate form instructions */ /* * BUG word(s) @@ -551,4 +555,5 @@ #define X86_BUG_ITS X86_BUG( 1*32+ 7) /* "its" CPU is affected by Indirect Target Selection */ #define X86_BUG_ITS_NATIVE_ONLY X86_BUG( 1*32+ 8) /* "its_native_only" CPU is affected by ITS, VMX is not affected */ #define X86_BUG_TSA X86_BUG( 1*32+ 9) /* "tsa" CPU is affected by Transient Scheduler Attacks */ +#define X86_BUG_VMSCAPE X86_BUG( 1*32+10) /* "vmscape" CPU is affected by VMSCAPE attacks from guests */ #endif /* _ASM_X86_CPUFEATURES_H */ diff --git a/tools/arch/x86/include/asm/msr-index.h b/tools/arch/x86/include/asm/msr-index.h index f627196eb79662..9e1720d73244f6 100644 --- a/tools/arch/x86/include/asm/msr-index.h +++ b/tools/arch/x86/include/asm/msr-index.h @@ -315,9 +315,12 @@ #define PERF_CAP_PT_IDX 16 #define MSR_PEBS_LD_LAT_THRESHOLD 0x000003f6 + +#define PERF_CAP_LBR_FMT 0x3f #define PERF_CAP_PEBS_TRAP BIT_ULL(6) #define PERF_CAP_ARCH_REG BIT_ULL(7) #define PERF_CAP_PEBS_FORMAT 0xf00 +#define PERF_CAP_FW_WRITES BIT_ULL(13) #define PERF_CAP_PEBS_BASELINE BIT_ULL(14) #define PERF_CAP_PEBS_TIMING_INFO BIT_ULL(17) #define PERF_CAP_PEBS_MASK (PERF_CAP_PEBS_TRAP | PERF_CAP_ARCH_REG | \ @@ -633,6 +636,11 @@ #define MSR_AMD_PPIN 0xc00102f1 #define MSR_AMD64_CPUID_FN_7 0xc0011002 #define MSR_AMD64_CPUID_FN_1 0xc0011004 + +#define MSR_AMD64_CPUID_EXT_FEAT 0xc0011005 +#define MSR_AMD64_CPUID_EXT_FEAT_TOPOEXT_BIT 54 +#define MSR_AMD64_CPUID_EXT_FEAT_TOPOEXT BIT_ULL(MSR_AMD64_CPUID_EXT_FEAT_TOPOEXT_BIT) + #define MSR_AMD64_LS_CFG 0xc0011020 #define MSR_AMD64_DC_CFG 0xc0011022 #define MSR_AMD64_TW_CFG 0xc0011023 @@ -701,8 +709,15 @@ #define MSR_AMD64_SNP_VMSA_REG_PROT BIT_ULL(MSR_AMD64_SNP_VMSA_REG_PROT_BIT) #define MSR_AMD64_SNP_SMT_PROT_BIT 17 #define MSR_AMD64_SNP_SMT_PROT BIT_ULL(MSR_AMD64_SNP_SMT_PROT_BIT) -#define MSR_AMD64_SNP_RESV_BIT 18 +#define MSR_AMD64_SNP_SECURE_AVIC_BIT 18 +#define MSR_AMD64_SNP_SECURE_AVIC BIT_ULL(MSR_AMD64_SNP_SECURE_AVIC_BIT) +#define MSR_AMD64_SNP_RESV_BIT 19 #define MSR_AMD64_SNP_RESERVED_MASK GENMASK_ULL(63, MSR_AMD64_SNP_RESV_BIT) +#define MSR_AMD64_SAVIC_CONTROL 0xc0010138 +#define MSR_AMD64_SAVIC_EN_BIT 0 +#define MSR_AMD64_SAVIC_EN BIT_ULL(MSR_AMD64_SAVIC_EN_BIT) +#define MSR_AMD64_SAVIC_ALLOWEDNMI_BIT 1 +#define MSR_AMD64_SAVIC_ALLOWEDNMI BIT_ULL(MSR_AMD64_SAVIC_ALLOWEDNMI_BIT) #define MSR_AMD64_RMP_BASE 0xc0010132 #define MSR_AMD64_RMP_END 0xc0010133 #define MSR_AMD64_RMP_CFG 0xc0010136 @@ -735,6 +750,7 @@ #define MSR_AMD64_PERF_CNTR_GLOBAL_STATUS 0xc0000300 #define MSR_AMD64_PERF_CNTR_GLOBAL_CTL 0xc0000301 #define MSR_AMD64_PERF_CNTR_GLOBAL_STATUS_CLR 0xc0000302 +#define MSR_AMD64_PERF_CNTR_GLOBAL_STATUS_SET 0xc0000303 /* AMD Hardware Feedback Support MSRs */ #define MSR_AMD_WORKLOAD_CLASS_CONFIG 0xc0000500 @@ -1225,6 +1241,8 @@ /* - AMD: */ #define MSR_IA32_MBA_BW_BASE 0xc0000200 #define MSR_IA32_SMBA_BW_BASE 0xc0000280 +#define MSR_IA32_L3_QOS_ABMC_CFG 0xc00003fd +#define MSR_IA32_L3_QOS_EXT_CFG 0xc00003ff #define MSR_IA32_EVT_CFG_BASE 0xc0000400 /* AMD-V MSRs */ diff --git a/tools/arch/x86/include/uapi/asm/kvm.h b/tools/arch/x86/include/uapi/asm/kvm.h index 0f15d683817d6a..d420c9c066d48c 100644 --- a/tools/arch/x86/include/uapi/asm/kvm.h +++ b/tools/arch/x86/include/uapi/asm/kvm.h @@ -35,6 +35,11 @@ #define MC_VECTOR 18 #define XM_VECTOR 19 #define VE_VECTOR 20 +#define CP_VECTOR 21 + +#define HV_VECTOR 28 +#define VC_VECTOR 29 +#define SX_VECTOR 30 /* Select x86 specific features in */ #define __KVM_HAVE_PIT @@ -411,6 +416,35 @@ struct kvm_xcrs { __u64 padding[16]; }; +#define KVM_X86_REG_TYPE_MSR 2 +#define KVM_X86_REG_TYPE_KVM 3 + +#define KVM_X86_KVM_REG_SIZE(reg) \ +({ \ + reg == KVM_REG_GUEST_SSP ? KVM_REG_SIZE_U64 : 0; \ +}) + +#define KVM_X86_REG_TYPE_SIZE(type, reg) \ +({ \ + __u64 type_size = (__u64)type << 32; \ + \ + type_size |= type == KVM_X86_REG_TYPE_MSR ? KVM_REG_SIZE_U64 : \ + type == KVM_X86_REG_TYPE_KVM ? KVM_X86_KVM_REG_SIZE(reg) : \ + 0; \ + type_size; \ +}) + +#define KVM_X86_REG_ID(type, index) \ + (KVM_REG_X86 | KVM_X86_REG_TYPE_SIZE(type, index) | index) + +#define KVM_X86_REG_MSR(index) \ + KVM_X86_REG_ID(KVM_X86_REG_TYPE_MSR, index) +#define KVM_X86_REG_KVM(index) \ + KVM_X86_REG_ID(KVM_X86_REG_TYPE_KVM, index) + +/* KVM-defined registers starting from 0 */ +#define KVM_REG_GUEST_SSP 0 + #define KVM_SYNC_X86_REGS (1UL << 0) #define KVM_SYNC_X86_SREGS (1UL << 1) #define KVM_SYNC_X86_EVENTS (1UL << 2) diff --git a/tools/arch/x86/include/uapi/asm/svm.h b/tools/arch/x86/include/uapi/asm/svm.h index 9c640a521a6700..650e3256ea7d73 100644 --- a/tools/arch/x86/include/uapi/asm/svm.h +++ b/tools/arch/x86/include/uapi/asm/svm.h @@ -118,6 +118,10 @@ #define SVM_VMGEXIT_AP_CREATE 1 #define SVM_VMGEXIT_AP_DESTROY 2 #define SVM_VMGEXIT_SNP_RUN_VMPL 0x80000018 +#define SVM_VMGEXIT_SAVIC 0x8000001a +#define SVM_VMGEXIT_SAVIC_REGISTER_GPA 0 +#define SVM_VMGEXIT_SAVIC_UNREGISTER_GPA 1 +#define SVM_VMGEXIT_SAVIC_SELF_GPA ~0ULL #define SVM_VMGEXIT_HV_FEATURES 0x8000fffd #define SVM_VMGEXIT_TERM_REQUEST 0x8000fffe #define SVM_VMGEXIT_TERM_REASON(reason_set, reason_code) \ diff --git a/tools/arch/x86/include/uapi/asm/vmx.h b/tools/arch/x86/include/uapi/asm/vmx.h index f0f4a4cf84a724..1baa86dfe02932 100644 --- a/tools/arch/x86/include/uapi/asm/vmx.h +++ b/tools/arch/x86/include/uapi/asm/vmx.h @@ -93,7 +93,10 @@ #define EXIT_REASON_TPAUSE 68 #define EXIT_REASON_BUS_LOCK 74 #define EXIT_REASON_NOTIFY 75 +#define EXIT_REASON_SEAMCALL 76 #define EXIT_REASON_TDCALL 77 +#define EXIT_REASON_MSR_READ_IMM 84 +#define EXIT_REASON_MSR_WRITE_IMM 85 #define VMX_EXIT_REASONS \ { EXIT_REASON_EXCEPTION_NMI, "EXCEPTION_NMI" }, \ @@ -158,7 +161,9 @@ { EXIT_REASON_TPAUSE, "TPAUSE" }, \ { EXIT_REASON_BUS_LOCK, "BUS_LOCK" }, \ { EXIT_REASON_NOTIFY, "NOTIFY" }, \ - { EXIT_REASON_TDCALL, "TDCALL" } + { EXIT_REASON_TDCALL, "TDCALL" }, \ + { EXIT_REASON_MSR_READ_IMM, "MSR_READ_IMM" }, \ + { EXIT_REASON_MSR_WRITE_IMM, "MSR_WRITE_IMM" } #define VMX_EXIT_REASON_FLAGS \ { VMX_EXIT_REASONS_FAILED_VMENTRY, "FAILED_VMENTRY" } diff --git a/tools/bpf/bpftool/Documentation/bpftool-prog.rst b/tools/bpf/bpftool/Documentation/bpftool-prog.rst index 009633294b0934..35aeeaf5f71166 100644 --- a/tools/bpf/bpftool/Documentation/bpftool-prog.rst +++ b/tools/bpf/bpftool/Documentation/bpftool-prog.rst @@ -182,7 +182,7 @@ bpftool prog tracelog bpftool prog tracelog { stdout | stderr } *PROG* Dump the BPF stream of the program. BPF programs can write to these streams - at runtime with the **bpf_stream_vprintk**\ () kfunc. The kernel may write + at runtime with the **bpf_stream_vprintk_impl**\ () kfunc. The kernel may write error messages to the standard error stream. This facility should be used only for debugging purposes. diff --git a/tools/build/feature/Makefile b/tools/build/feature/Makefile index 49b0add392b1c1..95646290cb89cd 100644 --- a/tools/build/feature/Makefile +++ b/tools/build/feature/Makefile @@ -107,7 +107,7 @@ all: $(FILES) __BUILD = $(CC) $(CFLAGS) -MD -Wall -Werror -o $@ $(patsubst %.bin,%.c,$(@F)) $(LDFLAGS) BUILD = $(__BUILD) > $(@:.bin=.make.output) 2>&1 BUILD_BFD = $(BUILD) -DPACKAGE='"perf"' -lbfd -ldl - BUILD_ALL = $(BUILD) -fstack-protector-all -O2 -D_FORTIFY_SOURCE=2 -ldw -lelf -lnuma -lelf -lslang $(FLAGS_PERL_EMBED) $(FLAGS_PYTHON_EMBED) -DPACKAGE='"perf"' -lbfd -ldl -lz -llzma -lzstd + BUILD_ALL = $(BUILD) -fstack-protector-all -O2 -D_FORTIFY_SOURCE=2 -ldw -lelf -lnuma -lelf -lslang $(FLAGS_PERL_EMBED) $(FLAGS_PYTHON_EMBED) -ldl -lz -llzma -lzstd __BUILDXX = $(CXX) $(CXXFLAGS) -MD -Wall -Werror -o $@ $(patsubst %.bin,%.cpp,$(@F)) $(LDFLAGS) BUILDXX = $(__BUILDXX) > $(@:.bin=.make.output) 2>&1 @@ -115,7 +115,7 @@ __BUILDXX = $(CXX) $(CXXFLAGS) -MD -Wall -Werror -o $@ $(patsubst %.bin,%.cpp,$( ############################### $(OUTPUT)test-all.bin: - $(BUILD_ALL) || $(BUILD_ALL) -lopcodes -liberty + $(BUILD_ALL) $(OUTPUT)test-hello.bin: $(BUILD) diff --git a/tools/include/asm-generic/bitops/__fls.h b/tools/include/asm-generic/bitops/__fls.h index e974ec932ec189..35f33780ca6c37 100644 --- a/tools/include/asm-generic/bitops/__fls.h +++ b/tools/include/asm-generic/bitops/__fls.h @@ -10,7 +10,7 @@ * * Undefined if no set bit exists, so code should check against 0 first. */ -static __always_inline unsigned int generic___fls(unsigned long word) +static __always_inline __attribute_const__ unsigned int generic___fls(unsigned long word) { unsigned int num = BITS_PER_LONG - 1; diff --git a/tools/include/asm-generic/bitops/fls.h b/tools/include/asm-generic/bitops/fls.h index 26f3ce1dd6e448..8eed3437edb95c 100644 --- a/tools/include/asm-generic/bitops/fls.h +++ b/tools/include/asm-generic/bitops/fls.h @@ -10,7 +10,7 @@ * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32. */ -static __always_inline int generic_fls(unsigned int x) +static __always_inline __attribute_const__ int generic_fls(unsigned int x) { int r = 32; diff --git a/tools/include/asm-generic/bitops/fls64.h b/tools/include/asm-generic/bitops/fls64.h index 866f2b2304ff63..b5f58dd261a370 100644 --- a/tools/include/asm-generic/bitops/fls64.h +++ b/tools/include/asm-generic/bitops/fls64.h @@ -16,7 +16,7 @@ * at position 64. */ #if BITS_PER_LONG == 32 -static __always_inline int fls64(__u64 x) +static __always_inline __attribute_const__ int fls64(__u64 x) { __u32 h = x >> 32; if (h) @@ -24,7 +24,7 @@ static __always_inline int fls64(__u64 x) return fls(x); } #elif BITS_PER_LONG == 64 -static __always_inline int fls64(__u64 x) +static __always_inline __attribute_const__ int fls64(__u64 x) { if (x == 0) return 0; diff --git a/tools/include/uapi/drm/drm.h b/tools/include/uapi/drm/drm.h index e63a71d3c607a6..3cd5cf15e3c9ce 100644 --- a/tools/include/uapi/drm/drm.h +++ b/tools/include/uapi/drm/drm.h @@ -597,34 +597,65 @@ struct drm_set_version { int drm_dd_minor; }; -/* DRM_IOCTL_GEM_CLOSE ioctl argument type */ +/** + * struct drm_gem_close - Argument for &DRM_IOCTL_GEM_CLOSE ioctl. + * @handle: Handle of the object to be closed. + * @pad: Padding. + * + * Releases the handle to an mm object. + */ struct drm_gem_close { - /** Handle of the object to be closed. */ __u32 handle; __u32 pad; }; -/* DRM_IOCTL_GEM_FLINK ioctl argument type */ +/** + * struct drm_gem_flink - Argument for &DRM_IOCTL_GEM_FLINK ioctl. + * @handle: Handle for the object being named. + * @name: Returned global name. + * + * Create a global name for an object, returning the name. + * + * Note that the name does not hold a reference; when the object + * is freed, the name goes away. + */ struct drm_gem_flink { - /** Handle for the object being named */ __u32 handle; - - /** Returned global name */ __u32 name; }; -/* DRM_IOCTL_GEM_OPEN ioctl argument type */ +/** + * struct drm_gem_open - Argument for &DRM_IOCTL_GEM_OPEN ioctl. + * @name: Name of object being opened. + * @handle: Returned handle for the object. + * @size: Returned size of the object + * + * Open an object using the global name, returning a handle and the size. + * + * This handle (of course) holds a reference to the object, so the object + * will not go away until the handle is deleted. + */ struct drm_gem_open { - /** Name of object being opened */ __u32 name; - - /** Returned handle for the object */ __u32 handle; - - /** Returned size of the object */ __u64 size; }; +/** + * struct drm_gem_change_handle - Argument for &DRM_IOCTL_GEM_CHANGE_HANDLE ioctl. + * @handle: The handle of a gem object. + * @new_handle: An available gem handle. + * + * This ioctl changes the handle of a GEM object to the specified one. + * The new handle must be unused. On success the old handle is closed + * and all further IOCTL should refer to the new handle only. + * Calls to DRM_IOCTL_PRIME_FD_TO_HANDLE will return the new handle. + */ +struct drm_gem_change_handle { + __u32 handle; + __u32 new_handle; +}; + /** * DRM_CAP_DUMB_BUFFER * @@ -1309,6 +1340,14 @@ extern "C" { */ #define DRM_IOCTL_SET_CLIENT_NAME DRM_IOWR(0xD1, struct drm_set_client_name) +/** + * DRM_IOCTL_GEM_CHANGE_HANDLE - Move an object to a different handle + * + * Some applications (notably CRIU) need objects to have specific gem handles. + * This ioctl changes the object at one gem handle to use a new gem handle. + */ +#define DRM_IOCTL_GEM_CHANGE_HANDLE DRM_IOWR(0xD2, struct drm_gem_change_handle) + /* * Device specific ioctls should only be in their respective headers * The device specific ioctl range is from 0x40 to 0x9f. diff --git a/tools/include/uapi/linux/kvm.h b/tools/include/uapi/linux/kvm.h index f0f0d49d254435..52f6000ab02084 100644 --- a/tools/include/uapi/linux/kvm.h +++ b/tools/include/uapi/linux/kvm.h @@ -962,6 +962,7 @@ struct kvm_enable_cap { #define KVM_CAP_ARM_EL2_E2H0 241 #define KVM_CAP_RISCV_MP_STATE_RESET 242 #define KVM_CAP_ARM_CACHEABLE_PFNMAP_SUPPORTED 243 +#define KVM_CAP_GUEST_MEMFD_FLAGS 244 struct kvm_irq_routing_irqchip { __u32 irqchip; @@ -1598,6 +1599,8 @@ struct kvm_memory_attributes { #define KVM_MEMORY_ATTRIBUTE_PRIVATE (1ULL << 3) #define KVM_CREATE_GUEST_MEMFD _IOWR(KVMIO, 0xd4, struct kvm_create_guest_memfd) +#define GUEST_MEMFD_FLAG_MMAP (1ULL << 0) +#define GUEST_MEMFD_FLAG_INIT_SHARED (1ULL << 1) struct kvm_create_guest_memfd { __u64 size; diff --git a/tools/lib/bpf/bpf_helpers.h b/tools/lib/bpf/bpf_helpers.h index 80c02854065617..d4e4e388e62589 100644 --- a/tools/lib/bpf/bpf_helpers.h +++ b/tools/lib/bpf/bpf_helpers.h @@ -315,20 +315,20 @@ enum libbpf_tristate { ___param, sizeof(___param)); \ }) -extern int bpf_stream_vprintk(int stream_id, const char *fmt__str, const void *args, - __u32 len__sz, void *aux__prog) __weak __ksym; - -#define bpf_stream_printk(stream_id, fmt, args...) \ -({ \ - static const char ___fmt[] = fmt; \ - unsigned long long ___param[___bpf_narg(args)]; \ - \ - _Pragma("GCC diagnostic push") \ - _Pragma("GCC diagnostic ignored \"-Wint-conversion\"") \ - ___bpf_fill(___param, args); \ - _Pragma("GCC diagnostic pop") \ - \ - bpf_stream_vprintk(stream_id, ___fmt, ___param, sizeof(___param), NULL);\ +extern int bpf_stream_vprintk_impl(int stream_id, const char *fmt__str, const void *args, + __u32 len__sz, void *aux__prog) __weak __ksym; + +#define bpf_stream_printk(stream_id, fmt, args...) \ +({ \ + static const char ___fmt[] = fmt; \ + unsigned long long ___param[___bpf_narg(args)]; \ + \ + _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Wint-conversion\"") \ + ___bpf_fill(___param, args); \ + _Pragma("GCC diagnostic pop") \ + \ + bpf_stream_vprintk_impl(stream_id, ___fmt, ___param, sizeof(___param), NULL); \ }) /* Use __bpf_printk when bpf_printk call has 3 or fewer fmt args diff --git a/tools/net/ynl/pyynl/ynl_gen_c.py b/tools/net/ynl/pyynl/ynl_gen_c.py index 58086b1010573f..aadeb3abcad859 100755 --- a/tools/net/ynl/pyynl/ynl_gen_c.py +++ b/tools/net/ynl/pyynl/ynl_gen_c.py @@ -861,6 +861,18 @@ def _setter_lines(self, ri, member, presence): return [f"{member} = {self.c_name};", f"{presence} = n_{self.c_name};"] + def free_needs_iter(self): + return self.sub_type == 'nest' + + def _free_lines(self, ri, var, ref): + lines = [] + if self.sub_type == 'nest': + lines += [ + f"for (i = 0; i < {var}->{ref}_count.{self.c_name}; i++)", + f'{self.nested_render_name}_free(&{var}->{ref}{self.c_name}[i]);', + ] + lines += f"free({var}->{ref}{self.c_name});", + return lines class TypeNestTypeValue(Type): def _complex_member_type(self, ri): diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config index 5700516aa84aec..2dd5f5a60568d0 100644 --- a/tools/perf/Makefile.config +++ b/tools/perf/Makefile.config @@ -354,9 +354,6 @@ FEATURE_CHECK_LDFLAGS-libpython := $(PYTHON_EMBED_LDOPTS) FEATURE_CHECK_LDFLAGS-libaio = -lrt -FEATURE_CHECK_LDFLAGS-disassembler-four-args = -lbfd -lopcodes -ldl -FEATURE_CHECK_LDFLAGS-disassembler-init-styled = -lbfd -lopcodes -ldl - CORE_CFLAGS += -fno-omit-frame-pointer CORE_CFLAGS += -Wall CORE_CFLAGS += -Wextra @@ -930,6 +927,8 @@ ifdef BUILD_NONDISTRO ifeq ($(feature-libbfd), 1) EXTLIBS += -lbfd -lopcodes + FEATURE_CHECK_LDFLAGS-disassembler-four-args = -lbfd -lopcodes -ldl + FEATURE_CHECK_LDFLAGS-disassembler-init-styled = -lbfd -lopcodes -ldl else # we are on a system that requires -liberty and (maybe) -lz # to link against -lbfd; test each case individually here diff --git a/tools/perf/arch/x86/entry/syscalls/syscall_64.tbl b/tools/perf/arch/x86/entry/syscalls/syscall_64.tbl index 92cf0fe2291eb9..ced2a1deecd7ce 100644 --- a/tools/perf/arch/x86/entry/syscalls/syscall_64.tbl +++ b/tools/perf/arch/x86/entry/syscalls/syscall_64.tbl @@ -345,6 +345,7 @@ 333 common io_pgetevents sys_io_pgetevents 334 common rseq sys_rseq 335 common uretprobe sys_uretprobe +336 common uprobe sys_uprobe # don't use numbers 387 through 423, add new calls after the last # 'common' entry 424 common pidfd_send_signal sys_pidfd_send_signal diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c index 078634461df270..e8962c985d34a1 100644 --- a/tools/perf/builtin-lock.c +++ b/tools/perf/builtin-lock.c @@ -1867,6 +1867,7 @@ static int __cmd_report(bool display_info) eops.sample = process_sample_event; eops.comm = perf_event__process_comm; eops.mmap = perf_event__process_mmap; + eops.mmap2 = perf_event__process_mmap2; eops.namespaces = perf_event__process_namespaces; eops.tracing_data = perf_event__process_tracing_data; session = perf_session__new(&data, &eops); @@ -2023,6 +2024,7 @@ static int __cmd_contention(int argc, const char **argv) eops.sample = process_sample_event; eops.comm = perf_event__process_comm; eops.mmap = perf_event__process_mmap; + eops.mmap2 = perf_event__process_mmap2; eops.tracing_data = perf_event__process_tracing_data; perf_env__init(&host_env); diff --git a/tools/perf/tests/shell/lock_contention.sh b/tools/perf/tests/shell/lock_contention.sh index 7248a74ca2a325..6dd90519f45cec 100755 --- a/tools/perf/tests/shell/lock_contention.sh +++ b/tools/perf/tests/shell/lock_contention.sh @@ -13,15 +13,18 @@ cleanup() { rm -f ${perfdata} rm -f ${result} rm -f ${errout} - trap - EXIT TERM INT + trap - EXIT TERM INT ERR } trap_cleanup() { + if (( $? == 139 )); then #SIGSEGV + err=1 + fi echo "Unexpected signal in ${FUNCNAME[1]}" cleanup exit ${err} } -trap trap_cleanup EXIT TERM INT +trap trap_cleanup EXIT TERM INT ERR check() { if [ "$(id -u)" != 0 ]; then @@ -145,7 +148,7 @@ test_aggr_cgroup() fi # the perf lock contention output goes to the stderr - perf lock con -a -b -g -E 1 -q -- perf bench sched messaging -p > /dev/null 2> ${result} + perf lock con -a -b --lock-cgroup -E 1 -q -- perf bench sched messaging -p > /dev/null 2> ${result} if [ "$(cat "${result}" | wc -l)" != "1" ]; then echo "[Fail] BPF result count is not 1:" "$(cat "${result}" | wc -l)" err=1 @@ -271,7 +274,7 @@ test_cgroup_filter() return fi - perf lock con -a -b -g -E 1 -F wait_total -q -- perf bench sched messaging -p > /dev/null 2> ${result} + perf lock con -a -b --lock-cgroup -E 1 -F wait_total -q -- perf bench sched messaging -p > /dev/null 2> ${result} if [ "$(cat "${result}" | wc -l)" != "1" ]; then echo "[Fail] BPF result should have a cgroup result:" "$(cat "${result}")" err=1 @@ -279,7 +282,7 @@ test_cgroup_filter() fi cgroup=$(cat "${result}" | awk '{ print $3 }') - perf lock con -a -b -g -E 1 -G "${cgroup}" -q -- perf bench sched messaging -p > /dev/null 2> ${result} + perf lock con -a -b --lock-cgroup -E 1 -G "${cgroup}" -q -- perf bench sched messaging -p > /dev/null 2> ${result} if [ "$(cat "${result}" | wc -l)" != "1" ]; then echo "[Fail] BPF result should have a result with cgroup filter:" "$(cat "${cgroup}")" err=1 @@ -338,4 +341,5 @@ test_aggr_task_stack_filter test_cgroup_filter test_csv_output +cleanup exit ${err} diff --git a/tools/perf/trace/beauty/include/uapi/linux/fcntl.h b/tools/perf/trace/beauty/include/uapi/linux/fcntl.h index f291ab4f94ebcc..3741ea1b73d850 100644 --- a/tools/perf/trace/beauty/include/uapi/linux/fcntl.h +++ b/tools/perf/trace/beauty/include/uapi/linux/fcntl.h @@ -111,6 +111,7 @@ #define PIDFD_SELF_THREAD_GROUP -10001 /* Current thread group leader. */ #define FD_PIDFS_ROOT -10002 /* Root of the pidfs filesystem */ +#define FD_NSFS_ROOT -10003 /* Root of the nsfs filesystem */ #define FD_INVALID -10009 /* Invalid file descriptor: -10000 - EBADF = -10009 */ /* Generic flags for the *at(2) family of syscalls. */ diff --git a/tools/perf/trace/beauty/include/uapi/linux/fs.h b/tools/perf/trace/beauty/include/uapi/linux/fs.h index 0bd678a4a10ef8..beb4c2d1e41cb1 100644 --- a/tools/perf/trace/beauty/include/uapi/linux/fs.h +++ b/tools/perf/trace/beauty/include/uapi/linux/fs.h @@ -430,10 +430,13 @@ typedef int __bitwise __kernel_rwf_t; /* buffered IO that drops the cache after reading or writing data */ #define RWF_DONTCACHE ((__force __kernel_rwf_t)0x00000080) +/* prevent pipe and socket writes from raising SIGPIPE */ +#define RWF_NOSIGNAL ((__force __kernel_rwf_t)0x00000100) + /* mask of flags supported by the kernel */ #define RWF_SUPPORTED (RWF_HIPRI | RWF_DSYNC | RWF_SYNC | RWF_NOWAIT |\ RWF_APPEND | RWF_NOAPPEND | RWF_ATOMIC |\ - RWF_DONTCACHE) + RWF_DONTCACHE | RWF_NOSIGNAL) #define PROCFS_IOCTL_MAGIC 'f' diff --git a/tools/perf/trace/beauty/include/uapi/linux/prctl.h b/tools/perf/trace/beauty/include/uapi/linux/prctl.h index ed3aed264aeb28..51c4e8c82b1e98 100644 --- a/tools/perf/trace/beauty/include/uapi/linux/prctl.h +++ b/tools/perf/trace/beauty/include/uapi/linux/prctl.h @@ -177,7 +177,17 @@ struct prctl_mm_map { #define PR_GET_TID_ADDRESS 40 +/* + * Flags for PR_SET_THP_DISABLE are only applicable when disabling. Bit 0 + * is reserved, so PR_GET_THP_DISABLE can return "1 | flags", to effectively + * return "1" when no flags were specified for PR_SET_THP_DISABLE. + */ #define PR_SET_THP_DISABLE 41 +/* + * Don't disable THPs when explicitly advised (e.g., MADV_HUGEPAGE / + * VM_HUGEPAGE, MADV_COLLAPSE). + */ +# define PR_THP_DISABLE_EXCEPT_ADVISED (1 << 1) #define PR_GET_THP_DISABLE 42 /* diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 4f2a6e10ed5cc0..4e12be579140aa 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -1022,12 +1022,9 @@ static int write_bpf_prog_info(struct feat_fd *ff, down_read(&env->bpf_progs.lock); - if (env->bpf_progs.infos_cnt == 0) - goto out; - ret = do_write(ff, &env->bpf_progs.infos_cnt, sizeof(env->bpf_progs.infos_cnt)); - if (ret < 0) + if (ret < 0 || env->bpf_progs.infos_cnt == 0) goto out; root = &env->bpf_progs.infos; @@ -1067,13 +1064,10 @@ static int write_bpf_btf(struct feat_fd *ff, down_read(&env->bpf_progs.lock); - if (env->bpf_progs.btfs_cnt == 0) - goto out; - ret = do_write(ff, &env->bpf_progs.btfs_cnt, sizeof(env->bpf_progs.btfs_cnt)); - if (ret < 0) + if (ret < 0 || env->bpf_progs.btfs_cnt == 0) goto out; root = &env->bpf_progs.btfs; diff --git a/tools/perf/util/libbfd.c b/tools/perf/util/libbfd.c index 01147fbf73b376..6434c2dccd4a46 100644 --- a/tools/perf/util/libbfd.c +++ b/tools/perf/util/libbfd.c @@ -38,6 +38,39 @@ struct a2l_data { asymbol **syms; }; +static bool perf_bfd_lock(void *bfd_mutex) +{ + mutex_lock(bfd_mutex); + return true; +} + +static bool perf_bfd_unlock(void *bfd_mutex) +{ + mutex_unlock(bfd_mutex); + return true; +} + +static void perf_bfd_init(void) +{ + static struct mutex bfd_mutex; + + mutex_init_recursive(&bfd_mutex); + + if (bfd_init() != BFD_INIT_MAGIC) { + pr_err("Error initializing libbfd\n"); + return; + } + if (!bfd_thread_init(perf_bfd_lock, perf_bfd_unlock, &bfd_mutex)) + pr_err("Error initializing libbfd threading\n"); +} + +static void ensure_bfd_init(void) +{ + static pthread_once_t bfd_init_once = PTHREAD_ONCE_INIT; + + pthread_once(&bfd_init_once, perf_bfd_init); +} + static int bfd_error(const char *string) { const char *errmsg; @@ -132,6 +165,7 @@ static struct a2l_data *addr2line_init(const char *path) bfd *abfd; struct a2l_data *a2l = NULL; + ensure_bfd_init(); abfd = bfd_openr(path, NULL); if (abfd == NULL) return NULL; @@ -288,6 +322,7 @@ int dso__load_bfd_symbols(struct dso *dso, const char *debugfile) bfd *abfd; u64 start, len; + ensure_bfd_init(); abfd = bfd_openr(debugfile, NULL); if (!abfd) return -1; @@ -393,6 +428,7 @@ int libbfd__read_build_id(const char *filename, struct build_id *bid, bool block if (fd < 0) return -1; + ensure_bfd_init(); abfd = bfd_fdopenr(filename, /*target=*/NULL, fd); if (!abfd) return -1; @@ -421,6 +457,7 @@ int libbfd_filename__read_debuglink(const char *filename, char *debuglink, asection *section; bfd *abfd; + ensure_bfd_init(); abfd = bfd_openr(filename, NULL); if (!abfd) return -1; @@ -480,6 +517,7 @@ int symbol__disassemble_bpf_libbfd(struct symbol *sym __maybe_unused, memset(tpath, 0, sizeof(tpath)); perf_exe(tpath, sizeof(tpath)); + ensure_bfd_init(); bfdf = bfd_openr(tpath, NULL); if (bfdf == NULL) abort(); diff --git a/tools/perf/util/mutex.c b/tools/perf/util/mutex.c index bca7f0717f355e..7aa1f3f55a7d40 100644 --- a/tools/perf/util/mutex.c +++ b/tools/perf/util/mutex.c @@ -17,7 +17,7 @@ static void check_err(const char *fn, int err) #define CHECK_ERR(err) check_err(__func__, err) -static void __mutex_init(struct mutex *mtx, bool pshared) +static void __mutex_init(struct mutex *mtx, bool pshared, bool recursive) { pthread_mutexattr_t attr; @@ -27,21 +27,27 @@ static void __mutex_init(struct mutex *mtx, bool pshared) /* In normal builds enable error checking, such as recursive usage. */ CHECK_ERR(pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK)); #endif + if (recursive) + CHECK_ERR(pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE)); if (pshared) CHECK_ERR(pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED)); - CHECK_ERR(pthread_mutex_init(&mtx->lock, &attr)); CHECK_ERR(pthread_mutexattr_destroy(&attr)); } void mutex_init(struct mutex *mtx) { - __mutex_init(mtx, /*pshared=*/false); + __mutex_init(mtx, /*pshared=*/false, /*recursive=*/false); } void mutex_init_pshared(struct mutex *mtx) { - __mutex_init(mtx, /*pshared=*/true); + __mutex_init(mtx, /*pshared=*/true, /*recursive=*/false); +} + +void mutex_init_recursive(struct mutex *mtx) +{ + __mutex_init(mtx, /*pshared=*/false, /*recursive=*/true); } void mutex_destroy(struct mutex *mtx) diff --git a/tools/perf/util/mutex.h b/tools/perf/util/mutex.h index 38458f00846fed..70232d8d094f8b 100644 --- a/tools/perf/util/mutex.h +++ b/tools/perf/util/mutex.h @@ -104,6 +104,8 @@ void mutex_init(struct mutex *mtx); * process-private attribute. */ void mutex_init_pshared(struct mutex *mtx); +/* Initializes a mutex that may be recursively held on the same thread. */ +void mutex_init_recursive(struct mutex *mtx); void mutex_destroy(struct mutex *mtx); void mutex_lock(struct mutex *mtx) EXCLUSIVE_LOCK_FUNCTION(*mtx); diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index cc26b7bf302b29..948d3e8ad782bc 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -112,9 +112,13 @@ static bool symbol_type__filter(char __symbol_type) // 'N' first seen in: // ffffffff9b35d130 N __pfx__RNCINvNtNtNtCsbDUBuN8AbD4_4core4iter8adapters3map12map_try_foldjNtCs6vVzKs5jPr6_12drm_panic_qr7VersionuINtNtNtBa_3ops12control_flow11ControlFlowB10_ENcB10_0NCINvNvNtNtNtB8_6traits8iterator8Iterator4find5checkB10_NCNvMB12_B10_13from_segments0E0E0B12_ // a seemingly Rust mangled name + // Ditto for '1': + // root@x1:~# grep ' 1 ' /proc/kallsyms + // ffffffffb098bc00 1 __pfx__RNCINvNtNtNtCsfwaGRd4cjqE_4core4iter8adapters3map12map_try_foldjNtCskFudTml27HW_12drm_panic_qr7VersionuINtNtNtBa_3ops12control_flow11ControlFlowB10_ENcB10_0NCINvNvNtNtNtB8_6traits8iterator8Iterator4find5checkB10_NCNvMB12_B10_13from_segments0E0E0B12_ + // ffffffffb098bc10 1 _RNCINvNtNtNtCsfwaGRd4cjqE_4core4iter8adapters3map12map_try_foldjNtCskFudTml27HW_12drm_panic_qr7VersionuINtNtNtBa_3ops12control_flow11ControlFlowB10_ENcB10_0NCINvNvNtNtNtB8_6traits8iterator8Iterator4find5checkB10_NCNvMB12_B10_13from_segments0E0E0B12_ char symbol_type = toupper(__symbol_type); return symbol_type == 'T' || symbol_type == 'W' || symbol_type == 'D' || symbol_type == 'B' || - __symbol_type == 'u' || __symbol_type == 'l' || __symbol_type == 'N'; + __symbol_type == 'u' || __symbol_type == 'l' || __symbol_type == 'N' || __symbol_type == '1'; } static int prefix_underscores_count(const char *str) diff --git a/tools/testing/selftests/bpf/config b/tools/testing/selftests/bpf/config index 70b28c1e653ead..f2a2fd236ca839 100644 --- a/tools/testing/selftests/bpf/config +++ b/tools/testing/selftests/bpf/config @@ -50,6 +50,7 @@ CONFIG_IPV6_SIT=y CONFIG_IPV6_TUNNEL=y CONFIG_KEYS=y CONFIG_LIRC=y +CONFIG_LIVEPATCH=y CONFIG_LWTUNNEL=y CONFIG_MODULE_SIG=y CONFIG_MODULE_SRCVERSION_ALL=y @@ -111,6 +112,8 @@ CONFIG_IP6_NF_FILTER=y CONFIG_NF_NAT=y CONFIG_PACKET=y CONFIG_RC_CORE=y +CONFIG_SAMPLES=y +CONFIG_SAMPLE_LIVEPATCH=m CONFIG_SECURITY=y CONFIG_SECURITYFS=y CONFIG_SYN_COOKIES=y diff --git a/tools/testing/selftests/bpf/prog_tests/livepatch_trampoline.c b/tools/testing/selftests/bpf/prog_tests/livepatch_trampoline.c new file mode 100644 index 00000000000000..72aa5376c30e91 --- /dev/null +++ b/tools/testing/selftests/bpf/prog_tests/livepatch_trampoline.c @@ -0,0 +1,107 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (c) 2025 Meta Platforms, Inc. and affiliates. */ + +#include +#include "testing_helpers.h" +#include "livepatch_trampoline.skel.h" + +static int load_livepatch(void) +{ + char path[4096]; + + /* CI will set KBUILD_OUTPUT */ + snprintf(path, sizeof(path), "%s/samples/livepatch/livepatch-sample.ko", + getenv("KBUILD_OUTPUT") ? : "../../../.."); + + return load_module(path, env_verbosity > VERBOSE_NONE); +} + +static void unload_livepatch(void) +{ + /* Disable the livepatch before unloading the module */ + system("echo 0 > /sys/kernel/livepatch/livepatch_sample/enabled"); + + unload_module("livepatch_sample", env_verbosity > VERBOSE_NONE); +} + +static void read_proc_cmdline(void) +{ + char buf[4096]; + int fd, ret; + + fd = open("/proc/cmdline", O_RDONLY); + if (!ASSERT_OK_FD(fd, "open /proc/cmdline")) + return; + + ret = read(fd, buf, sizeof(buf)); + if (!ASSERT_GT(ret, 0, "read /proc/cmdline")) + goto out; + + ASSERT_OK(strncmp(buf, "this has been live patched", 26), "strncmp"); + +out: + close(fd); +} + +static void __test_livepatch_trampoline(bool fexit_first) +{ + struct livepatch_trampoline *skel = NULL; + int err; + + skel = livepatch_trampoline__open_and_load(); + if (!ASSERT_OK_PTR(skel, "skel_open_and_load")) + goto out; + + skel->bss->my_pid = getpid(); + + if (!fexit_first) { + /* fentry program is loaded first by default */ + err = livepatch_trampoline__attach(skel); + if (!ASSERT_OK(err, "skel_attach")) + goto out; + } else { + /* Manually load fexit program first. */ + skel->links.fexit_cmdline = bpf_program__attach(skel->progs.fexit_cmdline); + if (!ASSERT_OK_PTR(skel->links.fexit_cmdline, "attach_fexit")) + goto out; + + skel->links.fentry_cmdline = bpf_program__attach(skel->progs.fentry_cmdline); + if (!ASSERT_OK_PTR(skel->links.fentry_cmdline, "attach_fentry")) + goto out; + } + + read_proc_cmdline(); + + ASSERT_EQ(skel->bss->fentry_hit, 1, "fentry_hit"); + ASSERT_EQ(skel->bss->fexit_hit, 1, "fexit_hit"); +out: + livepatch_trampoline__destroy(skel); +} + +void test_livepatch_trampoline(void) +{ + int retry_cnt = 0; + +retry: + if (load_livepatch()) { + if (retry_cnt) { + ASSERT_OK(1, "load_livepatch"); + goto out; + } + /* + * Something else (previous run of the same test?) loaded + * the KLP module. Unload the KLP module and retry. + */ + unload_livepatch(); + retry_cnt++; + goto retry; + } + + if (test__start_subtest("fentry_first")) + __test_livepatch_trampoline(false); + + if (test__start_subtest("fexit_first")) + __test_livepatch_trampoline(true); +out: + unload_livepatch(); +} diff --git a/tools/testing/selftests/bpf/prog_tests/mptcp.c b/tools/testing/selftests/bpf/prog_tests/mptcp.c index f8eb7f9d4fd20b..8fade8bdc4516c 100644 --- a/tools/testing/selftests/bpf/prog_tests/mptcp.c +++ b/tools/testing/selftests/bpf/prog_tests/mptcp.c @@ -6,11 +6,13 @@ #include #include #include +#include #include "cgroup_helpers.h" #include "network_helpers.h" #include "mptcp_sock.skel.h" #include "mptcpify.skel.h" #include "mptcp_subflow.skel.h" +#include "mptcp_sockmap.skel.h" #define NS_TEST "mptcp_ns" #define ADDR_1 "10.0.1.1" @@ -436,6 +438,142 @@ static void test_subflow(void) close(cgroup_fd); } +/* Test sockmap on MPTCP server handling non-mp-capable clients. */ +static void test_sockmap_with_mptcp_fallback(struct mptcp_sockmap *skel) +{ + int listen_fd = -1, client_fd1 = -1, client_fd2 = -1; + int server_fd1 = -1, server_fd2 = -1, sent, recvd; + char snd[9] = "123456789"; + char rcv[10]; + + /* start server with MPTCP enabled */ + listen_fd = start_mptcp_server(AF_INET, NULL, 0, 0); + if (!ASSERT_OK_FD(listen_fd, "sockmap-fb:start_mptcp_server")) + return; + + skel->bss->trace_port = ntohs(get_socket_local_port(listen_fd)); + skel->bss->sk_index = 0; + /* create client without MPTCP enabled */ + client_fd1 = connect_to_fd_opts(listen_fd, NULL); + if (!ASSERT_OK_FD(client_fd1, "sockmap-fb:connect_to_fd")) + goto end; + + server_fd1 = accept(listen_fd, NULL, 0); + skel->bss->sk_index = 1; + client_fd2 = connect_to_fd_opts(listen_fd, NULL); + if (!ASSERT_OK_FD(client_fd2, "sockmap-fb:connect_to_fd")) + goto end; + + server_fd2 = accept(listen_fd, NULL, 0); + /* test normal redirect behavior: data sent by client_fd1 can be + * received by client_fd2 + */ + skel->bss->redirect_idx = 1; + sent = send(client_fd1, snd, sizeof(snd), 0); + if (!ASSERT_EQ(sent, sizeof(snd), "sockmap-fb:send(client_fd1)")) + goto end; + + /* try to recv more bytes to avoid truncation check */ + recvd = recv(client_fd2, rcv, sizeof(rcv), 0); + if (!ASSERT_EQ(recvd, sizeof(snd), "sockmap-fb:recv(client_fd2)")) + goto end; + +end: + if (client_fd1 >= 0) + close(client_fd1); + if (client_fd2 >= 0) + close(client_fd2); + if (server_fd1 >= 0) + close(server_fd1); + if (server_fd2 >= 0) + close(server_fd2); + close(listen_fd); +} + +/* Test sockmap rejection of MPTCP sockets - both server and client sides. */ +static void test_sockmap_reject_mptcp(struct mptcp_sockmap *skel) +{ + int listen_fd = -1, server_fd = -1, client_fd1 = -1; + int err, zero = 0; + + /* start server with MPTCP enabled */ + listen_fd = start_mptcp_server(AF_INET, NULL, 0, 0); + if (!ASSERT_OK_FD(listen_fd, "start_mptcp_server")) + return; + + skel->bss->trace_port = ntohs(get_socket_local_port(listen_fd)); + skel->bss->sk_index = 0; + /* create client with MPTCP enabled */ + client_fd1 = connect_to_fd(listen_fd, 0); + if (!ASSERT_OK_FD(client_fd1, "connect_to_fd client_fd1")) + goto end; + + /* bpf_sock_map_update() called from sockops should reject MPTCP sk */ + if (!ASSERT_EQ(skel->bss->helper_ret, -EOPNOTSUPP, "should reject")) + goto end; + + server_fd = accept(listen_fd, NULL, 0); + err = bpf_map_update_elem(bpf_map__fd(skel->maps.sock_map), + &zero, &server_fd, BPF_NOEXIST); + if (!ASSERT_EQ(err, -EOPNOTSUPP, "server should be disallowed")) + goto end; + + /* MPTCP client should also be disallowed */ + err = bpf_map_update_elem(bpf_map__fd(skel->maps.sock_map), + &zero, &client_fd1, BPF_NOEXIST); + if (!ASSERT_EQ(err, -EOPNOTSUPP, "client should be disallowed")) + goto end; +end: + if (client_fd1 >= 0) + close(client_fd1); + if (server_fd >= 0) + close(server_fd); + close(listen_fd); +} + +static void test_mptcp_sockmap(void) +{ + struct mptcp_sockmap *skel; + struct netns_obj *netns; + int cgroup_fd, err; + + cgroup_fd = test__join_cgroup("/mptcp_sockmap"); + if (!ASSERT_OK_FD(cgroup_fd, "join_cgroup: mptcp_sockmap")) + return; + + skel = mptcp_sockmap__open_and_load(); + if (!ASSERT_OK_PTR(skel, "skel_open_load: mptcp_sockmap")) + goto close_cgroup; + + skel->links.mptcp_sockmap_inject = + bpf_program__attach_cgroup(skel->progs.mptcp_sockmap_inject, cgroup_fd); + if (!ASSERT_OK_PTR(skel->links.mptcp_sockmap_inject, "attach sockmap")) + goto skel_destroy; + + err = bpf_prog_attach(bpf_program__fd(skel->progs.mptcp_sockmap_redirect), + bpf_map__fd(skel->maps.sock_map), + BPF_SK_SKB_STREAM_VERDICT, 0); + if (!ASSERT_OK(err, "bpf_prog_attach stream verdict")) + goto skel_destroy; + + netns = netns_new(NS_TEST, true); + if (!ASSERT_OK_PTR(netns, "netns_new: mptcp_sockmap")) + goto skel_destroy; + + if (endpoint_init("subflow") < 0) + goto close_netns; + + test_sockmap_with_mptcp_fallback(skel); + test_sockmap_reject_mptcp(skel); + +close_netns: + netns_free(netns); +skel_destroy: + mptcp_sockmap__destroy(skel); +close_cgroup: + close(cgroup_fd); +} + void test_mptcp(void) { if (test__start_subtest("base")) @@ -444,4 +582,6 @@ void test_mptcp(void) test_mptcpify(); if (test__start_subtest("subflow")) test_subflow(); + if (test__start_subtest("sockmap")) + test_mptcp_sockmap(); } diff --git a/tools/testing/selftests/bpf/prog_tests/stacktrace_ips.c b/tools/testing/selftests/bpf/prog_tests/stacktrace_ips.c new file mode 100644 index 00000000000000..c9efdd2a5b18a5 --- /dev/null +++ b/tools/testing/selftests/bpf/prog_tests/stacktrace_ips.c @@ -0,0 +1,150 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include "stacktrace_ips.skel.h" + +#ifdef __x86_64__ +static int check_stacktrace_ips(int fd, __u32 key, int cnt, ...) +{ + __u64 ips[PERF_MAX_STACK_DEPTH]; + struct ksyms *ksyms = NULL; + int i, err = 0; + va_list args; + + /* sorted by addr */ + ksyms = load_kallsyms_local(); + if (!ASSERT_OK_PTR(ksyms, "load_kallsyms_local")) + return -1; + + /* unlikely, but... */ + if (!ASSERT_LT(cnt, PERF_MAX_STACK_DEPTH, "check_max")) + return -1; + + err = bpf_map_lookup_elem(fd, &key, ips); + if (err) + goto out; + + /* + * Compare all symbols provided via arguments with stacktrace ips, + * and their related symbol addresses.t + */ + va_start(args, cnt); + + for (i = 0; i < cnt; i++) { + unsigned long val; + struct ksym *ksym; + + val = va_arg(args, unsigned long); + ksym = ksym_search_local(ksyms, ips[i]); + if (!ASSERT_OK_PTR(ksym, "ksym_search_local")) + break; + ASSERT_EQ(ksym->addr, val, "stack_cmp"); + } + + va_end(args); + +out: + free_kallsyms_local(ksyms); + return err; +} + +static void test_stacktrace_ips_kprobe_multi(bool retprobe) +{ + LIBBPF_OPTS(bpf_kprobe_multi_opts, opts, + .retprobe = retprobe + ); + LIBBPF_OPTS(bpf_test_run_opts, topts); + struct stacktrace_ips *skel; + + skel = stacktrace_ips__open_and_load(); + if (!ASSERT_OK_PTR(skel, "stacktrace_ips__open_and_load")) + return; + + if (!skel->kconfig->CONFIG_UNWINDER_ORC) { + test__skip(); + goto cleanup; + } + + skel->links.kprobe_multi_test = bpf_program__attach_kprobe_multi_opts( + skel->progs.kprobe_multi_test, + "bpf_testmod_stacktrace_test", &opts); + if (!ASSERT_OK_PTR(skel->links.kprobe_multi_test, "bpf_program__attach_kprobe_multi_opts")) + goto cleanup; + + trigger_module_test_read(1); + + load_kallsyms(); + + check_stacktrace_ips(bpf_map__fd(skel->maps.stackmap), skel->bss->stack_key, 4, + ksym_get_addr("bpf_testmod_stacktrace_test_3"), + ksym_get_addr("bpf_testmod_stacktrace_test_2"), + ksym_get_addr("bpf_testmod_stacktrace_test_1"), + ksym_get_addr("bpf_testmod_test_read")); + +cleanup: + stacktrace_ips__destroy(skel); +} + +static void test_stacktrace_ips_raw_tp(void) +{ + __u32 info_len = sizeof(struct bpf_prog_info); + LIBBPF_OPTS(bpf_test_run_opts, topts); + struct bpf_prog_info info = {}; + struct stacktrace_ips *skel; + __u64 bpf_prog_ksym = 0; + int err; + + skel = stacktrace_ips__open_and_load(); + if (!ASSERT_OK_PTR(skel, "stacktrace_ips__open_and_load")) + return; + + if (!skel->kconfig->CONFIG_UNWINDER_ORC) { + test__skip(); + goto cleanup; + } + + skel->links.rawtp_test = bpf_program__attach_raw_tracepoint( + skel->progs.rawtp_test, + "bpf_testmod_test_read"); + if (!ASSERT_OK_PTR(skel->links.rawtp_test, "bpf_program__attach_raw_tracepoint")) + goto cleanup; + + /* get bpf program address */ + info.jited_ksyms = ptr_to_u64(&bpf_prog_ksym); + info.nr_jited_ksyms = 1; + err = bpf_prog_get_info_by_fd(bpf_program__fd(skel->progs.rawtp_test), + &info, &info_len); + if (!ASSERT_OK(err, "bpf_prog_get_info_by_fd")) + goto cleanup; + + trigger_module_test_read(1); + + load_kallsyms(); + + check_stacktrace_ips(bpf_map__fd(skel->maps.stackmap), skel->bss->stack_key, 2, + bpf_prog_ksym, + ksym_get_addr("bpf_trace_run2")); + +cleanup: + stacktrace_ips__destroy(skel); +} + +static void __test_stacktrace_ips(void) +{ + if (test__start_subtest("kprobe_multi")) + test_stacktrace_ips_kprobe_multi(false); + if (test__start_subtest("kretprobe_multi")) + test_stacktrace_ips_kprobe_multi(true); + if (test__start_subtest("raw_tp")) + test_stacktrace_ips_raw_tp(); +} +#else +static void __test_stacktrace_ips(void) +{ + test__skip(); +} +#endif + +void test_stacktrace_ips(void) +{ + __test_stacktrace_ips(); +} diff --git a/tools/testing/selftests/bpf/progs/iters_looping.c b/tools/testing/selftests/bpf/progs/iters_looping.c index 05fa5ce7fc594c..d00fd570255a99 100644 --- a/tools/testing/selftests/bpf/progs/iters_looping.c +++ b/tools/testing/selftests/bpf/progs/iters_looping.c @@ -161,3 +161,56 @@ int simplest_loop(void *ctx) return 0; } + +__used +static void iterator_with_diff_stack_depth(int x) +{ + struct bpf_iter_num iter; + + asm volatile ( + "if r1 == 42 goto 0f;" + "*(u64 *)(r10 - 128) = 0;" + "0:" + /* create iterator */ + "r1 = %[iter];" + "r2 = 0;" + "r3 = 10;" + "call %[bpf_iter_num_new];" + "1:" + /* consume next item */ + "r1 = %[iter];" + "call %[bpf_iter_num_next];" + "if r0 == 0 goto 2f;" + "goto 1b;" + "2:" + /* destroy iterator */ + "r1 = %[iter];" + "call %[bpf_iter_num_destroy];" + : + : __imm_ptr(iter), ITER_HELPERS + : __clobber_common, "r6" + ); +} + +SEC("socket") +__success +__naked int widening_stack_size_bug(void *ctx) +{ + /* + * Depending on iterator_with_diff_stack_depth() parameter value, + * subprogram stack depth is either 8 or 128 bytes. Arrange values so + * that it is 128 on a first call and 8 on a second. This triggered a + * bug in verifier's widen_imprecise_scalars() logic. + */ + asm volatile ( + "r6 = 0;" + "r1 = 0;" + "1:" + "call iterator_with_diff_stack_depth;" + "r1 = 42;" + "r6 += 1;" + "if r6 < 2 goto 1b;" + "r0 = 0;" + "exit;" + ::: __clobber_all); +} diff --git a/tools/testing/selftests/bpf/progs/livepatch_trampoline.c b/tools/testing/selftests/bpf/progs/livepatch_trampoline.c new file mode 100644 index 00000000000000..15579d5bcd91b8 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/livepatch_trampoline.c @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (c) 2025 Meta Platforms, Inc. and affiliates. */ + +#include +#include +#include + +int fentry_hit; +int fexit_hit; +int my_pid; + +SEC("fentry/cmdline_proc_show") +int BPF_PROG(fentry_cmdline) +{ + if (my_pid != (bpf_get_current_pid_tgid() >> 32)) + return 0; + + fentry_hit = 1; + return 0; +} + +SEC("fexit/cmdline_proc_show") +int BPF_PROG(fexit_cmdline) +{ + if (my_pid != (bpf_get_current_pid_tgid() >> 32)) + return 0; + + fexit_hit = 1; + return 0; +} diff --git a/tools/testing/selftests/bpf/progs/mptcp_sockmap.c b/tools/testing/selftests/bpf/progs/mptcp_sockmap.c new file mode 100644 index 00000000000000..d4eef0cbadb9f6 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/mptcp_sockmap.c @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include "bpf_tracing_net.h" + +char _license[] SEC("license") = "GPL"; + +int sk_index; +int redirect_idx; +int trace_port; +int helper_ret; +struct { + __uint(type, BPF_MAP_TYPE_SOCKMAP); + __uint(key_size, sizeof(__u32)); + __uint(value_size, sizeof(__u32)); + __uint(max_entries, 100); +} sock_map SEC(".maps"); + +SEC("sockops") +int mptcp_sockmap_inject(struct bpf_sock_ops *skops) +{ + struct bpf_sock *sk; + + /* only accept specified connection */ + if (skops->local_port != trace_port || + skops->op != BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB) + return 1; + + sk = skops->sk; + if (!sk) + return 1; + + /* update sk handler */ + helper_ret = bpf_sock_map_update(skops, &sock_map, &sk_index, BPF_NOEXIST); + + return 1; +} + +SEC("sk_skb/stream_verdict") +int mptcp_sockmap_redirect(struct __sk_buff *skb) +{ + /* redirect skb to the sk under sock_map[redirect_idx] */ + return bpf_sk_redirect_map(skb, &sock_map, redirect_idx, 0); +} diff --git a/tools/testing/selftests/bpf/progs/stacktrace_ips.c b/tools/testing/selftests/bpf/progs/stacktrace_ips.c new file mode 100644 index 00000000000000..a96c8150d7f5ae --- /dev/null +++ b/tools/testing/selftests/bpf/progs/stacktrace_ips.c @@ -0,0 +1,49 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2018 Facebook + +#include +#include +#include + +#ifndef PERF_MAX_STACK_DEPTH +#define PERF_MAX_STACK_DEPTH 127 +#endif + +typedef __u64 stack_trace_t[PERF_MAX_STACK_DEPTH]; + +struct { + __uint(type, BPF_MAP_TYPE_STACK_TRACE); + __uint(max_entries, 16384); + __type(key, __u32); + __type(value, stack_trace_t); +} stackmap SEC(".maps"); + +extern bool CONFIG_UNWINDER_ORC __kconfig __weak; + +/* + * This function is here to have CONFIG_UNWINDER_ORC + * used and added to object BTF. + */ +int unused(void) +{ + return CONFIG_UNWINDER_ORC ? 0 : 1; +} + +__u32 stack_key; + +SEC("kprobe.multi") +int kprobe_multi_test(struct pt_regs *ctx) +{ + stack_key = bpf_get_stackid(ctx, &stackmap, 0); + return 0; +} + +SEC("raw_tp/bpf_testmod_test_read") +int rawtp_test(void *ctx) +{ + /* Skip ebpf program entry in the stack. */ + stack_key = bpf_get_stackid(ctx, &stackmap, 0); + return 0; +} + +char _license[] SEC("license") = "GPL"; diff --git a/tools/testing/selftests/bpf/progs/stream_fail.c b/tools/testing/selftests/bpf/progs/stream_fail.c index b4a0d0cc8ec8a9..3662515f010774 100644 --- a/tools/testing/selftests/bpf/progs/stream_fail.c +++ b/tools/testing/selftests/bpf/progs/stream_fail.c @@ -10,7 +10,7 @@ SEC("syscall") __failure __msg("Possibly NULL pointer passed") int stream_vprintk_null_arg(void *ctx) { - bpf_stream_vprintk(BPF_STDOUT, "", NULL, 0, NULL); + bpf_stream_vprintk_impl(BPF_STDOUT, "", NULL, 0, NULL); return 0; } @@ -18,7 +18,7 @@ SEC("syscall") __failure __msg("R3 type=scalar expected=") int stream_vprintk_scalar_arg(void *ctx) { - bpf_stream_vprintk(BPF_STDOUT, "", (void *)46, 0, NULL); + bpf_stream_vprintk_impl(BPF_STDOUT, "", (void *)46, 0, NULL); return 0; } @@ -26,7 +26,7 @@ SEC("syscall") __failure __msg("arg#1 doesn't point to a const string") int stream_vprintk_string_arg(void *ctx) { - bpf_stream_vprintk(BPF_STDOUT, ctx, NULL, 0, NULL); + bpf_stream_vprintk_impl(BPF_STDOUT, ctx, NULL, 0, NULL); return 0; } diff --git a/tools/testing/selftests/bpf/progs/task_work.c b/tools/testing/selftests/bpf/progs/task_work.c index 23217f06a3ece6..663a80990f8f87 100644 --- a/tools/testing/selftests/bpf/progs/task_work.c +++ b/tools/testing/selftests/bpf/progs/task_work.c @@ -66,7 +66,7 @@ int oncpu_hash_map(struct pt_regs *args) if (!work) return 0; - bpf_task_work_schedule_resume(task, &work->tw, &hmap, process_work, NULL); + bpf_task_work_schedule_resume_impl(task, &work->tw, &hmap, process_work, NULL); return 0; } @@ -80,7 +80,7 @@ int oncpu_array_map(struct pt_regs *args) work = bpf_map_lookup_elem(&arrmap, &key); if (!work) return 0; - bpf_task_work_schedule_signal(task, &work->tw, &arrmap, process_work, NULL); + bpf_task_work_schedule_signal_impl(task, &work->tw, &arrmap, process_work, NULL); return 0; } @@ -102,6 +102,6 @@ int oncpu_lru_map(struct pt_regs *args) work = bpf_map_lookup_elem(&lrumap, &key); if (!work || work->data[0]) return 0; - bpf_task_work_schedule_resume(task, &work->tw, &lrumap, process_work, NULL); + bpf_task_work_schedule_resume_impl(task, &work->tw, &lrumap, process_work, NULL); return 0; } diff --git a/tools/testing/selftests/bpf/progs/task_work_fail.c b/tools/testing/selftests/bpf/progs/task_work_fail.c index 77fe8f28facdb6..1270953fd0926f 100644 --- a/tools/testing/selftests/bpf/progs/task_work_fail.c +++ b/tools/testing/selftests/bpf/progs/task_work_fail.c @@ -53,7 +53,7 @@ int mismatch_map(struct pt_regs *args) work = bpf_map_lookup_elem(&arrmap, &key); if (!work) return 0; - bpf_task_work_schedule_resume(task, &work->tw, &hmap, process_work, NULL); + bpf_task_work_schedule_resume_impl(task, &work->tw, &hmap, process_work, NULL); return 0; } @@ -65,7 +65,7 @@ int no_map_task_work(struct pt_regs *args) struct bpf_task_work tw; task = bpf_get_current_task_btf(); - bpf_task_work_schedule_resume(task, &tw, &hmap, process_work, NULL); + bpf_task_work_schedule_resume_impl(task, &tw, &hmap, process_work, NULL); return 0; } @@ -76,7 +76,7 @@ int task_work_null(struct pt_regs *args) struct task_struct *task; task = bpf_get_current_task_btf(); - bpf_task_work_schedule_resume(task, NULL, &hmap, process_work, NULL); + bpf_task_work_schedule_resume_impl(task, NULL, &hmap, process_work, NULL); return 0; } @@ -91,6 +91,6 @@ int map_null(struct pt_regs *args) work = bpf_map_lookup_elem(&arrmap, &key); if (!work) return 0; - bpf_task_work_schedule_resume(task, &work->tw, NULL, process_work, NULL); + bpf_task_work_schedule_resume_impl(task, &work->tw, NULL, process_work, NULL); return 0; } diff --git a/tools/testing/selftests/bpf/progs/task_work_stress.c b/tools/testing/selftests/bpf/progs/task_work_stress.c index 90fca06fff56ca..55e555f7f41be6 100644 --- a/tools/testing/selftests/bpf/progs/task_work_stress.c +++ b/tools/testing/selftests/bpf/progs/task_work_stress.c @@ -51,8 +51,8 @@ int schedule_task_work(void *ctx) if (!work) return 0; } - err = bpf_task_work_schedule_signal(bpf_get_current_task_btf(), &work->tw, &hmap, - process_work, NULL); + err = bpf_task_work_schedule_signal_impl(bpf_get_current_task_btf(), &work->tw, &hmap, + process_work, NULL); if (err) __sync_fetch_and_add(&schedule_error, 1); else diff --git a/tools/testing/selftests/bpf/test_kmods/bpf_testmod.c b/tools/testing/selftests/bpf/test_kmods/bpf_testmod.c index 8074bc5f6f2004..ed0a4721d8fd59 100644 --- a/tools/testing/selftests/bpf/test_kmods/bpf_testmod.c +++ b/tools/testing/selftests/bpf/test_kmods/bpf_testmod.c @@ -417,6 +417,30 @@ noinline int bpf_testmod_fentry_test11(u64 a, void *b, short c, int d, return a + (long)b + c + d + (long)e + f + g + h + i + j + k; } +noinline void bpf_testmod_stacktrace_test(void) +{ + /* used for stacktrace test as attach function */ + asm volatile (""); +} + +noinline void bpf_testmod_stacktrace_test_3(void) +{ + bpf_testmod_stacktrace_test(); + asm volatile (""); +} + +noinline void bpf_testmod_stacktrace_test_2(void) +{ + bpf_testmod_stacktrace_test_3(); + asm volatile (""); +} + +noinline void bpf_testmod_stacktrace_test_1(void) +{ + bpf_testmod_stacktrace_test_2(); + asm volatile (""); +} + int bpf_testmod_fentry_ok; noinline ssize_t @@ -497,6 +521,8 @@ bpf_testmod_test_read(struct file *file, struct kobject *kobj, 21, 22, 23, 24, 25, 26) != 231) goto out; + bpf_testmod_stacktrace_test_1(); + bpf_testmod_fentry_ok = 1; out: return -EIO; /* always fail */ diff --git a/tools/testing/selftests/drivers/net/Makefile b/tools/testing/selftests/drivers/net/Makefile index 6e41635bd55a46..71ee69e524d774 100644 --- a/tools/testing/selftests/drivers/net/Makefile +++ b/tools/testing/selftests/drivers/net/Makefile @@ -18,6 +18,7 @@ TEST_PROGS := \ netcons_fragmented_msg.sh \ netcons_overflow.sh \ netcons_sysdata.sh \ + netcons_torture.sh \ netpoll_basic.py \ ping.py \ psp.py \ diff --git a/tools/testing/selftests/drivers/net/bonding/Makefile b/tools/testing/selftests/drivers/net/bonding/Makefile index 402d4ee84f2e8f..6c5c60adb5e85c 100644 --- a/tools/testing/selftests/drivers/net/bonding/Makefile +++ b/tools/testing/selftests/drivers/net/bonding/Makefile @@ -14,6 +14,7 @@ TEST_PROGS := \ dev_addr_lists.sh \ mode-1-recovery-updelay.sh \ mode-2-recovery-updelay.sh \ + netcons_over_bonding.sh \ # end of TEST_PROGS TEST_FILES := \ @@ -24,6 +25,7 @@ TEST_FILES := \ TEST_INCLUDES := \ ../../../net/lib.sh \ + ../lib/sh/lib_netcons.sh \ ../../../net/forwarding/lib.sh \ # end of TEST_INCLUDES diff --git a/tools/testing/selftests/drivers/net/bonding/config b/tools/testing/selftests/drivers/net/bonding/config index 6bb290abd48bf2..99149437622348 100644 --- a/tools/testing/selftests/drivers/net/bonding/config +++ b/tools/testing/selftests/drivers/net/bonding/config @@ -1,5 +1,6 @@ CONFIG_BONDING=y CONFIG_BRIDGE=y +CONFIG_CONFIGFS_FS=y CONFIG_DUMMY=y CONFIG_INET_ESP=y CONFIG_INET_ESP_OFFLOAD=y @@ -9,6 +10,9 @@ CONFIG_MACVLAN=y CONFIG_NET_ACT_GACT=y CONFIG_NET_CLS_FLOWER=y CONFIG_NET_CLS_MATCHALL=m +CONFIG_NETCONSOLE=m +CONFIG_NETCONSOLE_DYNAMIC=y +CONFIG_NETCONSOLE_EXTENDED_LOG=y CONFIG_NETDEVSIM=m CONFIG_NET_SCH_INGRESS=y CONFIG_NLMON=y diff --git a/tools/testing/selftests/drivers/net/bonding/netcons_over_bonding.sh b/tools/testing/selftests/drivers/net/bonding/netcons_over_bonding.sh new file mode 100755 index 00000000000000..477cc9379500a3 --- /dev/null +++ b/tools/testing/selftests/drivers/net/bonding/netcons_over_bonding.sh @@ -0,0 +1,361 @@ +#!/usr/bin/env bash +# SPDX-License-Identifier: GPL-2.0 +# +# This selftest exercises trying to have multiple netpoll users at the same +# time. +# +# This selftest has multiple smalls test inside, and the goal is to +# get interfaces with bonding and netconsole in different orders in order +# to catch any possible issue. +# +# The main test composes of four interfaces being created using netdevsim; two +# of them are bonded to serve as the netconsole's transmit interface. The +# remaining two interfaces are similarly bonded and assigned to a separate +# network namespace, which acts as the receive interface, where socat monitors +# for incoming messages. +# +# A netconsole message is then sent to ensure it is properly received across +# this configuration. +# +# Later, run a few other tests, to make sure that bonding and netconsole +# cannot coexist. +# +# The test's objective is to exercise netpoll usage when managed simultaneously +# by multiple subsystems (netconsole and bonding). +# +# Author: Breno Leitao + +set -euo pipefail + +SCRIPTDIR=$(dirname "$(readlink -e "${BASH_SOURCE[0]}")") + +source "${SCRIPTDIR}"/../lib/sh/lib_netcons.sh + +modprobe netdevsim 2> /dev/null || true +modprobe netconsole 2> /dev/null || true +modprobe bonding 2> /dev/null || true +modprobe veth 2> /dev/null || true + +# The content of kmsg will be save to the following file +OUTPUT_FILE="/tmp/${TARGET}" + +# Check for basic system dependency and exit if not found +check_for_dependencies +# Set current loglevel to KERN_INFO(6), and default to KERN_NOTICE(5) +echo "6 5" > /proc/sys/kernel/printk +# Remove the namespace, interfaces and netconsole target on exit +trap cleanup_bond EXIT + +FORMAT="extended" +IP_VERSION="ipv4" +VETH0="veth"$(( RANDOM % 256)) +VETH1="veth"$((256 + RANDOM % 256)) +TXNS="" +RXNS="" + +# Create "bond_tx_XX" and "bond_rx_XX" interfaces, and set DSTIF and SRCIF with +# the bonding interfaces +function setup_bonding_ifaces() { + local RAND=$(( RANDOM % 100 )) + BOND_TX_MAIN_IF="bond_tx_$RAND" + BOND_RX_MAIN_IF="bond_rx_$RAND" + + # Setup TX + if ! ip -n "${TXNS}" link add "${BOND_TX_MAIN_IF}" type bond mode balance-rr + then + echo "Failed to create bond TX interface. Is CONFIG_BONDING set?" >&2 + # only clean nsim ifaces and namespace. Nothing else has been + # initialized + cleanup_bond_nsim + trap - EXIT + exit "${ksft_skip}" + fi + + # create_netdevsim() got the interface up, but it needs to be down + # before being enslaved. + ip -n "${TXNS}" \ + link set "${BOND_TX1_SLAVE_IF}" down + ip -n "${TXNS}" \ + link set "${BOND_TX2_SLAVE_IF}" down + ip -n "${TXNS}" \ + link set "${BOND_TX1_SLAVE_IF}" master "${BOND_TX_MAIN_IF}" + ip -n "${TXNS}" \ + link set "${BOND_TX2_SLAVE_IF}" master "${BOND_TX_MAIN_IF}" + ip -n "${TXNS}" \ + link set "${BOND_TX_MAIN_IF}" up + + # Setup RX + ip -n "${RXNS}" \ + link add "${BOND_RX_MAIN_IF}" type bond mode balance-rr + ip -n "${RXNS}" \ + link set "${BOND_RX1_SLAVE_IF}" down + ip -n "${RXNS}" \ + link set "${BOND_RX2_SLAVE_IF}" down + ip -n "${RXNS}" \ + link set "${BOND_RX1_SLAVE_IF}" master "${BOND_RX_MAIN_IF}" + ip -n "${RXNS}" \ + link set "${BOND_RX2_SLAVE_IF}" master "${BOND_RX_MAIN_IF}" + ip -n "${RXNS}" \ + link set "${BOND_RX_MAIN_IF}" up + + export DSTIF="${BOND_RX_MAIN_IF}" + export SRCIF="${BOND_TX_MAIN_IF}" +} + +# Create 4 netdevsim interfaces. Two of them will be bound to TX bonding iface +# and the other two will be bond to the RX interface (on the other namespace) +function create_ifaces_bond() { + BOND_TX1_SLAVE_IF=$(create_netdevsim "${NSIM_BOND_TX_1}" "${TXNS}") + BOND_TX2_SLAVE_IF=$(create_netdevsim "${NSIM_BOND_TX_2}" "${TXNS}") + BOND_RX1_SLAVE_IF=$(create_netdevsim "${NSIM_BOND_RX_1}" "${RXNS}") + BOND_RX2_SLAVE_IF=$(create_netdevsim "${NSIM_BOND_RX_2}" "${RXNS}") +} + +# netdevsim link BOND_TX to BOND_RX interfaces +function link_ifaces_bond() { + local BOND_TX1_SLAVE_IFIDX + local BOND_TX2_SLAVE_IFIDX + local BOND_RX1_SLAVE_IFIDX + local BOND_RX2_SLAVE_IFIDX + local TXNS_FD + local RXNS_FD + + BOND_TX1_SLAVE_IFIDX=$(ip netns exec "${TXNS}" \ + cat /sys/class/net/"$BOND_TX1_SLAVE_IF"/ifindex) + BOND_TX2_SLAVE_IFIDX=$(ip netns exec "${TXNS}" \ + cat /sys/class/net/"$BOND_TX2_SLAVE_IF"/ifindex) + BOND_RX1_SLAVE_IFIDX=$(ip netns exec "${RXNS}" \ + cat /sys/class/net/"$BOND_RX1_SLAVE_IF"/ifindex) + BOND_RX2_SLAVE_IFIDX=$(ip netns exec "${RXNS}" \ + cat /sys/class/net/"$BOND_RX2_SLAVE_IF"/ifindex) + + exec {TXNS_FD} "$NSIM_DEV_SYS_LINK" + echo "${TXNS_FD}:$BOND_TX2_SLAVE_IFIDX $RXNS_FD:$BOND_RX2_SLAVE_IFIDX" \ + > "$NSIM_DEV_SYS_LINK" + + exec {TXNS_FD}<&- + exec {RXNS_FD}<&- +} + +function create_all_ifaces() { + # setup_ns function is coming from lib.sh + setup_ns TXNS RXNS + export NAMESPACE="${RXNS}" + + # Create two interfaces for RX and two for TX + create_ifaces_bond + # Link netlink ifaces + link_ifaces_bond +} + +# configure DSTIF and SRCIF IPs +function configure_ifaces_ips() { + local IP_VERSION=${1:-"ipv4"} + select_ipv4_or_ipv6 "${IP_VERSION}" + + ip -n "${RXNS}" addr add "${DSTIP}"/24 dev "${DSTIF}" + ip -n "${RXNS}" link set "${DSTIF}" up + + ip -n "${TXNS}" addr add "${SRCIP}"/24 dev "${SRCIF}" + ip -n "${TXNS}" link set "${SRCIF}" up +} + +function test_enable_netpoll_on_enslaved_iface() { + echo 0 > "${NETCONS_PATH}"/enabled + + # At this stage, BOND_TX1_SLAVE_IF is enslaved to BOND_TX_MAIN_IF, and + # linked to BOND_RX1_SLAVE_IF inside the namespace. + echo "${BOND_TX1_SLAVE_IF}" > "${NETCONS_PATH}"/dev_name + + # This should fail with the following message in dmesg: + # netpoll: netconsole: ethX is a slave device, aborting + set +e + enable_netcons_ns 2> /dev/null + set -e + + if [[ $(cat "${NETCONS_PATH}"/enabled) -eq 1 ]] + then + echo "test failed: Bonding and netpoll cannot co-exists." >&2 + exit "${ksft_fail}" + fi +} + +function test_delete_bond_and_reenable_target() { + ip -n "${TXNS}" \ + link delete "${BOND_TX_MAIN_IF}" type bond + + # BOND_TX1_SLAVE_IF is not attached to a bond interface anymore + # netpoll can be plugged in there + echo "${BOND_TX1_SLAVE_IF}" > "${NETCONS_PATH}"/dev_name + + # this should work, since the interface is not enslaved + enable_netcons_ns + + if [[ $(cat "${NETCONS_PATH}"/enabled) -eq 0 ]] + then + echo "test failed: Unable to start netpoll on an unbond iface." >&2 + exit "${ksft_fail}" + fi +} + +# Send a netconsole message to the netconsole target +function test_send_netcons_msg_through_bond_iface() { + # Listen for netconsole port inside the namespace and + # destination interface + listen_port_and_save_to "${OUTPUT_FILE}" "${IP_VERSION}" & + # Wait for socat to start and listen to the port. + wait_for_port "${RXNS}" "${PORT}" "${IP_VERSION}" + # Send the message + echo "${MSG}: ${TARGET}" > /dev/kmsg + # Wait until socat saves the file to disk + busywait "${BUSYWAIT_TIMEOUT}" test -s "${OUTPUT_FILE}" + # Make sure the message was received in the dst part + # and exit + validate_result "${OUTPUT_FILE}" "${FORMAT}" + # kill socat in case it is still running + pkill_socat +} + +# BOND_TX1_SLAVE_IF has netconsole enabled on it, bind it to BOND_TX_MAIN_IF. +# Given BOND_TX_MAIN_IF was deleted, recreate it first +function test_enslave_netcons_enabled_iface { + # netconsole got disabled while the interface was down + if [[ $(cat "${NETCONS_PATH}"/enabled) -eq 0 ]] + then + echo "test failed: netconsole expected to be enabled against BOND_TX1_SLAVE_IF" >&2 + exit "${ksft_fail}" + fi + + # recreate the bonding iface. it got deleted by previous + # test (test_delete_bond_and_reenable_target) + ip -n "${TXNS}" \ + link add "${BOND_TX_MAIN_IF}" type bond mode balance-rr + + # sub-interface need to be down before attaching to bonding + # This will also disable netconsole. + ip -n "${TXNS}" \ + link set "${BOND_TX1_SLAVE_IF}" down + ip -n "${TXNS}" \ + link set "${BOND_TX1_SLAVE_IF}" master "${BOND_TX_MAIN_IF}" + ip -n "${TXNS}" \ + link set "${BOND_TX_MAIN_IF}" up + + # netconsole got disabled while the interface was down + if [[ $(cat "${NETCONS_PATH}"/enabled) -eq 1 ]] + then + echo "test failed: Device is part of a bond iface, cannot have netcons enabled" >&2 + exit "${ksft_fail}" + fi +} + +# Get netconsole enabled on a bonding interface and attach a second +# sub-interface. +function test_enslave_iface_to_bond { + # BOND_TX_MAIN_IF has only BOND_TX1_SLAVE_IF right now + echo "${BOND_TX_MAIN_IF}" > "${NETCONS_PATH}"/dev_name + enable_netcons_ns + + # netcons is attached to bond0 and BOND_TX1_SLAVE_IF is + # part of BOND_TX_MAIN_IF. Attach BOND_TX2_SLAVE_IF to BOND_TX_MAIN_IF. + ip -n "${TXNS}" \ + link set "${BOND_TX2_SLAVE_IF}" master "${BOND_TX_MAIN_IF}" + if [[ $(cat "${NETCONS_PATH}"/enabled) -eq 0 ]] + then + echo "test failed: Netconsole should be enabled on bonding interface. Failed" >&2 + exit "${ksft_fail}" + fi +} + +function test_enslave_iff_disabled_netpoll_iface { + local ret + + # Create two interfaces. veth interfaces it known to have + # IFF_DISABLE_NETPOLL set + if ! ip link add "${VETH0}" type veth peer name "${VETH1}" + then + echo "Failed to create veth TX interface. Is CONFIG_VETH set?" >&2 + exit "${ksft_skip}" + fi + set +e + # This will print RTNETLINK answers: Device or resource busy + ip link set "${VETH0}" master "${BOND_TX_MAIN_IF}" 2> /dev/null + ret=$? + set -e + if [[ $ret -eq 0 ]] + then + echo "test failed: veth interface could not be enslaved" + exit "${ksft_fail}" + fi +} + +# Given that netconsole picks the current net namespace, we need to enable it +# from inside the TXNS namespace +function enable_netcons_ns() { + ip netns exec "${TXNS}" sh -c \ + "mount -t configfs configfs /sys/kernel/config && echo 1 > $NETCONS_PATH/enabled" +} + +#################### +# Tests start here # +#################### + +# Create regular interfaces using netdevsim and link them +create_all_ifaces + +# Setup the bonding interfaces +# BOND_RX_MAIN_IF has BOND_RX{1,2}_SLAVE_IF +# BOND_TX_MAIN_IF has BOND_TX{1,2}_SLAVE_IF +setup_bonding_ifaces + +# Configure the ips as BOND_RX1_SLAVE_IF and BOND_TX1_SLAVE_IF +configure_ifaces_ips "${IP_VERSION}" + +_create_dynamic_target "${FORMAT}" "${NETCONS_PATH}" +enable_netcons_ns +set_user_data + +# Test #1 : Create an bonding interface and attach netpoll into +# the bonding interface. Netconsole/netpoll should work on +# the bonding interface. +test_send_netcons_msg_through_bond_iface +echo "test #1: netpoll on bonding interface worked. Test passed" >&2 + +# Test #2: Attach netpoll to an enslaved interface +# Try to attach netpoll to an enslaved sub-interface (while still being part of +# a bonding interface), which shouldn't be allowed +test_enable_netpoll_on_enslaved_iface +echo "test #2: netpoll correctly rejected enslaved interface (expected behavior). Test passed." >&2 + +# Test #3: Unplug the sub-interface from bond and enable netconsole +# Detach the interface from a bonding interface and attach netpoll again +test_delete_bond_and_reenable_target +echo "test #3: Able to attach to an unbound interface. Test passed." >&2 + +# Test #4: Enslave a sub-interface that had netconsole enabled +# Try to enslave an interface that has netconsole/netpoll enabled. +# Previous test has netconsole enabled in BOND_TX1_SLAVE_IF, try to enslave it +test_enslave_netcons_enabled_iface +echo "test #4: Enslaving an interface with netpoll attached. Test passed." >&2 + +# Test #5: Enslave a sub-interface to a bonding interface +# Enslave an interface to a bond interface that has netpoll attached +# At this stage, BOND_TX_MAIN_IF is created and BOND_TX1_SLAVE_IF is part of +# it. Netconsole is currently disabled +test_enslave_iface_to_bond +echo "test #5: Enslaving an interface to bond+netpoll. Test passed." >&2 + +# Test #6: Enslave a IFF_DISABLE_NETPOLL sub-interface to a bonding interface +# At this stage, BOND_TX_MAIN_IF has both sub interface and netconsole is +# enabled. This test will try to enslave an a veth (IFF_DISABLE_NETPOLL) interface +# and it should fail, with netpoll: veth0 doesn't support polling +test_enslave_iff_disabled_netpoll_iface +echo "test #6: Enslaving IFF_DISABLE_NETPOLL ifaces to bond iface is not supported. Test passed." >&2 + +cleanup_bond +trap - EXIT +exit "${EXIT_STATUS}" diff --git a/tools/testing/selftests/drivers/net/lib/sh/lib_netcons.sh b/tools/testing/selftests/drivers/net/lib/sh/lib_netcons.sh index 8e1085e896472d..87f89fd92f8c11 100644 --- a/tools/testing/selftests/drivers/net/lib/sh/lib_netcons.sh +++ b/tools/testing/selftests/drivers/net/lib/sh/lib_netcons.sh @@ -11,9 +11,11 @@ set -euo pipefail LIBDIR=$(dirname "$(readlink -e "${BASH_SOURCE[0]}")") SRCIF="" # to be populated later +SRCIP="" # to be populated later SRCIP4="192.0.2.1" SRCIP6="fc00::1" DSTIF="" # to be populated later +DSTIP="" # to be populated later DSTIP4="192.0.2.2" DSTIP6="fc00::2" @@ -28,17 +30,23 @@ NETCONS_PATH="${NETCONS_CONFIGFS}"/"${TARGET}" # NAMESPACE will be populated by setup_ns with a random value NAMESPACE="" -# IDs for netdevsim +# IDs for netdevsim. We either use NSIM_DEV_{1,2}_ID for standard test +# or NSIM_BOND_{T,R}X_{1,2} for the bonding tests. Not both at the +# same time. NSIM_DEV_1_ID=$((256 + RANDOM % 256)) NSIM_DEV_2_ID=$((512 + RANDOM % 256)) +NSIM_BOND_TX_1=$((768 + RANDOM % 256)) +NSIM_BOND_TX_2=$((1024 + RANDOM % 256)) +NSIM_BOND_RX_1=$((1280 + RANDOM % 256)) +NSIM_BOND_RX_2=$((1536 + RANDOM % 256)) NSIM_DEV_SYS_NEW="/sys/bus/netdevsim/new_device" +NSIM_DEV_SYS_LINK="/sys/bus/netdevsim/link_device" # Used to create and delete namespaces source "${LIBDIR}"/../../../../net/lib.sh # Create netdevsim interfaces create_ifaces() { - echo "$NSIM_DEV_2_ID" > "$NSIM_DEV_SYS_NEW" echo "$NSIM_DEV_1_ID" > "$NSIM_DEV_SYS_NEW" udevadm settle 2> /dev/null || true @@ -113,31 +121,38 @@ function set_network() { configure_ip } -function create_dynamic_target() { - local FORMAT=${1:-"extended"} +function _create_dynamic_target() { + local FORMAT="${1:?FORMAT parameter required}" + local NCPATH="${2:?NCPATH parameter required}" DSTMAC=$(ip netns exec "${NAMESPACE}" \ ip link show "${DSTIF}" | awk '/ether/ {print $2}') # Create a dynamic target - mkdir "${NETCONS_PATH}" + mkdir "${NCPATH}" - echo "${DSTIP}" > "${NETCONS_PATH}"/remote_ip - echo "${SRCIP}" > "${NETCONS_PATH}"/local_ip - echo "${DSTMAC}" > "${NETCONS_PATH}"/remote_mac - echo "${SRCIF}" > "${NETCONS_PATH}"/dev_name + echo "${DSTIP}" > "${NCPATH}"/remote_ip + echo "${SRCIP}" > "${NCPATH}"/local_ip + echo "${DSTMAC}" > "${NCPATH}"/remote_mac + echo "${SRCIF}" > "${NCPATH}"/dev_name if [ "${FORMAT}" == "basic" ] then # Basic target does not support release - echo 0 > "${NETCONS_PATH}"/release - echo 0 > "${NETCONS_PATH}"/extended + echo 0 > "${NCPATH}"/release + echo 0 > "${NCPATH}"/extended elif [ "${FORMAT}" == "extended" ] then - echo 1 > "${NETCONS_PATH}"/extended + echo 1 > "${NCPATH}"/extended fi +} - echo 1 > "${NETCONS_PATH}"/enabled +function create_dynamic_target() { + local FORMAT=${1:-"extended"} + local NCPATH=${2:-"$NETCONS_PATH"} + _create_dynamic_target "${FORMAT}" "${NCPATH}" + + echo 1 > "${NCPATH}"/enabled # This will make sure that the kernel was able to # load the netconsole driver configuration. The console message @@ -185,14 +200,26 @@ function do_cleanup() { echo "${DEFAULT_PRINTK_VALUES}" > /proc/sys/kernel/printk } -function cleanup() { +function cleanup_netcons() { # delete netconsole dynamic reconfiguration - echo 0 > "${NETCONS_PATH}"/enabled + # do not fail if the target is already disabled + if [[ ! -d "${NETCONS_PATH}" ]] + then + # in some cases this is called before netcons path is created + return + fi + if [[ $(cat "${NETCONS_PATH}"/enabled) != 0 ]] + then + echo 0 > "${NETCONS_PATH}"/enabled || true + fi # Remove all the keys that got created during the selftest find "${NETCONS_PATH}/userdata/" -mindepth 1 -type d -delete # Remove the configfs entry rmdir "${NETCONS_PATH}" +} +function cleanup() { + cleanup_netcons do_cleanup } @@ -369,3 +396,24 @@ function wait_for_port() { # more frequently on IPv6 sleep 1 } + +# Clean up netdevsim ifaces created for bonding test +function cleanup_bond_nsim() { + ip -n "${TXNS}" \ + link delete "${BOND_TX_MAIN_IF}" type bond || true + ip -n "${RXNS}" \ + link delete "${BOND_RX_MAIN_IF}" type bond || true + + cleanup_netdevsim "$NSIM_BOND_TX_1" + cleanup_netdevsim "$NSIM_BOND_TX_2" + cleanup_netdevsim "$NSIM_BOND_RX_1" + cleanup_netdevsim "$NSIM_BOND_RX_2" +} + +# cleanup tests that use bonding interfaces +function cleanup_bond() { + cleanup_netcons + cleanup_bond_nsim + cleanup_all_ns + ip link delete "${VETH0}" || true +} diff --git a/tools/testing/selftests/drivers/net/netcons_torture.sh b/tools/testing/selftests/drivers/net/netcons_torture.sh new file mode 100755 index 00000000000000..2ce9ee3719d1aa --- /dev/null +++ b/tools/testing/selftests/drivers/net/netcons_torture.sh @@ -0,0 +1,130 @@ +#!/usr/bin/env bash +# SPDX-License-Identifier: GPL-2.0 + +# Repeatedly send kernel messages, toggles netconsole targets on and off, +# creates and deletes targets in parallel, and toggles the source interface to +# simulate stress conditions. +# +# This test aims to verify the robustness of netconsole under dynamic +# configurations and concurrent operations. +# +# The major goal is to run this test with LOCKDEP, Kmemleak and KASAN to make +# sure no issues is reported. +# +# Author: Breno Leitao + +set -euo pipefail + +SCRIPTDIR=$(dirname "$(readlink -e "${BASH_SOURCE[0]}")") + +source "${SCRIPTDIR}"/lib/sh/lib_netcons.sh + +# Number of times the main loop run +ITERATIONS=${1:-150} + +# Only test extended format +FORMAT="extended" +# And ipv6 only +IP_VERSION="ipv6" + +# Create, enable and delete some targets. +create_and_delete_random_target() { + COUNT=2 + RND_PREFIX=$(mktemp -u netcons_rnd_XXXX_) + + if [ -d "${NETCONS_CONFIGFS}/${RND_PREFIX}${COUNT}" ] || \ + [ -d "${NETCONS_CONFIGFS}/${RND_PREFIX}0" ]; then + echo "Function didn't finish yet, skipping it." >&2 + return + fi + + # enable COUNT targets + for i in $(seq ${COUNT}) + do + RND_TARGET="${RND_PREFIX}"${i} + RND_TARGET_PATH="${NETCONS_CONFIGFS}"/"${RND_TARGET}" + + # Basic population so the target can come up + _create_dynamic_target "${FORMAT}" "${RND_TARGET_PATH}" + done + + echo "netconsole selftest: ${COUNT} additional targets were created" > /dev/kmsg + # disable them all + for i in $(seq ${COUNT}) + do + RND_TARGET="${RND_PREFIX}"${i} + RND_TARGET_PATH="${NETCONS_CONFIGFS}"/"${RND_TARGET}" + if [[ $(cat "${RND_TARGET_PATH}/enabled") -eq 1 ]] + then + echo 0 > "${RND_TARGET_PATH}"/enabled + fi + rmdir "${RND_TARGET_PATH}" + done +} + +# Disable and enable the target mid-air, while messages +# are being transmitted. +toggle_netcons_target() { + for i in $(seq 2) + do + if [ ! -d "${NETCONS_PATH}" ] + then + break + fi + echo 0 > "${NETCONS_PATH}"/enabled 2> /dev/null || true + # Try to enable a bit harder, given it might fail to enable + # Write to `enabled` might fail depending on the lock, which is + # highly contentious here + for _ in $(seq 5) + do + echo 1 > "${NETCONS_PATH}"/enabled 2> /dev/null || true + done + done +} + +toggle_iface(){ + ip link set "${SRCIF}" down + ip link set "${SRCIF}" up +} + +# Start here + +modprobe netdevsim 2> /dev/null || true +modprobe netconsole 2> /dev/null || true + +# Check for basic system dependency and exit if not found +check_for_dependencies +# Set current loglevel to KERN_INFO(6), and default to KERN_NOTICE(5) +echo "6 5" > /proc/sys/kernel/printk +# Remove the namespace, interfaces and netconsole target on exit +trap cleanup EXIT +# Create one namespace and two interfaces +set_network "${IP_VERSION}" +# Create a dynamic target for netconsole +create_dynamic_target "${FORMAT}" + +for i in $(seq "$ITERATIONS") +do + for _ in $(seq 10) + do + echo "${MSG}: ${TARGET} ${i}" > /dev/kmsg + done + wait + + if (( i % 30 == 0 )); then + toggle_netcons_target & + fi + + if (( i % 50 == 0 )); then + # create some targets, enable them, send msg and disable + # all in a parallel thread + create_and_delete_random_target & + fi + + if (( i % 70 == 0 )); then + toggle_iface & + fi +done +wait + +exit "${EXIT_STATUS}" diff --git a/tools/testing/selftests/drivers/net/netdevsim/Makefile b/tools/testing/selftests/drivers/net/netdevsim/Makefile index daf51113c8272e..df10c724351193 100644 --- a/tools/testing/selftests/drivers/net/netdevsim/Makefile +++ b/tools/testing/selftests/drivers/net/netdevsim/Makefile @@ -20,4 +20,8 @@ TEST_PROGS := \ udp_tunnel_nic.sh \ # end of TEST_PROGS +TEST_FILES := \ + ethtool-common.sh +# end of TEST_FILES + include ../../../lib.mk diff --git a/tools/testing/selftests/ftrace/test.d/filter/event-filter-function.tc b/tools/testing/selftests/ftrace/test.d/filter/event-filter-function.tc index c62165fabd0ce1..cfa16aa1f39ac5 100644 --- a/tools/testing/selftests/ftrace/test.d/filter/event-filter-function.tc +++ b/tools/testing/selftests/ftrace/test.d/filter/event-filter-function.tc @@ -20,6 +20,10 @@ sample_events() { echo 0 > tracing_on echo 0 > events/enable +# Clear functions caused by page cache; run sample_events twice +sample_events +sample_events + echo "Get the most frequently calling function" echo > trace sample_events diff --git a/tools/testing/selftests/iommu/iommufd.c b/tools/testing/selftests/iommu/iommufd.c index 3eebf5e3b974f4..bb4d33dde3c899 100644 --- a/tools/testing/selftests/iommu/iommufd.c +++ b/tools/testing/selftests/iommu/iommufd.c @@ -2638,6 +2638,8 @@ TEST_F(vfio_compat_mock_domain, map) ASSERT_EQ(0, ioctl(self->fd, VFIO_IOMMU_MAP_DMA, &map_cmd)); ASSERT_EQ(0, ioctl(self->fd, VFIO_IOMMU_UNMAP_DMA, &unmap_cmd)); ASSERT_EQ(BUFFER_SIZE, unmap_cmd.size); + /* Unmap of empty is success */ + ASSERT_EQ(0, ioctl(self->fd, VFIO_IOMMU_UNMAP_DMA, &unmap_cmd)); /* UNMAP_FLAG_ALL requires 0 iova/size */ ASSERT_EQ(0, ioctl(self->fd, VFIO_IOMMU_MAP_DMA, &map_cmd)); diff --git a/tools/testing/selftests/iommu/iommufd_utils.h b/tools/testing/selftests/iommu/iommufd_utils.h index 772ca1db6e5971..9f472c20c19052 100644 --- a/tools/testing/selftests/iommu/iommufd_utils.h +++ b/tools/testing/selftests/iommu/iommufd_utils.h @@ -1044,8 +1044,8 @@ static int _test_cmd_trigger_vevents(int fd, __u32 dev_id, __u32 nvevents) }; while (nvevents--) { - if (!ioctl(fd, _IOMMU_TEST_CMD(IOMMU_TEST_OP_TRIGGER_VEVENT), - &trigger_vevent_cmd)) + if (ioctl(fd, _IOMMU_TEST_CMD(IOMMU_TEST_OP_TRIGGER_VEVENT), + &trigger_vevent_cmd)) return -1; } return 0; diff --git a/tools/testing/selftests/kvm/arm64/get-reg-list.c b/tools/testing/selftests/kvm/arm64/get-reg-list.c index c9b84eeaab6b28..0a3a94c4cca16f 100644 --- a/tools/testing/selftests/kvm/arm64/get-reg-list.c +++ b/tools/testing/selftests/kvm/arm64/get-reg-list.c @@ -63,11 +63,13 @@ static struct feature_id_reg feat_id_regs[] = { REG_FEAT(HDFGWTR2_EL2, ID_AA64MMFR0_EL1, FGT, FGT2), REG_FEAT(ZCR_EL2, ID_AA64PFR0_EL1, SVE, IMP), REG_FEAT(SCTLR2_EL1, ID_AA64MMFR3_EL1, SCTLRX, IMP), + REG_FEAT(SCTLR2_EL2, ID_AA64MMFR3_EL1, SCTLRX, IMP), REG_FEAT(VDISR_EL2, ID_AA64PFR0_EL1, RAS, IMP), REG_FEAT(VSESR_EL2, ID_AA64PFR0_EL1, RAS, IMP), REG_FEAT(VNCR_EL2, ID_AA64MMFR4_EL1, NV_frac, NV2_ONLY), REG_FEAT(CNTHV_CTL_EL2, ID_AA64MMFR1_EL1, VH, IMP), REG_FEAT(CNTHV_CVAL_EL2,ID_AA64MMFR1_EL1, VH, IMP), + REG_FEAT(ZCR_EL2, ID_AA64PFR0_EL1, SVE, IMP), }; bool filter_reg(__u64 reg) @@ -718,6 +720,7 @@ static __u64 el2_regs[] = { SYS_REG(VMPIDR_EL2), SYS_REG(SCTLR_EL2), SYS_REG(ACTLR_EL2), + SYS_REG(SCTLR2_EL2), SYS_REG(HCR_EL2), SYS_REG(MDCR_EL2), SYS_REG(CPTR_EL2), diff --git a/tools/testing/selftests/kvm/lib/arm64/gic_v3_its.c b/tools/testing/selftests/kvm/lib/arm64/gic_v3_its.c index 09f27054564693..0e2f8ed90f3049 100644 --- a/tools/testing/selftests/kvm/lib/arm64/gic_v3_its.c +++ b/tools/testing/selftests/kvm/lib/arm64/gic_v3_its.c @@ -15,6 +15,8 @@ #include "gic_v3.h" #include "processor.h" +#define GITS_COLLECTION_TARGET_SHIFT 16 + static u64 its_read_u64(unsigned long offset) { return readq_relaxed(GITS_BASE_GVA + offset); @@ -163,6 +165,11 @@ static void its_encode_collection(struct its_cmd_block *cmd, u16 col) its_mask_encode(&cmd->raw_cmd[2], col, 15, 0); } +static u64 procnum_to_rdbase(u32 vcpu_id) +{ + return vcpu_id << GITS_COLLECTION_TARGET_SHIFT; +} + #define GITS_CMDQ_POLL_ITERATIONS 0 static void its_send_cmd(void *cmdq_base, struct its_cmd_block *cmd) @@ -217,7 +224,7 @@ void its_send_mapc_cmd(void *cmdq_base, u32 vcpu_id, u32 collection_id, bool val its_encode_cmd(&cmd, GITS_CMD_MAPC); its_encode_collection(&cmd, collection_id); - its_encode_target(&cmd, vcpu_id); + its_encode_target(&cmd, procnum_to_rdbase(vcpu_id)); its_encode_valid(&cmd, valid); its_send_cmd(cmdq_base, &cmd); diff --git a/tools/testing/selftests/net/.gitignore b/tools/testing/selftests/net/.gitignore index 439101b518eee2..8f9850a71f5426 100644 --- a/tools/testing/selftests/net/.gitignore +++ b/tools/testing/selftests/net/.gitignore @@ -45,6 +45,7 @@ skf_net_off socket so_incoming_cpu so_netns_cookie +so_peek_off so_txtime so_rcv_listener stress_reuseport_listen diff --git a/tools/testing/selftests/net/af_unix/Makefile b/tools/testing/selftests/net/af_unix/Makefile index de805cbbdf6932..528d14c598bb59 100644 --- a/tools/testing/selftests/net/af_unix/Makefile +++ b/tools/testing/selftests/net/af_unix/Makefile @@ -6,6 +6,7 @@ TEST_GEN_PROGS := \ scm_inq \ scm_pidfd \ scm_rights \ + so_peek_off \ unix_connect \ # end of TEST_GEN_PROGS diff --git a/tools/testing/selftests/net/af_unix/so_peek_off.c b/tools/testing/selftests/net/af_unix/so_peek_off.c new file mode 100644 index 00000000000000..1a77728128e520 --- /dev/null +++ b/tools/testing/selftests/net/af_unix/so_peek_off.c @@ -0,0 +1,162 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright 2025 Google LLC */ + +#include +#include + +#include + +#include "../../kselftest_harness.h" + +FIXTURE(so_peek_off) +{ + int fd[2]; /* 0: sender, 1: receiver */ +}; + +FIXTURE_VARIANT(so_peek_off) +{ + int type; +}; + +FIXTURE_VARIANT_ADD(so_peek_off, stream) +{ + .type = SOCK_STREAM, +}; + +FIXTURE_VARIANT_ADD(so_peek_off, dgram) +{ + .type = SOCK_DGRAM, +}; + +FIXTURE_VARIANT_ADD(so_peek_off, seqpacket) +{ + .type = SOCK_SEQPACKET, +}; + +FIXTURE_SETUP(so_peek_off) +{ + struct timeval timeout = { + .tv_sec = 0, + .tv_usec = 3000, + }; + int ret; + + ret = socketpair(AF_UNIX, variant->type, 0, self->fd); + ASSERT_EQ(0, ret); + + ret = setsockopt(self->fd[1], SOL_SOCKET, SO_RCVTIMEO_NEW, + &timeout, sizeof(timeout)); + ASSERT_EQ(0, ret); + + ret = setsockopt(self->fd[1], SOL_SOCKET, SO_PEEK_OFF, + &(int){0}, sizeof(int)); + ASSERT_EQ(0, ret); +} + +FIXTURE_TEARDOWN(so_peek_off) +{ + close_range(self->fd[0], self->fd[1], 0); +} + +#define sendeq(fd, str, flags) \ + do { \ + int bytes, len = strlen(str); \ + \ + bytes = send(fd, str, len, flags); \ + ASSERT_EQ(len, bytes); \ + } while (0) + +#define recveq(fd, str, buflen, flags) \ + do { \ + char buf[(buflen) + 1] = {}; \ + int bytes; \ + \ + bytes = recv(fd, buf, buflen, flags); \ + ASSERT_NE(-1, bytes); \ + ASSERT_STREQ(str, buf); \ + } while (0) + +#define async \ + for (pid_t pid = (pid = fork(), \ + pid < 0 ? \ + __TH_LOG("Failed to start async {}"), \ + _metadata->exit_code = KSFT_FAIL, \ + __bail(1, _metadata), \ + 0xdead : \ + pid); \ + !pid; exit(0)) + +TEST_F(so_peek_off, single_chunk) +{ + sendeq(self->fd[0], "aaaabbbb", 0); + + recveq(self->fd[1], "aaaa", 4, MSG_PEEK); + recveq(self->fd[1], "bbbb", 100, MSG_PEEK); +} + +TEST_F(so_peek_off, two_chunks) +{ + sendeq(self->fd[0], "aaaa", 0); + sendeq(self->fd[0], "bbbb", 0); + + recveq(self->fd[1], "aaaa", 4, MSG_PEEK); + recveq(self->fd[1], "bbbb", 100, MSG_PEEK); +} + +TEST_F(so_peek_off, two_chunks_blocking) +{ + async { + usleep(1000); + sendeq(self->fd[0], "aaaa", 0); + } + + recveq(self->fd[1], "aaaa", 4, MSG_PEEK); + + async { + usleep(1000); + sendeq(self->fd[0], "bbbb", 0); + } + + /* goto again; -> goto redo; in unix_stream_read_generic(). */ + recveq(self->fd[1], "bbbb", 100, MSG_PEEK); +} + +TEST_F(so_peek_off, two_chunks_overlap) +{ + sendeq(self->fd[0], "aaaa", 0); + recveq(self->fd[1], "aa", 2, MSG_PEEK); + + sendeq(self->fd[0], "bbbb", 0); + + if (variant->type == SOCK_STREAM) { + /* SOCK_STREAM tries to fill the buffer. */ + recveq(self->fd[1], "aabb", 4, MSG_PEEK); + recveq(self->fd[1], "bb", 100, MSG_PEEK); + } else { + /* SOCK_DGRAM and SOCK_SEQPACKET returns at the skb boundary. */ + recveq(self->fd[1], "aa", 100, MSG_PEEK); + recveq(self->fd[1], "bbbb", 100, MSG_PEEK); + } +} + +TEST_F(so_peek_off, two_chunks_overlap_blocking) +{ + async { + usleep(1000); + sendeq(self->fd[0], "aaaa", 0); + } + + recveq(self->fd[1], "aa", 2, MSG_PEEK); + + async { + usleep(1000); + sendeq(self->fd[0], "bbbb", 0); + } + + /* Even SOCK_STREAM does not wait if at least one byte is read. */ + recveq(self->fd[1], "aa", 100, MSG_PEEK); + + recveq(self->fd[1], "bbbb", 100, MSG_PEEK); +} + +TEST_HARNESS_MAIN diff --git a/tools/testing/selftests/net/forwarding/lib_sh_test.sh b/tools/testing/selftests/net/forwarding/lib_sh_test.sh index ff2accccaf4d43..b4eda6c6199ed4 100755 --- a/tools/testing/selftests/net/forwarding/lib_sh_test.sh +++ b/tools/testing/selftests/net/forwarding/lib_sh_test.sh @@ -30,6 +30,11 @@ tfail() do_test "tfail" false } +tfail2() +{ + do_test "tfail2" false +} + txfail() { FAIL_TO_XFAIL=yes do_test "txfail" false @@ -132,6 +137,8 @@ test_ret() ret_subtest $ksft_fail "tfail" txfail tfail ret_subtest $ksft_xfail "txfail" txfail txfail + + ret_subtest $ksft_fail "tfail2" tfail2 tfail } exit_status_tests_run() diff --git a/tools/testing/selftests/net/forwarding/local_termination.sh b/tools/testing/selftests/net/forwarding/local_termination.sh index ecd34f364125cb..892895659c7e4c 100755 --- a/tools/testing/selftests/net/forwarding/local_termination.sh +++ b/tools/testing/selftests/net/forwarding/local_termination.sh @@ -176,6 +176,8 @@ run_test() local rcv_dmac=$(mac_get $rcv_if_name) local should_receive + setup_wait + tcpdump_start $rcv_if_name mc_route_prepare $send_if_name diff --git a/tools/testing/selftests/net/gro.c b/tools/testing/selftests/net/gro.c index 2b1d9f2b3e9e86..cfc39f70635df8 100644 --- a/tools/testing/selftests/net/gro.c +++ b/tools/testing/selftests/net/gro.c @@ -754,11 +754,11 @@ static void send_ipv6_exthdr(int fd, struct sockaddr_ll *daddr, char *ext_data1, static char exthdr_pck[sizeof(buf) + MIN_EXTHDR_SIZE]; create_packet(buf, 0, 0, PAYLOAD_LEN, 0); - add_ipv6_exthdr(buf, exthdr_pck, IPPROTO_HOPOPTS, ext_data1); + add_ipv6_exthdr(buf, exthdr_pck, IPPROTO_DSTOPTS, ext_data1); write_packet(fd, exthdr_pck, total_hdr_len + PAYLOAD_LEN + MIN_EXTHDR_SIZE, daddr); create_packet(buf, PAYLOAD_LEN * 1, 0, PAYLOAD_LEN, 0); - add_ipv6_exthdr(buf, exthdr_pck, IPPROTO_HOPOPTS, ext_data2); + add_ipv6_exthdr(buf, exthdr_pck, IPPROTO_DSTOPTS, ext_data2); write_packet(fd, exthdr_pck, total_hdr_len + PAYLOAD_LEN + MIN_EXTHDR_SIZE, daddr); } @@ -989,6 +989,7 @@ static void check_recv_pkts(int fd, int *correct_payload, static void gro_sender(void) { + const int fin_delay_us = 100 * 1000; static char fin_pkt[MAX_HDR_LEN]; struct sockaddr_ll daddr = {}; int txfd = -1; @@ -1032,15 +1033,22 @@ static void gro_sender(void) write_packet(txfd, fin_pkt, total_hdr_len, &daddr); } else if (strcmp(testname, "tcp") == 0) { send_changed_checksum(txfd, &daddr); + /* Adding sleep before sending FIN so that it is not + * received prior to other packets. + */ + usleep(fin_delay_us); write_packet(txfd, fin_pkt, total_hdr_len, &daddr); send_changed_seq(txfd, &daddr); + usleep(fin_delay_us); write_packet(txfd, fin_pkt, total_hdr_len, &daddr); send_changed_ts(txfd, &daddr); + usleep(fin_delay_us); write_packet(txfd, fin_pkt, total_hdr_len, &daddr); send_diff_opt(txfd, &daddr); + usleep(fin_delay_us); write_packet(txfd, fin_pkt, total_hdr_len, &daddr); } else if (strcmp(testname, "ip") == 0) { send_changed_ECN(txfd, &daddr); diff --git a/tools/testing/selftests/net/lib.sh b/tools/testing/selftests/net/lib.sh index feba4ef69a5496..f448bafb3f208e 100644 --- a/tools/testing/selftests/net/lib.sh +++ b/tools/testing/selftests/net/lib.sh @@ -43,7 +43,7 @@ __ksft_status_merge() weights[$i]=$((weight++)) done - if [[ ${weights[$a]} > ${weights[$b]} ]]; then + if [[ ${weights[$a]} -ge ${weights[$b]} ]]; then echo "$a" return 0 else diff --git a/tools/testing/selftests/net/mptcp/mptcp_connect.c b/tools/testing/selftests/net/mptcp/mptcp_connect.c index b148cadb96d0b7..fc7e22b503d3bf 100644 --- a/tools/testing/selftests/net/mptcp/mptcp_connect.c +++ b/tools/testing/selftests/net/mptcp/mptcp_connect.c @@ -710,8 +710,14 @@ static int copyfd_io_poll(int infd, int peerfd, int outfd, bw = do_rnd_write(peerfd, winfo->buf + winfo->off, winfo->len); if (bw < 0) { - if (cfg_rcv_trunc) - return 0; + /* expected reset, continue to read */ + if (cfg_rcv_trunc && + (errno == ECONNRESET || + errno == EPIPE)) { + fds.events &= ~POLLOUT; + continue; + } + perror("write"); return 111; } @@ -737,8 +743,10 @@ static int copyfd_io_poll(int infd, int peerfd, int outfd, } if (fds.revents & (POLLERR | POLLNVAL)) { - if (cfg_rcv_trunc) - return 0; + if (cfg_rcv_trunc) { + fds.events &= ~(POLLERR | POLLNVAL); + continue; + } fprintf(stderr, "Unexpected revents: " "POLLERR/POLLNVAL(%x)\n", fds.revents); return 5; @@ -1433,7 +1441,7 @@ static void parse_opts(int argc, char **argv) */ if (cfg_truncate < 0) { cfg_rcv_trunc = true; - signal(SIGPIPE, handle_signal); + signal(SIGPIPE, SIG_IGN); } break; case 'j': diff --git a/tools/testing/selftests/net/mptcp/mptcp_connect.sh b/tools/testing/selftests/net/mptcp/mptcp_connect.sh index 47ecb5b3836eb5..9b7b93f8eb0c3f 100755 --- a/tools/testing/selftests/net/mptcp/mptcp_connect.sh +++ b/tools/testing/selftests/net/mptcp/mptcp_connect.sh @@ -492,7 +492,7 @@ do_transfer() "than expected (${expect_synrx})" retc=1 fi - if [ ${stat_ackrx_now_l} -lt ${expect_ackrx} ] && [ ${stat_ooo_now} -eq 0 ]; then + if [ ${stat_ackrx_now_l} -lt ${expect_ackrx} ]; then if [ ${stat_ooo_now} -eq 0 ]; then mptcp_lib_pr_fail "lower MPC ACK rx (${stat_ackrx_now_l})" \ "than expected (${expect_ackrx})" diff --git a/tools/testing/selftests/net/mptcp/mptcp_join.sh b/tools/testing/selftests/net/mptcp/mptcp_join.sh index 78a1aa4ecff2bc..43f31f8d587fe1 100755 --- a/tools/testing/selftests/net/mptcp/mptcp_join.sh +++ b/tools/testing/selftests/net/mptcp/mptcp_join.sh @@ -2532,7 +2532,7 @@ remove_tests() if reset "remove single subflow"; then pm_nl_set_limits $ns1 0 1 pm_nl_set_limits $ns2 0 1 - pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow + pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow,backup addr_nr_ns2=-1 speed=slow \ run_tests $ns1 $ns2 10.0.1.1 chk_join_nr 1 1 1 @@ -2545,8 +2545,8 @@ remove_tests() if reset "remove multiple subflows"; then pm_nl_set_limits $ns1 0 2 pm_nl_set_limits $ns2 0 2 - pm_nl_add_endpoint $ns2 10.0.2.2 flags subflow - pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow + pm_nl_add_endpoint $ns2 10.0.2.2 flags subflow,backup + pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow,backup addr_nr_ns2=-2 speed=slow \ run_tests $ns1 $ns2 10.0.1.1 chk_join_nr 2 2 2 @@ -2557,7 +2557,7 @@ remove_tests() # single address, remove if reset "remove single address"; then pm_nl_set_limits $ns1 0 1 - pm_nl_add_endpoint $ns1 10.0.2.1 flags signal + pm_nl_add_endpoint $ns1 10.0.2.1 flags signal,backup pm_nl_set_limits $ns2 1 1 addr_nr_ns1=-1 speed=slow \ run_tests $ns1 $ns2 10.0.1.1 @@ -2570,9 +2570,9 @@ remove_tests() # subflow and signal, remove if reset "remove subflow and signal"; then pm_nl_set_limits $ns1 0 2 - pm_nl_add_endpoint $ns1 10.0.2.1 flags signal + pm_nl_add_endpoint $ns1 10.0.2.1 flags signal,backup pm_nl_set_limits $ns2 1 2 - pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow + pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow,backup addr_nr_ns1=-1 addr_nr_ns2=-1 speed=slow \ run_tests $ns1 $ns2 10.0.1.1 chk_join_nr 2 2 2 @@ -2584,10 +2584,10 @@ remove_tests() # subflows and signal, remove if reset "remove subflows and signal"; then pm_nl_set_limits $ns1 0 3 - pm_nl_add_endpoint $ns1 10.0.2.1 flags signal + pm_nl_add_endpoint $ns1 10.0.2.1 flags signal,backup pm_nl_set_limits $ns2 1 3 - pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow - pm_nl_add_endpoint $ns2 10.0.4.2 flags subflow + pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow,backup + pm_nl_add_endpoint $ns2 10.0.4.2 flags subflow,backup addr_nr_ns1=-1 addr_nr_ns2=-2 speed=10 \ run_tests $ns1 $ns2 10.0.1.1 chk_join_nr 3 3 3 @@ -2599,9 +2599,9 @@ remove_tests() # addresses remove if reset "remove addresses"; then pm_nl_set_limits $ns1 3 3 - pm_nl_add_endpoint $ns1 10.0.2.1 flags signal id 250 - pm_nl_add_endpoint $ns1 10.0.3.1 flags signal - pm_nl_add_endpoint $ns1 10.0.4.1 flags signal + pm_nl_add_endpoint $ns1 10.0.2.1 flags signal,backup id 250 + pm_nl_add_endpoint $ns1 10.0.3.1 flags signal,backup + pm_nl_add_endpoint $ns1 10.0.4.1 flags signal,backup pm_nl_set_limits $ns2 3 3 addr_nr_ns1=-3 speed=10 \ run_tests $ns1 $ns2 10.0.1.1 @@ -2614,10 +2614,10 @@ remove_tests() # invalid addresses remove if reset "remove invalid addresses"; then pm_nl_set_limits $ns1 3 3 - pm_nl_add_endpoint $ns1 10.0.12.1 flags signal + pm_nl_add_endpoint $ns1 10.0.12.1 flags signal,backup # broadcast IP: no packet for this address will be received on ns1 - pm_nl_add_endpoint $ns1 224.0.0.1 flags signal - pm_nl_add_endpoint $ns1 10.0.3.1 flags signal + pm_nl_add_endpoint $ns1 224.0.0.1 flags signal,backup + pm_nl_add_endpoint $ns1 10.0.3.1 flags signal,backup pm_nl_set_limits $ns2 2 2 addr_nr_ns1=-3 speed=10 \ run_tests $ns1 $ns2 10.0.1.1 @@ -2631,10 +2631,10 @@ remove_tests() # subflows and signal, flush if reset "flush subflows and signal"; then pm_nl_set_limits $ns1 0 3 - pm_nl_add_endpoint $ns1 10.0.2.1 flags signal + pm_nl_add_endpoint $ns1 10.0.2.1 flags signal,backup pm_nl_set_limits $ns2 1 3 - pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow - pm_nl_add_endpoint $ns2 10.0.4.2 flags subflow + pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow,backup + pm_nl_add_endpoint $ns2 10.0.4.2 flags subflow,backup addr_nr_ns1=-8 addr_nr_ns2=-8 speed=slow \ run_tests $ns1 $ns2 10.0.1.1 chk_join_nr 3 3 3 @@ -2647,9 +2647,9 @@ remove_tests() if reset "flush subflows"; then pm_nl_set_limits $ns1 3 3 pm_nl_set_limits $ns2 3 3 - pm_nl_add_endpoint $ns2 10.0.2.2 flags subflow id 150 - pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow - pm_nl_add_endpoint $ns2 10.0.4.2 flags subflow + pm_nl_add_endpoint $ns2 10.0.2.2 flags subflow,backup id 150 + pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow,backup + pm_nl_add_endpoint $ns2 10.0.4.2 flags subflow,backup addr_nr_ns1=-8 addr_nr_ns2=-8 speed=slow \ run_tests $ns1 $ns2 10.0.1.1 chk_join_nr 3 3 3 @@ -2666,9 +2666,9 @@ remove_tests() # addresses flush if reset "flush addresses"; then pm_nl_set_limits $ns1 3 3 - pm_nl_add_endpoint $ns1 10.0.2.1 flags signal id 250 - pm_nl_add_endpoint $ns1 10.0.3.1 flags signal - pm_nl_add_endpoint $ns1 10.0.4.1 flags signal + pm_nl_add_endpoint $ns1 10.0.2.1 flags signal,backup id 250 + pm_nl_add_endpoint $ns1 10.0.3.1 flags signal,backup + pm_nl_add_endpoint $ns1 10.0.4.1 flags signal,backup pm_nl_set_limits $ns2 3 3 addr_nr_ns1=-8 addr_nr_ns2=-8 speed=slow \ run_tests $ns1 $ns2 10.0.1.1 @@ -2681,9 +2681,9 @@ remove_tests() # invalid addresses flush if reset "flush invalid addresses"; then pm_nl_set_limits $ns1 3 3 - pm_nl_add_endpoint $ns1 10.0.12.1 flags signal - pm_nl_add_endpoint $ns1 10.0.3.1 flags signal - pm_nl_add_endpoint $ns1 10.0.14.1 flags signal + pm_nl_add_endpoint $ns1 10.0.12.1 flags signal,backup + pm_nl_add_endpoint $ns1 10.0.3.1 flags signal,backup + pm_nl_add_endpoint $ns1 10.0.14.1 flags signal,backup pm_nl_set_limits $ns2 3 3 addr_nr_ns1=-8 speed=slow \ run_tests $ns1 $ns2 10.0.1.1 @@ -3500,7 +3500,6 @@ fullmesh_tests() fastclose_tests() { if reset_check_counter "fastclose test" "MPTcpExtMPFastcloseTx"; then - MPTCP_LIB_SUBTEST_FLAKY=1 test_linkfail=1024 fastclose=client \ run_tests $ns1 $ns2 10.0.1.1 chk_join_nr 0 0 0 @@ -3509,7 +3508,6 @@ fastclose_tests() fi if reset_check_counter "fastclose server test" "MPTcpExtMPFastcloseRx"; then - MPTCP_LIB_SUBTEST_FLAKY=1 test_linkfail=1024 fastclose=server \ run_tests $ns1 $ns2 10.0.1.1 join_rst_nr=1 \ @@ -3806,7 +3804,7 @@ userspace_tests() continue_if mptcp_lib_has_file '/proc/sys/net/mptcp/pm_type'; then set_userspace_pm $ns1 pm_nl_set_limits $ns2 2 2 - { speed=5 \ + { timeout_test=120 test_linkfail=128 speed=5 \ run_tests $ns1 $ns2 10.0.1.1 & } 2>/dev/null local tests_pid=$! wait_mpj $ns1 @@ -3831,7 +3829,7 @@ userspace_tests() chk_mptcp_info subflows 0 subflows 0 chk_subflows_total 1 1 kill_events_pids - mptcp_lib_kill_wait $tests_pid + mptcp_lib_kill_group_wait $tests_pid fi # userspace pm create destroy subflow @@ -3839,7 +3837,7 @@ userspace_tests() continue_if mptcp_lib_has_file '/proc/sys/net/mptcp/pm_type'; then set_userspace_pm $ns2 pm_nl_set_limits $ns1 0 1 - { speed=5 \ + { timeout_test=120 test_linkfail=128 speed=5 \ run_tests $ns1 $ns2 10.0.1.1 & } 2>/dev/null local tests_pid=$! wait_mpj $ns2 @@ -3859,7 +3857,7 @@ userspace_tests() chk_mptcp_info subflows 0 subflows 0 chk_subflows_total 1 1 kill_events_pids - mptcp_lib_kill_wait $tests_pid + mptcp_lib_kill_group_wait $tests_pid fi # userspace pm create id 0 subflow @@ -3867,7 +3865,7 @@ userspace_tests() continue_if mptcp_lib_has_file '/proc/sys/net/mptcp/pm_type'; then set_userspace_pm $ns2 pm_nl_set_limits $ns1 0 1 - { speed=5 \ + { timeout_test=120 test_linkfail=128 speed=5 \ run_tests $ns1 $ns2 10.0.1.1 & } 2>/dev/null local tests_pid=$! wait_mpj $ns2 @@ -3880,7 +3878,7 @@ userspace_tests() chk_mptcp_info subflows 1 subflows 1 chk_subflows_total 2 2 kill_events_pids - mptcp_lib_kill_wait $tests_pid + mptcp_lib_kill_group_wait $tests_pid fi # userspace pm remove initial subflow @@ -3888,7 +3886,7 @@ userspace_tests() continue_if mptcp_lib_has_file '/proc/sys/net/mptcp/pm_type'; then set_userspace_pm $ns2 pm_nl_set_limits $ns1 0 1 - { speed=5 \ + { timeout_test=120 test_linkfail=128 speed=5 \ run_tests $ns1 $ns2 10.0.1.1 & } 2>/dev/null local tests_pid=$! wait_mpj $ns2 @@ -3904,7 +3902,7 @@ userspace_tests() chk_mptcp_info subflows 1 subflows 1 chk_subflows_total 1 1 kill_events_pids - mptcp_lib_kill_wait $tests_pid + mptcp_lib_kill_group_wait $tests_pid fi # userspace pm send RM_ADDR for ID 0 @@ -3912,7 +3910,7 @@ userspace_tests() continue_if mptcp_lib_has_file '/proc/sys/net/mptcp/pm_type'; then set_userspace_pm $ns1 pm_nl_set_limits $ns2 1 1 - { speed=5 \ + { timeout_test=120 test_linkfail=128 speed=5 \ run_tests $ns1 $ns2 10.0.1.1 & } 2>/dev/null local tests_pid=$! wait_mpj $ns1 @@ -3930,7 +3928,7 @@ userspace_tests() chk_mptcp_info subflows 1 subflows 1 chk_subflows_total 1 1 kill_events_pids - mptcp_lib_kill_wait $tests_pid + mptcp_lib_kill_group_wait $tests_pid fi } @@ -3943,7 +3941,7 @@ endpoint_tests() pm_nl_set_limits $ns1 2 2 pm_nl_set_limits $ns2 2 2 pm_nl_add_endpoint $ns1 10.0.2.1 flags signal - { speed=slow \ + { timeout_test=120 test_linkfail=128 speed=slow \ run_tests $ns1 $ns2 10.0.1.1 & } 2>/dev/null local tests_pid=$! @@ -3960,7 +3958,7 @@ endpoint_tests() pm_nl_add_endpoint $ns2 10.0.2.2 flags signal pm_nl_check_endpoint "modif is allowed" \ $ns2 10.0.2.2 id 1 flags signal - mptcp_lib_kill_wait $tests_pid + mptcp_lib_kill_group_wait $tests_pid fi if reset_with_tcp_filter "delete and re-add" ns2 10.0.3.2 REJECT OUTPUT && @@ -3970,7 +3968,7 @@ endpoint_tests() pm_nl_set_limits $ns2 0 3 pm_nl_add_endpoint $ns2 10.0.1.2 id 1 dev ns2eth1 flags subflow pm_nl_add_endpoint $ns2 10.0.2.2 id 2 dev ns2eth2 flags subflow - { test_linkfail=4 speed=5 \ + { timeout_test=120 test_linkfail=128 speed=5 \ run_tests $ns1 $ns2 10.0.1.1 & } 2>/dev/null local tests_pid=$! @@ -4015,7 +4013,7 @@ endpoint_tests() chk_mptcp_info subflows 3 subflows 3 done - mptcp_lib_kill_wait $tests_pid + mptcp_lib_kill_group_wait $tests_pid kill_events_pids chk_evt_nr ns1 MPTCP_LIB_EVENT_LISTENER_CREATED 1 @@ -4048,7 +4046,7 @@ endpoint_tests() # broadcast IP: no packet for this address will be received on ns1 pm_nl_add_endpoint $ns1 224.0.0.1 id 2 flags signal pm_nl_add_endpoint $ns1 10.0.1.1 id 42 flags signal - { test_linkfail=4 speed=5 \ + { timeout_test=120 test_linkfail=128 speed=5 \ run_tests $ns1 $ns2 10.0.1.1 & } 2>/dev/null local tests_pid=$! @@ -4057,39 +4055,46 @@ endpoint_tests() $ns1 10.0.2.1 id 1 flags signal chk_subflow_nr "before delete" 2 chk_mptcp_info subflows 1 subflows 1 + chk_mptcp_info add_addr_signal 2 add_addr_accepted 1 pm_nl_del_endpoint $ns1 1 10.0.2.1 pm_nl_del_endpoint $ns1 2 224.0.0.1 sleep 0.5 chk_subflow_nr "after delete" 1 chk_mptcp_info subflows 0 subflows 0 + chk_mptcp_info add_addr_signal 0 add_addr_accepted 0 pm_nl_add_endpoint $ns1 10.0.2.1 id 1 flags signal pm_nl_add_endpoint $ns1 10.0.3.1 id 2 flags signal wait_mpj $ns2 chk_subflow_nr "after re-add" 3 chk_mptcp_info subflows 2 subflows 2 + chk_mptcp_info add_addr_signal 2 add_addr_accepted 2 pm_nl_del_endpoint $ns1 42 10.0.1.1 sleep 0.5 chk_subflow_nr "after delete ID 0" 2 chk_mptcp_info subflows 2 subflows 2 + chk_mptcp_info add_addr_signal 2 add_addr_accepted 2 pm_nl_add_endpoint $ns1 10.0.1.1 id 99 flags signal wait_mpj $ns2 chk_subflow_nr "after re-add ID 0" 3 chk_mptcp_info subflows 3 subflows 3 + chk_mptcp_info add_addr_signal 3 add_addr_accepted 2 pm_nl_del_endpoint $ns1 99 10.0.1.1 sleep 0.5 chk_subflow_nr "after re-delete ID 0" 2 chk_mptcp_info subflows 2 subflows 2 + chk_mptcp_info add_addr_signal 2 add_addr_accepted 2 pm_nl_add_endpoint $ns1 10.0.1.1 id 88 flags signal wait_mpj $ns2 chk_subflow_nr "after re-re-add ID 0" 3 chk_mptcp_info subflows 3 subflows 3 - mptcp_lib_kill_wait $tests_pid + chk_mptcp_info add_addr_signal 3 add_addr_accepted 2 + mptcp_lib_kill_group_wait $tests_pid kill_events_pids chk_evt_nr ns1 MPTCP_LIB_EVENT_LISTENER_CREATED 1 @@ -4121,7 +4126,7 @@ endpoint_tests() # broadcast IP: no packet for this address will be received on ns1 pm_nl_add_endpoint $ns1 224.0.0.1 id 2 flags signal pm_nl_add_endpoint $ns2 10.0.3.2 id 3 flags subflow - { test_linkfail=4 speed=20 \ + { timeout_test=120 test_linkfail=128 speed=20 \ run_tests $ns1 $ns2 10.0.1.1 & } 2>/dev/null local tests_pid=$! @@ -4137,7 +4142,7 @@ endpoint_tests() wait_mpj $ns2 pm_nl_add_endpoint $ns1 10.0.3.1 id 2 flags signal wait_mpj $ns2 - mptcp_lib_kill_wait $tests_pid + mptcp_lib_kill_group_wait $tests_pid join_syn_tx=3 join_connect_err=1 \ chk_join_nr 2 2 2 diff --git a/tools/testing/selftests/net/mptcp/mptcp_lib.sh b/tools/testing/selftests/net/mptcp/mptcp_lib.sh index d62e653d48b0f2..f4388900016abc 100644 --- a/tools/testing/selftests/net/mptcp/mptcp_lib.sh +++ b/tools/testing/selftests/net/mptcp/mptcp_lib.sh @@ -350,6 +350,27 @@ mptcp_lib_kill_wait() { wait "${1}" 2>/dev/null } +# $1: PID +mptcp_lib_pid_list_children() { + local curr="${1}" + # evoke 'ps' only once + local pids="${2:-"$(ps o pid,ppid)"}" + + echo "${curr}" + + local pid + for pid in $(echo "${pids}" | awk "\$2 == ${curr} { print \$1 }"); do + mptcp_lib_pid_list_children "${pid}" "${pids}" + done +} + +# $1: PID +mptcp_lib_kill_group_wait() { + # Some users might not have procps-ng: cannot use "kill -- -PID" + mptcp_lib_pid_list_children "${1}" | xargs -r kill &>/dev/null + wait "${1}" 2>/dev/null +} + # $1: IP address mptcp_lib_is_v6() { [ -z "${1##*:*}" ] diff --git a/tools/testing/selftests/tc-testing/tc-tests/infra/qdiscs.json b/tools/testing/selftests/tc-testing/tc-tests/infra/qdiscs.json index 998e5a2f457965..0091bcd91c2ccb 100644 --- a/tools/testing/selftests/tc-testing/tc-tests/infra/qdiscs.json +++ b/tools/testing/selftests/tc-testing/tc-tests/infra/qdiscs.json @@ -961,5 +961,49 @@ "teardown": [ "$TC qdisc del dev $DUMMY root" ] + }, + { + "id": "4989", + "name": "Try to add an fq child to an ingress qdisc", + "category": [ + "qdisc", + "ingress" + ], + "plugins": { + "requires": "nsPlugin" + }, + "setup": [ + "$TC qdisc add dev $DUMMY handle ffff:0 ingress" + ], + "cmdUnderTest": "$TC qdisc add dev $DUMMY parent ffff:0 handle ffe0:0 fq", + "expExitCode": "2", + "verifyCmd": "$TC -j qdisc ls dev $DUMMY handle ffe0:", + "matchJSON": [], + "matchCount": "1", + "teardown": [ + "$TC qdisc del dev $DUMMY ingress" + ] + }, + { + "id": "c2b0", + "name": "Try to add an fq child to a clsact qdisc", + "category": [ + "qdisc", + "ingress" + ], + "plugins": { + "requires": "nsPlugin" + }, + "setup": [ + "$TC qdisc add dev $DUMMY handle ffff:0 clsact" + ], + "cmdUnderTest": "$TC qdisc add dev $DUMMY parent ffff:0 handle ffe0:0 fq", + "expExitCode": "2", + "verifyCmd": "$TC -j qdisc ls dev $DUMMY handle ffe0:", + "matchJSON": [], + "matchCount": "1", + "teardown": [ + "$TC qdisc del dev $DUMMY clsact" + ] } ] diff --git a/tools/testing/selftests/user_events/perf_test.c b/tools/testing/selftests/user_events/perf_test.c index 5288e768b207a9..68625362add283 100644 --- a/tools/testing/selftests/user_events/perf_test.c +++ b/tools/testing/selftests/user_events/perf_test.c @@ -236,7 +236,7 @@ TEST_F(user, perf_empty_events) { ASSERT_EQ(1 << reg.enable_bit, self->check); /* Ensure write shows up at correct offset */ - ASSERT_NE(-1, write(self->data_fd, ®.write_index, + ASSERT_NE(-1, write(self->data_fd, (void *)®.write_index, sizeof(reg.write_index))); val = (void *)(((char *)perf_page) + perf_page->data_offset); ASSERT_EQ(PERF_RECORD_SAMPLE, *val); diff --git a/tools/testing/selftests/vfio/lib/include/vfio_util.h b/tools/testing/selftests/vfio/lib/include/vfio_util.h index 240409bf5f8ad6..69ec0c85648106 100644 --- a/tools/testing/selftests/vfio/lib/include/vfio_util.h +++ b/tools/testing/selftests/vfio/lib/include/vfio_util.h @@ -4,9 +4,12 @@ #include #include -#include + +#include +#include #include #include +#include #include "../../../kselftest.h" @@ -185,6 +188,13 @@ struct vfio_pci_device { struct vfio_pci_driver driver; }; +struct iova_allocator { + struct iommu_iova_range *ranges; + u32 nranges; + u32 range_idx; + u64 range_offset; +}; + /* * Return the BDF string of the device that the test should use. * @@ -206,6 +216,13 @@ struct vfio_pci_device *vfio_pci_device_init(const char *bdf, const char *iommu_ void vfio_pci_device_cleanup(struct vfio_pci_device *device); void vfio_pci_device_reset(struct vfio_pci_device *device); +struct iommu_iova_range *vfio_pci_iova_ranges(struct vfio_pci_device *device, + u32 *nranges); + +struct iova_allocator *iova_allocator_init(struct vfio_pci_device *device); +void iova_allocator_cleanup(struct iova_allocator *allocator); +iova_t iova_allocator_alloc(struct iova_allocator *allocator, size_t size); + int __vfio_pci_dma_map(struct vfio_pci_device *device, struct vfio_dma_region *region); int __vfio_pci_dma_unmap(struct vfio_pci_device *device, diff --git a/tools/testing/selftests/vfio/lib/vfio_pci_device.c b/tools/testing/selftests/vfio/lib/vfio_pci_device.c index a381fd253aa7ec..b479a359da121c 100644 --- a/tools/testing/selftests/vfio/lib/vfio_pci_device.c +++ b/tools/testing/selftests/vfio/lib/vfio_pci_device.c @@ -12,11 +12,12 @@ #include #include +#include #include #include +#include #include #include -#include #include "../../../kselftest.h" #include @@ -29,6 +30,249 @@ VFIO_ASSERT_EQ(__ret, 0, "ioctl(%s, %s, %s) returned %d\n", #_fd, #_op, #_arg, __ret); \ } while (0) +static struct vfio_info_cap_header *next_cap_hdr(void *buf, u32 bufsz, + u32 *cap_offset) +{ + struct vfio_info_cap_header *hdr; + + if (!*cap_offset) + return NULL; + + VFIO_ASSERT_LT(*cap_offset, bufsz); + VFIO_ASSERT_GE(bufsz - *cap_offset, sizeof(*hdr)); + + hdr = (struct vfio_info_cap_header *)((u8 *)buf + *cap_offset); + *cap_offset = hdr->next; + + return hdr; +} + +static struct vfio_info_cap_header *vfio_iommu_info_cap_hdr(struct vfio_iommu_type1_info *info, + u16 cap_id) +{ + struct vfio_info_cap_header *hdr; + u32 cap_offset = info->cap_offset; + u32 max_depth; + u32 depth = 0; + + if (!(info->flags & VFIO_IOMMU_INFO_CAPS)) + return NULL; + + if (cap_offset) + VFIO_ASSERT_GE(cap_offset, sizeof(*info)); + + max_depth = (info->argsz - sizeof(*info)) / sizeof(*hdr); + + while ((hdr = next_cap_hdr(info, info->argsz, &cap_offset))) { + depth++; + VFIO_ASSERT_LE(depth, max_depth, "Capability chain contains a cycle\n"); + + if (hdr->id == cap_id) + return hdr; + } + + return NULL; +} + +/* Return buffer including capability chain, if present. Free with free() */ +static struct vfio_iommu_type1_info *vfio_iommu_get_info(struct vfio_pci_device *device) +{ + struct vfio_iommu_type1_info *info; + + info = malloc(sizeof(*info)); + VFIO_ASSERT_NOT_NULL(info); + + *info = (struct vfio_iommu_type1_info) { + .argsz = sizeof(*info), + }; + + ioctl_assert(device->container_fd, VFIO_IOMMU_GET_INFO, info); + VFIO_ASSERT_GE(info->argsz, sizeof(*info)); + + info = realloc(info, info->argsz); + VFIO_ASSERT_NOT_NULL(info); + + ioctl_assert(device->container_fd, VFIO_IOMMU_GET_INFO, info); + VFIO_ASSERT_GE(info->argsz, sizeof(*info)); + + return info; +} + +/* + * Return iova ranges for the device's container. Normalize vfio_iommu_type1 to + * report iommufd's iommu_iova_range. Free with free(). + */ +static struct iommu_iova_range *vfio_iommu_iova_ranges(struct vfio_pci_device *device, + u32 *nranges) +{ + struct vfio_iommu_type1_info_cap_iova_range *cap_range; + struct vfio_iommu_type1_info *info; + struct vfio_info_cap_header *hdr; + struct iommu_iova_range *ranges = NULL; + + info = vfio_iommu_get_info(device); + hdr = vfio_iommu_info_cap_hdr(info, VFIO_IOMMU_TYPE1_INFO_CAP_IOVA_RANGE); + VFIO_ASSERT_NOT_NULL(hdr); + + cap_range = container_of(hdr, struct vfio_iommu_type1_info_cap_iova_range, header); + VFIO_ASSERT_GT(cap_range->nr_iovas, 0); + + ranges = calloc(cap_range->nr_iovas, sizeof(*ranges)); + VFIO_ASSERT_NOT_NULL(ranges); + + for (u32 i = 0; i < cap_range->nr_iovas; i++) { + ranges[i] = (struct iommu_iova_range){ + .start = cap_range->iova_ranges[i].start, + .last = cap_range->iova_ranges[i].end, + }; + } + + *nranges = cap_range->nr_iovas; + + free(info); + return ranges; +} + +/* Return iova ranges of the device's IOAS. Free with free() */ +static struct iommu_iova_range *iommufd_iova_ranges(struct vfio_pci_device *device, + u32 *nranges) +{ + struct iommu_iova_range *ranges; + int ret; + + struct iommu_ioas_iova_ranges query = { + .size = sizeof(query), + .ioas_id = device->ioas_id, + }; + + ret = ioctl(device->iommufd, IOMMU_IOAS_IOVA_RANGES, &query); + VFIO_ASSERT_EQ(ret, -1); + VFIO_ASSERT_EQ(errno, EMSGSIZE); + VFIO_ASSERT_GT(query.num_iovas, 0); + + ranges = calloc(query.num_iovas, sizeof(*ranges)); + VFIO_ASSERT_NOT_NULL(ranges); + + query.allowed_iovas = (uintptr_t)ranges; + + ioctl_assert(device->iommufd, IOMMU_IOAS_IOVA_RANGES, &query); + *nranges = query.num_iovas; + + return ranges; +} + +static int iova_range_comp(const void *a, const void *b) +{ + const struct iommu_iova_range *ra = a, *rb = b; + + if (ra->start < rb->start) + return -1; + + if (ra->start > rb->start) + return 1; + + return 0; +} + +/* Return sorted IOVA ranges of the device. Free with free(). */ +struct iommu_iova_range *vfio_pci_iova_ranges(struct vfio_pci_device *device, + u32 *nranges) +{ + struct iommu_iova_range *ranges; + + if (device->iommufd) + ranges = iommufd_iova_ranges(device, nranges); + else + ranges = vfio_iommu_iova_ranges(device, nranges); + + if (!ranges) + return NULL; + + VFIO_ASSERT_GT(*nranges, 0); + + /* Sort and check that ranges are sane and non-overlapping */ + qsort(ranges, *nranges, sizeof(*ranges), iova_range_comp); + VFIO_ASSERT_LT(ranges[0].start, ranges[0].last); + + for (u32 i = 1; i < *nranges; i++) { + VFIO_ASSERT_LT(ranges[i].start, ranges[i].last); + VFIO_ASSERT_LT(ranges[i - 1].last, ranges[i].start); + } + + return ranges; +} + +struct iova_allocator *iova_allocator_init(struct vfio_pci_device *device) +{ + struct iova_allocator *allocator; + struct iommu_iova_range *ranges; + u32 nranges; + + ranges = vfio_pci_iova_ranges(device, &nranges); + VFIO_ASSERT_NOT_NULL(ranges); + + allocator = malloc(sizeof(*allocator)); + VFIO_ASSERT_NOT_NULL(allocator); + + *allocator = (struct iova_allocator){ + .ranges = ranges, + .nranges = nranges, + .range_idx = 0, + .range_offset = 0, + }; + + return allocator; +} + +void iova_allocator_cleanup(struct iova_allocator *allocator) +{ + free(allocator->ranges); + free(allocator); +} + +iova_t iova_allocator_alloc(struct iova_allocator *allocator, size_t size) +{ + VFIO_ASSERT_GT(size, 0, "Invalid size arg, zero\n"); + VFIO_ASSERT_EQ(size & (size - 1), 0, "Invalid size arg, non-power-of-2\n"); + + for (;;) { + struct iommu_iova_range *range; + iova_t iova, last; + + VFIO_ASSERT_LT(allocator->range_idx, allocator->nranges, + "IOVA allocator out of space\n"); + + range = &allocator->ranges[allocator->range_idx]; + iova = range->start + allocator->range_offset; + + /* Check for sufficient space at the current offset */ + if (check_add_overflow(iova, size - 1, &last) || + last > range->last) + goto next_range; + + /* Align iova to size */ + iova = last & ~(size - 1); + + /* Check for sufficient space at the aligned iova */ + if (check_add_overflow(iova, size - 1, &last) || + last > range->last) + goto next_range; + + if (last == range->last) { + allocator->range_idx++; + allocator->range_offset = 0; + } else { + allocator->range_offset = last - range->start + 1; + } + + return iova; + +next_range: + allocator->range_idx++; + allocator->range_offset = 0; + } +} + iova_t __to_iova(struct vfio_pci_device *device, void *vaddr) { struct vfio_dma_region *region; diff --git a/tools/testing/selftests/vfio/vfio_dma_mapping_test.c b/tools/testing/selftests/vfio/vfio_dma_mapping_test.c index 4f1ea79a200c68..102603d4407d60 100644 --- a/tools/testing/selftests/vfio/vfio_dma_mapping_test.c +++ b/tools/testing/selftests/vfio/vfio_dma_mapping_test.c @@ -3,6 +3,8 @@ #include #include +#include +#include #include #include #include @@ -93,6 +95,7 @@ static int iommu_mapping_get(const char *bdf, u64 iova, FIXTURE(vfio_dma_mapping_test) { struct vfio_pci_device *device; + struct iova_allocator *iova_allocator; }; FIXTURE_VARIANT(vfio_dma_mapping_test) { @@ -117,10 +120,12 @@ FIXTURE_VARIANT_ADD_ALL_IOMMU_MODES(anonymous_hugetlb_1gb, SZ_1G, MAP_HUGETLB | FIXTURE_SETUP(vfio_dma_mapping_test) { self->device = vfio_pci_device_init(device_bdf, variant->iommu_mode); + self->iova_allocator = iova_allocator_init(self->device); } FIXTURE_TEARDOWN(vfio_dma_mapping_test) { + iova_allocator_cleanup(self->iova_allocator); vfio_pci_device_cleanup(self->device); } @@ -142,7 +147,7 @@ TEST_F(vfio_dma_mapping_test, dma_map_unmap) else ASSERT_NE(region.vaddr, MAP_FAILED); - region.iova = (u64)region.vaddr; + region.iova = iova_allocator_alloc(self->iova_allocator, size); region.size = size; vfio_pci_dma_map(self->device, ®ion); @@ -219,7 +224,10 @@ FIXTURE_VARIANT_ADD_ALL_IOMMU_MODES(); FIXTURE_SETUP(vfio_dma_map_limit_test) { struct vfio_dma_region *region = &self->region; + struct iommu_iova_range *ranges; u64 region_size = getpagesize(); + iova_t last_iova; + u32 nranges; /* * Over-allocate mmap by double the size to provide enough backing vaddr @@ -232,8 +240,13 @@ FIXTURE_SETUP(vfio_dma_map_limit_test) MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); ASSERT_NE(region->vaddr, MAP_FAILED); - /* One page prior to the end of address space */ - region->iova = ~(iova_t)0 & ~(region_size - 1); + ranges = vfio_pci_iova_ranges(self->device, &nranges); + VFIO_ASSERT_NOT_NULL(ranges); + last_iova = ranges[nranges - 1].last; + free(ranges); + + /* One page prior to the last iova */ + region->iova = last_iova & ~(region_size - 1); region->size = region_size; } @@ -276,6 +289,7 @@ TEST_F(vfio_dma_map_limit_test, overflow) struct vfio_dma_region *region = &self->region; int rc; + region->iova = ~(iova_t)0 & ~(region->size - 1); region->size = self->mmap_size; rc = __vfio_pci_dma_map(self->device, region); diff --git a/tools/testing/selftests/vfio/vfio_pci_driver_test.c b/tools/testing/selftests/vfio/vfio_pci_driver_test.c index 2dbd70b7db6275..f69eec8b928d17 100644 --- a/tools/testing/selftests/vfio/vfio_pci_driver_test.c +++ b/tools/testing/selftests/vfio/vfio_pci_driver_test.c @@ -19,6 +19,7 @@ static const char *device_bdf; } while (0) static void region_setup(struct vfio_pci_device *device, + struct iova_allocator *iova_allocator, struct vfio_dma_region *region, u64 size) { const int flags = MAP_SHARED | MAP_ANONYMOUS; @@ -29,7 +30,7 @@ static void region_setup(struct vfio_pci_device *device, VFIO_ASSERT_NE(vaddr, MAP_FAILED); region->vaddr = vaddr; - region->iova = (u64)vaddr; + region->iova = iova_allocator_alloc(iova_allocator, size); region->size = size; vfio_pci_dma_map(device, region); @@ -44,6 +45,7 @@ static void region_teardown(struct vfio_pci_device *device, FIXTURE(vfio_pci_driver_test) { struct vfio_pci_device *device; + struct iova_allocator *iova_allocator; struct vfio_dma_region memcpy_region; void *vaddr; int msi_fd; @@ -72,14 +74,15 @@ FIXTURE_SETUP(vfio_pci_driver_test) struct vfio_pci_driver *driver; self->device = vfio_pci_device_init(device_bdf, variant->iommu_mode); + self->iova_allocator = iova_allocator_init(self->device); driver = &self->device->driver; - region_setup(self->device, &self->memcpy_region, SZ_1G); - region_setup(self->device, &driver->region, SZ_2M); + region_setup(self->device, self->iova_allocator, &self->memcpy_region, SZ_1G); + region_setup(self->device, self->iova_allocator, &driver->region, SZ_2M); /* Any IOVA that doesn't overlap memcpy_region and driver->region. */ - self->unmapped_iova = 8UL * SZ_1G; + self->unmapped_iova = iova_allocator_alloc(self->iova_allocator, SZ_1G); vfio_pci_driver_init(self->device); self->msi_fd = self->device->msi_eventfds[driver->msi]; @@ -108,6 +111,7 @@ FIXTURE_TEARDOWN(vfio_pci_driver_test) region_teardown(self->device, &self->memcpy_region); region_teardown(self->device, &driver->region); + iova_allocator_cleanup(self->iova_allocator); vfio_pci_device_cleanup(self->device); } diff --git a/tools/testing/selftests/vsock/vmtest.sh b/tools/testing/selftests/vsock/vmtest.sh index edacebfc163251..8ceeb8a7894f5b 100755 --- a/tools/testing/selftests/vsock/vmtest.sh +++ b/tools/testing/selftests/vsock/vmtest.sh @@ -389,9 +389,9 @@ run_test() { local rc host_oops_cnt_before=$(dmesg | grep -c -i 'Oops') - host_warn_cnt_before=$(dmesg --level=warn | wc -l) + host_warn_cnt_before=$(dmesg --level=warn | grep -c -i 'vsock') vm_oops_cnt_before=$(vm_ssh -- dmesg | grep -c -i 'Oops') - vm_warn_cnt_before=$(vm_ssh -- dmesg --level=warn | wc -l) + vm_warn_cnt_before=$(vm_ssh -- dmesg --level=warn | grep -c -i 'vsock') name=$(echo "${1}" | awk '{ print $1 }') eval test_"${name}" @@ -403,7 +403,7 @@ run_test() { rc=$KSFT_FAIL fi - host_warn_cnt_after=$(dmesg --level=warn | wc -l) + host_warn_cnt_after=$(dmesg --level=warn | grep -c -i 'vsock') if [[ ${host_warn_cnt_after} -gt ${host_warn_cnt_before} ]]; then echo "FAIL: kernel warning detected on host" | log_host "${name}" rc=$KSFT_FAIL @@ -415,7 +415,7 @@ run_test() { rc=$KSFT_FAIL fi - vm_warn_cnt_after=$(vm_ssh -- dmesg --level=warn | wc -l) + vm_warn_cnt_after=$(vm_ssh -- dmesg --level=warn | grep -c -i 'vsock') if [[ ${vm_warn_cnt_after} -gt ${vm_warn_cnt_before} ]]; then echo "FAIL: kernel warning detected on vm" | log_host "${name}" rc=$KSFT_FAIL diff --git a/tools/tracing/latency/latency-collector.c b/tools/tracing/latency/latency-collector.c index cf263fe9deaf4b..ef97916e3873a1 100644 --- a/tools/tracing/latency/latency-collector.c +++ b/tools/tracing/latency/latency-collector.c @@ -1725,7 +1725,7 @@ static void show_usage(void) "-n, --notrace\t\tIf latency is detected, do not print out the content of\n" "\t\t\tthe trace file to standard output\n\n" -"-t, --threads NRTHR\tRun NRTHR threads for printing. Default is %d.\n\n" +"-e, --threads NRTHR\tRun NRTHR threads for printing. Default is %d.\n\n" "-r, --random\t\tArbitrarily sleep a certain amount of time, default\n" "\t\t\t%ld ms, before reading the trace file. The\n" diff --git a/virt/kvm/guest_memfd.c b/virt/kvm/guest_memfd.c index fbca8c0972da6e..ffadc5ee8e0455 100644 --- a/virt/kvm/guest_memfd.c +++ b/virt/kvm/guest_memfd.c @@ -623,31 +623,50 @@ int kvm_gmem_bind(struct kvm *kvm, struct kvm_memory_slot *slot, return r; } -void kvm_gmem_unbind(struct kvm_memory_slot *slot) +static void __kvm_gmem_unbind(struct kvm_memory_slot *slot, struct kvm_gmem *gmem) { unsigned long start = slot->gmem.pgoff; unsigned long end = start + slot->npages; - struct kvm_gmem *gmem; + + xa_store_range(&gmem->bindings, start, end - 1, NULL, GFP_KERNEL); + + /* + * synchronize_srcu(&kvm->srcu) ensured that kvm_gmem_get_pfn() + * cannot see this memslot. + */ + WRITE_ONCE(slot->gmem.file, NULL); +} + +void kvm_gmem_unbind(struct kvm_memory_slot *slot) +{ struct file *file; /* - * Nothing to do if the underlying file was already closed (or is being - * closed right now), kvm_gmem_release() invalidates all bindings. + * Nothing to do if the underlying file was _already_ closed, as + * kvm_gmem_release() invalidates and nullifies all bindings. */ - file = kvm_gmem_get_file(slot); - if (!file) + if (!slot->gmem.file) return; - gmem = file->private_data; - - filemap_invalidate_lock(file->f_mapping); - xa_store_range(&gmem->bindings, start, end - 1, NULL, GFP_KERNEL); + file = kvm_gmem_get_file(slot); /* - * synchronize_srcu(&kvm->srcu) ensured that kvm_gmem_get_pfn() - * cannot see this memslot. + * However, if the file is _being_ closed, then the bindings need to be + * removed as kvm_gmem_release() might not run until after the memslot + * is freed. Note, modifying the bindings is safe even though the file + * is dying as kvm_gmem_release() nullifies slot->gmem.file under + * slots_lock, and only puts its reference to KVM after destroying all + * bindings. I.e. reaching this point means kvm_gmem_release() hasn't + * yet destroyed the bindings or freed the gmem_file, and can't do so + * until the caller drops slots_lock. */ - WRITE_ONCE(slot->gmem.file, NULL); + if (!file) { + __kvm_gmem_unbind(slot, slot->gmem.file->private_data); + return; + } + + filemap_invalidate_lock(file->f_mapping); + __kvm_gmem_unbind(slot, file->private_data); filemap_invalidate_unlock(file->f_mapping); fput(file);