]> Git Repo - linux.git/commitdiff
Merge tag 'sound-6.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai...
authorLinus Torvalds <[email protected]>
Thu, 27 Apr 2023 17:58:37 +0000 (10:58 -0700)
committerLinus Torvalds <[email protected]>
Thu, 27 Apr 2023 17:58:37 +0000 (10:58 -0700)
Pull sound updates from Takashi Iwai:
 "At this time, it's an interesting mixture of changes for both old and
  new stuff. Majority of changes are about ASoC (lots of systematic
  changes for converting remove callbacks to void, and cleanups), while
  we got the fixes and the enhancements of very old PCI cards, too.

  Here are some highlights:

  ALSA/ASoC Core:
   - Continued effort of more ASoC core cleanups
   - Minor improvements for XRUN handling in indirect PCM helpers
   - Code refactoring of PCM core code

  ASoC:
   - Continued feature and simplification work on SOF, including
     addition of a no-DSP mode for bringup, HDA MLink and extensions to
     the IPC4 protocol
   - Hibernation support for CS35L45
   - More DT binding conversions
   - Support for Cirrus Logic CS35L56, Freescale QMC, Maxim MAX98363,
     nVidia systems with MAX9809x and RT5631, Realtek RT712, Renesas
     R-Car Gen4, Rockchip RK3588 and TI TAS5733

  ALSA:
   - Lots of works for legacy emu10k1 and ymfpci PCI drivers
   - PCM kselftest fixes and enhancements"

* tag 'sound-6.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (586 commits)
  ALSA: emu10k1: use high-level I/O in set_filterQ()
  ALSA: emu10k1: use high-level I/O functions also during init
  ALSA: emu10k1: fix error handling in snd_audigy_i2c_volume_put()
  ALSA: emu10k1: don't stop DSP in _snd_emu10k1_{,audigy_}init_efx()
  ALSA: emu10k1: fix SNDRV_EMU10K1_IOCTL_SINGLE_STEP
  ALSA: emu10k1: skip Sound Blaster-specific hacks for E-MU cards
  ALSA: emu10k1: fixup DSP defines
  ALSA: emu10k1: pull in some register definitions from kX-project
  ALSA: emu10k1: remove some bogus defines
  ALSA: emu10k1: eliminate some unused defines
  ALSA: emu10k1: fix lineup of EMU_HANA_* defines
  ALSA: emu10k1: comment updates
  ALSA: emu10k1: fix snd_emu1010_fpga_read() input masking for rev2 cards
  ALSA: emu10k1: remove unused emu->pcm_playback_efx_substream field
  ALSA: emu10k1: remove unused `resume` parameter from snd_emu10k1_init()
  ALSA: emu10k1: minor optimizations
  ALSA: emu10k1: remove remaining cruft from snd_emu10k1_emu1010_init()
  ALSA: emu10k1: remove apparently pointless EMU_HANA_OPTION_CARDS reads
  ALSA: emu10k1: remove apparently pointless FPGA reads
  ALSA: emu10k1: stop doing weird things with HCFG in snd_emu10k1_emu1010_init()
  ...

15 files changed:
1  2 
Documentation/devicetree/bindings/sound/everest,es8316.yaml
Documentation/devicetree/bindings/sound/qcom,lpass-rx-macro.yaml
Documentation/devicetree/bindings/sound/qcom,lpass-tx-macro.yaml
Documentation/devicetree/bindings/sound/qcom,wcd934x.yaml
Documentation/devicetree/bindings/sound/simple-card.yaml
MAINTAINERS
arch/powerpc/platforms/8xx/cpm1.c
sound/core/pcm_native.c
sound/pci/emu10k1/emupcm.c
sound/pci/hda/patch_hdmi.c
sound/pci/ymfpci/ymfpci.c
sound/pci/ymfpci/ymfpci_main.c
sound/soc/fsl/fsl_sai.c
sound/soc/sof/ipc4-topology.c
sound/soc/sof/pm.c

index 9f2b111818ea418565acd1a171860d74ff0c866b,80cd81ecae6fc81e7acc40bb7328d53bff290354..b6079b3c440d54566321b47df8afdef2b738b745
@@@ -28,6 -28,10 +28,10 @@@ properties
      items:
        - const: mclk
  
+   port:
+     $ref: audio-graph-port.yaml#
+     unevaluatedProperties: false
    "#sound-dai-cells":
      const: 0
  
@@@ -40,7 -44,7 +44,7 @@@ unevaluatedProperties: fals
  
  examples:
    - |
 -    i2c0 {
 +    i2c {
        #address-cells = <1>;
        #size-cells = <0>;
        es8316: codec@11 {
index e6fcf542cf878a93c4cb7cf9f952b5f912406a05,0ae3c81abdf89ea4c4eb0034634fd099283b1531..ec4b0ac8ad68c0589f6ffc11127e89421ea41798
@@@ -9,15 -9,13 +9,13 @@@ title: LPASS(Low Power Audio Subsystem
  maintainers:
    - Srinivas Kandagatla <[email protected]>
  
- allOf:
-   - $ref: dai-common.yaml#
  properties:
    compatible:
      enum:
        - qcom,sc7280-lpass-rx-macro
        - qcom,sm8250-lpass-rx-macro
        - qcom,sm8450-lpass-rx-macro
+       - qcom,sm8550-lpass-rx-macro
        - qcom,sc8280xp-lpass-rx-macro
  
    reg:
      const: 0
  
    clocks:
+     minItems: 3
      maxItems: 5
  
    clock-names:
-     oneOf:
-       - items:   # for ADSP based platforms
-           - const: mclk
-           - const: npl
-           - const: macro
-           - const: dcodec
-           - const: fsgen
-       - items:   # for ADSP bypass based platforms
-           - const: mclk
-           - const: npl
-           - const: fsgen
+     minItems: 3
+     maxItems: 5
  
    clock-output-names:
      maxItems: 1
@@@ -61,6 -51,65 +51,65 @@@ required
    - reg
    - "#sound-dai-cells"
  
 -            - items:   #for ADSP based platforms
+ allOf:
+   - $ref: dai-common.yaml#
+   - if:
+       properties:
+         compatible:
+           enum:
+             - qcom,sc7280-lpass-rx-macro
+     then:
+       properties:
+         clock-names:
+           oneOf:
 -            - items:   #for ADSP bypass based platforms
++            - items:   # for ADSP based platforms
+                 - const: mclk
+                 - const: npl
+                 - const: macro
+                 - const: dcodec
+                 - const: fsgen
++            - items:   # for ADSP bypass based platforms
+                 - const: mclk
+                 - const: npl
+                 - const: fsgen
+   - if:
+       properties:
+         compatible:
+           enum:
+             - qcom,sc8280xp-lpass-rx-macro
+             - qcom,sm8250-lpass-rx-macro
+             - qcom,sm8450-lpass-rx-macro
+     then:
+       properties:
+         clocks:
+           minItems: 5
+           maxItems: 5
+         clock-names:
+           items:
+             - const: mclk
+             - const: npl
+             - const: macro
+             - const: dcodec
+             - const: fsgen
+   - if:
+       properties:
+         compatible:
+           enum:
+             - qcom,sm8550-lpass-rx-macro
+     then:
+       properties:
+         clocks:
+           minItems: 4
+           maxItems: 4
+         clock-names:
+           items:
+             - const: mclk
+             - const: macro
+             - const: dcodec
+             - const: fsgen
  unevaluatedProperties: false
  
  examples:
index 6c8751497d36fbb41f3c739f1ec17875eb3aa932,9d6e67524dafa93d2c72ede5448f33c692b49e8f..4156981fe02b6f68c9eda7222bde9e73400b9844
@@@ -9,15 -9,13 +9,13 @@@ title: LPASS(Low Power Audio Subsystem
  maintainers:
    - Srinivas Kandagatla <[email protected]>
  
- allOf:
-   - $ref: dai-common.yaml#
  properties:
    compatible:
      enum:
        - qcom,sc7280-lpass-tx-macro
        - qcom,sm8250-lpass-tx-macro
        - qcom,sm8450-lpass-tx-macro
+       - qcom,sm8550-lpass-tx-macro
        - qcom,sc8280xp-lpass-tx-macro
  
    reg:
      const: 0
  
    clocks:
-     oneOf:
-       - maxItems: 3
-       - maxItems: 5
+     minItems: 3
+     maxItems: 5
  
    clock-names:
-     oneOf:
-       - items:   # for ADSP based platforms
-           - const: mclk
-           - const: npl
-           - const: macro
-           - const: dcodec
-           - const: fsgen
-       - items:   # for ADSP bypass based platforms
-           - const: mclk
-           - const: npl
-           - const: fsgen
+     minItems: 3
+     maxItems: 5
  
    clock-output-names:
      maxItems: 1
@@@ -67,6 -55,65 +55,65 @@@ required
    - reg
    - "#sound-dai-cells"
  
 -            - items:   #for ADSP based platforms
+ allOf:
+   - $ref: dai-common.yaml#
+   - if:
+       properties:
+         compatible:
+           enum:
+             - qcom,sc7280-lpass-tx-macro
+     then:
+       properties:
+         clock-names:
+           oneOf:
 -            - items:   #for ADSP bypass based platforms
++            - items:   # for ADSP based platforms
+                 - const: mclk
+                 - const: npl
+                 - const: macro
+                 - const: dcodec
+                 - const: fsgen
++            - items:   # for ADSP bypass based platforms
+                 - const: mclk
+                 - const: npl
+                 - const: fsgen
+   - if:
+       properties:
+         compatible:
+           enum:
+             - qcom,sc8280xp-lpass-tx-macro
+             - qcom,sm8250-lpass-tx-macro
+             - qcom,sm8450-lpass-tx-macro
+     then:
+       properties:
+         clocks:
+           minItems: 5
+           maxItems: 5
+         clock-names:
+           items:
+             - const: mclk
+             - const: npl
+             - const: macro
+             - const: dcodec
+             - const: fsgen
+   - if:
+       properties:
+         compatible:
+           enum:
+             - qcom,sm8550-lpass-tx-macro
+     then:
+       properties:
+         clocks:
+           minItems: 4
+           maxItems: 4
+         clock-names:
+           items:
+             - const: mclk
+             - const: macro
+             - const: dcodec
+             - const: fsgen
  unevaluatedProperties: false
  
  examples:
index 30506d91fddd67508a3b29091efa881c782c5268,ae8346b9d332c10cc189f2eb8ddddbccd49d2fb8..4df59f3b7b018c74ae59a96ca31dab940f8645d0
@@@ -134,7 -134,6 +134,7 @@@ properties
  patternProperties:
    "^.*@[0-9a-f]+$":
      type: object
 +    additionalProperties: true
      description: |
        WCD934x subnode for each slave devices. Bindings of each subnodes
        depends on the specific driver providing the functionality and
@@@ -152,6 -151,7 +152,7 @@@ required
    - reg
  
  allOf:
+   - $ref: dai-common.yaml#
    - if:
        required:
          - slim-ifc-dev
index 806e2fff165f9c646d3a2fc53c37fc7eb9a941ae,066f632105b79f4429540b9e6843f5eb4f4c8e4e..b05e05c81cc4d2d035566982ce9a4ebbefcfc229
@@@ -78,7 -78,7 +78,7 @@@ definitions
      $ref: /schemas/types.yaml#/definitions/uint32
  
    prefix:
-     description: "device name prefix"
+     description: device name prefix
      $ref: /schemas/types.yaml#/definitions/string
  
    label:
@@@ -262,9 -262,9 +262,9 @@@ required
  additionalProperties: false
  
  examples:
 -#--------------------
 +# --------------------
  # single DAI link
 -#--------------------
 +# --------------------
    - |
      sound {
          compatible = "simple-audio-card";
          };
      };
  
 -#--------------------
 +# --------------------
  # Multi DAI links
 -#--------------------
 +# --------------------
    - |
      sound {
          compatible = "simple-audio-card";
          };
      };
  
 -#--------------------
 +# --------------------
  # route audio from IMX6 SSI2 through TLV320DAC3100 codec
  # through TPA6130A2 amplifier to headphones:
 -#--------------------
 +# --------------------
    - |
      sound {
          compatible = "simple-audio-card";
          };
      };
  
 -#--------------------
 +# --------------------
  # Sampling Rate Conversion
 -#--------------------
 +# --------------------
    - |
      sound {
          compatible = "simple-audio-card";
          };
      };
  
 -#--------------------
 +# --------------------
  # 2 CPU 1 Codec (Mixing)
 -#--------------------
 +# --------------------
    - |
      sound {
          compatible = "simple-audio-card";
          };
      };
  
 -#--------------------
 +# --------------------
  # Multi DAI links with DPCM:
  #
  # CPU0 ------ ak4613
  # CPU3 --/                /* DPCM 5ch/6ch */
  # CPU4 --/                /* DPCM 7ch/8ch */
  # CPU5 ------ PCM3168A-c
 -#--------------------
 +# --------------------
    - |
      sound {
          compatible = "simple-audio-card";
diff --combined MAINTAINERS
index a9b604a796fcabc84c1e8dbfd789773e8c4b1566,b39ec6dbcdc989875ddfd2cbb6398b7b03ce269e..b5169b19449a9c95028fa635af034adc17a3a34a
@@@ -73,7 -73,7 +73,7 @@@ Tips for patch submitter
        and ideally, should come with a patch proposal. Please do not send
        automated reports to this list either. Such bugs will be handled
        better and faster in the usual public places. See
 -      Documentation/admin-guide/security-bugs.rst for details.
 +      Documentation/process/security-bugs.rst for details.
  
  8.    Happy hacking.
  
@@@ -224,13 -224,13 +224,13 @@@ S:      Orphan / Obsolet
  F:    drivers/net/ethernet/8390/
  
  9P FILE SYSTEM
 -M:    Eric Van Hensbergen <ericvh@gmail.com>
 +M:    Eric Van Hensbergen <ericvh@kernel.org>
  M:    Latchesar Ionkov <[email protected]>
  M:    Dominique Martinet <[email protected]>
  R:    Christian Schoenebeck <[email protected]>
 -L:    v9fs[email protected]
 +L:    v9fs@lists.linux.dev
  S:    Maintained
 -W:    http://swik.net/v9fs
 +W:    http://github.com/v9fs
  Q:    http://patchwork.kernel.org/project/v9fs-devel/list/
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/ericvh/v9fs.git
  T:    git git://github.com/martinetd/linux.git
@@@ -1041,15 -1041,6 +1041,15 @@@ F:    drivers/gpu/drm/amd/include/vi_struc
  F:    include/uapi/linux/kfd_ioctl.h
  F:    include/uapi/linux/kfd_sysfs.h
  
 +AMD PDS CORE DRIVER
 +M:    Shannon Nelson <[email protected]>
 +M:    Brett Creeley <[email protected]>
 +L:    [email protected]
 +S:    Supported
 +F:    Documentation/networking/device_drivers/ethernet/amd/pds_core.rst
 +F:    drivers/net/ethernet/amd/pds_core/
 +F:    include/linux/pds/
 +
  AMD SPI DRIVER
  M:    Sanjay R Mehta <[email protected]>
  S:    Maintained
@@@ -1080,7 -1071,7 +1080,7 @@@ M:      Naveen Krishna Chatradhi <naveenkris
  R:    Carlos Bilbao <[email protected]>
  L:    [email protected]
  S:    Maintained
 -F:    Documentation/x86/amd_hsmp.rst
 +F:    Documentation/arch/x86/amd_hsmp.rst
  F:    arch/x86/include/asm/amd_hsmp.h
  F:    arch/x86/include/uapi/asm/amd_hsmp.h
  F:    drivers/platform/x86/amd/hsmp.c
@@@ -1236,6 -1227,12 +1236,6 @@@ F:     Documentation/devicetree/bindings/ii
  F:    drivers/iio/addac/ad74413r.c
  F:    include/dt-bindings/iio/addac/adi,ad74413r.h
  
 -ANALOG DEVICES INC AD9389B DRIVER
 -M:    Hans Verkuil <[email protected]>
 -L:    [email protected]
 -S:    Maintained
 -F:    drivers/media/i2c/ad9389b*
 -
  ANALOG DEVICES INC ADA4250 DRIVER
  M:    Antoniu Miclaus <[email protected]>
  L:    [email protected]
@@@ -2075,6 -2072,7 +2075,7 @@@ M:      Alexander Sverdlin <alexander.sverdl
  L:    [email protected] (moderated for non-subscribers)
  S:    Maintained
  F:    Documentation/devicetree/bindings/iio/adc/cirrus,ep9301-adc.yaml
+ F:    Documentation/devicetree/bindings/sound/cirrus,ep9301-*
  F:    arch/arm/boot/compressed/misc-ep93xx.h
  F:    arch/arm/mach-ep93xx/
  F:    drivers/iio/adc/ep93xx_adc.c
@@@ -2278,7 -2276,7 +2279,7 @@@ F:      arch/arm/boot/dts/intel-ixp
  F:    arch/arm/mach-ixp4xx/
  F:    drivers/bus/intel-ixp4xx-eb.c
  F:    drivers/clocksource/timer-ixp4xx.c
 -F:    drivers/crypto/ixp4xx_crypto.c
 +F:    drivers/crypto/intel/ixp4xx/ixp4xx_crypto.c
  F:    drivers/gpio/gpio-ixp4xx.c
  F:    drivers/irqchip/irq-ixp4xx.c
  
@@@ -2607,12 -2605,6 +2608,12 @@@ F:    include/dt-bindings/*/qcom
  F:    include/linux/*/qcom*
  F:    include/linux/soc/qcom/
  
 +ARM/QUALCOMM CHROMEBOOK SUPPORT
 +R:    [email protected]
 +F:    arch/arm64/boot/dts/qcom/sc7180*
 +F:    arch/arm64/boot/dts/qcom/sc7280*
 +F:    arch/arm64/boot/dts/qcom/sdm845-cheza*
 +
  ARM/RDA MICRO ARCHITECTURE
  M:    Manivannan Sadhasivam <[email protected]>
  L:    [email protected] (moderated for non-subscribers)
@@@ -2663,7 -2655,6 +2664,7 @@@ F:      arch/arm64/boot/dts/renesas
  F:    arch/riscv/boot/dts/renesas/
  F:    drivers/soc/renesas/
  F:    include/linux/soc/renesas/
 +K:    \brenesas,
  
  ARM/RISCPC ARCHITECTURE
  M:    Russell King <[email protected]>
@@@ -4441,13 -4432,6 +4442,13 @@@ S:    Maintaine
  F:    drivers/scsi/BusLogic.*
  F:    drivers/scsi/FlashPoint.*
  
 +BXCAN CAN NETWORK DRIVER
 +M:    Dario Binacchi <[email protected]>
 +L:    [email protected]
 +S:    Maintained
 +F:    Documentation/devicetree/bindings/net/can/st,stm32-bxcan.yaml
 +F:    drivers/net/can/bxcan.c
 +
  C-MEDIA CMI8788 DRIVER
  M:    Clemens Ladisch <[email protected]>
  L:    [email protected] (moderated for non-subscribers)
@@@ -4478,14 -4462,14 +4479,14 @@@ F:   Documentation/devicetree/bindings/ne
  F:    drivers/net/ieee802154/ca8210.c
  
  CANAAN/KENDRYTE K210 SOC FPIOA DRIVER
 -M:    Damien Le Moal <d[email protected]>
 +M:    Damien Le Moal <d[email protected]>
  L:    [email protected]
  L:    [email protected] (pinctrl driver)
  F:    Documentation/devicetree/bindings/pinctrl/canaan,k210-fpioa.yaml
  F:    drivers/pinctrl/pinctrl-k210.c
  
  CANAAN/KENDRYTE K210 SOC RESET CONTROLLER DRIVER
 -M:    Damien Le Moal <d[email protected]>
 +M:    Damien Le Moal <d[email protected]>
  L:    [email protected]
  L:    [email protected]
  S:    Maintained
@@@ -4493,7 -4477,7 +4494,7 @@@ F:      Documentation/devicetree/bindings/re
  F:    drivers/reset/reset-k210.c
  
  CANAAN/KENDRYTE K210 SOC SYSTEM CONTROLLER DRIVER
 -M:    Damien Le Moal <d[email protected]>
 +M:    Damien Le Moal <d[email protected]>
  L:    [email protected]
  S:    Maintained
  F:      Documentation/devicetree/bindings/mfd/canaan,k210-sysctl.yaml
@@@ -4922,6 -4906,7 +4923,7 @@@ L:      [email protected]
  S:    Maintained
  F:    Documentation/devicetree/bindings/sound/cirrus,cs*
  F:    include/dt-bindings/sound/cs*
+ F:    include/sound/cs*
  F:    sound/pci/hda/cs*
  F:    sound/pci/hda/hda_cs_dsp_ctl.*
  F:    sound/soc/codecs/cs*
@@@ -5957,6 -5942,11 +5959,6 @@@ F:     drivers/devfreq/event
  F:    include/dt-bindings/pmu/exynos_ppmu.h
  F:    include/linux/devfreq-event.h
  
 -DEVICE NUMBER REGISTRY
 -M:    Torben Mathiasen <[email protected]>
 -S:    Maintained
 -W:    http://lanana.org/docs/device-list/index.html
 -
  DEVICE RESOURCE MANAGEMENT HELPERS
  M:    Hans de Goede <[email protected]>
  R:    Matti Vaittinen <[email protected]>
@@@ -5983,7 -5973,7 +5985,7 @@@ F:      include/linux/dm-*.
  F:    include/uapi/linux/dm-*.h
  
  DEVLINK
 -M:    Jiri Pirko <jiri@nvidia.com>
 +M:    Jiri Pirko <jiri@resnulli.us>
  L:    [email protected]
  S:    Supported
  F:    Documentation/networking/devlink
@@@ -6219,7 -6209,6 +6221,7 @@@ DOCUMENTATION REPORTING ISSUE
  M:    Thorsten Leemhuis <[email protected]>
  L:    [email protected]
  S:    Maintained
 +F:    Documentation/admin-guide/quickly-build-trimmed-linux.rst
  F:    Documentation/admin-guide/reporting-issues.rst
  
  DOCUMENTATION SCRIPTS
@@@ -6531,7 -6520,6 +6533,7 @@@ L:      [email protected]
  L:    [email protected]
  L:    [email protected]
  S:    Maintained
 +B:    https://gitlab.freedesktop.org/drm/msm/-/issues
  T:    git https://gitlab.freedesktop.org/drm/msm.git
  F:    Documentation/devicetree/bindings/display/msm/
  F:    drivers/gpu/drm/msm/
@@@ -6551,13 -6539,6 +6553,13 @@@ T:    git git://anongit.freedesktop.org/dr
  F:    Documentation/devicetree/bindings/display/panel/sony,acx424akp.yaml
  F:    drivers/gpu/drm/panel/panel-novatek-nt35560.c
  
 +DRM DRIVER FOR NOVATEK NT36523 PANELS
 +M:    Jianhua Lu <[email protected]>
 +S:    Maintained
 +T:    git git://anongit.freedesktop.org/drm/drm-misc
 +F:    Documentation/devicetree/bindings/display/panel/novatek,nt36523.yaml
 +F:    drivers/gpu/drm/panel/panel-novatek-nt36523.c
 +
  DRM DRIVER FOR NOVATEK NT36672A PANELS
  M:    Sumit Semwal <[email protected]>
  S:    Maintained
@@@ -6638,16 -6619,6 +6640,16 @@@ T:    git git://anongit.freedesktop.org/dr
  F:    Documentation/devicetree/bindings/display/panel/samsung,lms397kf04.yaml
  F:    drivers/gpu/drm/panel/panel-samsung-db7430.c
  
 +DRM DRIVER FOR SAMSUNG MIPI DSIM BRIDGE
 +M:    Inki Dae <[email protected]>
 +M:    Jagan Teki <[email protected]>
 +M:    Marek Szyprowski <[email protected]>
 +S:    Maintained
 +T:    git git://anongit.freedesktop.org/drm/drm-misc
 +F:    Documentation/devicetree/bindings/display/bridge/samsung,mipi-dsim.yaml
 +F:    drivers/gpu/drm/bridge/samsung-dsim.c
 +F:    include/drm/bridge/samsung-dsim.h
 +
  DRM DRIVER FOR SAMSUNG S6D27A1 PANELS
  M:    Markuss Broks <[email protected]>
  S:    Maintained
@@@ -6855,7 -6826,6 +6857,7 @@@ S:      Maintaine
  T:    git git://anongit.freedesktop.org/drm/drm-misc
  F:    Documentation/devicetree/bindings/display/bridge/
  F:    drivers/gpu/drm/bridge/
 +F:    include/drm/drm_bridge.h
  
  DRM DRIVERS FOR EXYNOS
  M:    Inki Dae <[email protected]>
@@@ -6948,7 -6918,6 +6950,7 @@@ F:      drivers/phy/mediatek/phy-mtk-mipi
  
  DRM DRIVERS FOR NVIDIA TEGRA
  M:    Thierry Reding <[email protected]>
 +M:    Mikko Perttunen <[email protected]>
  L:    [email protected]
  L:    [email protected]
  S:    Supported
@@@ -7077,7 -7046,7 +7079,7 @@@ F:      Documentation/devicetree/bindings/di
  F:    drivers/gpu/drm/xlnx/
  
  DRM PANEL DRIVERS
 -M:    Thierry Reding <[email protected]>
 +M:    Neil Armstrong <[email protected]>
  R:    Sam Ravnborg <[email protected]>
  L:    [email protected]
  S:    Maintained
@@@ -7761,7 -7730,6 +7763,7 @@@ T:      git git://git.kernel.org/pub/scm/lin
  F:    Documentation/filesystems/ext4/
  F:    fs/ext4/
  F:    include/trace/events/ext4.h
 +F:    include/uapi/linux/ext4.h
  
  Extended Verification Module (EVM)
  M:    Mimi Zohar <[email protected]>
@@@ -8134,7 -8102,7 +8136,7 @@@ M:      Pankaj Gupta <[email protected]
  M:    Gaurav Jain <[email protected]>
  L:    [email protected]
  S:    Maintained
 -F:    Documentation/devicetree/bindings/crypto/fsl-sec4.txt
 +F:    Documentation/devicetree/bindings/crypto/fsl,sec-v4.0*
  F:    drivers/crypto/caam/
  
  FREESCALE COLDFIRE M5441X MMC DRIVER
@@@ -8250,7 -8218,6 +8252,7 @@@ F:      drivers/net/ethernet/freescale/dpa
  
  FREESCALE QORIQ DPAA FMAN DRIVER
  M:    Madalin Bucur <[email protected]>
 +R:    Sean Anderson <[email protected]>
  L:    [email protected]
  S:    Maintained
  F:    Documentation/devicetree/bindings/net/fsl-fman.txt
@@@ -8282,6 -8249,23 +8284,23 @@@ S:    Maintaine
  F:    drivers/soc/fsl/qe/
  F:    include/soc/fsl/qe/
  
+ FREESCALE QUICC ENGINE QMC DRIVER
+ M:    Herve Codina <[email protected]>
+ L:    [email protected]
+ S:    Maintained
+ F:    Documentation/devicetree/bindings/soc/fsl/cpm_qe/fsl,cpm1-scc-qmc.yaml
+ F:    drivers/soc/fsl/qe/qmc.c
+ F:    include/soc/fsl/qe/qmc.h
+ FREESCALE QUICC ENGINE TSA DRIVER
+ M:    Herve Codina <[email protected]>
+ L:    [email protected]
+ S:    Maintained
+ F:    Documentation/devicetree/bindings/soc/fsl/cpm_qe/fsl,cpm1-tsa.yaml
+ F:    drivers/soc/fsl/qe/tsa.c
+ F:    drivers/soc/fsl/qe/tsa.h
+ F:    include/dt-bindings/soc/cpm1-fsl,tsa.h
  FREESCALE QUICC ENGINE UCC ETHERNET DRIVER
  M:    Li Yang <[email protected]>
  L:    [email protected]
@@@ -8333,6 -8317,14 +8352,14 @@@ F:    sound/soc/fsl/fsl
  F:    sound/soc/fsl/imx*
  F:    sound/soc/fsl/mpc8610_hpcd.c
  
+ FREESCALE SOC SOUND QMC DRIVER
+ M:    Herve Codina <[email protected]>
+ L:    [email protected] (moderated for non-subscribers)
+ L:    [email protected]
+ S:    Maintained
+ F:    Documentation/devicetree/bindings/sound/fsl,qmc-audio.yaml
+ F:    sound/soc/fsl/fsl_qmc_audio.c
  FREESCALE USB PERIPHERAL DRIVERS
  M:    Li Yang <[email protected]>
  L:    [email protected]
  S:    Maintained
  F:    drivers/platform/x86/fujitsu-laptop.c
  
 -FUJITSU M-5MO LS CAMERA ISP DRIVER
 -M:    Kyungmin Park <[email protected]>
 -M:    Heungjun Kim <[email protected]>
 -L:    [email protected]
 -S:    Maintained
 -F:    drivers/media/i2c/m5mols/
 -F:    include/media/i2c/m5mols.h
 -
  FUJITSU TABLET EXTRAS
  M:    Robert Gerlach <[email protected]>
  L:    [email protected]
@@@ -8716,7 -8716,7 +8743,7 @@@ F:      drivers/input/touchscreen/goodix
  
  GOOGLE ETHERNET DRIVERS
  M:    Jeroen de Borst <[email protected]>
 -M:    Catherine Sullivan <csully@google.com>
 +M:    Praveen Kaligineedi <pkaligineedi@google.com>
  R:    Shailend Chand <[email protected]>
  L:    [email protected]
  S:    Supported
@@@ -8779,6 -8779,7 +8806,6 @@@ F:      Documentation/admin-guide/gpio
  F:    Documentation/devicetree/bindings/gpio/
  F:    Documentation/driver-api/gpio/
  F:    drivers/gpio/
 -F:    include/asm-generic/gpio.h
  F:    include/dt-bindings/gpio/
  F:    include/linux/gpio.h
  F:    include/linux/gpio/
@@@ -8965,17 -8966,6 +8992,17 @@@ Q:    http://patchwork.linuxtv.org/project
  T:    git git://linuxtv.org/anttip/media_tree.git
  F:    drivers/media/usb/hackrf/
  
 +HANDSHAKE UPCALL FOR TRANSPORT LAYER SECURITY
 +M:    Chuck Lever <[email protected]>
 +L:    [email protected]
 +L:    [email protected]
 +S:    Maintained
 +F:    Documentation/netlink/specs/handshake.yaml
 +F:    Documentation/networking/tls-handshake.rst
 +F:    include/net/handshake.h
 +F:    include/trace/events/handshake.h
 +F:    net/handshake/
 +
  HANTRO VPU CODEC DRIVER
  M:    Ezequiel Garcia <[email protected]>
  M:    Philipp Zabel <[email protected]>
@@@ -9765,7 -9755,7 +9792,7 @@@ F:      include/linux/i3c
  IA64 (Itanium) PLATFORM
  L:    [email protected]
  S:    Orphan
 -F:    Documentation/ia64/
 +F:    Documentation/arch/ia64/
  F:    arch/ia64/
  
  IBM Operation Panel Input Driver
@@@ -10319,14 -10309,12 +10346,14 @@@ M:        Andy Shevchenko <[email protected]
  L:    [email protected]
  S:    Supported
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/andy/linux-gpio-intel.git
 +F:    drivers/gpio/gpio-elkhartlake.c
  F:    drivers/gpio/gpio-ich.c
  F:    drivers/gpio/gpio-merrifield.c
  F:    drivers/gpio/gpio-ml-ioh.c
  F:    drivers/gpio/gpio-pch.c
  F:    drivers/gpio/gpio-sch.c
  F:    drivers/gpio/gpio-sodaville.c
 +F:    drivers/gpio/gpio-tangier.c
  
  INTEL GVT-g DRIVERS (Intel GPU Virtualization)
  M:    Zhenyu Wang <[email protected]>
@@@ -10419,7 -10407,7 +10446,7 @@@ INTEL IXP4XX CRYPTO SUPPOR
  M:    Corentin Labbe <[email protected]>
  L:    [email protected]
  S:    Maintained
 -F:    drivers/crypto/ixp4xx_crypto.c
 +F:    drivers/crypto/intel/ixp4xx/ixp4xx_crypto.c
  
  INTEL ISHTP ECLITE DRIVER
  M:    Sumesh K Naduvalath <[email protected]>
@@@ -10454,11 -10442,11 +10481,11 @@@ INTEL KEEM BAY OCS AES/SM4 CRYPTO DRIVE
  M:    Daniele Alessandrelli <[email protected]>
  S:    Maintained
  F:    Documentation/devicetree/bindings/crypto/intel,keembay-ocs-aes.yaml
 -F:    drivers/crypto/keembay/Kconfig
 -F:    drivers/crypto/keembay/Makefile
 -F:    drivers/crypto/keembay/keembay-ocs-aes-core.c
 -F:    drivers/crypto/keembay/ocs-aes.c
 -F:    drivers/crypto/keembay/ocs-aes.h
 +F:    drivers/crypto/intel/keembay/Kconfig
 +F:    drivers/crypto/intel/keembay/Makefile
 +F:    drivers/crypto/intel/keembay/keembay-ocs-aes-core.c
 +F:    drivers/crypto/intel/keembay/ocs-aes.c
 +F:    drivers/crypto/intel/keembay/ocs-aes.h
  
  INTEL KEEM BAY OCS ECC CRYPTO DRIVER
  M:    Daniele Alessandrelli <[email protected]>
@@@ -10466,20 -10454,20 +10493,20 @@@ M:        Prabhjot Khurana <prabhjot.khurana@i
  M:    Mark Gross <[email protected]>
  S:    Maintained
  F:    Documentation/devicetree/bindings/crypto/intel,keembay-ocs-ecc.yaml
 -F:    drivers/crypto/keembay/Kconfig
 -F:    drivers/crypto/keembay/Makefile
 -F:    drivers/crypto/keembay/keembay-ocs-ecc.c
 +F:    drivers/crypto/intel/keembay/Kconfig
 +F:    drivers/crypto/intel/keembay/Makefile
 +F:    drivers/crypto/intel/keembay/keembay-ocs-ecc.c
  
  INTEL KEEM BAY OCS HCU CRYPTO DRIVER
  M:    Daniele Alessandrelli <[email protected]>
  M:    Declan Murphy <[email protected]>
  S:    Maintained
  F:    Documentation/devicetree/bindings/crypto/intel,keembay-ocs-hcu.yaml
 -F:    drivers/crypto/keembay/Kconfig
 -F:    drivers/crypto/keembay/Makefile
 -F:    drivers/crypto/keembay/keembay-ocs-hcu-core.c
 -F:    drivers/crypto/keembay/ocs-hcu.c
 -F:    drivers/crypto/keembay/ocs-hcu.h
 +F:    drivers/crypto/intel/keembay/Kconfig
 +F:    drivers/crypto/intel/keembay/Makefile
 +F:    drivers/crypto/intel/keembay/keembay-ocs-hcu-core.c
 +F:    drivers/crypto/intel/keembay/ocs-hcu.c
 +F:    drivers/crypto/intel/keembay/ocs-hcu.h
  
  INTEL THUNDER BAY EMMC PHY DRIVER
  M:    Nandhini Srikandan <[email protected]>
  S:    Supported
  W:    http://tboot.sourceforge.net
  T:    hg http://tboot.hg.sourceforge.net:8000/hgroot/tboot/tboot
 -F:    Documentation/x86/intel_txt.rst
 +F:    Documentation/arch/x86/intel_txt.rst
  F:    arch/x86/kernel/tboot.c
  F:    include/linux/tboot.h
  
  S:    Supported
  Q:    https://patchwork.kernel.org/project/intel-sgx/list/
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git x86/sgx
 -F:    Documentation/x86/sgx.rst
 +F:    Documentation/arch/x86/sgx.rst
  F:    arch/x86/entry/vdso/vsgx.S
  F:    arch/x86/include/asm/sgx.h
  F:    arch/x86/include/uapi/asm/sgx.h
@@@ -11796,7 -11784,7 +11823,7 @@@ T:   git git://git.kernel.org/pub/scm/lin
  F:    drivers/ata/sata_promise.*
  
  LIBATA SUBSYSTEM (Serial and Parallel ATA drivers)
 -M:    Damien Le Moal <d[email protected]>
 +M:    Damien Le Moal <d[email protected]>
  L:    [email protected]
  S:    Maintained
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/dlemoal/libata.git
@@@ -11932,7 -11920,6 +11959,7 @@@ M:   Scott Wood <[email protected]
  L:    [email protected]
  S:    Odd fixes
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/scottwood/linux.git
 +F:    Documentation/devicetree/bindings/cache/freescale-l2cache.txt
  F:    Documentation/devicetree/bindings/powerpc/fsl/
  F:    arch/powerpc/platforms/83xx/
  F:    arch/powerpc/platforms/85xx/
@@@ -12156,13 -12143,6 +12183,13 @@@ S: Maintaine
  F:    Documentation/devicetree/bindings/pinctrl/loongson,ls2k-pinctrl.yaml
  F:    drivers/pinctrl/pinctrl-loongson2.c
  
 +LOONGSON GPIO DRIVER
 +M:    Yinbo Zhu <[email protected]>
 +L:    [email protected]
 +S:    Maintained
 +F:    Documentation/devicetree/bindings/gpio/loongson,ls-gpio.yaml
 +F:    drivers/gpio/gpio-loongson-64bit.c
 +
  LOONGSON-2 SOC SERIES CLOCK DRIVER
  M:    Yinbo Zhu <[email protected]>
  L:    [email protected]
@@@ -12322,7 -12302,7 +12349,7 @@@ T:   git git://git.kernel.org/pub/scm/lin
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless-next.git
  F:    Documentation/networking/mac80211-injection.rst
  F:    Documentation/networking/mac80211_hwsim/mac80211_hwsim.rst
 -F:    drivers/net/wireless/mac80211_hwsim.[ch]
 +F:    drivers/net/wireless/virtual/mac80211_hwsim.[ch]
  F:    include/net/mac80211.h
  F:    net/mac80211/
  
  S:    Maintained
  F:    drivers/net/ethernet/mediatek/
  
 +MEDIATEK ETHERNET PCS DRIVER
 +M:    Alexander Couzens <[email protected]>
 +M:    Daniel Golle <[email protected]>
 +L:    [email protected]
 +S:    Maintained
 +F:    drivers/net/pcs/pcs-mtk-lynxi.c
 +F:    include/linux/pcs/pcs-mtk-lynxi.h
 +
  MEDIATEK I2C CONTROLLER DRIVER
  M:    Qii Wang <[email protected]>
  L:    [email protected]
@@@ -13221,11 -13193,8 +13248,11 @@@ MEDIATEK SWITCH DRIVE
  M:    Sean Wang <[email protected]>
  M:    Landen Chao <[email protected]>
  M:    DENG Qingfang <[email protected]>
 +M:    Daniel Golle <[email protected]>
  L:    [email protected]
  S:    Maintained
 +F:    drivers/net/dsa/mt7530-mdio.c
 +F:    drivers/net/dsa/mt7530-mmio.c
  F:    drivers/net/dsa/mt7530.*
  F:    net/dsa/tag_mtk.c
  
@@@ -13651,9 -13620,13 +13678,13 @@@ F: Documentation/devicetree/bindings/se
  F:    drivers/spi/spi-at91-usart.c
  
  MICROCHIP AUDIO ASOC DRIVERS
- M:    Codrin Ciubotariu <codrin.ciubotariu@microchip.com>
+ M:    Claudiu Beznea <claudiu.beznea@microchip.com>
  L:    [email protected] (moderated for non-subscribers)
  S:    Supported
+ F:    Documentation/devicetree/bindings/sound/atmel*
+ F:    Documentation/devicetree/bindings/sound/axentia,tse850-pcm5142.txt
+ F:    Documentation/devicetree/bindings/sound/microchip,sama7g5-*
+ F:    Documentation/devicetree/bindings/sound/mikroe,mikroe-proto.txt
  F:    sound/soc/atmel
  
  MICROCHIP CSI2DC DRIVER
@@@ -13826,9 -13799,10 +13857,10 @@@ S: Supporte
  F:    drivers/spi/spi-atmel.*
  
  MICROCHIP SSC DRIVER
- M:    Codrin Ciubotariu <codrin.ciubotariu@microchip.com>
+ M:    Claudiu Beznea <claudiu.beznea@microchip.com>
  L:    [email protected] (moderated for non-subscribers)
  S:    Supported
+ F:    Documentation/devicetree/bindings/misc/atmel-ssc.txt
  F:    drivers/misc/atmel-ssc.c
  F:    include/linux/atmel-ssc.h
  
@@@ -14196,13 -14170,6 +14228,13 @@@ S: Odd Fixe
  F:    Documentation/devicetree/bindings/net/ieee802154/mrf24j40.txt
  F:    drivers/net/ieee802154/mrf24j40.c
  
 +MSI EC DRIVER
 +M:    Nikita Kravets <[email protected]>
 +L:    [email protected]
 +S:    Maintained
 +W:    https://github.com/BeardOverflow/msi-ec
 +F:    drivers/platform/x86/msi-ec.*
 +
  MSI LAPTOP SUPPORT
  M:    "Lee, Chun-Yi" <[email protected]>
  L:    [email protected]
  S:    Maintained
  F:    drivers/mtd/devices/docg3*
  
 -MT9M032 APTINA SENSOR DRIVER
 -M:    Laurent Pinchart <[email protected]>
 -L:    [email protected]
 -S:    Maintained
 -T:    git git://linuxtv.org/media_tree.git
 -F:    drivers/media/i2c/mt9m032.c
 -F:    include/media/i2c/mt9m032.h
 -
  MT9P031 APTINA CAMERA SENSOR
  M:    Laurent Pinchart <[email protected]>
  L:    [email protected]
@@@ -14256,6 -14231,14 +14288,6 @@@ F:  Documentation/devicetree/bindings/me
  F:    drivers/media/i2c/mt9p031.c
  F:    include/media/i2c/mt9p031.h
  
 -MT9T001 APTINA CAMERA SENSOR
 -M:    Laurent Pinchart <[email protected]>
 -L:    [email protected]
 -S:    Maintained
 -T:    git git://linuxtv.org/media_tree.git
 -F:    drivers/media/i2c/mt9t001.c
 -F:    include/media/i2c/mt9t001.h
 -
  MT9T112 APTINA CAMERA SENSOR
  M:    Jacopo Mondi <[email protected]>
  L:    [email protected]
@@@ -14642,14 -14625,11 +14674,14 @@@ F:        net/netlabel
  
  NETWORKING [MPTCP]
  M:    Matthieu Baerts <[email protected]>
 +M:    Mat Martineau <[email protected]>
  L:    [email protected]
  L:    [email protected]
  S:    Maintained
  W:    https://github.com/multipath-tcp/mptcp_net-next/wiki
  B:    https://github.com/multipath-tcp/mptcp_net-next/issues
 +T:    git https://github.com/multipath-tcp/mptcp_net-next.git export-net
 +T:    git https://github.com/multipath-tcp/mptcp_net-next.git export
  F:    Documentation/networking/mptcp-sysctl.rst
  F:    include/net/mptcp.h
  F:    include/trace/events/mptcp.h
@@@ -14708,10 -14688,13 +14740,10 @@@ F:        net/ipv4/nexthop.
  
  NFC SUBSYSTEM
  M:    Krzysztof Kozlowski <[email protected]>
 -L:    [email protected] (subscribers-only)
  L:    [email protected]
  S:    Maintained
 -B:    mailto:[email protected]
  F:    Documentation/devicetree/bindings/net/nfc/
  F:    drivers/nfc/
 -F:    include/linux/platform_data/nfcmrvl.h
  F:    include/net/nfc/
  F:    include/uapi/linux/nfc.h
  F:    net/nfc/
  NFC VIRTUAL NCI DEVICE DRIVER
  M:    Bongsu Jeon <[email protected]>
  L:    [email protected]
 -L:    [email protected] (subscribers-only)
  S:    Supported
  F:    drivers/nfc/virtual_ncidev.c
  F:    tools/testing/selftests/nci/
@@@ -14794,7 -14778,7 +14826,7 @@@ F:   include/uapi/linux/nitro_enclaves.
  F:    samples/nitro_enclaves/
  
  NOHZ, DYNTICKS SUPPORT
 -M:    Frederic Weisbecker <f[email protected]>
 +M:    Frederic Weisbecker <f[email protected]>
  M:    Thomas Gleixner <[email protected]>
  M:    Ingo Molnar <[email protected]>
  L:    [email protected]
@@@ -14920,12 -14904,12 +14952,12 @@@ M:        Sagi Grimberg <[email protected]
  L:    [email protected]
  S:    Supported
  W:    http://git.infradead.org/nvme.git
 -T:    git://git.infradead.org/nvme.git
 +T:    git git://git.infradead.org/nvme.git
  F:    Documentation/nvme/
 -F:    drivers/nvme/host/
  F:    drivers/nvme/common/
 -F:    include/linux/nvme.h
 +F:    drivers/nvme/host/
  F:    include/linux/nvme-*.h
 +F:    include/linux/nvme.h
  F:    include/uapi/linux/nvme_ioctl.h
  
  NVM EXPRESS FABRICS AUTHENTICATION
@@@ -14960,7 -14944,7 +14992,7 @@@ M:   Chaitanya Kulkarni <[email protected]
  L:    [email protected]
  S:    Supported
  W:    http://git.infradead.org/nvme.git
 -T:    git://git.infradead.org/nvme.git
 +T:    git git://git.infradead.org/nvme.git
  F:    drivers/nvme/target/
  
  NVMEM FRAMEWORK
@@@ -15009,13 -14993,6 +15041,13 @@@ F: Documentation/devicetree/bindings/cl
  F:    drivers/clk/imx/
  F:    include/dt-bindings/clock/imx*
  
 +NXP i.MX 8M ISI DRIVER
 +M:    Laurent Pinchart <[email protected]>
 +L:    [email protected]
 +S:    Maintained
 +F:    Documentation/devicetree/bindings/media/nxp,imx8-isi.yaml
 +F:    drivers/media/platform/nxp/imx8-isi/
 +
  NXP i.MX 8MQ DCSS DRIVER
  M:    Laurentiu Palcu <[email protected]>
  R:    Lucas Stach <[email protected]>
@@@ -15097,6 -15074,7 +15129,6 @@@ F:   Documentation/devicetree/bindings/so
  F:    sound/soc/codecs/tfa989x.c
  
  NXP-NCI NFC DRIVER
 -L:    [email protected] (subscribers-only)
  S:    Orphan
  F:    Documentation/devicetree/bindings/net/nfc/nxp,nci.yaml
  F:    drivers/nfc/nxp-nci
@@@ -15133,7 -15111,7 +15165,7 @@@ F:   Documentation/hwmon/nzxt-smart2.rs
  F:    drivers/hwmon/nzxt-smart2.c
  
  OBJAGG
 -M:    Jiri Pirko <jiri@nvidia.com>
 +M:    Jiri Pirko <jiri@resnulli.us>
  L:    [email protected]
  S:    Supported
  F:    include/linux/objagg.h
@@@ -15443,7 -15421,6 +15475,7 @@@ M:   Shunqian Zheng <[email protected]
  L:    [email protected]
  S:    Maintained
  T:    git git://linuxtv.org/media_tree.git
 +F:    Documentation/devicetree/bindings/media/i2c/ovti,ov2685.yaml
  F:    drivers/media/i2c/ov2685.c
  
  OMNIVISION OV2740 SENSOR DRIVER
@@@ -15535,7 -15512,7 +15567,7 @@@ F:   Documentation/devicetree/bindings/me
  F:    drivers/media/i2c/ov7740.c
  
  OMNIVISION OV8856 SENSOR DRIVER
 -M:    Dongchun Zhu <dongchun.zhu@mediatek.com>
 +M:    Sakari Ailus <[email protected].com>
  L:    [email protected]
  S:    Maintained
  T:    git git://linuxtv.org/media_tree.git
  S:    Maintained
  F:    drivers/ptp/ptp_ocp.c
  
 +INTEL PTP DFL ToD DRIVER
 +M:    Tianfei Zhang <[email protected]>
 +L:    [email protected]
 +L:    [email protected]
 +S:    Maintained
 +F:    drivers/ptp/ptp_dfl_tod.c
 +
  OPENCORES I2C BUS DRIVER
  M:    Peter Korsgaard <[email protected]>
  M:    Andrew Lunn <[email protected]>
@@@ -15704,7 -15674,7 +15736,7 @@@ S:   Maintaine
  W:    http://openrisc.io
  T:    git https://github.com/openrisc/linux.git
  F:    Documentation/devicetree/bindings/openrisc/
 -F:    Documentation/openrisc/
 +F:    Documentation/arch/openrisc/
  F:    arch/openrisc/
  F:    drivers/irqchip/irq-ompic.c
  F:    drivers/irqchip/irq-or1k-*
@@@ -15900,7 -15870,7 +15932,7 @@@ W:   https://parisc.wiki.kernel.or
  Q:    http://patchwork.kernel.org/project/linux-parisc/list/
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/jejb/parisc-2.6.git
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux.git
 -F:    Documentation/parisc/
 +F:    Documentation/arch/parisc/
  F:    arch/parisc/
  F:    drivers/char/agp/parisc-agp.c
  F:    drivers/input/misc/hp_sdc_rtc.c
@@@ -15915,7 -15885,7 +15947,7 @@@ F:   drivers/video/logo/logo_parisc
  F:    include/linux/hp_sdc.h
  
  PARMAN
 -M:    Jiri Pirko <jiri@nvidia.com>
 +M:    Jiri Pirko <jiri@resnulli.us>
  L:    [email protected]
  S:    Supported
  F:    include/linux/parman.h
@@@ -16035,8 -16005,6 +16067,8 @@@ M:   Lucas Stach <[email protected]
  L:    [email protected]
  L:    [email protected] (moderated for non-subscribers)
  S:    Maintained
 +F:    Documentation/devicetree/bindings/pci/fsl,imx6q-pcie-common.yaml
 +F:    Documentation/devicetree/bindings/pci/fsl,imx6q-pcie-ep.yaml
  F:    Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml
  F:    drivers/pci/controller/dwc/*imx6*
  
@@@ -16395,6 -16363,12 +16427,6 @@@ S:  Maintaine
  F:    crypto/pcrypt.c
  F:    include/crypto/pcrypt.h
  
 -PEAQ WMI HOTKEYS DRIVER
 -M:    Hans de Goede <[email protected]>
 -L:    [email protected]
 -S:    Maintained
 -F:    drivers/platform/x86/peaq-wmi.c
 -
  PECI HARDWARE MONITORING DRIVERS
  M:    Iwona Winiarska <[email protected]>
  L:    [email protected]
@@@ -16831,8 -16805,9 +16863,8 @@@ F:   include/uapi/linux/if_pppol2tp.
  F:    net/l2tp/l2tp_ppp.c
  
  PPP PROTOCOL DRIVERS AND COMPRESSORS
 -M:    Paul Mackerras <[email protected]>
  L:    [email protected]
 -S:    Maintained
 +S:    Orphan
  F:    drivers/net/ppp/ppp_*
  
  PPS SUPPORT
@@@ -17076,7 -17051,7 +17108,7 @@@ QAT DRIVE
  M:    Giovanni Cabiddu <[email protected]>
  L:    [email protected]
  S:    Supported
 -F:    drivers/crypto/qat/
 +F:    drivers/crypto/intel/qat/
  
  QCOM AUDIO (ASoC) DRIVERS
  M:    Srinivas Kandagatla <[email protected]>
@@@ -17226,12 -17201,6 +17258,12 @@@ F: fs/qnx4
  F:    include/uapi/linux/qnx4_fs.h
  F:    include/uapi/linux/qnxtypes.h
  
 +QNX6 FILESYSTEM
 +S:    Orphan
 +F:    Documentation/filesystems/qnx6.rst
 +F:    fs/qnx6/
 +F:    include/linux/qnx6_fs.h
 +
  QORIQ DPAA2 FSL-MC BUS DRIVER
  M:    Stuart Yoder <[email protected]>
  M:    Laurentiu Tudor <[email protected]>
@@@ -17260,7 -17229,7 +17292,7 @@@ S:   Supporte
  W:    https://wireless.wiki.kernel.org/en/users/Drivers/ath10k
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git
  F:    drivers/net/wireless/ath/ath10k/
 -F:    Documentation/devicetree/bindings/net/wireless/qcom,ath10k.txt
 +F:    Documentation/devicetree/bindings/net/wireless/qcom,ath10k.yaml
  
  QUALCOMM ATHEROS ATH11K WIRELESS DRIVER
  M:    Kalle Valo <[email protected]>
@@@ -17296,7 -17265,6 +17328,7 @@@ F:   drivers/net/wwan/qcom_bam_dmux.
  QUALCOMM CAMERA SUBSYSTEM DRIVER
  M:    Robert Foss <[email protected]>
  M:    Todor Tomov <[email protected]>
 +M:    Bryan O'Donoghue <[email protected]>
  L:    [email protected]
  S:    Maintained
  F:    Documentation/admin-guide/media/qcom_camss.rst
@@@ -17312,16 -17280,6 +17344,16 @@@ F: Documentation/devicetree/bindings/cl
  F:    drivers/clk/qcom/
  F:    include/dt-bindings/clock/qcom,*
  
 +QUALCOMM CLOUD AI (QAIC) DRIVER
 +M:    Jeffrey Hugo <[email protected]>
 +L:    [email protected]
 +L:    [email protected]
 +S:    Supported
 +T:    git git://anongit.freedesktop.org/drm/drm-misc
 +F:    Documentation/accel/qaic/
 +F:    drivers/accel/qaic/
 +F:    include/uapi/drm/qaic_accel.h
 +
  QUALCOMM CORE POWER REDUCTION (CPR) AVS DRIVER
  M:    Bjorn Andersson <[email protected]>
  M:    Konrad Dybcio <[email protected]>
@@@ -17344,7 -17302,6 +17376,7 @@@ M:   Thara Gopinath <thara.gopinath@gmail
  L:    [email protected]
  L:    [email protected]
  S:    Maintained
 +F:    Documentation/devicetree/bindings/crypto/qcom-qce.yaml
  F:    drivers/crypto/qce/
  
  QUALCOMM EMAC GIGABIT ETHERNET DRIVER
@@@ -17358,7 -17315,7 +17390,7 @@@ M:   Vinod Koul <[email protected]
  R:    Bhupesh Sharma <[email protected]>
  L:    [email protected]
  S:    Maintained
 -F:    Documentation/devicetree/bindings/net/qcom,ethqos.txt
 +F:    Documentation/devicetree/bindings/net/qcom,ethqos.yaml
  F:    drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
  
  QUALCOMM FASTRPC DRIVER
@@@ -17618,7 -17575,7 +17650,7 @@@ F:   include/ras/ras_event.
  RAYLINK/WEBGEAR 802.11 WIRELESS LAN DRIVER
  L:    [email protected]
  S:    Orphan
 -F:    drivers/net/wireless/ray*
 +F:    drivers/net/wireless/legacy/ray*
  
  RC-CORE / LIRC FRAMEWORK
  M:    Sean Young <[email protected]>
@@@ -17704,7 -17661,7 +17736,7 @@@ M:   Fenghua Yu <[email protected]
  M:    Reinette Chatre <[email protected]>
  L:    [email protected]
  S:    Supported
 -F:    Documentation/x86/resctrl*
 +F:    Documentation/arch/x86/resctrl*
  F:    arch/x86/include/asm/resctrl.h
  F:    arch/x86/kernel/cpu/resctrl/
  F:    tools/testing/selftests/resctrl/
@@@ -17713,13 -17670,11 +17745,13 @@@ READ-COPY UPDATE (RCU
  M:    "Paul E. McKenney" <[email protected]>
  M:    Frederic Weisbecker <[email protected]> (kernel/rcu/tree_nocb.h)
  M:    Neeraj Upadhyay <[email protected]> (kernel/rcu/tasks.h)
 +M:    Joel Fernandes <[email protected]>
  M:    Josh Triplett <[email protected]>
 +M:    Boqun Feng <[email protected]>
  R:    Steven Rostedt <[email protected]>
  R:    Mathieu Desnoyers <[email protected]>
  R:    Lai Jiangshan <[email protected]>
 -R:    Joel Fernandes <[email protected]>
 +R:    Zqiang <[email protected]>
  L:    [email protected]
  S:    Supported
  W:    http://www.rdrop.com/users/paulmck/RCU/
@@@ -18067,7 -18022,7 +18099,7 @@@ F:   Documentation/devicetree/bindings/sp
  F:    Documentation/devicetree/bindings/usb/microchip,mpfs-musb.yaml
  F:    arch/riscv/boot/dts/microchip/
  F:    drivers/char/hw_random/mpfs-rng.c
 -F:    drivers/clk/microchip/clk-mpfs.c
 +F:    drivers/clk/microchip/clk-mpfs*.c
  F:    drivers/i2c/busses/i2c-microchip-corei2c.c
  F:    drivers/mailbox/mailbox-mpfs.c
  F:    drivers/pci/controller/pcie-microchip-host.c
@@@ -18368,9 -18323,8 +18400,9 @@@ F:   drivers/s390/block/dasd
  F:    include/linux/dasd_mod.h
  
  S390 IOMMU (PCI)
 +M:    Niklas Schnelle <[email protected]>
  M:    Matthew Rosato <[email protected]>
 -M:    Gerald Schaefer <[email protected]>
 +R:    Gerald Schaefer <[email protected]>
  L:    [email protected]
  S:    Supported
  F:    drivers/iommu/s390-iommu.c
@@@ -18565,6 -18519,7 +18597,6 @@@ F:   include/media/drv-intf/s3c_camif.
  
  SAMSUNG S3FWRN5 NFC DRIVER
  M:    Krzysztof Kozlowski <[email protected]>
 -L:    [email protected] (subscribers-only)
  S:    Maintained
  F:    Documentation/devicetree/bindings/net/nfc/samsung,s3fwrn5.yaml
  F:    drivers/nfc/s3fwrn5
@@@ -18574,7 -18529,6 +18606,7 @@@ M:   Sylwester Nawrocki <s.nawrocki@samsu
  M:    Andrzej Hajda <[email protected]>
  L:    [email protected]
  S:    Supported
 +F:    Documentation/devicetree/bindings/media/samsung,s5c73m3.yaml
  F:    drivers/media/i2c/s5c73m3/*
  
  SAMSUNG S5K5BAF CAMERA DRIVER
@@@ -18599,11 -18553,6 +18631,11 @@@ M: Sylwester Nawrocki <s.nawrocki@samsu
  L:    [email protected]
  S:    Supported
  Q:    https://patchwork.linuxtv.org/project/linux-media/list/
 +F:    Documentation/devicetree/bindings/media/samsung,exynos4210-csis.yaml
 +F:    Documentation/devicetree/bindings/media/samsung,exynos4210-fimc.yaml
 +F:    Documentation/devicetree/bindings/media/samsung,exynos4212-fimc-is.yaml
 +F:    Documentation/devicetree/bindings/media/samsung,exynos4212-fimc-lite.yaml
 +F:    Documentation/devicetree/bindings/media/samsung,fimc.yaml
  F:    drivers/media/platform/samsung/exynos4-is/
  
  SAMSUNG SOC CLOCK DRIVERS
@@@ -18885,7 -18834,7 +18917,7 @@@ F:   include/uapi/linux/sed
  SECURITY CONTACT
  M:    Security Officers <[email protected]>
  S:    Supported
 -F:    Documentation/admin-guide/security-bugs.rst
 +F:    Documentation/process/security-bugs.rst
  
  SECURITY SUBSYSTEM
  M:    Paul Moore <[email protected]>
@@@ -18907,8 -18856,8 +18939,8 @@@ S:   Supporte
  W:    https://selinuxproject.org
  W:    https://github.com/SELinuxProject
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux.git
 -F:    Documentation/ABI/obsolete/sysfs-selinux-checkreqprot
 -F:    Documentation/ABI/obsolete/sysfs-selinux-disable
 +F:    Documentation/ABI/removed/sysfs-selinux-checkreqprot
 +F:    Documentation/ABI/removed/sysfs-selinux-disable
  F:    Documentation/admin-guide/LSM/SELinux.rst
  F:    include/trace/events/avc.h
  F:    include/uapi/linux/selinux_netlink.h
@@@ -18994,14 -18943,6 +19026,14 @@@ S: Supporte
  F:    Documentation/networking/devlink/sfc.rst
  F:    drivers/net/ethernet/sfc/
  
 +SFCTEMP HWMON DRIVER
 +M:    Emil Renner Berthing <[email protected]>
 +L:    [email protected]
 +S:    Maintained
 +F:    Documentation/devicetree/bindings/hwmon/starfive,jh71x0-temp.yaml
 +F:    Documentation/hwmon/sfctemp.rst
 +F:    drivers/hwmon/sfctemp.c
 +
  SFF/SFP/SFP+ MODULE SUPPORT
  M:    Russell King <[email protected]>
  L:    [email protected]
  S:    Odd Fixes
  W:    https://linuxtv.org
  T:    git git://linuxtv.org/media_tree.git
 +F:    Documentation/devicetree/bindings/media/silabs,si470x.yaml
  F:    drivers/media/radio/si470x/radio-si470x-i2c.c
  
  SI470X FM RADIO RECEIVER USB DRIVER
@@@ -19166,7 -19106,6 +19198,7 @@@ M:   Conor Dooley <[email protected]
  L:    [email protected]
  S:    Maintained
  T:    git https://git.kernel.org/pub/scm/linux/kernel/git/conor/linux.git/
 +F:    Documentation/devicetree/bindings/cache/sifive,ccache0.yaml
  F:    drivers/soc/sifive/
  
  SILEAD TOUCHSCREEN DRIVER
@@@ -19243,7 -19182,9 +19275,7 @@@ W:   http://www.brownhat.org/sis900.htm
  F:    drivers/net/ethernet/sis/sis900.*
  
  SIS FRAMEBUFFER DRIVER
 -M:    Thomas Winischhofer <[email protected]>
 -S:    Maintained
 -W:    http://www.winischhofer.net/linuxsisvga.shtml
 +S:    Orphan
  F:    Documentation/fb/sisfb.rst
  F:    drivers/video/fbdev/sis/
  F:    include/video/sisfb.h
@@@ -19998,13 -19939,6 +20030,13 @@@ M: Emil Renner Berthing <[email protected]
  S:    Maintained
  F:    arch/riscv/boot/dts/starfive/
  
 +STARFIVE DWMAC GLUE LAYER
 +M:    Emil Renner Berthing <[email protected]>
 +M:    Samin Guo <[email protected]>
 +S:    Maintained
 +F:    Documentation/devicetree/bindings/net/starfive,jh7110-dwmac.yaml
 +F:    drivers/net/ethernet/stmicro/stmmac/dwmac-starfive.c
 +
  STARFIVE JH7100 CLOCK DRIVERS
  M:    Emil Renner Berthing <[email protected]>
  S:    Maintained
@@@ -20215,7 -20149,7 +20247,7 @@@ M:   John Paul Adrian Glaubitz <glaubitz@
  L:    [email protected]
  S:    Maintained
  Q:    http://patchwork.kernel.org/project/linux-sh/list/
 -F:    Documentation/sh/
 +F:    Documentation/arch/sh/
  F:    arch/sh/
  F:    drivers/sh/
  
@@@ -20275,7 -20209,7 +20307,7 @@@ M:   Vineet Gupta <[email protected]
  L:    [email protected]
  S:    Supported
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc.git
 -F:    Documentation/arc/
 +F:    Documentation/arch/arc
  F:    Documentation/devicetree/bindings/arc/*
  F:    Documentation/devicetree/bindings/interrupt-controller/snps,arc*
  F:    arch/arc/
@@@ -20745,6 -20679,7 +20777,6 @@@ F:   sound/soc/codecs/tscs*.
  TENSILICA XTENSA PORT (xtensa)
  M:    Chris Zankel <[email protected]>
  M:    Max Filippov <[email protected]>
 -L:    [email protected]
  S:    Maintained
  T:    git https://github.com/jcmvbkbc/linux-xtensa.git
  F:    arch/xtensa/
  S:    Maintained
  F:    Documentation/driver-api/thermal/power_allocator.rst
  F:    drivers/thermal/gov_power_allocator.c
 -F:    include/trace/events/thermal_power_allocator.h
 +F:    drivers/thermal/thermal_trace_ipa.h
  
  THINKPAD ACPI EXTRAS DRIVER
  M:    Henrique de Moraes Holschuh <[email protected]>
@@@ -21080,6 -21015,7 +21112,6 @@@ F:   drivers/iio/magnetometer/tmag5273.
  TI TRF7970A NFC DRIVER
  M:    Mark Greer <[email protected]>
  L:    [email protected]
 -L:    [email protected] (subscribers-only)
  S:    Supported
  F:    Documentation/devicetree/bindings/net/nfc/ti,trf7970a.yaml
  F:    drivers/nfc/trf7970a.c
@@@ -21171,6 -21107,7 +21203,6 @@@ F:   Documentation/hwmon/tmp401.rs
  F:    drivers/hwmon/tmp401.c
  
  TMP464 HARDWARE MONITOR DRIVER
 -M:    Agathe Porte <[email protected]>
  M:    Guenter Roeck <[email protected]>
  L:    [email protected]
  S:    Maintained
@@@ -21333,14 -21270,6 +21365,14 @@@ S: Maintaine
  F:    Documentation/tools/rtla/
  F:    tools/tracing/rtla/
  
 +TECHNICAL ADVISORY BOARD PROCESS DOCS
 +M:    "Theodore Ts'o" <[email protected]>
 +M:    Greg Kroah-Hartman <[email protected]>
 +L:    [email protected]
 +S:    Maintained
 +F:    Documentation/process/researcher-guidelines.rst
 +F:    Documentation/process/contribution-maturity-model.rst
 +
  TRADITIONAL CHINESE DOCUMENTATION
  M:    Hu Haowen <[email protected]>
  L:    [email protected] (moderated for non-subscribers)
@@@ -21748,7 -21677,6 +21780,7 @@@ USB OVER IP DRIVE
  M:    Valentina Manea <[email protected]>
  M:    Shuah Khan <[email protected]>
  M:    Shuah Khan <[email protected]>
 +R:    Hongren Zheng <[email protected]>
  L:    [email protected]
  S:    Maintained
  F:    Documentation/usb/usbip_protocol.rst
@@@ -21895,7 -21823,7 +21927,7 @@@ USB WIRELESS RNDIS DRIVER (rndis_wlan
  M:    Jussi Kivilinna <[email protected]>
  L:    [email protected]
  S:    Maintained
 -F:    drivers/net/wireless/rndis_wlan.c
 +F:    drivers/net/wireless/legacy/rndis_wlan.c
  
  USB XHCI DRIVER
  M:    Mathias Nyman <[email protected]>
  L:    [email protected]
  S:    Maintained
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost.git
 +F:    kernel/vhost_task.c
  F:    drivers/vhost/
 +F:    include/linux/sched/vhost_task.h
  F:    include/linux/vhost_iotlb.h
  F:    include/uapi/linux/vhost.h
  
@@@ -22651,7 -22577,7 +22683,7 @@@ F:   drivers/input/misc/wistron_btns.
  WL3501 WIRELESS PCMCIA CARD DRIVER
  L:    [email protected]
  S:    Odd fixes
 -F:    drivers/net/wireless/wl3501*
 +F:    drivers/net/wireless/legacy/wl3501*
  
  WOLFSON MICROELECTRONICS DRIVERS
  L:    [email protected]
  S:    Maintained
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git x86/core
  F:    Documentation/devicetree/bindings/x86/
 -F:    Documentation/x86/
 +F:    Documentation/arch/x86/
  F:    arch/x86/
  
  X86 ENTRY CODE
@@@ -22760,24 -22686,13 +22792,24 @@@ S:        Maintaine
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git x86/asm
  F:    arch/x86/entry/
  
 +X86 HARDWARE VULNERABILITIES
 +M:    Thomas Gleixner <[email protected]>
 +M:    Borislav Petkov <[email protected]>
 +M:    Peter Zijlstra <[email protected]>
 +M:    Josh Poimboeuf <[email protected]>
 +R:    Pawan Gupta <[email protected]>
 +S:    Maintained
 +F:    Documentation/admin-guide/hw-vuln/
 +F:    arch/x86/include/asm/nospec-branch.h
 +F:    arch/x86/kernel/cpu/bugs.c
 +
  X86 MCE INFRASTRUCTURE
  M:    Tony Luck <[email protected]>
  M:    Borislav Petkov <[email protected]>
  L:    [email protected]
  S:    Maintained
  F:    Documentation/ABI/testing/sysfs-mce
 -F:    Documentation/x86/x86_64/machinecheck.rst
 +F:    Documentation/arch/x86/x86_64/machinecheck.rst
  F:    arch/x86/kernel/cpu/mce/*
  
  X86 MICROCODE UPDATE SUPPORT
@@@ -22799,7 -22714,7 +22831,7 @@@ M:   Hans de Goede <[email protected]
  L:    [email protected]
  S:    Maintained
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/pdx86/platform-drivers-x86.git
 -F:    drivers/platform/x86/x86-android-tablets.c
 +F:    drivers/platform/x86/x86-android-tablets/
  
  X86 PLATFORM DRIVERS
  M:    Hans de Goede <[email protected]>
@@@ -23148,6 -23063,7 +23180,6 @@@ F:   drivers/i2c/busses/i2c-xlp9xx.
  
  XRA1403 GPIO EXPANDER
  M:    Nandor Han <[email protected]>
 -M:    Semi Malinen <[email protected]>
  L:    [email protected]
  S:    Maintained
  F:    Documentation/devicetree/bindings/gpio/gpio-xra1403.txt
@@@ -23155,6 -23071,7 +23187,6 @@@ F:   drivers/gpio/gpio-xra1403.
  
  XTENSA XTFPGA PLATFORM SUPPORT
  M:    Max Filippov <[email protected]>
 -L:    [email protected]
  S:    Maintained
  F:    drivers/spi/spi-xtensa-xtfpga.c
  F:    sound/soc/xtensa/xtfpga-i2s.c
@@@ -23237,7 -23154,7 +23269,7 @@@ S:   Maintaine
  F:    arch/x86/kernel/cpu/zhaoxin.c
  
  ZONEFS FILESYSTEM
 -M:    Damien Le Moal <d[email protected]>
 +M:    Damien Le Moal <d[email protected]>
  M:    Naohiro Aota <[email protected]>
  R:    Johannes Thumshirn <[email protected]>
  L:    [email protected]
  S:    Maintained
  F:    mm/zswap.c
  
 +NXP BLUETOOTH WIRELESS DRIVERS
 +M:    Amitkumar Karwar <[email protected]>
 +M:    Neeraj Kale <[email protected]>
 +S:    Maintained
 +F:    Documentation/devicetree/bindings/net/bluetooth/nxp,88w8987-bt.yaml
 +F:    drivers/bluetooth/btnxpuart.c
 +
  THE REST
  M:    Linus Torvalds <[email protected]>
  L:    [email protected]
index 56ca14f77543bbc5a5a6644fc3c48ca1d7100843,c57fcda7a4bbecd3cfa5229a77f546528b2f4180..34ab29966c8bf01984b5a7c62513ba61de47f24e
@@@ -44,7 -44,7 +44,7 @@@
  #include <asm/fs_pd.h>
  
  #ifdef CONFIG_8xx_GPIO
 -#include <linux/of_gpio.h>
 +#include <linux/gpio/legacy-of-mm-gpiochip.h>
  #endif
  
  #define CPM_MAP_SIZE    (0x4000)
@@@ -94,7 -94,7 +94,7 @@@ int cpm_command(u32 command, u8 opcode
        int i, ret;
        unsigned long flags;
  
-       if (command & 0xffffff0f)
+       if (command & 0xffffff03)
                return -EINVAL;
  
        spin_lock_irqsave(&cmd_lock, flags);
diff --combined sound/core/pcm_native.c
index 5868661d461bc85c8ad2abfd60e4533fa04cd680,3d0c4a5b701b18b2f4519dbc6fdd30506509cc97..91c87cdb786e81c9f91ded5b0e61af41c950aba8
@@@ -958,7 -958,7 +958,7 @@@ static int snd_pcm_sw_params(struct snd
        if (snd_pcm_running(substream)) {
                if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
                    runtime->silence_size > 0)
-                       snd_pcm_playback_silence(substream, ULONG_MAX);
+                       snd_pcm_playback_silence(substream);
                err = snd_pcm_update_state(substream, runtime);
        }
        snd_pcm_stream_unlock_irq(substream);
@@@ -1455,7 -1455,7 +1455,7 @@@ static void snd_pcm_post_start(struct s
        __snd_pcm_set_state(runtime, state);
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
            runtime->silence_size > 0)
-               snd_pcm_playback_silence(substream, ULONG_MAX);
+               snd_pcm_playback_silence(substream);
        snd_pcm_timer_notify(substream, SNDRV_TIMER_EVENT_MSTART);
  }
  
@@@ -1916,7 -1916,7 +1916,7 @@@ static void snd_pcm_post_reset(struct s
        runtime->control->appl_ptr = runtime->status->hw_ptr;
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
            runtime->silence_size > 0)
-               snd_pcm_playback_silence(substream, ULONG_MAX);
+               snd_pcm_playback_silence(substream);
        snd_pcm_stream_unlock_irq(substream);
  }
  
@@@ -2159,12 -2159,12 +2159,12 @@@ static int snd_pcm_drain(struct snd_pcm
                if (runtime->no_period_wakeup)
                        tout = MAX_SCHEDULE_TIMEOUT;
                else {
-                       tout = 10;
+                       tout = 100;
                        if (runtime->rate) {
-                               long t = runtime->period_size * 2 / runtime->rate;
+                               long t = runtime->buffer_size * 1100 / runtime->rate;
                                tout = max(t, tout);
                        }
-                       tout = msecs_to_jiffies(tout * 1000);
+                       tout = msecs_to_jiffies(tout);
                }
                tout = schedule_timeout(tout);
  
                                result = -ESTRPIPE;
                        else {
                                dev_dbg(substream->pcm->card->dev,
-                                       "playback drain error (DMA or IRQ trouble?)\n");
+                                       "playback drain timeout (DMA or IRQ trouble?)\n");
                                snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP);
                                result = -EIO;
                        }
@@@ -3521,7 -3521,6 +3521,7 @@@ static ssize_t snd_pcm_readv(struct kio
        unsigned long i;
        void __user **bufs;
        snd_pcm_uframes_t frames;
 +      const struct iovec *iov = iter_iov(to);
  
        pcm_file = iocb->ki_filp->private_data;
        substream = pcm_file->substream;
        if (runtime->state == SNDRV_PCM_STATE_OPEN ||
            runtime->state == SNDRV_PCM_STATE_DISCONNECTED)
                return -EBADFD;
 -      if (!iter_is_iovec(to))
 +      if (!to->user_backed)
                return -EINVAL;
        if (to->nr_segs > 1024 || to->nr_segs != runtime->channels)
                return -EINVAL;
 -      if (!frame_aligned(runtime, to->iov->iov_len))
 +      if (!frame_aligned(runtime, iov->iov_len))
                return -EINVAL;
 -      frames = bytes_to_samples(runtime, to->iov->iov_len);
 +      frames = bytes_to_samples(runtime, iov->iov_len);
        bufs = kmalloc_array(to->nr_segs, sizeof(void *), GFP_KERNEL);
        if (bufs == NULL)
                return -ENOMEM;
 -      for (i = 0; i < to->nr_segs; ++i)
 -              bufs[i] = to->iov[i].iov_base;
 +      for (i = 0; i < to->nr_segs; ++i) {
 +              bufs[i] = iov->iov_base;
 +              iov++;
 +      }
        result = snd_pcm_lib_readv(substream, bufs, frames);
        if (result > 0)
                result = frames_to_bytes(runtime, result);
@@@ -3561,7 -3558,6 +3561,7 @@@ static ssize_t snd_pcm_writev(struct ki
        unsigned long i;
        void __user **bufs;
        snd_pcm_uframes_t frames;
 +      const struct iovec *iov = iter_iov(from);
  
        pcm_file = iocb->ki_filp->private_data;
        substream = pcm_file->substream;
        if (runtime->state == SNDRV_PCM_STATE_OPEN ||
            runtime->state == SNDRV_PCM_STATE_DISCONNECTED)
                return -EBADFD;
 -      if (!iter_is_iovec(from))
 +      if (!from->user_backed)
                return -EINVAL;
        if (from->nr_segs > 128 || from->nr_segs != runtime->channels ||
 -          !frame_aligned(runtime, from->iov->iov_len))
 +          !frame_aligned(runtime, iov->iov_len))
                return -EINVAL;
 -      frames = bytes_to_samples(runtime, from->iov->iov_len);
 +      frames = bytes_to_samples(runtime, iov->iov_len);
        bufs = kmalloc_array(from->nr_segs, sizeof(void *), GFP_KERNEL);
        if (bufs == NULL)
                return -ENOMEM;
 -      for (i = 0; i < from->nr_segs; ++i)
 -              bufs[i] = from->iov[i].iov_base;
 +      for (i = 0; i < from->nr_segs; ++i) {
 +              bufs[i] = iov->iov_base;
 +              iov++;
 +      }
        result = snd_pcm_lib_writev(substream, bufs, frames);
        if (result > 0)
                result = frames_to_bytes(runtime, result);
index 6ec394fb1846845464b5e80158ce401ea4c03fcd,cc07bf4c6eb48a51b271acb77ba9023cd69be67f..b0c0ef342756f825c161520b2a80019c9f58949f
@@@ -76,23 -76,6 +76,6 @@@ static void snd_emu10k1_pcm_efx_interru
        snd_pcm_period_elapsed(emu->pcm_capture_efx_substream);
  }      
  
- static snd_pcm_uframes_t snd_emu10k1_efx_playback_pointer(struct snd_pcm_substream *substream)
- {
-       struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
-       struct snd_pcm_runtime *runtime = substream->runtime;
-       struct snd_emu10k1_pcm *epcm = runtime->private_data;
-       unsigned int ptr;
-       if (!epcm->running)
-               return 0;
-       ptr = snd_emu10k1_ptr_read(emu, CCCA, epcm->voices[0]->number) & 0x00ffffff;
-       ptr += runtime->buffer_size;
-       ptr -= epcm->ccca_start_addr;
-       ptr %= runtime->buffer_size;
-       return ptr;
- }
  static int snd_emu10k1_pcm_channel_alloc(struct snd_emu10k1_pcm * epcm, int voices)
  {
        int err, i;
@@@ -343,7 -326,6 +326,6 @@@ static void snd_emu10k1_pcm_init_voice(
        } else
                snd_emu10k1_ptr_write(emu, FXRT, voice,
                                      snd_emu10k1_compose_send_routing(send_routing));
-       /* Stop CA */
        /* Assumption that PT is already 0 so no harm overwriting */
        snd_emu10k1_ptr_write(emu, PTRX, voice, (send_amount[0] << 8) | send_amount[1]);
        snd_emu10k1_ptr_write(emu, DSL, voice, end_addr | (send_amount[3] << 24));
@@@ -429,36 -411,6 +411,6 @@@ static int snd_emu10k1_playback_hw_para
  }
  
  static int snd_emu10k1_playback_hw_free(struct snd_pcm_substream *substream)
- {
-       struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
-       struct snd_pcm_runtime *runtime = substream->runtime;
-       struct snd_emu10k1_pcm *epcm;
-       if (runtime->private_data == NULL)
-               return 0;
-       epcm = runtime->private_data;
-       if (epcm->extra) {
-               snd_emu10k1_voice_free(epcm->emu, epcm->extra);
-               epcm->extra = NULL;
-       }
-       if (epcm->voices[1]) {
-               snd_emu10k1_voice_free(epcm->emu, epcm->voices[1]);
-               epcm->voices[1] = NULL;
-       }
-       if (epcm->voices[0]) {
-               snd_emu10k1_voice_free(epcm->emu, epcm->voices[0]);
-               epcm->voices[0] = NULL;
-       }
-       if (epcm->memblk) {
-               snd_emu10k1_free_pages(emu, epcm->memblk);
-               epcm->memblk = NULL;
-               epcm->start_addr = 0;
-       }
-       snd_pcm_lib_free_pages(substream);
-       return 0;
- }
- static int snd_emu10k1_efx_playback_hw_free(struct snd_pcm_substream *substream)
  {
        struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
        struct snd_pcm_runtime *runtime = substream->runtime;
@@@ -527,9 -479,6 +479,6 @@@ static int snd_emu10k1_efx_playback_pre
        start_addr = epcm->start_addr;
        end_addr = epcm->start_addr + snd_pcm_lib_buffer_bytes(substream);
  
-       /*
-        * the kX driver leaves some space between voices
-        */
        channel_size = ( end_addr - start_addr ) / NUM_EFX_PLAYBACK;
  
        snd_emu10k1_pcm_init_voice(emu, 1, 1, epcm->extra,
@@@ -1091,8 -1040,6 +1040,6 @@@ static int snd_emu10k1_efx_playback_ope
        epcm->type = PLAYBACK_EFX;
        epcm->substream = substream;
        
-       emu->pcm_playback_efx_substream = substream;
        runtime->private_data = epcm;
        runtime->private_free = snd_emu10k1_pcm_free_substream;
        runtime->hw = snd_emu10k1_efx_playback;
@@@ -1236,7 -1183,7 +1183,7 @@@ static int snd_emu10k1_capture_mic_clos
  {
        struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
  
 -      emu->capture_interrupt = NULL;
 +      emu->capture_mic_interrupt = NULL;
        emu->pcm_capture_mic_substream = NULL;
        return 0;
  }
@@@ -1267,9 -1214,7 +1214,7 @@@ static int snd_emu10k1_capture_efx_open
        runtime->hw.rate_min = runtime->hw.rate_max = 48000;
        spin_lock_irq(&emu->reg_lock);
        if (emu->card_capabilities->emu_model) {
-               /*  Nb. of channels has been increased to 16 */
                /* TODO
-                * SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE
                 * SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
                 * SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 |
                 * SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000
                 * Need to add mixer control to fix sample rate
                 *                 
                 * There are 32 mono channels of 16bits each.
-                * 24bit Audio uses 2x channels over 16bit
-                * 96kHz uses 2x channels over 48kHz
-                * 192kHz uses 4x channels over 48kHz
-                * So, for 48kHz 24bit, one has 16 channels
-                * for 96kHz 24bit, one has 8 channels
-                * for 192kHz 24bit, one has 4 channels
-                *
+                * 24bit Audio uses 2x channels over 16bit,
+                * 96kHz uses 2x channels over 48kHz,
+                * 192kHz uses 4x channels over 48kHz.
+                * So, for 48kHz 24bit, one has 16 channels,
+                * for 96kHz 24bit, one has 8 channels,
+                * for 192kHz 24bit, one has 4 channels.
+                * 1010rev2 and 1616(m) cards have double that,
+                * but we don't exceed 16 channels anyway.
                 */
  #if 1
                switch (emu->emu1010.internal_clock) {
@@@ -1344,7 -1290,7 +1290,7 @@@ static int snd_emu10k1_capture_efx_clos
  {
        struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
  
 -      emu->capture_interrupt = NULL;
 +      emu->capture_efx_interrupt = NULL;
        emu->pcm_capture_efx_substream = NULL;
        return 0;
  }
@@@ -1372,10 -1318,10 +1318,10 @@@ static const struct snd_pcm_ops snd_emu
        .open =                 snd_emu10k1_efx_playback_open,
        .close =                snd_emu10k1_efx_playback_close,
        .hw_params =            snd_emu10k1_playback_hw_params,
-       .hw_free =              snd_emu10k1_efx_playback_hw_free,
+       .hw_free =              snd_emu10k1_playback_hw_free,
        .prepare =              snd_emu10k1_efx_playback_prepare,
        .trigger =              snd_emu10k1_efx_playback_trigger,
-       .pointer =              snd_emu10k1_efx_playback_pointer,
+       .pointer =              snd_emu10k1_playback_pointer,
  };
  
  int snd_emu10k1_pcm(struct snd_emu10k1 *emu, int device)
@@@ -1508,11 -1454,12 +1454,12 @@@ static int snd_emu10k1_pcm_efx_voices_m
                        nval[idx / 32] |= 1 << (idx % 32);
                        bits++;
                }
-               
+       // Check that the number of requested channels is a power of two
+       // not bigger than the number of available channels.
        for (idx = 0; idx < nefxb; idx++)
                if (1 << idx == bits)
                        break;
-       
        if (idx >= nefxb)
                return -EINVAL;
  
@@@ -1781,28 -1728,23 +1728,27 @@@ int snd_emu10k1_pcm_efx(struct snd_emu1
        struct snd_kcontrol *kctl;
        int err;
  
 -      err = snd_pcm_new(emu->card, "emu10k1 efx", device, 8, 1, &pcm);
 +      err = snd_pcm_new(emu->card, "emu10k1 efx", device, emu->audigy ? 0 : 8, 1, &pcm);
        if (err < 0)
                return err;
  
        pcm->private_data = emu;
  
 -      snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_emu10k1_fx8010_playback_ops);
 +      if (!emu->audigy)
 +              snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_emu10k1_fx8010_playback_ops);
        snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_emu10k1_capture_efx_ops);
  
        pcm->info_flags = 0;
 -      strcpy(pcm->name, "Multichannel Capture/PT Playback");
 +      if (emu->audigy)
 +              strcpy(pcm->name, "Multichannel Capture");
 +      else
 +              strcpy(pcm->name, "Multichannel Capture/PT Playback");
        emu->pcm_efx = pcm;
  
        /* EFX capture - record the "FXBUS2" channels, by default we connect the EXTINs 
         * to these
         */     
        
-       /* emu->efx_voices_mask[0] = FXWC_DEFAULTROUTE_C | FXWC_DEFAULTROUTE_A; */
        if (emu->audigy) {
                emu->efx_voices_mask[0] = 0;
                if (emu->card_capabilities->emu_model)
index 5c6980394dcec2e2d92730e0cbb54eb7b73f2277,ae17e21e57c340a4c6fd3dd86492c605bc02d46f..ee051bdfaff6f7dd69e880145b96e3f172a9143d
@@@ -81,7 -81,6 +81,7 @@@ struct hdmi_spec_per_pin 
        struct delayed_work work;
        struct hdmi_pcm *pcm; /* pointer to spec->pcm_rec[n] dynamically*/
        int pcm_idx; /* which pcm is attached. -1 means no pcm is attached */
 +      int prev_pcm_idx; /* previously assigned pcm index */
        int repoll_count;
        bool setup; /* the stream has been set up by prepare callback */
        bool silent_stream;
@@@ -1381,17 -1380,9 +1381,17 @@@ static void hdmi_attach_hda_pcm(struct 
        /* pcm already be attached to the pin */
        if (per_pin->pcm)
                return;
 +      /* try the previously used slot at first */
 +      idx = per_pin->prev_pcm_idx;
 +      if (idx >= 0) {
 +              if (!test_bit(idx, &spec->pcm_bitmap))
 +                      goto found;
 +              per_pin->prev_pcm_idx = -1; /* no longer valid, clear it */
 +      }
        idx = hdmi_find_pcm_slot(spec, per_pin);
        if (idx == -EBUSY)
                return;
 + found:
        per_pin->pcm_idx = idx;
        per_pin->pcm = get_hdmi_pcm(spec, idx);
        set_bit(idx, &spec->pcm_bitmap);
@@@ -1407,7 -1398,6 +1407,7 @@@ static void hdmi_detach_hda_pcm(struct 
                return;
        idx = per_pin->pcm_idx;
        per_pin->pcm_idx = -1;
 +      per_pin->prev_pcm_idx = idx; /* remember the previous index */
        per_pin->pcm = NULL;
        if (idx >= 0 && idx < spec->pcm_used)
                clear_bit(idx, &spec->pcm_bitmap);
@@@ -1934,7 -1924,6 +1934,7 @@@ static int hdmi_add_pin(struct hda_code
  
                per_pin->pcm = NULL;
                per_pin->pcm_idx = -1;
 +              per_pin->prev_pcm_idx = -1;
                per_pin->pin_nid = pin_nid;
                per_pin->pin_nid_idx = spec->num_nids;
                per_pin->dev_id = i;
@@@ -2104,10 -2093,6 +2104,6 @@@ static int generic_hdmi_playback_pcm_pr
                goto unlock;
        }
  
-       if (snd_BUG_ON(pin_idx < 0)) {
-               err = -EINVAL;
-               goto unlock;
-       }
        per_pin = get_pin(spec, pin_idx);
  
        /* Verify pin:cvt selections to avoid silent audio after S3.
@@@ -2199,13 -2184,13 +2195,13 @@@ static int hdmi_pcm_close(struct hda_pc
                snd_hda_spdif_ctls_unassign(codec, pcm_idx);
                clear_bit(pcm_idx, &spec->pcm_in_use);
                pin_idx = hinfo_to_pin_index(codec, hinfo);
+               /*
+                * In such a case, return 0 to match the behavior in
+                * hdmi_pcm_open()
+                */
                if (pin_idx < 0)
                        goto unlock;
  
-               if (snd_BUG_ON(pin_idx < 0)) {
-                       err = -EINVAL;
-                       goto unlock;
-               }
                per_pin = get_pin(spec, pin_idx);
  
                if (spec->dyn_pin_out) {
@@@ -4604,7 -4589,7 +4600,7 @@@ HDA_CODEC_ENTRY(0x80862814, "DG1 HDMI"
  HDA_CODEC_ENTRY(0x80862815, "Alderlake HDMI", patch_i915_tgl_hdmi),
  HDA_CODEC_ENTRY(0x80862816, "Rocketlake HDMI",        patch_i915_tgl_hdmi),
  HDA_CODEC_ENTRY(0x80862818, "Raptorlake HDMI",        patch_i915_tgl_hdmi),
 -HDA_CODEC_ENTRY(0x80862819, "DG2 HDMI",       patch_i915_adlp_hdmi),
 +HDA_CODEC_ENTRY(0x80862819, "DG2 HDMI",       patch_i915_tgl_hdmi),
  HDA_CODEC_ENTRY(0x8086281a, "Jasperlake HDMI",        patch_i915_icl_hdmi),
  HDA_CODEC_ENTRY(0x8086281b, "Elkhartlake HDMI",       patch_i915_icl_hdmi),
  HDA_CODEC_ENTRY(0x8086281c, "Alderlake-P HDMI", patch_i915_adlp_hdmi),
index 82d4e0fda91be6a0bfac709c780405d47277afd8,03f880f2e282dc4f1d60b03db662f9d388ad1864..b033bd2909405241d0aee3faf3205ac1c41275ab
@@@ -98,8 -98,10 +98,10 @@@ static int snd_ymfpci_create_gameport(s
                case 0x204: legacy_ctrl2 |= 2 << 6; break;
                case 0x205: legacy_ctrl2 |= 3 << 6; break;
                default:
-                       dev_err(chip->card->dev,
-                               "invalid joystick port %#x", io_port);
+                       if (io_port > 0)
+                               dev_err(chip->card->dev,
+                                       "The %s does not support arbitrary IO ports for the game port (requested 0x%x)\n",
+                                       chip->card->shortname, (unsigned int)io_port);
                        return -EINVAL;
                }
        }
@@@ -170,7 -172,7 +172,7 @@@ static int snd_card_ymfpci_probe(struc
                return -ENOENT;
        }
  
 -      err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
 +      err = snd_devm_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
                           sizeof(*chip), &card);
        if (err < 0)
                return err;
        default: model = str = "???"; break;
        }
  
+       strcpy(card->driver, str);
+       sprintf(card->shortname, "Yamaha %s (%s)", model, str);
+       sprintf(card->longname, "%s at 0x%lx, irq %i",
+               card->shortname,
+               chip->reg_area_phys,
+               chip->irq);
        legacy_ctrl = 0;
        legacy_ctrl2 = 0x0800;  /* SBEN = 0, SMOD = 01, LAD = 0 */
  
                case 0x398: legacy_ctrl2 |= 1; break;
                case 0x3a0: legacy_ctrl2 |= 2; break;
                case 0x3a8: legacy_ctrl2 |= 3; break;
-               default: fm_port[dev] = 0; break;
+               default:
+                       if (fm_port[dev] > 0)
+                               dev_err(card->dev,
+                                       "The %s does not support arbitrary IO ports for FM (requested 0x%x)\n",
+                                       card->shortname, (unsigned int)fm_port[dev]);
+                       fm_port[dev] = 0;
+                       break;
                }
                if (fm_port[dev] > 0)
                        fm_res = devm_request_region(&pci->dev, fm_port[dev],
                case 0x300: legacy_ctrl2 |= 1 << 4; break;
                case 0x332: legacy_ctrl2 |= 2 << 4; break;
                case 0x334: legacy_ctrl2 |= 3 << 4; break;
-               default: mpu_port[dev] = 0; break;
+               default:
+                       if (mpu_port[dev] > 0)
+                               dev_err(card->dev,
+                                       "The %s does not support arbitrary IO ports for MPU-401 (requested 0x%x)\n",
+                                       card->shortname, (unsigned int)mpu_port[dev]);
+                       mpu_port[dev] = 0;
+                       break;
                }
                if (mpu_port[dev] > 0)
                        mpu_res = devm_request_region(&pci->dev, mpu_port[dev],
        if (err  < 0)
                return err;
  
-       strcpy(card->driver, str);
-       sprintf(card->shortname, "Yamaha %s (%s)", model, str);
-       sprintf(card->longname, "%s at 0x%lx, irq %i",
-               card->shortname,
-               chip->reg_area_phys,
-               chip->irq);
        err = snd_ymfpci_pcm(chip, 0);
        if (err < 0)
                return err;
@@@ -337,11 -352,9 +352,9 @@@ static struct pci_driver ymfpci_driver 
        .name = KBUILD_MODNAME,
        .id_table = snd_ymfpci_ids,
        .probe = snd_card_ymfpci_probe,
- #ifdef CONFIG_PM_SLEEP
        .driver = {
-               .pm = &snd_ymfpci_pm,
+               .pm = pm_sleep_ptr(&snd_ymfpci_pm),
        },
- #endif
  };
  
  module_pci_driver(ymfpci_driver);
index b492c32ce07049aaff4c941be5fef2f76cd9bdb8,5f1a201754fadc1549bcd0f8ee7d805c7011d87f..6971eec45a4dbb5a2a613b95286d50f5d2e71a11
  
  static void snd_ymfpci_irq_wait(struct snd_ymfpci *chip);
  
- static inline u8 snd_ymfpci_readb(struct snd_ymfpci *chip, u32 offset)
- {
-       return readb(chip->reg_area_virt + offset);
- }
  static inline void snd_ymfpci_writeb(struct snd_ymfpci *chip, u32 offset, u8 val)
  {
        writeb(val, chip->reg_area_virt + offset);
@@@ -2165,7 -2160,7 +2160,7 @@@ static int snd_ymfpci_memalloc(struct s
        chip->work_base = ptr;
        chip->work_base_addr = ptr_addr;
        
 -      snd_BUG_ON(ptr + chip->work_size !=
 +      snd_BUG_ON(ptr + PAGE_ALIGN(chip->work_size) !=
                   chip->work_ptr->area + chip->work_ptr->bytes);
  
        snd_ymfpci_writel(chip, YDSXGR_PLAYCTRLBASE, chip->bank_base_playback_addr);
@@@ -2219,57 -2214,33 +2214,33 @@@ static void snd_ymfpci_free(struct snd_
  
        snd_ymfpci_free_gameport(chip);
        
-       pci_write_config_word(chip->pci, 0x40, chip->old_legacy_ctrl);
+       pci_write_config_word(chip->pci, PCIR_DSXG_LEGACY, chip->old_legacy_ctrl);
        
        release_firmware(chip->dsp_microcode);
        release_firmware(chip->controller_microcode);
  }
  
- #ifdef CONFIG_PM_SLEEP
- static const int saved_regs_index[] = {
-       /* spdif */
-       YDSXGR_SPDIFOUTCTRL,
-       YDSXGR_SPDIFOUTSTATUS,
-       YDSXGR_SPDIFINCTRL,
-       /* volumes */
-       YDSXGR_PRIADCLOOPVOL,
-       YDSXGR_NATIVEDACINVOL,
-       YDSXGR_NATIVEDACOUTVOL,
-       YDSXGR_BUF441OUTVOL,
-       YDSXGR_NATIVEADCINVOL,
-       YDSXGR_SPDIFLOOPVOL,
-       YDSXGR_SPDIFOUTVOL,
-       YDSXGR_ZVOUTVOL,
-       YDSXGR_LEGACYOUTVOL,
-       /* address bases */
-       YDSXGR_PLAYCTRLBASE,
-       YDSXGR_RECCTRLBASE,
-       YDSXGR_EFFCTRLBASE,
-       YDSXGR_WORKBASE,
-       /* capture set up */
-       YDSXGR_MAPOFREC,
-       YDSXGR_RECFORMAT,
-       YDSXGR_RECSLOTSR,
-       YDSXGR_ADCFORMAT,
-       YDSXGR_ADCSLOTSR,
- };
- #define YDSXGR_NUM_SAVED_REGS ARRAY_SIZE(saved_regs_index)
  static int snd_ymfpci_suspend(struct device *dev)
  {
        struct snd_card *card = dev_get_drvdata(dev);
        struct snd_ymfpci *chip = card->private_data;
-       unsigned int i;
-       
+       unsigned int i, legacy_reg_count = DSXG_PCI_NUM_SAVED_LEGACY_REGS;
+       if (chip->pci->device >= 0x0010) /* YMF 744/754 */
+               legacy_reg_count = DSXG_PCI_NUM_SAVED_REGS;
        snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
        snd_ac97_suspend(chip->ac97);
        for (i = 0; i < YDSXGR_NUM_SAVED_REGS; i++)
                chip->saved_regs[i] = snd_ymfpci_readl(chip, saved_regs_index[i]);
        chip->saved_ydsxgr_mode = snd_ymfpci_readl(chip, YDSXGR_MODE);
-       pci_read_config_word(chip->pci, PCIR_DSXG_LEGACY,
-                            &chip->saved_dsxg_legacy);
-       pci_read_config_word(chip->pci, PCIR_DSXG_ELEGACY,
-                            &chip->saved_dsxg_elegacy);
+       for (i = 0; i < legacy_reg_count; i++)
+               pci_read_config_word(chip->pci, pci_saved_regs_index[i],
+                                     chip->saved_dsxg_pci_regs + i);
        snd_ymfpci_writel(chip, YDSXGR_NATIVEDACOUTVOL, 0);
        snd_ymfpci_writel(chip, YDSXGR_BUF441OUTVOL, 0);
        snd_ymfpci_disable_dsp(chip);
@@@ -2281,7 -2252,10 +2252,10 @@@ static int snd_ymfpci_resume(struct dev
        struct pci_dev *pci = to_pci_dev(dev);
        struct snd_card *card = dev_get_drvdata(dev);
        struct snd_ymfpci *chip = card->private_data;
-       unsigned int i;
+       unsigned int i, legacy_reg_count = DSXG_PCI_NUM_SAVED_LEGACY_REGS;
+       if (chip->pci->device >= 0x0010) /* YMF 744/754 */
+               legacy_reg_count = DSXG_PCI_NUM_SAVED_REGS;
  
        snd_ymfpci_aclink_reset(pci);
        snd_ymfpci_codec_ready(chip, 0);
  
        snd_ac97_resume(chip->ac97);
  
-       pci_write_config_word(chip->pci, PCIR_DSXG_LEGACY,
-                             chip->saved_dsxg_legacy);
-       pci_write_config_word(chip->pci, PCIR_DSXG_ELEGACY,
-                             chip->saved_dsxg_elegacy);
+       for (i = 0; i < legacy_reg_count; i++)
+               pci_write_config_word(chip->pci, pci_saved_regs_index[i],
+                                     chip->saved_dsxg_pci_regs[i]);
  
        /* start hw again */
        if (chip->start_count > 0) {
        return 0;
  }
  
- SIMPLE_DEV_PM_OPS(snd_ymfpci_pm, snd_ymfpci_suspend, snd_ymfpci_resume);
- #endif /* CONFIG_PM_SLEEP */
+ DEFINE_SIMPLE_DEV_PM_OPS(snd_ymfpci_pm, snd_ymfpci_suspend, snd_ymfpci_resume);
  
  int snd_ymfpci_create(struct snd_card *card,
                      struct pci_dev *pci,
-                     unsigned short old_legacy_ctrl)
+                     u16 old_legacy_ctrl)
  {
        struct snd_ymfpci *chip = card->private_data;
        int err;
        if (err < 0)
                return err;
  
- #ifdef CONFIG_PM_SLEEP
-       chip->saved_regs = devm_kmalloc_array(&pci->dev, YDSXGR_NUM_SAVED_REGS,
-                                             sizeof(u32), GFP_KERNEL);
-       if (!chip->saved_regs)
-               return -ENOMEM;
- #endif
        snd_ymfpci_proc_init(card, chip);
  
        return 0;
diff --combined sound/soc/fsl/fsl_sai.c
index 990bba0be1fb1cb2b8edae47ce9347f27250a6e9,07d13dca852e94756e4762e543b26747780635ac..abdaffb00fbdc978509538b3b667d0c2fad78c73
@@@ -1380,18 -1380,18 +1380,18 @@@ static int fsl_sai_probe(struct platfor
        sai->cpu_dai_drv.symmetric_channels = 1;
        sai->cpu_dai_drv.symmetric_sample_bits = 1;
  
-       if (of_find_property(np, "fsl,sai-synchronous-rx", NULL) &&
-           of_find_property(np, "fsl,sai-asynchronous", NULL)) {
+       if (of_property_read_bool(np, "fsl,sai-synchronous-rx") &&
+           of_property_read_bool(np, "fsl,sai-asynchronous")) {
                /* error out if both synchronous and asynchronous are present */
                dev_err(dev, "invalid binding for synchronous mode\n");
                return -EINVAL;
        }
  
-       if (of_find_property(np, "fsl,sai-synchronous-rx", NULL)) {
+       if (of_property_read_bool(np, "fsl,sai-synchronous-rx")) {
                /* Sync Rx with Tx */
                sai->synchronous[RX] = false;
                sai->synchronous[TX] = true;
-       } else if (of_find_property(np, "fsl,sai-asynchronous", NULL)) {
+       } else if (of_property_read_bool(np, "fsl,sai-asynchronous")) {
                /* Discard all settings for asynchronous mode */
                sai->synchronous[RX] = false;
                sai->synchronous[TX] = false;
                sai->cpu_dai_drv.symmetric_sample_bits = 0;
        }
  
-       if (of_find_property(np, "fsl,sai-mclk-direction-output", NULL) &&
+       if (of_property_read_bool(np, "fsl,sai-mclk-direction-output") &&
            of_device_is_compatible(np, "fsl,imx6ul-sai")) {
                gpr = syscon_regmap_lookup_by_compatible("fsl,imx6ul-iomuxc-gpr");
                if (IS_ERR(gpr)) {
                dev_warn(dev, "Error reading SAI version: %d\n", ret);
  
        /* Select MCLK direction */
-       if (of_find_property(np, "fsl,sai-mclk-direction-output", NULL) &&
+       if (of_property_read_bool(np, "fsl,sai-mclk-direction-output") &&
            sai->soc_data->max_register >= FSL_SAI_MCTL) {
                regmap_update_bits(sai->regmap, FSL_SAI_MCTL,
                                   FSL_SAI_MCTL_MCLK_EN, FSL_SAI_MCTL_MCLK_EN);
@@@ -1489,13 -1489,11 +1489,11 @@@ err_pm_disable
        return ret;
  }
  
- static int fsl_sai_remove(struct platform_device *pdev)
+ static void fsl_sai_remove(struct platform_device *pdev)
  {
        pm_runtime_disable(&pdev->dev);
        if (!pm_runtime_status_suspended(&pdev->dev))
                fsl_sai_runtime_suspend(&pdev->dev);
-       return 0;
  }
  
  static const struct fsl_sai_soc_data fsl_sai_vf610_data = {
@@@ -1546,7 -1544,7 +1544,7 @@@ static const struct fsl_sai_soc_data fs
        .use_imx_pcm = true,
        .use_edma = true,
        .fifo_depth = 64,
 -      .pins = 1,
 +      .pins = 4,
        .reg_offset = 0,
        .mclk0_is_mclk1 = false,
        .flags = 0,
@@@ -1696,7 -1694,7 +1694,7 @@@ static const struct dev_pm_ops fsl_sai_
  
  static struct platform_driver fsl_sai_driver = {
        .probe = fsl_sai_probe,
-       .remove = fsl_sai_remove,
+       .remove_new = fsl_sai_remove,
        .driver = {
                .name = "fsl-sai",
                .pm = &fsl_sai_pm_ops,
index 3a5394c3dd83bf35053bd5e398de7f345bd1c7ba,a010e7c38817e05649b4b61123642ed68f2dac4d..059eebf0a68756dc6c99882e7dcd6f0a118daa69
@@@ -6,6 -6,7 +6,7 @@@
  // Copyright(c) 2022 Intel Corporation. All rights reserved.
  //
  //
+ #include <linux/bitfield.h>
  #include <uapi/sound/sof/tokens.h>
  #include <sound/pcm_params.h>
  #include <sound/sof/ext_manifest4.h>
  
  #define SOF_IPC4_GAIN_PARAM_ID  0
  #define SOF_IPC4_TPLG_ABI_SIZE 6
+ #define SOF_IPC4_CHAIN_DMA_BUF_SIZE_MS 2
  
  static DEFINE_IDA(alh_group_ida);
  static DEFINE_IDA(pipeline_ida);
  
  static const struct sof_topology_token ipc4_sched_tokens[] = {
        {SOF_TKN_SCHED_LP_MODE, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
-               offsetof(struct sof_ipc4_pipeline, lp_mode)}
+               offsetof(struct sof_ipc4_pipeline, lp_mode)},
+       {SOF_TKN_SCHED_USE_CHAIN_DMA, SND_SOC_TPLG_TUPLE_TYPE_BOOL, get_token_u16,
+               offsetof(struct sof_ipc4_pipeline, use_chain_dma)},
+       {SOF_TKN_SCHED_CORE, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
+               offsetof(struct sof_ipc4_pipeline, core_id)},
  };
  
  static const struct sof_topology_token pipeline_tokens[] = {
@@@ -39,45 -45,48 +45,48 @@@ static const struct sof_topology_token 
                offsetof(struct sof_ipc4_base_module_cfg, is_pages)},
  };
  
- static const struct sof_topology_token ipc4_audio_format_buffer_size_tokens[] = {
-       {SOF_TKN_CAVS_AUDIO_FORMAT_IBS, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
-               offsetof(struct sof_ipc4_base_module_cfg, ibs)},
-       {SOF_TKN_CAVS_AUDIO_FORMAT_OBS, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
-               offsetof(struct sof_ipc4_base_module_cfg, obs)},
- };
  static const struct sof_topology_token ipc4_in_audio_format_tokens[] = {
        {SOF_TKN_CAVS_AUDIO_FORMAT_IN_RATE, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
-               offsetof(struct sof_ipc4_audio_format, sampling_frequency)},
+               offsetof(struct sof_ipc4_pin_format, audio_fmt.sampling_frequency)},
        {SOF_TKN_CAVS_AUDIO_FORMAT_IN_BIT_DEPTH, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
-               offsetof(struct sof_ipc4_audio_format, bit_depth)},
+               offsetof(struct sof_ipc4_pin_format, audio_fmt.bit_depth)},
        {SOF_TKN_CAVS_AUDIO_FORMAT_IN_CH_MAP, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
-               offsetof(struct sof_ipc4_audio_format, ch_map)},
+               offsetof(struct sof_ipc4_pin_format, audio_fmt.ch_map)},
        {SOF_TKN_CAVS_AUDIO_FORMAT_IN_CH_CFG, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
-               offsetof(struct sof_ipc4_audio_format, ch_cfg)},
+               offsetof(struct sof_ipc4_pin_format, audio_fmt.ch_cfg)},
        {SOF_TKN_CAVS_AUDIO_FORMAT_IN_INTERLEAVING_STYLE, SND_SOC_TPLG_TUPLE_TYPE_WORD,
-               get_token_u32, offsetof(struct sof_ipc4_audio_format, interleaving_style)},
+               get_token_u32, offsetof(struct sof_ipc4_pin_format,
+               audio_fmt.interleaving_style)},
        {SOF_TKN_CAVS_AUDIO_FORMAT_IN_FMT_CFG, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
-               offsetof(struct sof_ipc4_audio_format, fmt_cfg)},
+               offsetof(struct sof_ipc4_pin_format, audio_fmt.fmt_cfg)},
+       {SOF_TKN_CAVS_AUDIO_FORMAT_PIN_INDEX, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
+               offsetof(struct sof_ipc4_pin_format, pin_index)},
+       {SOF_TKN_CAVS_AUDIO_FORMAT_IBS, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
+               offsetof(struct sof_ipc4_pin_format, buffer_size)},
  };
  
  static const struct sof_topology_token ipc4_out_audio_format_tokens[] = {
        {SOF_TKN_CAVS_AUDIO_FORMAT_OUT_RATE, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
-               offsetof(struct sof_ipc4_audio_format, sampling_frequency)},
+               offsetof(struct sof_ipc4_pin_format, audio_fmt.sampling_frequency)},
        {SOF_TKN_CAVS_AUDIO_FORMAT_OUT_BIT_DEPTH, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
-               offsetof(struct sof_ipc4_audio_format, bit_depth)},
+               offsetof(struct sof_ipc4_pin_format, audio_fmt.bit_depth)},
        {SOF_TKN_CAVS_AUDIO_FORMAT_OUT_CH_MAP, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
-               offsetof(struct sof_ipc4_audio_format, ch_map)},
+               offsetof(struct sof_ipc4_pin_format, audio_fmt.ch_map)},
        {SOF_TKN_CAVS_AUDIO_FORMAT_OUT_CH_CFG, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
-               offsetof(struct sof_ipc4_audio_format, ch_cfg)},
+               offsetof(struct sof_ipc4_pin_format, audio_fmt.ch_cfg)},
        {SOF_TKN_CAVS_AUDIO_FORMAT_OUT_INTERLEAVING_STYLE, SND_SOC_TPLG_TUPLE_TYPE_WORD,
-               get_token_u32, offsetof(struct sof_ipc4_audio_format, interleaving_style)},
+               get_token_u32, offsetof(struct sof_ipc4_pin_format,
+               audio_fmt.interleaving_style)},
        {SOF_TKN_CAVS_AUDIO_FORMAT_OUT_FMT_CFG, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
-               offsetof(struct sof_ipc4_audio_format, fmt_cfg)},
+               offsetof(struct sof_ipc4_pin_format, audio_fmt.fmt_cfg)},
+       {SOF_TKN_CAVS_AUDIO_FORMAT_PIN_INDEX, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
+               offsetof(struct sof_ipc4_pin_format, pin_index)},
+       {SOF_TKN_CAVS_AUDIO_FORMAT_OBS, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
+               offsetof(struct sof_ipc4_pin_format, buffer_size)},
  };
  
- static const struct sof_topology_token ipc4_copier_gateway_cfg_tokens[] = {
-       {SOF_TKN_CAVS_AUDIO_FORMAT_DMA_BUFFER_SIZE, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 0},
+ static const struct sof_topology_token ipc4_copier_deep_buffer_tokens[] = {
+       {SOF_TKN_INTEL_COPIER_DEEP_BUFFER_DMA_MS, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 0},
  };
  
  static const struct sof_topology_token ipc4_copier_tokens[] = {
  };
  
  static const struct sof_topology_token ipc4_audio_fmt_num_tokens[] = {
-       {SOF_TKN_COMP_NUM_AUDIO_FORMATS, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
-               0},
+       {SOF_TKN_COMP_NUM_INPUT_AUDIO_FORMATS, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
+               offsetof(struct sof_ipc4_available_audio_format, num_input_formats)},
+       {SOF_TKN_COMP_NUM_OUTPUT_AUDIO_FORMATS, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
+               offsetof(struct sof_ipc4_available_audio_format, num_output_formats)},
  };
  
  static const struct sof_topology_token dai_tokens[] = {
  static const struct sof_topology_token comp_ext_tokens[] = {
        {SOF_TKN_COMP_UUID, SND_SOC_TPLG_TUPLE_TYPE_UUID, get_token_uuid,
                offsetof(struct snd_sof_widget, uuid)},
+       {SOF_TKN_COMP_CORE_ID, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
+               offsetof(struct snd_sof_widget, core)},
  };
  
  static const struct sof_topology_token gain_tokens[] = {
@@@ -131,11 -144,8 +144,8 @@@ static const struct sof_token_info ipc4
                ipc4_in_audio_format_tokens, ARRAY_SIZE(ipc4_in_audio_format_tokens)},
        [SOF_OUT_AUDIO_FORMAT_TOKENS] = {"IPC4 Output Audio format tokens",
                ipc4_out_audio_format_tokens, ARRAY_SIZE(ipc4_out_audio_format_tokens)},
-       [SOF_AUDIO_FORMAT_BUFFER_SIZE_TOKENS] = {"IPC4 Audio format buffer size tokens",
-               ipc4_audio_format_buffer_size_tokens,
-               ARRAY_SIZE(ipc4_audio_format_buffer_size_tokens)},
-       [SOF_COPIER_GATEWAY_CFG_TOKENS] = {"IPC4 Copier gateway config tokens",
-               ipc4_copier_gateway_cfg_tokens, ARRAY_SIZE(ipc4_copier_gateway_cfg_tokens)},
+       [SOF_COPIER_DEEP_BUFFER_TOKENS] = {"IPC4 Copier deep buffer tokens",
+               ipc4_copier_deep_buffer_tokens, ARRAY_SIZE(ipc4_copier_deep_buffer_tokens)},
        [SOF_COPIER_TOKENS] = {"IPC4 Copier tokens", ipc4_copier_tokens,
                ARRAY_SIZE(ipc4_copier_tokens)},
        [SOF_AUDIO_FMT_NUM_TOKENS] = {"IPC4 Audio format number tokens",
        [SOF_SRC_TOKENS] = {"SRC tokens", src_tokens, ARRAY_SIZE(src_tokens)},
  };
  
- static void sof_ipc4_dbg_audio_format(struct device *dev,
-                                     struct sof_ipc4_audio_format *format,
-                                     size_t object_size, int num_format)
+ static void sof_ipc4_dbg_audio_format(struct device *dev, struct sof_ipc4_pin_format *pin_fmt,
+                                     int num_formats)
  {
-       struct sof_ipc4_audio_format *fmt;
-       void *ptr = format;
        int i;
  
-       for (i = 0; i < num_format; i++, ptr = (u8 *)ptr + object_size) {
-               fmt = ptr;
+       for (i = 0; i < num_formats; i++) {
+               struct sof_ipc4_audio_format *fmt = &pin_fmt[i].audio_fmt;
                dev_dbg(dev,
-                       " #%d: %uHz, %ubit (ch_map %#x ch_cfg %u interleaving_style %u fmt_cfg %#x)\n",
-                       i, fmt->sampling_frequency, fmt->bit_depth, fmt->ch_map,
-                       fmt->ch_cfg, fmt->interleaving_style, fmt->fmt_cfg);
+                       "Pin index #%d: %uHz, %ubit (ch_map %#x ch_cfg %u interleaving_style %u fmt_cfg %#x) buffer size %d\n",
+                       pin_fmt[i].pin_index, fmt->sampling_frequency, fmt->bit_depth, fmt->ch_map,
+                       fmt->ch_cfg, fmt->interleaving_style, fmt->fmt_cfg,
+                       pin_fmt[i].buffer_size);
        }
  }
  
+ static const struct sof_ipc4_audio_format *
+ sof_ipc4_get_input_pin_audio_fmt(struct snd_sof_widget *swidget, int pin_index)
+ {
+       struct sof_ipc4_base_module_cfg_ext *base_cfg_ext;
+       struct sof_ipc4_process *process;
+       int i;
+       if (swidget->id != snd_soc_dapm_effect) {
+               struct sof_ipc4_base_module_cfg *base = swidget->private;
+               /* For non-process modules, base module config format is used for all input pins */
+               return &base->audio_fmt;
+       }
+       process = swidget->private;
+       base_cfg_ext = process->base_config_ext;
+       /*
+        * If there are multiple input formats available for a pin, the first available format
+        * is chosen.
+        */
+       for (i = 0; i < base_cfg_ext->num_input_pin_fmts; i++) {
+               struct sof_ipc4_pin_format *pin_format = &base_cfg_ext->pin_formats[i];
+               if (pin_format->pin_index == pin_index)
+                       return &pin_format->audio_fmt;
+       }
+       return NULL;
+ }
  /**
   * sof_ipc4_get_audio_fmt - get available audio formats from swidget->tuples
   * @scomp: pointer to pointer to SOC component
   * @swidget: pointer to struct snd_sof_widget containing tuples
   * @available_fmt: pointer to struct sof_ipc4_available_audio_format being filling in
-  * @has_out_format: true if available_fmt contains output format
+  * @module_base_cfg: Pointer to the base_config in the module init IPC payload
   *
   * Return: 0 if successful
   */
  static int sof_ipc4_get_audio_fmt(struct snd_soc_component *scomp,
                                  struct snd_sof_widget *swidget,
                                  struct sof_ipc4_available_audio_format *available_fmt,
-                                 bool has_out_format)
+                                 struct sof_ipc4_base_module_cfg *module_base_cfg)
  {
-       struct sof_ipc4_base_module_cfg *base_config;
-       struct sof_ipc4_audio_format *out_format;
-       int audio_fmt_num = 0;
-       int ret, i;
+       struct sof_ipc4_pin_format *in_format = NULL;
+       struct sof_ipc4_pin_format *out_format;
+       int ret;
  
-       ret = sof_update_ipc_object(scomp, &audio_fmt_num,
+       ret = sof_update_ipc_object(scomp, available_fmt,
                                    SOF_AUDIO_FMT_NUM_TOKENS, swidget->tuples,
-                                   swidget->num_tuples, sizeof(audio_fmt_num), 1);
-       if (ret || audio_fmt_num <= 0) {
-               dev_err(scomp->dev, "Invalid number of audio formats: %d\n", audio_fmt_num);
-               return -EINVAL;
-       }
-       available_fmt->audio_fmt_num = audio_fmt_num;
-       dev_dbg(scomp->dev, "Number of audio formats: %d\n", available_fmt->audio_fmt_num);
-       base_config = kcalloc(available_fmt->audio_fmt_num, sizeof(*base_config), GFP_KERNEL);
-       if (!base_config)
-               return -ENOMEM;
-       /* set cpc and is_pages for all base_cfg */
-       for (i = 0; i < available_fmt->audio_fmt_num; i++) {
-               ret = sof_update_ipc_object(scomp, &base_config[i],
-                                           SOF_COMP_TOKENS, swidget->tuples,
-                                           swidget->num_tuples, sizeof(*base_config), 1);
-               if (ret) {
-                       dev_err(scomp->dev, "parse comp tokens failed %d\n", ret);
-                       goto err_in;
-               }
+                                   swidget->num_tuples, sizeof(available_fmt), 1);
+       if (ret) {
+               dev_err(scomp->dev, "Failed to parse audio format token count\n");
+               return ret;
        }
  
-       /* copy the ibs/obs for each base_cfg */
-       ret = sof_update_ipc_object(scomp, base_config,
-                                   SOF_AUDIO_FORMAT_BUFFER_SIZE_TOKENS, swidget->tuples,
-                                   swidget->num_tuples, sizeof(*base_config),
-                                   available_fmt->audio_fmt_num);
-       if (ret) {
-               dev_err(scomp->dev, "parse buffer size tokens failed %d\n", ret);
-               goto err_in;
+       if (!available_fmt->num_input_formats && !available_fmt->num_output_formats) {
+               dev_err(scomp->dev, "No input/output pin formats set in topology\n");
+               return -EINVAL;
        }
  
-       for (i = 0; i < available_fmt->audio_fmt_num; i++)
-               dev_dbg(scomp->dev, "%d: ibs: %d obs: %d cpc: %d is_pages: %d\n", i,
-                       base_config[i].ibs, base_config[i].obs,
-                       base_config[i].cpc, base_config[i].is_pages);
+       dev_dbg(scomp->dev,
+               "Number of input audio formats: %d. Number of output audio formats: %d\n",
+               available_fmt->num_input_formats, available_fmt->num_output_formats);
  
-       ret = sof_update_ipc_object(scomp, &base_config->audio_fmt,
-                                   SOF_IN_AUDIO_FORMAT_TOKENS, swidget->tuples,
-                                   swidget->num_tuples, sizeof(*base_config),
-                                   available_fmt->audio_fmt_num);
+       /* set cpc and is_pages in the module's base_config */
+       ret = sof_update_ipc_object(scomp, module_base_cfg, SOF_COMP_TOKENS, swidget->tuples,
+                                   swidget->num_tuples, sizeof(*module_base_cfg), 1);
        if (ret) {
-               dev_err(scomp->dev, "parse base_config audio_fmt tokens failed %d\n", ret);
-               goto err_in;
+               dev_err(scomp->dev, "parse comp tokens for %s failed, error: %d\n",
+                       swidget->widget->name, ret);
+               return ret;
        }
  
-       dev_dbg(scomp->dev, "Get input audio formats for %s\n", swidget->widget->name);
-       sof_ipc4_dbg_audio_format(scomp->dev, &base_config->audio_fmt,
-                                 sizeof(*base_config),
-                                 available_fmt->audio_fmt_num);
+       dev_dbg(scomp->dev, "widget %s cpc: %d is_pages: %d\n",
+               swidget->widget->name, module_base_cfg->cpc, module_base_cfg->is_pages);
  
-       available_fmt->base_config = base_config;
+       if (available_fmt->num_input_formats) {
+               in_format = kcalloc(available_fmt->num_input_formats,
+                                   sizeof(*in_format), GFP_KERNEL);
+               if (!in_format)
+                       return -ENOMEM;
+               available_fmt->input_pin_fmts = in_format;
  
-       if (!has_out_format)
-               return 0;
+               ret = sof_update_ipc_object(scomp, in_format,
+                                           SOF_IN_AUDIO_FORMAT_TOKENS, swidget->tuples,
+                                           swidget->num_tuples, sizeof(*in_format),
+                                           available_fmt->num_input_formats);
+               if (ret) {
+                       dev_err(scomp->dev, "parse input audio fmt tokens failed %d\n", ret);
+                       goto err_in;
+               }
  
-       out_format = kcalloc(available_fmt->audio_fmt_num, sizeof(*out_format), GFP_KERNEL);
-       if (!out_format) {
-               ret = -ENOMEM;
-               goto err_in;
+               dev_dbg(scomp->dev, "Input audio formats for %s\n", swidget->widget->name);
+               sof_ipc4_dbg_audio_format(scomp->dev, in_format,
+                                         available_fmt->num_input_formats);
        }
  
-       ret = sof_update_ipc_object(scomp, out_format,
-                                   SOF_OUT_AUDIO_FORMAT_TOKENS, swidget->tuples,
-                                   swidget->num_tuples, sizeof(*out_format),
-                                   available_fmt->audio_fmt_num);
+       if (available_fmt->num_output_formats) {
+               out_format = kcalloc(available_fmt->num_output_formats, sizeof(*out_format),
+                                    GFP_KERNEL);
+               if (!out_format) {
+                       ret = -ENOMEM;
+                       goto err_in;
+               }
  
-       if (ret) {
-               dev_err(scomp->dev, "parse output audio_fmt tokens failed\n");
-               goto err_out;
-       }
+               ret = sof_update_ipc_object(scomp, out_format,
+                                           SOF_OUT_AUDIO_FORMAT_TOKENS, swidget->tuples,
+                                           swidget->num_tuples, sizeof(*out_format),
+                                           available_fmt->num_output_formats);
+               if (ret) {
+                       dev_err(scomp->dev, "parse output audio fmt tokens failed\n");
+                       goto err_out;
+               }
  
-       available_fmt->out_audio_fmt = out_format;
-       dev_dbg(scomp->dev, "Get output audio formats for %s\n", swidget->widget->name);
-       sof_ipc4_dbg_audio_format(scomp->dev, out_format, sizeof(*out_format),
-                                 available_fmt->audio_fmt_num);
+               available_fmt->output_pin_fmts = out_format;
+               dev_dbg(scomp->dev, "Output audio formats for %s\n", swidget->widget->name);
+               sof_ipc4_dbg_audio_format(scomp->dev, out_format,
+                                         available_fmt->num_output_formats);
+       }
  
        return 0;
  
  err_out:
        kfree(out_format);
  err_in:
-       kfree(base_config);
+       kfree(in_format);
+       available_fmt->input_pin_fmts = NULL;
        return ret;
  }
  
  static void sof_ipc4_free_audio_fmt(struct sof_ipc4_available_audio_format *available_fmt)
  
  {
-       kfree(available_fmt->base_config);
-       available_fmt->base_config = NULL;
-       kfree(available_fmt->out_audio_fmt);
-       available_fmt->out_audio_fmt = NULL;
+       kfree(available_fmt->output_pin_fmts);
+       available_fmt->output_pin_fmts = NULL;
+       kfree(available_fmt->input_pin_fmts);
+       available_fmt->input_pin_fmts = NULL;
  }
  
  static void sof_ipc4_widget_free_comp_pipeline(struct snd_sof_widget *swidget)
@@@ -326,13 -356,31 +356,31 @@@ static int sof_ipc4_widget_setup_msg(st
        return 0;
  }
  
+ static void sof_ipc4_widget_update_kcontrol_module_id(struct snd_sof_widget *swidget)
+ {
+       struct snd_soc_component *scomp = swidget->scomp;
+       struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
+       struct sof_ipc4_fw_module *fw_module = swidget->module_info;
+       struct snd_sof_control *scontrol;
+       /* update module ID for all kcontrols for this widget */
+       list_for_each_entry(scontrol, &sdev->kcontrol_list, list) {
+               if (scontrol->comp_id == swidget->comp_id) {
+                       struct sof_ipc4_control_data *cdata = scontrol->ipc_control_data;
+                       struct sof_ipc4_msg *msg = &cdata->msg;
+                       msg->primary |= fw_module->man4_module_entry.id;
+               }
+       }
+ }
  static int sof_ipc4_widget_setup_pcm(struct snd_sof_widget *swidget)
  {
        struct sof_ipc4_available_audio_format *available_fmt;
        struct snd_soc_component *scomp = swidget->scomp;
        struct sof_ipc4_copier *ipc4_copier;
        int node_type = 0;
-       int ret, i;
+       int ret;
  
        ipc4_copier = kzalloc(sizeof(*ipc4_copier), GFP_KERNEL);
        if (!ipc4_copier)
  
        dev_dbg(scomp->dev, "Updating IPC structure for %s\n", swidget->widget->name);
  
-       ret = sof_ipc4_get_audio_fmt(scomp, swidget, available_fmt, true);
+       ret = sof_ipc4_get_audio_fmt(scomp, swidget, available_fmt,
+                                    &ipc4_copier->data.base_config);
        if (ret)
                goto free_copier;
  
-       available_fmt->dma_buffer_size = kcalloc(available_fmt->audio_fmt_num, sizeof(u32),
-                                                GFP_KERNEL);
-       if (!available_fmt->dma_buffer_size) {
-               ret = -ENOMEM;
-               goto free_available_fmt;
-       }
        /*
         * This callback is used by host copier and module-to-module copier,
         * and only host copier needs to set gtw_cfg.
        if (!WIDGET_IS_AIF(swidget->id))
                goto skip_gtw_cfg;
  
-       ret = sof_update_ipc_object(scomp, available_fmt->dma_buffer_size,
-                                   SOF_COPIER_GATEWAY_CFG_TOKENS, swidget->tuples,
-                                   swidget->num_tuples, sizeof(u32),
-                                   available_fmt->audio_fmt_num);
-       if (ret) {
-               dev_err(scomp->dev, "Failed to parse dma buffer size in audio format for %s\n",
-                       swidget->widget->name);
-               goto err;
-       }
-       dev_dbg(scomp->dev, "dma buffer size:\n");
-       for (i = 0; i < available_fmt->audio_fmt_num; i++)
-               dev_dbg(scomp->dev, "%d: %u\n", i,
-                       available_fmt->dma_buffer_size[i]);
        ret = sof_update_ipc_object(scomp, &node_type,
                                    SOF_COPIER_TOKENS, swidget->tuples,
                                    swidget->num_tuples, sizeof(node_type), 1);
        if (ret) {
                dev_err(scomp->dev, "parse host copier node type token failed %d\n",
                        ret);
-               goto err;
+               goto free_available_fmt;
        }
        dev_dbg(scomp->dev, "host copier '%s' node_type %u\n", swidget->widget->name, node_type);
  
@@@ -391,7 -418,7 +418,7 @@@ skip_gtw_cfg
        ipc4_copier->gtw_attr = kzalloc(sizeof(*ipc4_copier->gtw_attr), GFP_KERNEL);
        if (!ipc4_copier->gtw_attr) {
                ret = -ENOMEM;
-               goto err;
+               goto free_available_fmt;
        }
  
        ipc4_copier->copier_config = (uint32_t *)ipc4_copier->gtw_attr;
  
  free_gtw_attr:
        kfree(ipc4_copier->gtw_attr);
- err:
-       kfree(available_fmt->dma_buffer_size);
  free_available_fmt:
        sof_ipc4_free_audio_fmt(available_fmt);
  free_copier:
@@@ -441,9 -466,7 +466,7 @@@ static void sof_ipc4_widget_free_comp_p
                return;
  
        available_fmt = &ipc4_copier->available_fmt;
-       kfree(available_fmt->dma_buffer_size);
-       kfree(available_fmt->base_config);
-       kfree(available_fmt->out_audio_fmt);
+       kfree(available_fmt->output_pin_fmts);
        kfree(ipc4_copier->gtw_attr);
        kfree(ipc4_copier);
        swidget->private = NULL;
@@@ -455,8 -478,10 +478,10 @@@ static int sof_ipc4_widget_setup_comp_d
        struct snd_soc_component *scomp = swidget->scomp;
        struct snd_sof_dai *dai = swidget->private;
        struct sof_ipc4_copier *ipc4_copier;
+       struct snd_sof_widget *pipe_widget;
+       struct sof_ipc4_pipeline *pipeline;
        int node_type = 0;
-       int ret, i;
+       int ret;
  
        ipc4_copier = kzalloc(sizeof(*ipc4_copier), GFP_KERNEL);
        if (!ipc4_copier)
  
        dev_dbg(scomp->dev, "Updating IPC structure for %s\n", swidget->widget->name);
  
-       ret = sof_ipc4_get_audio_fmt(scomp, swidget, available_fmt, true);
+       ret = sof_ipc4_get_audio_fmt(scomp, swidget, available_fmt,
+                                    &ipc4_copier->data.base_config);
        if (ret)
                goto free_copier;
  
-       available_fmt->dma_buffer_size = kcalloc(available_fmt->audio_fmt_num, sizeof(u32),
-                                                GFP_KERNEL);
-       if (!available_fmt->dma_buffer_size) {
-               ret = -ENOMEM;
-               goto free_available_fmt;
-       }
-       ret = sof_update_ipc_object(scomp, available_fmt->dma_buffer_size,
-                                   SOF_COPIER_GATEWAY_CFG_TOKENS, swidget->tuples,
-                                   swidget->num_tuples, sizeof(u32),
-                                   available_fmt->audio_fmt_num);
-       if (ret) {
-               dev_err(scomp->dev, "Failed to parse dma buffer size in audio format for %s\n",
-                       swidget->widget->name);
-               goto err;
-       }
-       for (i = 0; i < available_fmt->audio_fmt_num; i++)
-               dev_dbg(scomp->dev, "%d: dma buffer size: %u\n", i,
-                       available_fmt->dma_buffer_size[i]);
        ret = sof_update_ipc_object(scomp, &node_type,
                                    SOF_COPIER_TOKENS, swidget->tuples,
                                    swidget->num_tuples, sizeof(node_type), 1);
        if (ret) {
                dev_err(scomp->dev, "parse dai node type failed %d\n", ret);
-               goto err;
+               goto free_available_fmt;
        }
  
        ret = sof_update_ipc_object(scomp, ipc4_copier,
                                    swidget->num_tuples, sizeof(u32), 1);
        if (ret) {
                dev_err(scomp->dev, "parse dai copier node token failed %d\n", ret);
-               goto err;
+               goto free_available_fmt;
        }
  
        dev_dbg(scomp->dev, "dai %s node_type %u dai_type %u dai_index %d\n", swidget->widget->name,
  
        ipc4_copier->data.gtw_cfg.node_id = SOF_IPC4_NODE_TYPE(node_type);
  
+       pipe_widget = swidget->spipe->pipe_widget;
+       pipeline = pipe_widget->private;
+       if (pipeline->use_chain_dma && ipc4_copier->dai_type != SOF_DAI_INTEL_HDA) {
+               dev_err(scomp->dev,
+                       "Bad DAI type '%d', Chained DMA is only supported by HDA DAIs (%d).\n",
+                       ipc4_copier->dai_type, SOF_DAI_INTEL_HDA);
+               ret = -ENODEV;
+               goto free_available_fmt;
+       }
        switch (ipc4_copier->dai_type) {
        case SOF_DAI_INTEL_ALH:
        {
                struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
                struct sof_ipc4_alh_configuration_blob *blob;
+               struct snd_soc_dapm_path *p;
                struct snd_sof_widget *w;
+               int src_num = 0;
+               snd_soc_dapm_widget_for_each_source_path(swidget->widget, p)
+                       src_num++;
+               if (swidget->id == snd_soc_dapm_dai_in && src_num == 0) {
+                       /*
+                        * The blob will not be used if the ALH copier is playback direction
+                        * and doesn't connect to any source.
+                        * It is fine to call kfree(ipc4_copier->copier_config) since
+                        * ipc4_copier->copier_config is null.
+                        */
+                       ret = 0;
+                       break;
+               }
  
                blob = kzalloc(sizeof(*blob), GFP_KERNEL);
                if (!blob) {
                        ret = -ENOMEM;
-                       goto err;
+                       goto free_available_fmt;
                }
  
                list_for_each_entry(w, &sdev->widget_list, list) {
                ipc4_copier->gtw_attr = kzalloc(sizeof(*ipc4_copier->gtw_attr), GFP_KERNEL);
                if (!ipc4_copier->gtw_attr) {
                        ret = -ENOMEM;
-                       goto err;
+                       goto free_available_fmt;
                }
  
                ipc4_copier->copier_config = (uint32_t *)ipc4_copier->gtw_attr;
  
  free_copier_config:
        kfree(ipc4_copier->copier_config);
- err:
-       kfree(available_fmt->dma_buffer_size);
  free_available_fmt:
        sof_ipc4_free_audio_fmt(available_fmt);
  free_copier:
@@@ -601,9 -630,7 +630,7 @@@ static void sof_ipc4_widget_free_comp_d
        ipc4_copier = dai->private;
        available_fmt = &ipc4_copier->available_fmt;
  
-       kfree(available_fmt->dma_buffer_size);
-       kfree(available_fmt->base_config);
-       kfree(available_fmt->out_audio_fmt);
+       kfree(available_fmt->output_pin_fmts);
        if (ipc4_copier->dai_type != SOF_DAI_INTEL_SSP &&
            ipc4_copier->dai_type != SOF_DAI_INTEL_DMIC)
                kfree(ipc4_copier->copier_config);
@@@ -629,6 -656,14 +656,14 @@@ static int sof_ipc4_widget_setup_comp_p
                goto err;
        }
  
+       swidget->core = pipeline->core_id;
+       if (pipeline->use_chain_dma) {
+               dev_dbg(scomp->dev, "Set up chain DMA for %s\n", swidget->widget->name);
+               swidget->private = pipeline;
+               return 0;
+       }
        /* parse one set of pipeline tokens */
        ret = sof_update_ipc_object(scomp, swidget, SOF_PIPELINE_TOKENS, swidget->tuples,
                                    swidget->num_tuples, sizeof(*swidget), 1);
        /* TODO: Get priority from topology */
        pipeline->priority = 0;
  
-       dev_dbg(scomp->dev, "pipeline '%s': id %d pri %d lp mode %d\n",
+       dev_dbg(scomp->dev, "pipeline '%s': id %d, pri %d, core_id %u, lp mode %d\n",
                swidget->widget->name, swidget->pipeline_id,
-               pipeline->priority, pipeline->lp_mode);
+               pipeline->priority, pipeline->core_id, pipeline->lp_mode);
  
        swidget->private = pipeline;
  
        pipeline->msg.primary |= SOF_IPC4_MSG_TARGET(SOF_IPC4_FW_GEN_MSG);
  
        pipeline->msg.extension = pipeline->lp_mode;
+       pipeline->msg.extension |= SOF_IPC4_GLB_PIPE_EXT_CORE_ID(pipeline->core_id);
        pipeline->state = SOF_IPC4_PIPE_UNINITIALIZED;
  
        return 0;
@@@ -663,9 -699,6 +699,6 @@@ err
  static int sof_ipc4_widget_setup_comp_pga(struct snd_sof_widget *swidget)
  {
        struct snd_soc_component *scomp = swidget->scomp;
-       struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
-       struct sof_ipc4_fw_module *fw_module;
-       struct snd_sof_control *scontrol;
        struct sof_ipc4_gain *gain;
        int ret;
  
        gain->data.channels = SOF_IPC4_GAIN_ALL_CHANNELS_MASK;
        gain->data.init_val = SOF_IPC4_VOL_ZERO_DB;
  
-       /* The out_audio_fmt in topology is ignored as it is not required to be sent to the FW */
-       ret = sof_ipc4_get_audio_fmt(scomp, swidget, &gain->available_fmt, false);
+       ret = sof_ipc4_get_audio_fmt(scomp, swidget, &gain->available_fmt, &gain->base_config);
        if (ret)
                goto err;
  
        if (ret)
                goto err;
  
-       fw_module = swidget->module_info;
-       /* update module ID for all kcontrols for this widget */
-       list_for_each_entry(scontrol, &sdev->kcontrol_list, list)
-               if (scontrol->comp_id == swidget->comp_id) {
-                       struct sof_ipc4_control_data *cdata = scontrol->ipc_control_data;
-                       struct sof_ipc4_msg *msg = &cdata->msg;
-                       msg->primary |= fw_module->man4_module_entry.id;
-               }
+       sof_ipc4_widget_update_kcontrol_module_id(swidget);
  
        return 0;
  err:
@@@ -744,8 -767,8 +767,8 @@@ static int sof_ipc4_widget_setup_comp_m
  
        swidget->private = mixer;
  
-       /* The out_audio_fmt in topology is ignored as it is not required to be sent to the FW */
-       ret = sof_ipc4_get_audio_fmt(scomp, swidget, &mixer->available_fmt, false);
+       ret = sof_ipc4_get_audio_fmt(scomp, swidget, &mixer->available_fmt,
+                                    &mixer->base_config);
        if (ret)
                goto err;
  
@@@ -775,8 -798,7 +798,7 @@@ static int sof_ipc4_widget_setup_comp_s
  
        swidget->private = src;
  
-       /* The out_audio_fmt in topology is ignored as it is not required by SRC */
-       ret = sof_ipc4_get_audio_fmt(scomp, swidget, &src->available_fmt, false);
+       ret = sof_ipc4_get_audio_fmt(scomp, swidget, &src->available_fmt, &src->base_config);
        if (ret)
                goto err;
  
@@@ -825,6 -847,94 +847,94 @@@ static void sof_ipc4_widget_free_comp_m
        swidget->private = NULL;
  }
  
+ /*
+  * Add the process modules support. The process modules are defined as snd_soc_dapm_effect modules.
+  */
+ static int sof_ipc4_widget_setup_comp_process(struct snd_sof_widget *swidget)
+ {
+       struct snd_soc_component *scomp = swidget->scomp;
+       struct sof_ipc4_fw_module *fw_module;
+       struct sof_ipc4_process *process;
+       void *cfg;
+       int ret;
+       process = kzalloc(sizeof(*process), GFP_KERNEL);
+       if (!process)
+               return -ENOMEM;
+       swidget->private = process;
+       ret = sof_ipc4_get_audio_fmt(scomp, swidget, &process->available_fmt,
+                                    &process->base_config);
+       if (ret)
+               goto err;
+       ret = sof_ipc4_widget_setup_msg(swidget, &process->msg);
+       if (ret)
+               goto err;
+       /* parse process init module payload config type from module info */
+       fw_module = swidget->module_info;
+       process->init_config = FIELD_GET(SOF_IPC4_MODULE_INIT_CONFIG_MASK,
+                                        fw_module->man4_module_entry.type);
+       process->ipc_config_size = sizeof(struct sof_ipc4_base_module_cfg);
+       /* allocate memory for base config extension if needed */
+       if (process->init_config == SOF_IPC4_MODULE_INIT_CONFIG_TYPE_BASE_CFG_WITH_EXT) {
+               struct sof_ipc4_base_module_cfg_ext *base_cfg_ext;
+               u32 ext_size = struct_size(base_cfg_ext, pin_formats,
+                                               swidget->num_input_pins + swidget->num_output_pins);
+               base_cfg_ext = kzalloc(ext_size, GFP_KERNEL);
+               if (!base_cfg_ext) {
+                       ret = -ENOMEM;
+                       goto free_available_fmt;
+               }
+               base_cfg_ext->num_input_pin_fmts = swidget->num_input_pins;
+               base_cfg_ext->num_output_pin_fmts = swidget->num_output_pins;
+               process->base_config_ext = base_cfg_ext;
+               process->base_config_ext_size = ext_size;
+               process->ipc_config_size += ext_size;
+       }
+       cfg = kzalloc(process->ipc_config_size, GFP_KERNEL);
+       if (!cfg) {
+               ret = -ENOMEM;
+               goto free_base_cfg_ext;
+       }
+       process->ipc_config_data = cfg;
+       sof_ipc4_widget_update_kcontrol_module_id(swidget);
+       return 0;
+ free_base_cfg_ext:
+       kfree(process->base_config_ext);
+       process->base_config_ext = NULL;
+ free_available_fmt:
+       sof_ipc4_free_audio_fmt(&process->available_fmt);
+ err:
+       kfree(process);
+       swidget->private = NULL;
+       return ret;
+ }
+ static void sof_ipc4_widget_free_comp_process(struct snd_sof_widget *swidget)
+ {
+       struct sof_ipc4_process *process = swidget->private;
+       if (!process)
+               return;
+       kfree(process->ipc_config_data);
+       kfree(process->base_config_ext);
+       sof_ipc4_free_audio_fmt(&process->available_fmt);
+       kfree(swidget->private);
+       swidget->private = NULL;
+ }
  static void
  sof_ipc4_update_pipeline_mem_usage(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget,
                                   struct sof_ipc4_base_module_cfg *base_config)
@@@ -876,22 -986,62 +986,62 @@@ static int sof_ipc4_widget_assign_insta
        return 0;
  }
  
+ /* update hw_params based on the audio stream format */
+ static int sof_ipc4_update_hw_params(struct snd_sof_dev *sdev, struct snd_pcm_hw_params *params,
+                                    struct sof_ipc4_audio_format *fmt)
+ {
+       snd_pcm_format_t snd_fmt;
+       struct snd_interval *i;
+       struct snd_mask *m;
+       int valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt->fmt_cfg);
+       unsigned int channels, rate;
+       switch (valid_bits) {
+       case 16:
+               snd_fmt = SNDRV_PCM_FORMAT_S16_LE;
+               break;
+       case 24:
+               snd_fmt = SNDRV_PCM_FORMAT_S24_LE;
+               break;
+       case 32:
+               snd_fmt = SNDRV_PCM_FORMAT_S32_LE;
+               break;
+       default:
+               dev_err(sdev->dev, "invalid PCM valid_bits %d\n", valid_bits);
+               return -EINVAL;
+       }
+       m = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
+       snd_mask_none(m);
+       snd_mask_set_format(m, snd_fmt);
+       rate = fmt->sampling_frequency;
+       i = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
+       i->min = rate;
+       i->max = rate;
+       channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(fmt->fmt_cfg);
+       i = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
+       i->min = channels;
+       i->max = channels;
+       return 0;
+ }
  static int sof_ipc4_init_audio_fmt(struct snd_sof_dev *sdev,
                                   struct snd_sof_widget *swidget,
                                   struct sof_ipc4_base_module_cfg *base_config,
-                                  struct sof_ipc4_audio_format *out_format,
                                   struct snd_pcm_hw_params *params,
                                   struct sof_ipc4_available_audio_format *available_fmt,
-                                  size_t object_offset)
+                                  struct sof_ipc4_pin_format *pin_fmts, u32 pin_fmts_size)
  {
-       void *ptr = available_fmt->ref_audio_fmt;
        u32 valid_bits;
        u32 channels;
        u32 rate;
        int sample_valid_bits;
        int i;
  
-       if (!ptr) {
+       if (!pin_fmts) {
                dev_err(sdev->dev, "no reference formats for %s\n", swidget->widget->name);
                return -EINVAL;
        }
                return -EINVAL;
        }
  
-       if (!available_fmt->audio_fmt_num) {
+       if (!pin_fmts_size) {
                dev_err(sdev->dev, "no formats available for %s\n", swidget->widget->name);
                return -EINVAL;
        }
  
        /*
-        * Search supported audio formats to match rate, channels ,and
+        * Search supported audio formats with pin index 0 to match rate, channels ,and
         * sample_valid_bytes from runtime params
         */
-       for (i = 0; i < available_fmt->audio_fmt_num; i++, ptr = (u8 *)ptr + object_offset) {
-               struct sof_ipc4_audio_format *fmt = ptr;
+       for (i = 0; i < pin_fmts_size; i++) {
+               struct sof_ipc4_audio_format *fmt = &pin_fmts[i].audio_fmt;
+               if (pin_fmts[i].pin_index)
+                       continue;
  
                rate = fmt->sampling_frequency;
                channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(fmt->fmt_cfg);
                valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt->fmt_cfg);
                if (params_rate(params) == rate && params_channels(params) == channels &&
                    sample_valid_bits == valid_bits) {
-                       dev_dbg(sdev->dev, "matching audio format index for %uHz, %ubit, %u channels: %d\n",
+                       dev_dbg(sdev->dev, "matched audio format index for %uHz, %ubit, %u channels: %d\n",
                                rate, valid_bits, channels, i);
-                       /* copy ibs/obs and input format */
-                       memcpy(base_config, &available_fmt->base_config[i],
-                              sizeof(struct sof_ipc4_base_module_cfg));
-                       /* copy output format */
-                       if (out_format)
-                               memcpy(out_format, &available_fmt->out_audio_fmt[i],
-                                      sizeof(struct sof_ipc4_audio_format));
                        break;
                }
        }
  
-       if (i == available_fmt->audio_fmt_num) {
+       if (i == pin_fmts_size) {
                dev_err(sdev->dev, "%s: Unsupported audio format: %uHz, %ubit, %u channels\n",
                        __func__, params_rate(params), sample_valid_bits, params_channels(params));
                return -EINVAL;
        }
  
-       dev_dbg(sdev->dev, "Init input audio formats for %s\n", swidget->widget->name);
-       sof_ipc4_dbg_audio_format(sdev->dev, &base_config->audio_fmt,
-                                 sizeof(*base_config), 1);
-       if (out_format) {
-               dev_dbg(sdev->dev, "Init output audio formats for %s\n", swidget->widget->name);
-               sof_ipc4_dbg_audio_format(sdev->dev, out_format,
-                                         sizeof(*out_format), 1);
+       /* copy input format */
+       if (available_fmt->num_input_formats && i < available_fmt->num_input_formats) {
+               memcpy(&base_config->audio_fmt, &available_fmt->input_pin_fmts[i].audio_fmt,
+                      sizeof(struct sof_ipc4_audio_format));
+               /* set base_cfg ibs/obs */
+               base_config->ibs = available_fmt->input_pin_fmts[i].buffer_size;
+               dev_dbg(sdev->dev, "Init input audio formats for %s\n", swidget->widget->name);
+               sof_ipc4_dbg_audio_format(sdev->dev, &available_fmt->input_pin_fmts[i], 1);
        }
  
+       if (available_fmt->num_output_formats && i < available_fmt->num_output_formats)
+               base_config->obs = available_fmt->output_pin_fmts[i].buffer_size;
        /* Return the index of the matched format */
        return i;
  }
@@@ -974,11 -1124,21 +1124,21 @@@ static void sof_ipc4_unprepare_copier_m
        pipeline->mem_usage = 0;
  
        if (WIDGET_IS_AIF(swidget->id) || swidget->id == snd_soc_dapm_buffer) {
+               if (pipeline->use_chain_dma) {
+                       pipeline->msg.primary = 0;
+                       pipeline->msg.extension = 0;
+               }
                ipc4_copier = swidget->private;
        } else if (WIDGET_IS_DAI(swidget->id)) {
                struct snd_sof_dai *dai = swidget->private;
  
                ipc4_copier = dai->private;
+               if (pipeline->use_chain_dma) {
+                       pipeline->msg.primary = 0;
+                       pipeline->msg.extension = 0;
+               }
                if (ipc4_copier->dai_type == SOF_DAI_INTEL_ALH) {
                        struct sof_ipc4_copier_data *copier_data = &ipc4_copier->data;
                        struct sof_ipc4_alh_configuration_blob *blob;
@@@ -1109,6 -1269,69 +1269,69 @@@ static int snd_sof_get_nhlt_endpoint_da
  }
  #endif
  
+ static int ipc4_set_fmt_mask(struct snd_mask *fmt, unsigned int bit_depth)
+ {
+       switch (bit_depth) {
+       case 16:
+               snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S16_LE);
+               break;
+       case 24:
+               snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S24_LE);
+               break;
+       case 32:
+               snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S32_LE);
+               break;
+       default:
+               return -EINVAL;
+       }
+       return 0;
+ }
+ static int ipc4_copier_set_capture_fmt(struct snd_sof_dev *sdev,
+                                      struct snd_pcm_hw_params *pipeline_params,
+                                      struct snd_pcm_hw_params *fe_params,
+                                      struct sof_ipc4_available_audio_format *available_fmt)
+ {
+       struct sof_ipc4_audio_format *audio_fmt;
+       unsigned int sample_valid_bits;
+       bool multiple_formats = false;
+       bool fe_format_match = false;
+       struct snd_mask *fmt;
+       int i;
+       for (i = 0; i < available_fmt->num_output_formats; i++) {
+               unsigned int val;
+               audio_fmt = &available_fmt->output_pin_fmts[i].audio_fmt;
+               val = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(audio_fmt->fmt_cfg);
+               if (i == 0)
+                       sample_valid_bits = val;
+               else if (sample_valid_bits != val)
+                       multiple_formats = true;
+               if (snd_pcm_format_width(params_format(fe_params)) == val)
+                       fe_format_match = true;
+       }
+       fmt = hw_param_mask(pipeline_params, SNDRV_PCM_HW_PARAM_FORMAT);
+       snd_mask_none(fmt);
+       if (multiple_formats) {
+               if (fe_format_match) {
+                       /* multiple formats defined and one matches FE */
+                       snd_mask_set_format(fmt, params_format(fe_params));
+                       return 0;
+               }
+               dev_err(sdev->dev, "Multiple audio formats for single dai_out not supported\n");
+               return -EINVAL;
+       }
+       return ipc4_set_fmt_mask(fmt, sample_valid_bits);
+ }
  static int
  sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget,
                               struct snd_pcm_hw_params *fe_params,
        struct sof_ipc4_available_audio_format *available_fmt;
        struct snd_soc_component *scomp = swidget->scomp;
        struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
+       struct sof_ipc4_pin_format *format_list_to_search;
        struct sof_ipc4_copier_data *copier_data;
        struct snd_pcm_hw_params *ref_params;
        struct sof_ipc4_copier *ipc4_copier;
        struct snd_sof_dai *dai;
        struct snd_mask *fmt;
        int out_sample_valid_bits;
-       size_t ref_audio_fmt_size;
        void **ipc_config_data;
        int *ipc_config_size;
        u32 **data;
        int ipc_size, ret;
+       u32 deep_buffer_dma_ms = 0;
+       u32 format_list_count;
  
        dev_dbg(sdev->dev, "copier %s, type %d", swidget->widget->name, swidget->id);
  
                struct snd_sof_widget *pipe_widget;
                struct sof_ipc4_pipeline *pipeline;
  
-               pipe_widget = swidget->spipe->pipe_widget;
-               pipeline = pipe_widget->private;
+               /* parse the deep buffer dma size */
+               ret = sof_update_ipc_object(scomp, &deep_buffer_dma_ms,
+                                           SOF_COPIER_DEEP_BUFFER_TOKENS, swidget->tuples,
+                                           swidget->num_tuples, sizeof(u32), 1);
+               if (ret) {
+                       dev_err(scomp->dev, "Failed to parse deep buffer dma size for %s\n",
+                               swidget->widget->name);
+                       return ret;
+               }
                ipc4_copier = (struct sof_ipc4_copier *)swidget->private;
                gtw_attr = ipc4_copier->gtw_attr;
                copier_data = &ipc4_copier->data;
                available_fmt = &ipc4_copier->available_fmt;
  
+               pipe_widget = swidget->spipe->pipe_widget;
+               pipeline = pipe_widget->private;
+               if (pipeline->use_chain_dma) {
+                       u32 host_dma_id;
+                       u32 fifo_size;
+                       host_dma_id = platform_params->stream_tag - 1;
+                       pipeline->msg.primary |= SOF_IPC4_GLB_CHAIN_DMA_HOST_ID(host_dma_id);
+                       /* Set SCS bit for S16_LE format only */
+                       if (params_format(fe_params) == SNDRV_PCM_FORMAT_S16_LE)
+                               pipeline->msg.primary |= SOF_IPC4_GLB_CHAIN_DMA_SCS_MASK;
+                       /*
+                        * Despite its name the bitfield 'fifo_size' is used to define DMA buffer
+                        * size. The expression calculates 2ms buffer size.
+                        */
+                       fifo_size = DIV_ROUND_UP((SOF_IPC4_CHAIN_DMA_BUF_SIZE_MS *
+                                                 params_rate(fe_params) *
+                                                 params_channels(fe_params) *
+                                                 params_physical_width(fe_params)), 8000);
+                       pipeline->msg.extension |= SOF_IPC4_GLB_EXT_CHAIN_DMA_FIFO_SIZE(fifo_size);
+                       /*
+                        * Chain DMA does not support stream timestamping, set node_id to invalid
+                        * to skip the code in sof_ipc4_get_stream_start_offset().
+                        */
+                       copier_data->gtw_cfg.node_id = SOF_IPC4_INVALID_NODE_ID;
+                       return 0;
+               }
                /*
-                * base_config->audio_fmt and out_audio_fmt represent the input and output audio
-                * formats. Use the input format as the reference to match pcm params for playback
-                * and the output format as reference for capture.
+                * Use the input_pin_fmts to match pcm params for playback and the output_pin_fmts
+                * for capture.
                 */
                if (dir == SNDRV_PCM_STREAM_PLAYBACK) {
-                       available_fmt->ref_audio_fmt = &available_fmt->base_config->audio_fmt;
-                       ref_audio_fmt_size = sizeof(struct sof_ipc4_base_module_cfg);
+                       format_list_to_search = available_fmt->input_pin_fmts;
+                       format_list_count = available_fmt->num_input_formats;
                } else {
-                       available_fmt->ref_audio_fmt = available_fmt->out_audio_fmt;
-                       ref_audio_fmt_size = sizeof(struct sof_ipc4_audio_format);
+                       format_list_to_search = available_fmt->output_pin_fmts;
+                       format_list_count = available_fmt->num_output_formats;
                }
                copier_data->gtw_cfg.node_id &= ~SOF_IPC4_NODE_INDEX_MASK;
                copier_data->gtw_cfg.node_id |=
                        SOF_IPC4_NODE_INDEX(platform_params->stream_tag - 1);
        case snd_soc_dapm_dai_in:
        case snd_soc_dapm_dai_out:
        {
+               struct snd_sof_widget *pipe_widget = swidget->spipe->pipe_widget;
+               struct sof_ipc4_pipeline *pipeline = pipe_widget->private;
+               if (pipeline->use_chain_dma)
+                       return 0;
                dai = swidget->private;
  
                ipc4_copier = (struct sof_ipc4_copier *)dai->private;
                copier_data = &ipc4_copier->data;
                available_fmt = &ipc4_copier->available_fmt;
                if (dir == SNDRV_PCM_STREAM_CAPTURE) {
-                       available_fmt->ref_audio_fmt = available_fmt->out_audio_fmt;
-                       ref_audio_fmt_size = sizeof(struct sof_ipc4_audio_format);
+                       format_list_to_search = available_fmt->output_pin_fmts;
+                       format_list_count = available_fmt->num_output_formats;
  
-                       /*
-                        * modify the input params for the dai copier as it only supports
-                        * 32-bit always
-                        */
-                       fmt = hw_param_mask(pipeline_params, SNDRV_PCM_HW_PARAM_FORMAT);
-                       snd_mask_none(fmt);
-                       snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S32_LE);
+                       ret = ipc4_copier_set_capture_fmt(sdev, pipeline_params, fe_params,
+                                                         available_fmt);
+                       if (ret < 0)
+                               return ret;
                } else {
-                       available_fmt->ref_audio_fmt = &available_fmt->base_config->audio_fmt;
-                       ref_audio_fmt_size = sizeof(struct sof_ipc4_base_module_cfg);
+                       format_list_to_search = available_fmt->input_pin_fmts;
+                       format_list_count = available_fmt->num_input_formats;
                }
  
                ref_params = pipeline_params;
                copier_data = &ipc4_copier->data;
                available_fmt = &ipc4_copier->available_fmt;
  
-               /*
-                * base_config->audio_fmt represent the input audio formats. Use
-                * the input format as the reference to match pcm params
-                */
-               available_fmt->ref_audio_fmt = &available_fmt->base_config->audio_fmt;
-               ref_audio_fmt_size = sizeof(struct sof_ipc4_base_module_cfg);
+               /* Use the input formats to match pcm params */
+               format_list_to_search = available_fmt->input_pin_fmts;
+               format_list_count = available_fmt->num_input_formats;
                ref_params = pipeline_params;
  
                break;
        }
  
        /* set input and output audio formats */
-       ret = sof_ipc4_init_audio_fmt(sdev, swidget, &copier_data->base_config,
-                                     &copier_data->out_format, ref_params,
-                                     available_fmt, ref_audio_fmt_size);
+       ret = sof_ipc4_init_audio_fmt(sdev, swidget, &copier_data->base_config, ref_params,
+                                     available_fmt, format_list_to_search, format_list_count);
        if (ret < 0)
                return ret;
  
+       /*
+        * Set the output format. Current topology defines pin 0 input and output formats in pairs.
+        * This assumes that the pin 0 formats are defined before all other pins.
+        * So pick the output audio format with the same index as the chosen
+        * input format. This logic will need to be updated when the format definitions
+        * in topology change.
+        */
+       memcpy(&copier_data->out_format, &available_fmt->output_pin_fmts[ret].audio_fmt,
+              sizeof(struct sof_ipc4_audio_format));
+       dev_dbg(sdev->dev, "Output audio format for %s\n", swidget->widget->name);
+       sof_ipc4_dbg_audio_format(sdev->dev, &available_fmt->output_pin_fmts[ret], 1);
        switch (swidget->id) {
        case snd_soc_dapm_dai_in:
        case snd_soc_dapm_dai_out:
        out_sample_valid_bits =
                SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(copier_data->out_format.fmt_cfg);
        snd_mask_none(fmt);
-       switch (out_sample_valid_bits) {
-       case 16:
-               snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S16_LE);
+       ret = ipc4_set_fmt_mask(fmt, out_sample_valid_bits);
+       if (ret)
+               return ret;
+       /*
+        * Set the gateway dma_buffer_size to 2ms buffer size to meet the FW expectation. In the
+        * deep buffer case, set the dma_buffer_size depending on the deep_buffer_dma_ms set
+        * in topology.
+        */
+       switch (swidget->id) {
+       case snd_soc_dapm_dai_in:
+               copier_data->gtw_cfg.dma_buffer_size =
+                       SOF_IPC4_MIN_DMA_BUFFER_SIZE * copier_data->base_config.ibs;
                break;
-       case 24:
-               snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S24_LE);
+       case snd_soc_dapm_aif_in:
+                       copier_data->gtw_cfg.dma_buffer_size =
+                               max((u32)SOF_IPC4_MIN_DMA_BUFFER_SIZE, deep_buffer_dma_ms) *
+                                       copier_data->base_config.ibs;
                break;
-       case 32:
-               snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S32_LE);
+       case snd_soc_dapm_dai_out:
+       case snd_soc_dapm_aif_out:
+               copier_data->gtw_cfg.dma_buffer_size =
+                       SOF_IPC4_MIN_DMA_BUFFER_SIZE * copier_data->base_config.obs;
                break;
        default:
-               dev_err(sdev->dev, "invalid sample frame format %d\n",
-                       params_format(pipeline_params));
-               return -EINVAL;
+               break;
        }
  
-       /* set the gateway dma_buffer_size using the matched ID returned above */
-       copier_data->gtw_cfg.dma_buffer_size = available_fmt->dma_buffer_size[ret];
        data = &ipc4_copier->copier_config;
        ipc_config_size = &ipc4_copier->ipc_config_size;
        ipc_config_data = &ipc4_copier->ipc_config_data;
@@@ -1377,14 -1663,13 +1663,13 @@@ static int sof_ipc4_prepare_gain_module
        struct snd_soc_component *scomp = swidget->scomp;
        struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
        struct sof_ipc4_gain *gain = swidget->private;
+       struct sof_ipc4_available_audio_format *available_fmt = &gain->available_fmt;
        int ret;
  
-       gain->available_fmt.ref_audio_fmt = &gain->available_fmt.base_config->audio_fmt;
-       /* output format is not required to be sent to the FW for gain */
        ret = sof_ipc4_init_audio_fmt(sdev, swidget, &gain->base_config,
-                                     NULL, pipeline_params, &gain->available_fmt,
-                                     sizeof(gain->base_config));
+                                     pipeline_params, available_fmt,
+                                     available_fmt->input_pin_fmts,
+                                     available_fmt->num_input_formats);
        if (ret < 0)
                return ret;
  
@@@ -1402,15 -1687,13 +1687,13 @@@ static int sof_ipc4_prepare_mixer_modul
        struct snd_soc_component *scomp = swidget->scomp;
        struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
        struct sof_ipc4_mixer *mixer = swidget->private;
+       struct sof_ipc4_available_audio_format *available_fmt = &mixer->available_fmt;
        int ret;
  
-       /* only 32bit is supported by mixer */
-       mixer->available_fmt.ref_audio_fmt = &mixer->available_fmt.base_config->audio_fmt;
-       /* output format is not required to be sent to the FW for mixer */
        ret = sof_ipc4_init_audio_fmt(sdev, swidget, &mixer->base_config,
-                                     NULL, pipeline_params, &mixer->available_fmt,
-                                     sizeof(mixer->base_config));
+                                     pipeline_params, available_fmt,
+                                     available_fmt->input_pin_fmts,
+                                     available_fmt->num_input_formats);
        if (ret < 0)
                return ret;
  
@@@ -1428,15 -1711,14 +1711,14 @@@ static int sof_ipc4_prepare_src_module(
        struct snd_soc_component *scomp = swidget->scomp;
        struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
        struct sof_ipc4_src *src = swidget->private;
+       struct sof_ipc4_available_audio_format *available_fmt = &src->available_fmt;
        struct snd_interval *rate;
        int ret;
  
-       src->available_fmt.ref_audio_fmt = &src->available_fmt.base_config->audio_fmt;
-       /* output format is not required to be sent to the FW for SRC */
        ret = sof_ipc4_init_audio_fmt(sdev, swidget, &src->base_config,
-                                     NULL, pipeline_params, &src->available_fmt,
-                                     sizeof(src->base_config));
+                                     pipeline_params, available_fmt,
+                                     available_fmt->input_pin_fmts,
+                                     available_fmt->num_input_formats);
        if (ret < 0)
                return ret;
  
        return 0;
  }
  
+ static int
+ sof_ipc4_process_set_pin_formats(struct snd_sof_widget *swidget, int pin_type)
+ {
+       struct sof_ipc4_process *process = swidget->private;
+       struct sof_ipc4_base_module_cfg_ext *base_cfg_ext = process->base_config_ext;
+       struct sof_ipc4_available_audio_format *available_fmt = &process->available_fmt;
+       struct sof_ipc4_pin_format *pin_format, *format_list_to_search;
+       struct snd_soc_component *scomp = swidget->scomp;
+       int num_pins, format_list_count;
+       int pin_format_offset = 0;
+       int i, j;
+       /* set number of pins, offset of pin format and format list to search based on pin type */
+       if (pin_type == SOF_PIN_TYPE_INPUT) {
+               num_pins = swidget->num_input_pins;
+               format_list_to_search = available_fmt->input_pin_fmts;
+               format_list_count = available_fmt->num_input_formats;
+       } else {
+               num_pins = swidget->num_output_pins;
+               pin_format_offset = swidget->num_input_pins;
+               format_list_to_search = available_fmt->output_pin_fmts;
+               format_list_count = available_fmt->num_output_formats;
+       }
+       for (i = pin_format_offset; i < num_pins + pin_format_offset; i++) {
+               pin_format = &base_cfg_ext->pin_formats[i];
+               /* Pin 0 audio formats are derived from the base config input/output format */
+               if (i == pin_format_offset) {
+                       if (pin_type == SOF_PIN_TYPE_INPUT) {
+                               pin_format->buffer_size = process->base_config.ibs;
+                               pin_format->audio_fmt = process->base_config.audio_fmt;
+                       } else {
+                               pin_format->buffer_size = process->base_config.obs;
+                               pin_format->audio_fmt = process->output_format;
+                       }
+                       continue;
+               }
+               /*
+                * For all other pins, find the pin formats from those set in topology. If there
+                * is more than one format specified for a pin, this will pick the first available
+                * one.
+                */
+               for (j = 0; j < format_list_count; j++) {
+                       struct sof_ipc4_pin_format *pin_format_item = &format_list_to_search[j];
+                       if (pin_format_item->pin_index == i - pin_format_offset) {
+                               *pin_format = *pin_format_item;
+                               break;
+                       }
+               }
+               if (j == format_list_count) {
+                       dev_err(scomp->dev, "%s pin %d format not found for %s\n",
+                               (pin_type == SOF_PIN_TYPE_INPUT) ? "input" : "output",
+                               i - pin_format_offset, swidget->widget->name);
+                       return -EINVAL;
+               }
+       }
+       return 0;
+ }
+ static int sof_ipc4_process_add_base_cfg_extn(struct snd_sof_widget *swidget)
+ {
+       int ret, i;
+       /* copy input and output pin formats */
+       for (i = 0; i <= SOF_PIN_TYPE_OUTPUT; i++) {
+               ret = sof_ipc4_process_set_pin_formats(swidget, i);
+               if (ret < 0)
+                       return ret;
+       }
+       return 0;
+ }
+ static int sof_ipc4_prepare_process_module(struct snd_sof_widget *swidget,
+                                          struct snd_pcm_hw_params *fe_params,
+                                          struct snd_sof_platform_stream_params *platform_params,
+                                          struct snd_pcm_hw_params *pipeline_params, int dir)
+ {
+       struct snd_soc_component *scomp = swidget->scomp;
+       struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
+       struct sof_ipc4_process *process = swidget->private;
+       struct sof_ipc4_available_audio_format *available_fmt = &process->available_fmt;
+       void *cfg = process->ipc_config_data;
+       int ret;
+       ret = sof_ipc4_init_audio_fmt(sdev, swidget, &process->base_config,
+                                     pipeline_params, available_fmt,
+                                     available_fmt->input_pin_fmts,
+                                     available_fmt->num_input_formats);
+       if (ret < 0)
+               return ret;
+       /* copy Pin 0 output format */
+       if (available_fmt->num_output_formats && ret < available_fmt->num_output_formats &&
+           !available_fmt->output_pin_fmts[ret].pin_index) {
+               memcpy(&process->output_format, &available_fmt->output_pin_fmts[ret].audio_fmt,
+                      sizeof(struct sof_ipc4_audio_format));
+               /* modify the pipeline params with the pin 0 output format */
+               ret = sof_ipc4_update_hw_params(sdev, pipeline_params, &process->output_format);
+               if (ret)
+                       return ret;
+       }
+       /* update pipeline memory usage */
+       sof_ipc4_update_pipeline_mem_usage(sdev, swidget, &process->base_config);
+       /* ipc_config_data is composed of the base_config followed by an optional extension */
+       memcpy(cfg, &process->base_config, sizeof(struct sof_ipc4_base_module_cfg));
+       cfg += sizeof(struct sof_ipc4_base_module_cfg);
+       if (process->init_config == SOF_IPC4_MODULE_INIT_CONFIG_TYPE_BASE_CFG_WITH_EXT) {
+               struct sof_ipc4_base_module_cfg_ext *base_cfg_ext = process->base_config_ext;
+               ret = sof_ipc4_process_add_base_cfg_extn(swidget);
+               if (ret < 0)
+                       return ret;
+               memcpy(cfg, base_cfg_ext, process->base_config_ext_size);
+       }
+       return 0;
+ }
  static int sof_ipc4_control_load_volume(struct snd_sof_dev *sdev, struct snd_sof_control *scontrol)
  {
        struct sof_ipc4_control_data *control_data;
        return 0;
  }
  
+ static int sof_ipc4_control_load_bytes(struct snd_sof_dev *sdev, struct snd_sof_control *scontrol)
+ {
+       struct sof_ipc4_control_data *control_data;
+       struct sof_ipc4_msg *msg;
+       int ret;
+       if (scontrol->max_size < (sizeof(*control_data) + sizeof(struct sof_abi_hdr))) {
+               dev_err(sdev->dev, "insufficient size for a bytes control %s: %zu.\n",
+                       scontrol->name, scontrol->max_size);
+               return -EINVAL;
+       }
+       if (scontrol->priv_size > scontrol->max_size - sizeof(*control_data)) {
+               dev_err(sdev->dev, "scontrol %s bytes data size %zu exceeds max %zu.\n",
+                       scontrol->name, scontrol->priv_size,
+                       scontrol->max_size - sizeof(*control_data));
+               return -EINVAL;
+       }
+       scontrol->size = sizeof(struct sof_ipc4_control_data) + scontrol->priv_size;
+       scontrol->ipc_control_data = kzalloc(scontrol->max_size, GFP_KERNEL);
+       if (!scontrol->ipc_control_data)
+               return -ENOMEM;
+       control_data = scontrol->ipc_control_data;
+       control_data->index = scontrol->index;
+       if (scontrol->priv_size > 0) {
+               memcpy(control_data->data, scontrol->priv, scontrol->priv_size);
+               kfree(scontrol->priv);
+               scontrol->priv = NULL;
+               if (control_data->data->magic != SOF_IPC4_ABI_MAGIC) {
+                       dev_err(sdev->dev, "Wrong ABI magic (%#x) for control: %s\n",
+                               control_data->data->magic, scontrol->name);
+                       ret = -EINVAL;
+                       goto err;
+               }
+               /* TODO: check the ABI version */
+               if (control_data->data->size + sizeof(struct sof_abi_hdr) !=
+                   scontrol->priv_size) {
+                       dev_err(sdev->dev, "Control %s conflict in bytes %zu vs. priv size %zu.\n",
+                               scontrol->name,
+                               control_data->data->size + sizeof(struct sof_abi_hdr),
+                               scontrol->priv_size);
+                       ret = -EINVAL;
+                       goto err;
+               }
+       }
+       msg = &control_data->msg;
+       msg->primary = SOF_IPC4_MSG_TYPE_SET(SOF_IPC4_MOD_LARGE_CONFIG_SET);
+       msg->primary |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST);
+       msg->primary |= SOF_IPC4_MSG_TARGET(SOF_IPC4_MODULE_MSG);
+       return 0;
+ err:
+       kfree(scontrol->ipc_control_data);
+       scontrol->ipc_control_data = NULL;
+       return ret;
+ }
  static int sof_ipc4_control_setup(struct snd_sof_dev *sdev, struct snd_sof_control *scontrol)
  {
        switch (scontrol->info_type) {
        case SND_SOC_TPLG_CTL_VOLSW_SX:
        case SND_SOC_TPLG_CTL_VOLSW_XR_SX:
                return sof_ipc4_control_load_volume(sdev, scontrol);
+       case SND_SOC_TPLG_CTL_BYTES:
+               return sof_ipc4_control_load_bytes(sdev, scontrol);
        default:
                break;
        }
@@@ -1511,6 -1989,12 +1989,12 @@@ static int sof_ipc4_widget_setup(struc
        case snd_soc_dapm_scheduler:
                pipeline = swidget->private;
  
+               if (pipeline->use_chain_dma) {
+                       dev_warn(sdev->dev, "use_chain_dma set for scheduler %s",
+                                swidget->widget->name);
+                       return 0;
+               }
                dev_dbg(sdev->dev, "pipeline: %d memory pages: %d\n", swidget->pipeline_id,
                        pipeline->mem_usage);
  
        {
                struct sof_ipc4_copier *ipc4_copier = swidget->private;
  
+               pipeline = pipe_widget->private;
+               if (pipeline->use_chain_dma)
+                       return 0;
                ipc_size = ipc4_copier->ipc_config_size;
                ipc_data = ipc4_copier->ipc_config_data;
  
                struct snd_sof_dai *dai = swidget->private;
                struct sof_ipc4_copier *ipc4_copier = dai->private;
  
+               pipeline = pipe_widget->private;
+               if (pipeline->use_chain_dma)
+                       return 0;
                ipc_size = ipc4_copier->ipc_config_size;
                ipc_data = ipc4_copier->ipc_config_data;
  
                msg = &src->msg;
                break;
        }
+       case snd_soc_dapm_effect:
+       {
+               struct sof_ipc4_process *process = swidget->private;
+               if (!process->ipc_config_size) {
+                       dev_err(sdev->dev, "module %s has no config data!\n",
+                               swidget->widget->name);
+                       return -EINVAL;
+               }
+               ipc_size = process->ipc_config_size;
+               ipc_data = process->ipc_config_data;
+               msg = &process->msg;
+               break;
+       }
        default:
                dev_err(sdev->dev, "widget type %d not supported", swidget->id);
                return -EINVAL;
        msg->data_size = ipc_size;
        msg->data_ptr = ipc_data;
  
-       ret = sof_ipc_tx_message(sdev->ipc, msg, ipc_size, NULL, 0);
+       ret = sof_ipc_tx_message_no_reply(sdev->ipc, msg, ipc_size);
        if (ret < 0) {
                dev_err(sdev->dev, "failed to create module %s\n", swidget->widget->name);
  
@@@ -1640,6 -2148,13 +2148,13 @@@ static int sof_ipc4_widget_free(struct 
                struct sof_ipc4_msg msg = {{ 0 }};
                u32 header;
  
+               if (pipeline->use_chain_dma) {
+                       dev_warn(sdev->dev, "use_chain_dma set for scheduler %s",
+                                swidget->widget->name);
+                       mutex_unlock(&ipc4_data->pipeline_state_mutex);
+                       return 0;
+               }
                header = SOF_IPC4_GLB_PIPE_INSTANCE_ID(swidget->instance_id);
                header |= SOF_IPC4_MSG_TYPE_SET(SOF_IPC4_GLB_DELETE_PIPELINE);
                header |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST);
  
                msg.primary = header;
  
-               ret = sof_ipc_tx_message(sdev->ipc, &msg, 0, NULL, 0);
+               ret = sof_ipc_tx_message_no_reply(sdev->ipc, &msg, 0);
                if (ret < 0)
                        dev_err(sdev->dev, "failed to free pipeline widget %s\n",
                                swidget->widget->name);
                pipeline->state = SOF_IPC4_PIPE_UNINITIALIZED;
                ida_free(&pipeline_ida, swidget->instance_id);
        } else {
-               ida_free(&fw_module->m_ida, swidget->instance_id);
+               struct snd_sof_widget *pipe_widget = swidget->spipe->pipe_widget;
+               struct sof_ipc4_pipeline *pipeline = pipe_widget->private;
+               if (!pipeline->use_chain_dma)
+                       ida_free(&fw_module->m_ida, swidget->instance_id);
        }
  
        mutex_unlock(&ipc4_data->pipeline_state_mutex);
@@@ -1675,17 -2194,17 +2194,17 @@@ static int sof_ipc4_get_queue_id(struc
        u32 num_pins;
        int i;
  
-       if (pin_type == SOF_PIN_TYPE_SOURCE) {
+       if (pin_type == SOF_PIN_TYPE_OUTPUT) {
                current_swidget = src_widget;
-               pin_binding = src_widget->src_pin_binding;
-               queue_ida = &src_widget->src_queue_ida;
-               num_pins = src_widget->num_source_pins;
+               pin_binding = src_widget->output_pin_binding;
+               queue_ida = &src_widget->output_queue_ida;
+               num_pins = src_widget->num_output_pins;
                buddy_name = sink_widget->widget->name;
        } else {
                current_swidget = sink_widget;
-               pin_binding = sink_widget->sink_pin_binding;
-               queue_ida = &sink_widget->sink_queue_ida;
-               num_pins = sink_widget->num_sink_pins;
+               pin_binding = sink_widget->input_pin_binding;
+               queue_ida = &sink_widget->input_queue_ida;
+               num_pins = sink_widget->num_input_pins;
                buddy_name = src_widget->widget->name;
        }
  
  
        if (num_pins < 1) {
                dev_err(scomp->dev, "invalid %s num_pins: %d for queue allocation for %s\n",
-                       (pin_type == SOF_PIN_TYPE_SOURCE ? "source" : "sink"),
+                       (pin_type == SOF_PIN_TYPE_OUTPUT ? "output" : "input"),
                        num_pins, current_swidget->widget->name);
                return -EINVAL;
        }
  
-       /* If there is only one sink/source pin, queue id must be 0 */
+       /* If there is only one input/output pin, queue id must be 0 */
        if (num_pins == 1)
                return 0;
  
                 * mixed use pin binding array and ida for queue ID allocation.
                 */
                dev_err(scomp->dev, "no %s queue id found from pin binding array for %s\n",
-                       (pin_type == SOF_PIN_TYPE_SOURCE ? "source" : "sink"),
+                       (pin_type == SOF_PIN_TYPE_OUTPUT ? "output" : "input"),
                        current_swidget->widget->name);
                return -EINVAL;
        }
@@@ -1729,14 -2248,14 +2248,14 @@@ static void sof_ipc4_put_queue_id(struc
        char **pin_binding;
        int num_pins;
  
-       if (pin_type == SOF_PIN_TYPE_SOURCE) {
-               pin_binding = swidget->src_pin_binding;
-               queue_ida = &swidget->src_queue_ida;
-               num_pins = swidget->num_source_pins;
+       if (pin_type == SOF_PIN_TYPE_OUTPUT) {
+               pin_binding = swidget->output_pin_binding;
+               queue_ida = &swidget->output_queue_ida;
+               num_pins = swidget->num_output_pins;
        } else {
-               pin_binding = swidget->sink_pin_binding;
-               queue_ida = &swidget->sink_queue_ida;
-               num_pins = swidget->num_sink_pins;
+               pin_binding = swidget->input_pin_binding;
+               queue_ida = &swidget->input_queue_ida;
+               num_pins = swidget->num_input_pins;
        }
  
        /* Nothing to free if queue ID is not allocated with ida. */
@@@ -1751,9 -2270,9 +2270,9 @@@ static int sof_ipc4_set_copier_sink_for
                                           struct snd_sof_widget *sink_widget,
                                           int sink_id)
  {
-       struct sof_ipc4_base_module_cfg *sink_config = sink_widget->private;
-       struct sof_ipc4_base_module_cfg *src_config;
        struct sof_ipc4_copier_config_set_sink_format format;
+       struct sof_ipc4_base_module_cfg *src_config;
+       const struct sof_ipc4_audio_format *pin_fmt;
        struct sof_ipc4_fw_module *fw_module;
        struct sof_ipc4_msg msg = {{ 0 }};
        u32 header, extension;
  
        format.sink_id = sink_id;
        memcpy(&format.source_fmt, &src_config->audio_fmt, sizeof(format.source_fmt));
-       memcpy(&format.sink_fmt, &sink_config->audio_fmt, sizeof(format.sink_fmt));
+       pin_fmt = sof_ipc4_get_input_pin_audio_fmt(sink_widget, sink_id);
+       if (!pin_fmt) {
+               dev_err(sdev->dev, "Unable to get pin %d format for %s",
+                       sink_id, sink_widget->widget->name);
+               return -EINVAL;
+       }
+       memcpy(&format.sink_fmt, pin_fmt, sizeof(format.sink_fmt));
        msg.data_size = sizeof(format);
        msg.data_ptr = &format;
  
        msg.primary = header;
        msg.extension = extension;
  
-       return sof_ipc_tx_message(sdev->ipc, &msg, msg.data_size, NULL, 0);
+       return sof_ipc_tx_message_no_reply(sdev->ipc, &msg, msg.data_size);
  }
  
  static int sof_ipc4_route_setup(struct snd_sof_dev *sdev, struct snd_sof_route *sroute)
  {
        struct snd_sof_widget *src_widget = sroute->src_widget;
        struct snd_sof_widget *sink_widget = sroute->sink_widget;
+       struct snd_sof_widget *src_pipe_widget = src_widget->spipe->pipe_widget;
+       struct snd_sof_widget *sink_pipe_widget = sink_widget->spipe->pipe_widget;
        struct sof_ipc4_fw_module *src_fw_module = src_widget->module_info;
        struct sof_ipc4_fw_module *sink_fw_module = sink_widget->module_info;
+       struct sof_ipc4_pipeline *src_pipeline = src_pipe_widget->private;
+       struct sof_ipc4_pipeline *sink_pipeline = sink_pipe_widget->private;
        struct sof_ipc4_msg msg = {{ 0 }};
        u32 header, extension;
        int ret;
  
+       /* no route set up if chain DMA is used */
+       if (src_pipeline->use_chain_dma || sink_pipeline->use_chain_dma) {
+               if (!src_pipeline->use_chain_dma || !sink_pipeline->use_chain_dma) {
+                       dev_err(sdev->dev,
+                               "use_chain_dma must be set for both src %s and sink %s pipelines\n",
+                               src_widget->widget->name, sink_widget->widget->name);
+                       return -EINVAL;
+               }
+               return 0;
+       }
        if (!src_fw_module || !sink_fw_module) {
 -              /* The NULL module will print as "(efault)" */
 -              dev_err(sdev->dev, "source %s or sink %s widget weren't set up properly\n",
 -                      src_fw_module->man4_module_entry.name,
 -                      sink_fw_module->man4_module_entry.name);
 +              dev_err(sdev->dev,
 +                      "cannot bind %s -> %s, no firmware module for: %s%s\n",
 +                      src_widget->widget->name, sink_widget->widget->name,
 +                      src_fw_module ? "" : " source",
 +                      sink_fw_module ? "" : " sink");
 +
                return -ENODEV;
        }
  
        sroute->src_queue_id = sof_ipc4_get_queue_id(src_widget, sink_widget,
-                                                    SOF_PIN_TYPE_SOURCE);
+                                                    SOF_PIN_TYPE_OUTPUT);
        if (sroute->src_queue_id < 0) {
                dev_err(sdev->dev, "failed to get queue ID for source widget: %s\n",
                        src_widget->widget->name);
        }
  
        sroute->dst_queue_id = sof_ipc4_get_queue_id(src_widget, sink_widget,
-                                                    SOF_PIN_TYPE_SINK);
+                                                    SOF_PIN_TYPE_INPUT);
        if (sroute->dst_queue_id < 0) {
                dev_err(sdev->dev, "failed to get queue ID for sink widget: %s\n",
                        sink_widget->widget->name);
                sof_ipc4_put_queue_id(src_widget, sroute->src_queue_id,
-                                     SOF_PIN_TYPE_SOURCE);
+                                     SOF_PIN_TYPE_OUTPUT);
                return sroute->dst_queue_id;
        }
  
        msg.primary = header;
        msg.extension = extension;
  
-       ret = sof_ipc_tx_message(sdev->ipc, &msg, 0, NULL, 0);
+       ret = sof_ipc_tx_message_no_reply(sdev->ipc, &msg, 0);
        if (ret < 0) {
                dev_err(sdev->dev, "failed to bind modules %s:%d -> %s:%d\n",
                        src_widget->widget->name, sroute->src_queue_id,
        return ret;
  
  out:
-       sof_ipc4_put_queue_id(src_widget, sroute->src_queue_id, SOF_PIN_TYPE_SOURCE);
-       sof_ipc4_put_queue_id(sink_widget, sroute->dst_queue_id, SOF_PIN_TYPE_SINK);
+       sof_ipc4_put_queue_id(src_widget, sroute->src_queue_id, SOF_PIN_TYPE_OUTPUT);
+       sof_ipc4_put_queue_id(sink_widget, sroute->dst_queue_id, SOF_PIN_TYPE_INPUT);
        return ret;
  }
  
@@@ -1885,9 -2426,17 +2428,17 @@@ static int sof_ipc4_route_free(struct s
        struct sof_ipc4_fw_module *src_fw_module = src_widget->module_info;
        struct sof_ipc4_fw_module *sink_fw_module = sink_widget->module_info;
        struct sof_ipc4_msg msg = {{ 0 }};
+       struct snd_sof_widget *src_pipe_widget = src_widget->spipe->pipe_widget;
+       struct snd_sof_widget *sink_pipe_widget = sink_widget->spipe->pipe_widget;
+       struct sof_ipc4_pipeline *src_pipeline = src_pipe_widget->private;
+       struct sof_ipc4_pipeline *sink_pipeline = sink_pipe_widget->private;
        u32 header, extension;
        int ret = 0;
  
+       /* no route is set up if chain DMA is used */
+       if (src_pipeline->use_chain_dma || sink_pipeline->use_chain_dma)
+               return 0;
        dev_dbg(sdev->dev, "unbind modules %s:%d -> %s:%d\n",
                src_widget->widget->name, sroute->src_queue_id,
                sink_widget->widget->name, sroute->dst_queue_id);
        msg.primary = header;
        msg.extension = extension;
  
-       ret = sof_ipc_tx_message(sdev->ipc, &msg, 0, NULL, 0);
+       ret = sof_ipc_tx_message_no_reply(sdev->ipc, &msg, 0);
        if (ret < 0)
                dev_err(sdev->dev, "failed to unbind modules %s:%d -> %s:%d\n",
                        src_widget->widget->name, sroute->src_queue_id,
                        sink_widget->widget->name, sroute->dst_queue_id);
  out:
-       sof_ipc4_put_queue_id(sink_widget, sroute->dst_queue_id, SOF_PIN_TYPE_SINK);
-       sof_ipc4_put_queue_id(src_widget, sroute->src_queue_id, SOF_PIN_TYPE_SOURCE);
+       sof_ipc4_put_queue_id(sink_widget, sroute->dst_queue_id, SOF_PIN_TYPE_INPUT);
+       sof_ipc4_put_queue_id(src_widget, sroute->src_queue_id, SOF_PIN_TYPE_OUTPUT);
  
        return ret;
  }
@@@ -1949,6 -2498,11 +2500,11 @@@ static int sof_ipc4_dai_config(struct s
  
        switch (ipc4_copier->dai_type) {
        case SOF_DAI_INTEL_HDA:
+               if (pipeline->use_chain_dma) {
+                       pipeline->msg.primary &= ~SOF_IPC4_GLB_CHAIN_DMA_LINK_ID_MASK;
+                       pipeline->msg.primary |= SOF_IPC4_GLB_CHAIN_DMA_LINK_ID(data->dai_data);
+                       break;
+               }
                gtw_attr = ipc4_copier->gtw_attr;
                gtw_attr->lp_buffer_alloc = pipeline->lp_mode;
                pipeline->skip_during_fe_trigger = true;
@@@ -2149,10 -2703,9 +2705,9 @@@ static int sof_ipc4_link_setup(struct s
  static enum sof_tokens common_copier_token_list[] = {
        SOF_COMP_TOKENS,
        SOF_AUDIO_FMT_NUM_TOKENS,
-       SOF_AUDIO_FORMAT_BUFFER_SIZE_TOKENS,
        SOF_IN_AUDIO_FORMAT_TOKENS,
        SOF_OUT_AUDIO_FORMAT_TOKENS,
-       SOF_COPIER_GATEWAY_CFG_TOKENS,
+       SOF_COPIER_DEEP_BUFFER_TOKENS,
        SOF_COPIER_TOKENS,
        SOF_COMP_EXT_TOKENS,
  };
@@@ -2165,10 -2718,8 +2720,8 @@@ static enum sof_tokens pipeline_token_l
  static enum sof_tokens dai_token_list[] = {
        SOF_COMP_TOKENS,
        SOF_AUDIO_FMT_NUM_TOKENS,
-       SOF_AUDIO_FORMAT_BUFFER_SIZE_TOKENS,
        SOF_IN_AUDIO_FORMAT_TOKENS,
        SOF_OUT_AUDIO_FORMAT_TOKENS,
-       SOF_COPIER_GATEWAY_CFG_TOKENS,
        SOF_COPIER_TOKENS,
        SOF_DAI_TOKENS,
        SOF_COMP_EXT_TOKENS,
@@@ -2178,8 -2729,8 +2731,8 @@@ static enum sof_tokens pga_token_list[
        SOF_COMP_TOKENS,
        SOF_GAIN_TOKENS,
        SOF_AUDIO_FMT_NUM_TOKENS,
-       SOF_AUDIO_FORMAT_BUFFER_SIZE_TOKENS,
        SOF_IN_AUDIO_FORMAT_TOKENS,
+       SOF_OUT_AUDIO_FORMAT_TOKENS,
        SOF_COMP_EXT_TOKENS,
  };
  
@@@ -2187,7 -2738,7 +2740,7 @@@ static enum sof_tokens mixer_token_list
        SOF_COMP_TOKENS,
        SOF_AUDIO_FMT_NUM_TOKENS,
        SOF_IN_AUDIO_FORMAT_TOKENS,
-       SOF_AUDIO_FORMAT_BUFFER_SIZE_TOKENS,
+       SOF_OUT_AUDIO_FORMAT_TOKENS,
        SOF_COMP_EXT_TOKENS,
  };
  
@@@ -2196,7 -2747,15 +2749,15 @@@ static enum sof_tokens src_token_list[
        SOF_SRC_TOKENS,
        SOF_AUDIO_FMT_NUM_TOKENS,
        SOF_IN_AUDIO_FORMAT_TOKENS,
-       SOF_AUDIO_FORMAT_BUFFER_SIZE_TOKENS,
+       SOF_OUT_AUDIO_FORMAT_TOKENS,
+       SOF_COMP_EXT_TOKENS,
+ };
+ static enum sof_tokens process_token_list[] = {
+       SOF_COMP_TOKENS,
+       SOF_AUDIO_FMT_NUM_TOKENS,
+       SOF_IN_AUDIO_FORMAT_TOKENS,
+       SOF_OUT_AUDIO_FORMAT_TOKENS,
        SOF_COMP_EXT_TOKENS,
  };
  
@@@ -2237,6 -2796,11 +2798,11 @@@ static const struct sof_ipc_tplg_widget
                                src_token_list, ARRAY_SIZE(src_token_list),
                                NULL, sof_ipc4_prepare_src_module,
                                NULL},
+       [snd_soc_dapm_effect] = {sof_ipc4_widget_setup_comp_process,
+                               sof_ipc4_widget_free_comp_process,
+                               process_token_list, ARRAY_SIZE(process_token_list),
+                               NULL, sof_ipc4_prepare_process_module,
+                               NULL},
  };
  
  const struct sof_ipc_tplg_ops ipc4_tplg_ops = {
diff --combined sound/soc/sof/pm.c
index 85412aeb1ca16b0ed66d4db24a5e449be4370e57,c74ce8d414e71a69592b402b34f5de33825fdae9..2fdbc53ca7150b3ad5f597d22705d83fc87ce7c3
@@@ -103,6 -103,11 +103,11 @@@ static int sof_resume(struct device *de
                return ret;
        }
  
+       if (sdev->dspless_mode_selected) {
+               sof_set_fw_state(sdev, SOF_DSPLESS_MODE);
+               return 0;
+       }
        /*
         * Nothing further to be done for platforms that support the low power
         * D0 substate. Resume trace and return when resuming from
@@@ -183,7 -188,6 +188,7 @@@ static int sof_suspend(struct device *d
        const struct sof_ipc_tplg_ops *tplg_ops = sof_ipc_get_ops(sdev, tplg);
        pm_message_t pm_state;
        u32 target_state = snd_sof_dsp_power_target(sdev);
 +      u32 old_state = sdev->dsp_power_state.state;
        int ret;
  
        /* do nothing if dsp suspend callback is not set */
        if (runtime_suspend && !sof_ops(sdev)->runtime_suspend)
                return 0;
  
 -      if (tplg_ops && tplg_ops->tear_down_all_pipelines)
 +      /* we need to tear down pipelines only if the DSP hardware is
 +       * active, which happens for PCI devices. if the device is
 +       * suspended, it is brought back to full power and then
 +       * suspended again
 +       */
 +      if (tplg_ops && tplg_ops->tear_down_all_pipelines && (old_state == SOF_DSP_PM_D0))
                tplg_ops->tear_down_all_pipelines(sdev, false);
  
        if (sdev->fw_state != SOF_FW_BOOT_COMPLETE)
This page took 0.33498 seconds and 4 git commands to generate.