aboutsummaryrefslogtreecommitdiffstats
path: root/meta-agl-bsp
diff options
context:
space:
mode:
authorScott Murray <scott.murray@konsulko.com>2022-05-09 17:53:46 -0400
committerScott Murray <scott.murray@konsulko.com>2022-05-10 10:19:22 +0000
commit0d59423263be43f22cf8d597a6da4ec5f2d7f142 (patch)
tree82d36f3f62946556c9fdb15ea0dfa21456d6800f /meta-agl-bsp
parent4f5cf5dc8de803407fa9d3ffa13994309edde985 (diff)
meta-agl-bsp: update virtio-aarch64
Updates to get the virtio-aarch64 machine building after the upgrade to Yocto Project 4.0 / kirkstone: - Switch to the 5.15 linux-yocto kernel and drop the local backport of the 5.10 recipe. - Fix override syntax in the machine-specific linux-yocto bbappend. - Remove all the patches applied for the virtio and virtio-snd configuration fragments, they seem to have all been applied upstream. Bug-AGL: SPEC-4356 Signed-off-by: Scott Murray <scott.murray@konsulko.com> Change-Id: I96d4bb9b04d74280d1a3767fe17284fe6049fcba Reviewed-on: https://gerrit.automotivelinux.org/gerrit/c/AGL/meta-agl/+/27465 Reviewed-by: Vasyl Vavrychuk <vasyl.vavrychuk@opensynergy.com> Tested-by: Jenkins Job builder account ci-image-build: Jenkins Job builder account ci-image-boot-test: Jenkins Job builder account
Diffstat (limited to 'meta-agl-bsp')
-rw-r--r--meta-agl-bsp/conf/machine/include/virtio.inc13
-rw-r--r--meta-agl-bsp/virtualization-layer/recipes-kernel/linux/linux-yocto/virtio-kmeta/bsp/virtio/virtio-input-add-multi-touch-support.patch66
-rw-r--r--meta-agl-bsp/virtualization-layer/recipes-kernel/linux/linux-yocto/virtio-kmeta/bsp/virtio/virtio-snd/0001-uapi-virtio_ids-add-a-sound-device-type-ID-from-OASI.patch28
-rw-r--r--meta-agl-bsp/virtualization-layer/recipes-kernel/linux/linux-yocto/virtio-kmeta/bsp/virtio/virtio-snd/0002-ALSA-virtio-add-virtio-sound-driver.patch849
-rw-r--r--meta-agl-bsp/virtualization-layer/recipes-kernel/linux/linux-yocto/virtio-kmeta/bsp/virtio/virtio-snd/0003-ALSA-virtio-handling-control-messages.patch528
-rw-r--r--meta-agl-bsp/virtualization-layer/recipes-kernel/linux/linux-yocto/virtio-kmeta/bsp/virtio/virtio-snd/0004-ALSA-virtio-build-PCM-devices-and-substream-hardware.patch703
-rw-r--r--meta-agl-bsp/virtualization-layer/recipes-kernel/linux/linux-yocto/virtio-kmeta/bsp/virtio/virtio-snd/0005-ALSA-virtio-handling-control-and-I-O-messages-for-th.patch645
-rw-r--r--meta-agl-bsp/virtualization-layer/recipes-kernel/linux/linux-yocto/virtio-kmeta/bsp/virtio/virtio-snd/0006-ALSA-virtio-PCM-substream-operators.patch525
-rw-r--r--meta-agl-bsp/virtualization-layer/recipes-kernel/linux/linux-yocto/virtio-kmeta/bsp/virtio/virtio-snd/0007-ALSA-virtio-introduce-jack-support.patch351
-rw-r--r--meta-agl-bsp/virtualization-layer/recipes-kernel/linux/linux-yocto/virtio-kmeta/bsp/virtio/virtio-snd/0008-ALSA-virtio-introduce-PCM-channel-map-support.patch335
-rw-r--r--meta-agl-bsp/virtualization-layer/recipes-kernel/linux/linux-yocto/virtio-kmeta/bsp/virtio/virtio-snd/0009-ALSA-virtio-introduce-device-suspend-resume-support.patch174
-rw-r--r--meta-agl-bsp/virtualization-layer/recipes-kernel/linux/linux-yocto/virtio-kmeta/bsp/virtio/virtio-snd/virtio-snd.scc9
-rw-r--r--meta-agl-bsp/virtualization-layer/recipes-kernel/linux/linux-yocto/virtio-kmeta/bsp/virtio/virtio.scc1
-rw-r--r--meta-agl-bsp/virtualization-layer/recipes-kernel/linux/linux-yocto_%.bbappend2
-rw-r--r--meta-agl-bsp/virtualization-layer/recipes-kernel/linux/linux-yocto_5.10.bb58
15 files changed, 2 insertions, 4285 deletions
diff --git a/meta-agl-bsp/conf/machine/include/virtio.inc b/meta-agl-bsp/conf/machine/include/virtio.inc
index 8ee71a80b..6f8a638a0 100644
--- a/meta-agl-bsp/conf/machine/include/virtio.inc
+++ b/meta-agl-bsp/conf/machine/include/virtio.inc
@@ -16,19 +16,8 @@ RDEPENDS:${KERNEL_PACKAGE_NAME}-base = ""
PREFERRED_PROVIDER_virtual/kernel ??= "linux-yocto"
# Use newer kernel
-PREFERRED_VERSION_linux-yocto = "5.10.%"
-
-# Clear since it is set to 'sllin' in packagegroup-agl-demo.bb, and sllin is not
-# compatible with kernel 5.10 at the moment.
-LIN_DRIVERS = ""
-
-# Clear since it is set to 'lttng-modules' in packagegroup-core-tools-profile.bb,
-# and lttng-modules are not compatible with 5.10 kernel used for virtio.
-LTTNGMODULES:virtio-all = ""
+PREFERRED_VERSION_linux-yocto = "5.15.%"
EXTRA_IMAGEDEPENDS += "qemu-native qemu-helper-native"
IMAGE_CLASSES += "qemuboot"
-
-# most driver fails to compile
-MOST_DRIVERS ?= ""
diff --git a/meta-agl-bsp/virtualization-layer/recipes-kernel/linux/linux-yocto/virtio-kmeta/bsp/virtio/virtio-input-add-multi-touch-support.patch b/meta-agl-bsp/virtualization-layer/recipes-kernel/linux/linux-yocto/virtio-kmeta/bsp/virtio/virtio-input-add-multi-touch-support.patch
deleted file mode 100644
index 59a9f9b5d..000000000
--- a/meta-agl-bsp/virtualization-layer/recipes-kernel/linux/linux-yocto/virtio-kmeta/bsp/virtio/virtio-input-add-multi-touch-support.patch
+++ /dev/null
@@ -1,66 +0,0 @@
-From 16c10bede8b3d8594279752bf53153491f3f944f Mon Sep 17 00:00:00 2001
-From: Mathias Crombez <mathias.crombez@faurecia.com>
-Date: Fri, 15 Jan 2021 02:26:23 +0200
-Subject: [PATCH] virtio-input: add multi-touch support
-
-Without multi-touch slots allocated, ABS_MT_SLOT events will be lost by
-input_handle_abs_event.
-
-Implementation is based on uinput_create_device.
-
-Signed-off-by: Mathias Crombez <mathias.crombez@faurecia.com>
-Co-developed-by: Vasyl Vavrychuk <vasyl.vavrychuk@opensynergy.com>
-Signed-off-by: Vasyl Vavrychuk <vasyl.vavrychuk@opensynergy.com>
-Link: https://lore.kernel.org/r/20210115002623.8576-1-vasyl.vavrychuk@opensynergy.com
-Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
-Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
----
- drivers/virtio/virtio_input.c | 11 ++++++++++-
- 1 file changed, 10 insertions(+), 1 deletion(-)
-
-diff --git a/drivers/virtio/virtio_input.c b/drivers/virtio/virtio_input.c
-index 244965c20d9b..ce51ae165943 100644
---- a/drivers/virtio/virtio_input.c
-+++ b/drivers/virtio/virtio_input.c
-@@ -7,6 +7,7 @@
-
- #include <uapi/linux/virtio_ids.h>
- #include <uapi/linux/virtio_input.h>
-+#include <linux/input/mt.h>
-
- struct virtio_input {
- struct virtio_device *vdev;
-@@ -219,7 +220,7 @@ static int virtinput_probe(struct virtio_device *vdev)
- struct virtio_input *vi;
- unsigned long flags;
- size_t size;
-- int abs, err;
-+ int abs, err, nslots;
-
- if (!virtio_has_feature(vdev, VIRTIO_F_VERSION_1))
- return -ENODEV;
-@@ -304,6 +305,13 @@ static int virtinput_probe(struct virtio_device *vdev)
- continue;
- virtinput_cfg_abs(vi, abs);
- }
-+
-+ if (test_bit(ABS_MT_SLOT, vi->idev->absbit)) {
-+ nslots = input_abs_get_max(vi->idev, ABS_MT_SLOT) + 1;
-+ err = input_mt_init_slots(vi->idev, nslots, 0);
-+ if (err)
-+ goto err_mt_init_slots;
-+ }
- }
-
- virtio_device_ready(vdev);
-@@ -319,6 +327,7 @@ static int virtinput_probe(struct virtio_device *vdev)
- spin_lock_irqsave(&vi->lock, flags);
- vi->ready = false;
- spin_unlock_irqrestore(&vi->lock, flags);
-+err_mt_init_slots:
- input_free_device(vi->idev);
- err_input_alloc:
- vdev->config->del_vqs(vdev);
---
-2.31.1
-
diff --git a/meta-agl-bsp/virtualization-layer/recipes-kernel/linux/linux-yocto/virtio-kmeta/bsp/virtio/virtio-snd/0001-uapi-virtio_ids-add-a-sound-device-type-ID-from-OASI.patch b/meta-agl-bsp/virtualization-layer/recipes-kernel/linux/linux-yocto/virtio-kmeta/bsp/virtio/virtio-snd/0001-uapi-virtio_ids-add-a-sound-device-type-ID-from-OASI.patch
deleted file mode 100644
index e303d10c7..000000000
--- a/meta-agl-bsp/virtualization-layer/recipes-kernel/linux/linux-yocto/virtio-kmeta/bsp/virtio/virtio-snd/0001-uapi-virtio_ids-add-a-sound-device-type-ID-from-OASI.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From 6afbb3650d7e02785030f1212c88b50d7296bb45 Mon Sep 17 00:00:00 2001
-From: Anton Yakovlev <anton.yakovlev@opensynergy.com>
-Date: Tue, 2 Mar 2021 17:47:01 +0100
-Subject: [PATCH] uapi: virtio_ids: add a sound device type ID from OASIS spec
-
-The OASIS virtio spec defines a sound device type ID that is not
-present in the header yet.
-
-Signed-off-by: Anton Yakovlev <anton.yakovlev@opensynergy.com>
-Link: https://lore.kernel.org/r/20210302164709.3142702-2-anton.yakovlev@opensynergy.com
-Signed-off-by: Takashi Iwai <tiwai@suse.de>
-Signed-off-by: Vasyl Vavrychuk <vasyl.vavrychuk@opensynergy.com>
----
- include/uapi/linux/virtio_ids.h | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/include/uapi/linux/virtio_ids.h b/include/uapi/linux/virtio_ids.h
-index b052355ac7a3..bc740d6d2259 100644
---- a/include/uapi/linux/virtio_ids.h
-+++ b/include/uapi/linux/virtio_ids.h
-@@ -45,6 +45,7 @@
- #define VIRTIO_ID_CRYPTO 20 /* virtio crypto */
- #define VIRTIO_ID_IOMMU 23 /* virtio IOMMU */
- #define VIRTIO_ID_MEM 24 /* virtio mem */
-+#define VIRTIO_ID_SOUND 25 /* virtio sound */
- #define VIRTIO_ID_FS 26 /* virtio filesystem */
- #define VIRTIO_ID_PMEM 27 /* virtio pmem */
- #define VIRTIO_ID_MAC80211_HWSIM 29 /* virtio mac80211-hwsim */
diff --git a/meta-agl-bsp/virtualization-layer/recipes-kernel/linux/linux-yocto/virtio-kmeta/bsp/virtio/virtio-snd/0002-ALSA-virtio-add-virtio-sound-driver.patch b/meta-agl-bsp/virtualization-layer/recipes-kernel/linux/linux-yocto/virtio-kmeta/bsp/virtio/virtio-snd/0002-ALSA-virtio-add-virtio-sound-driver.patch
deleted file mode 100644
index e2f80442f..000000000
--- a/meta-agl-bsp/virtualization-layer/recipes-kernel/linux/linux-yocto/virtio-kmeta/bsp/virtio/virtio-snd/0002-ALSA-virtio-add-virtio-sound-driver.patch
+++ /dev/null
@@ -1,849 +0,0 @@
-From a1cde5ccba57562aa77739b63b50586e6b197b52 Mon Sep 17 00:00:00 2001
-From: Anton Yakovlev <anton.yakovlev@opensynergy.com>
-Date: Tue, 2 Mar 2021 17:47:02 +0100
-Subject: [PATCH] ALSA: virtio: add virtio sound driver
-
-Introduce skeleton of the virtio sound driver. The driver implements
-the virtio sound device specification, which has become part of the
-virtio standard.
-
-Initial initialization of the device, virtqueues and creation of an
-empty ALSA sound device.
-
-Signed-off-by: Anton Yakovlev <anton.yakovlev@opensynergy.com>
-Link: https://lore.kernel.org/r/20210302164709.3142702-3-anton.yakovlev@opensynergy.com
-Signed-off-by: Takashi Iwai <tiwai@suse.de>
-Signed-off-by: Vasyl Vavrychuk <vasyl.vavrychuk@opensynergy.com>
----
- MAINTAINERS | 9 +
- include/uapi/linux/virtio_snd.h | 334 ++++++++++++++++++++++++++++++++
- sound/Kconfig | 2 +
- sound/Makefile | 3 +-
- sound/virtio/Kconfig | 10 +
- sound/virtio/Makefile | 7 +
- sound/virtio/virtio_card.c | 324 +++++++++++++++++++++++++++++++
- sound/virtio/virtio_card.h | 65 +++++++
- 8 files changed, 753 insertions(+), 1 deletion(-)
- create mode 100644 include/uapi/linux/virtio_snd.h
- create mode 100644 sound/virtio/Kconfig
- create mode 100644 sound/virtio/Makefile
- create mode 100644 sound/virtio/virtio_card.c
- create mode 100644 sound/virtio/virtio_card.h
-
-diff --git a/MAINTAINERS b/MAINTAINERS
-index 407ae5c24566..49772b741967 100644
---- a/MAINTAINERS
-+++ b/MAINTAINERS
-@@ -18670,6 +18670,15 @@ W: https://virtio-mem.gitlab.io/
- F: drivers/virtio/virtio_mem.c
- F: include/uapi/linux/virtio_mem.h
-
-+VIRTIO SOUND DRIVER
-+M: Anton Yakovlev <anton.yakovlev@opensynergy.com>
-+M: "Michael S. Tsirkin" <mst@redhat.com>
-+L: virtualization@lists.linux-foundation.org
-+L: alsa-devel@alsa-project.org (moderated for non-subscribers)
-+S: Maintained
-+F: include/uapi/linux/virtio_snd.h
-+F: sound/virtio/*
-+
- VIRTUAL BOX GUEST DEVICE DRIVER
- M: Hans de Goede <hdegoede@redhat.com>
- M: Arnd Bergmann <arnd@arndb.de>
-diff --git a/include/uapi/linux/virtio_snd.h b/include/uapi/linux/virtio_snd.h
-new file mode 100644
-index 000000000000..dfe49547a7b0
---- /dev/null
-+++ b/include/uapi/linux/virtio_snd.h
-@@ -0,0 +1,334 @@
-+/* SPDX-License-Identifier: BSD-3-Clause */
-+/*
-+ * Copyright (C) 2021 OpenSynergy GmbH
-+ */
-+#ifndef VIRTIO_SND_IF_H
-+#define VIRTIO_SND_IF_H
-+
-+#include <linux/virtio_types.h>
-+
-+/*******************************************************************************
-+ * CONFIGURATION SPACE
-+ */
-+struct virtio_snd_config {
-+ /* # of available physical jacks */
-+ __le32 jacks;
-+ /* # of available PCM streams */
-+ __le32 streams;
-+ /* # of available channel maps */
-+ __le32 chmaps;
-+};
-+
-+enum {
-+ /* device virtqueue indexes */
-+ VIRTIO_SND_VQ_CONTROL = 0,
-+ VIRTIO_SND_VQ_EVENT,
-+ VIRTIO_SND_VQ_TX,
-+ VIRTIO_SND_VQ_RX,
-+ /* # of device virtqueues */
-+ VIRTIO_SND_VQ_MAX
-+};
-+
-+/*******************************************************************************
-+ * COMMON DEFINITIONS
-+ */
-+
-+/* supported dataflow directions */
-+enum {
-+ VIRTIO_SND_D_OUTPUT = 0,
-+ VIRTIO_SND_D_INPUT
-+};
-+
-+enum {
-+ /* jack control request types */
-+ VIRTIO_SND_R_JACK_INFO = 1,
-+ VIRTIO_SND_R_JACK_REMAP,
-+
-+ /* PCM control request types */
-+ VIRTIO_SND_R_PCM_INFO = 0x0100,
-+ VIRTIO_SND_R_PCM_SET_PARAMS,
-+ VIRTIO_SND_R_PCM_PREPARE,
-+ VIRTIO_SND_R_PCM_RELEASE,
-+ VIRTIO_SND_R_PCM_START,
-+ VIRTIO_SND_R_PCM_STOP,
-+
-+ /* channel map control request types */
-+ VIRTIO_SND_R_CHMAP_INFO = 0x0200,
-+
-+ /* jack event types */
-+ VIRTIO_SND_EVT_JACK_CONNECTED = 0x1000,
-+ VIRTIO_SND_EVT_JACK_DISCONNECTED,
-+
-+ /* PCM event types */
-+ VIRTIO_SND_EVT_PCM_PERIOD_ELAPSED = 0x1100,
-+ VIRTIO_SND_EVT_PCM_XRUN,
-+
-+ /* common status codes */
-+ VIRTIO_SND_S_OK = 0x8000,
-+ VIRTIO_SND_S_BAD_MSG,
-+ VIRTIO_SND_S_NOT_SUPP,
-+ VIRTIO_SND_S_IO_ERR
-+};
-+
-+/* common header */
-+struct virtio_snd_hdr {
-+ __le32 code;
-+};
-+
-+/* event notification */
-+struct virtio_snd_event {
-+ /* VIRTIO_SND_EVT_XXX */
-+ struct virtio_snd_hdr hdr;
-+ /* optional event data */
-+ __le32 data;
-+};
-+
-+/* common control request to query an item information */
-+struct virtio_snd_query_info {
-+ /* VIRTIO_SND_R_XXX_INFO */
-+ struct virtio_snd_hdr hdr;
-+ /* item start identifier */
-+ __le32 start_id;
-+ /* item count to query */
-+ __le32 count;
-+ /* item information size in bytes */
-+ __le32 size;
-+};
-+
-+/* common item information header */
-+struct virtio_snd_info {
-+ /* function group node id (High Definition Audio Specification 7.1.2) */
-+ __le32 hda_fn_nid;
-+};
-+
-+/*******************************************************************************
-+ * JACK CONTROL MESSAGES
-+ */
-+struct virtio_snd_jack_hdr {
-+ /* VIRTIO_SND_R_JACK_XXX */
-+ struct virtio_snd_hdr hdr;
-+ /* 0 ... virtio_snd_config::jacks - 1 */
-+ __le32 jack_id;
-+};
-+
-+/* supported jack features */
-+enum {
-+ VIRTIO_SND_JACK_F_REMAP = 0
-+};
-+
-+struct virtio_snd_jack_info {
-+ /* common header */
-+ struct virtio_snd_info hdr;
-+ /* supported feature bit map (1 << VIRTIO_SND_JACK_F_XXX) */
-+ __le32 features;
-+ /* pin configuration (High Definition Audio Specification 7.3.3.31) */
-+ __le32 hda_reg_defconf;
-+ /* pin capabilities (High Definition Audio Specification 7.3.4.9) */
-+ __le32 hda_reg_caps;
-+ /* current jack connection status (0: disconnected, 1: connected) */
-+ __u8 connected;
-+
-+ __u8 padding[7];
-+};
-+
-+/* jack remapping control request */
-+struct virtio_snd_jack_remap {
-+ /* .code = VIRTIO_SND_R_JACK_REMAP */
-+ struct virtio_snd_jack_hdr hdr;
-+ /* selected association number */
-+ __le32 association;
-+ /* selected sequence number */
-+ __le32 sequence;
-+};
-+
-+/*******************************************************************************
-+ * PCM CONTROL MESSAGES
-+ */
-+struct virtio_snd_pcm_hdr {
-+ /* VIRTIO_SND_R_PCM_XXX */
-+ struct virtio_snd_hdr hdr;
-+ /* 0 ... virtio_snd_config::streams - 1 */
-+ __le32 stream_id;
-+};
-+
-+/* supported PCM stream features */
-+enum {
-+ VIRTIO_SND_PCM_F_SHMEM_HOST = 0,
-+ VIRTIO_SND_PCM_F_SHMEM_GUEST,
-+ VIRTIO_SND_PCM_F_MSG_POLLING,
-+ VIRTIO_SND_PCM_F_EVT_SHMEM_PERIODS,
-+ VIRTIO_SND_PCM_F_EVT_XRUNS
-+};
-+
-+/* supported PCM sample formats */
-+enum {
-+ /* analog formats (width / physical width) */
-+ VIRTIO_SND_PCM_FMT_IMA_ADPCM = 0, /* 4 / 4 bits */
-+ VIRTIO_SND_PCM_FMT_MU_LAW, /* 8 / 8 bits */
-+ VIRTIO_SND_PCM_FMT_A_LAW, /* 8 / 8 bits */
-+ VIRTIO_SND_PCM_FMT_S8, /* 8 / 8 bits */
-+ VIRTIO_SND_PCM_FMT_U8, /* 8 / 8 bits */
-+ VIRTIO_SND_PCM_FMT_S16, /* 16 / 16 bits */
-+ VIRTIO_SND_PCM_FMT_U16, /* 16 / 16 bits */
-+ VIRTIO_SND_PCM_FMT_S18_3, /* 18 / 24 bits */
-+ VIRTIO_SND_PCM_FMT_U18_3, /* 18 / 24 bits */
-+ VIRTIO_SND_PCM_FMT_S20_3, /* 20 / 24 bits */
-+ VIRTIO_SND_PCM_FMT_U20_3, /* 20 / 24 bits */
-+ VIRTIO_SND_PCM_FMT_S24_3, /* 24 / 24 bits */
-+ VIRTIO_SND_PCM_FMT_U24_3, /* 24 / 24 bits */
-+ VIRTIO_SND_PCM_FMT_S20, /* 20 / 32 bits */
-+ VIRTIO_SND_PCM_FMT_U20, /* 20 / 32 bits */
-+ VIRTIO_SND_PCM_FMT_S24, /* 24 / 32 bits */
-+ VIRTIO_SND_PCM_FMT_U24, /* 24 / 32 bits */
-+ VIRTIO_SND_PCM_FMT_S32, /* 32 / 32 bits */
-+ VIRTIO_SND_PCM_FMT_U32, /* 32 / 32 bits */
-+ VIRTIO_SND_PCM_FMT_FLOAT, /* 32 / 32 bits */
-+ VIRTIO_SND_PCM_FMT_FLOAT64, /* 64 / 64 bits */
-+ /* digital formats (width / physical width) */
-+ VIRTIO_SND_PCM_FMT_DSD_U8, /* 8 / 8 bits */
-+ VIRTIO_SND_PCM_FMT_DSD_U16, /* 16 / 16 bits */
-+ VIRTIO_SND_PCM_FMT_DSD_U32, /* 32 / 32 bits */
-+ VIRTIO_SND_PCM_FMT_IEC958_SUBFRAME /* 32 / 32 bits */
-+};
-+
-+/* supported PCM frame rates */
-+enum {
-+ VIRTIO_SND_PCM_RATE_5512 = 0,
-+ VIRTIO_SND_PCM_RATE_8000,
-+ VIRTIO_SND_PCM_RATE_11025,
-+ VIRTIO_SND_PCM_RATE_16000,
-+ VIRTIO_SND_PCM_RATE_22050,
-+ VIRTIO_SND_PCM_RATE_32000,
-+ VIRTIO_SND_PCM_RATE_44100,
-+ VIRTIO_SND_PCM_RATE_48000,
-+ VIRTIO_SND_PCM_RATE_64000,
-+ VIRTIO_SND_PCM_RATE_88200,
-+ VIRTIO_SND_PCM_RATE_96000,
-+ VIRTIO_SND_PCM_RATE_176400,
-+ VIRTIO_SND_PCM_RATE_192000,
-+ VIRTIO_SND_PCM_RATE_384000
-+};
-+
-+struct virtio_snd_pcm_info {
-+ /* common header */
-+ struct virtio_snd_info hdr;
-+ /* supported feature bit map (1 << VIRTIO_SND_PCM_F_XXX) */
-+ __le32 features;
-+ /* supported sample format bit map (1 << VIRTIO_SND_PCM_FMT_XXX) */
-+ __le64 formats;
-+ /* supported frame rate bit map (1 << VIRTIO_SND_PCM_RATE_XXX) */
-+ __le64 rates;
-+ /* dataflow direction (VIRTIO_SND_D_XXX) */
-+ __u8 direction;
-+ /* minimum # of supported channels */
-+ __u8 channels_min;
-+ /* maximum # of supported channels */
-+ __u8 channels_max;
-+
-+ __u8 padding[5];
-+};
-+
-+/* set PCM stream format */
-+struct virtio_snd_pcm_set_params {
-+ /* .code = VIRTIO_SND_R_PCM_SET_PARAMS */
-+ struct virtio_snd_pcm_hdr hdr;
-+ /* size of the hardware buffer */
-+ __le32 buffer_bytes;
-+ /* size of the hardware period */
-+ __le32 period_bytes;
-+ /* selected feature bit map (1 << VIRTIO_SND_PCM_F_XXX) */
-+ __le32 features;
-+ /* selected # of channels */
-+ __u8 channels;
-+ /* selected sample format (VIRTIO_SND_PCM_FMT_XXX) */
-+ __u8 format;
-+ /* selected frame rate (VIRTIO_SND_PCM_RATE_XXX) */
-+ __u8 rate;
-+
-+ __u8 padding;
-+};
-+
-+/*******************************************************************************
-+ * PCM I/O MESSAGES
-+ */
-+
-+/* I/O request header */
-+struct virtio_snd_pcm_xfer {
-+ /* 0 ... virtio_snd_config::streams - 1 */
-+ __le32 stream_id;
-+};
-+
-+/* I/O request status */
-+struct virtio_snd_pcm_status {
-+ /* VIRTIO_SND_S_XXX */
-+ __le32 status;
-+ /* current device latency */
-+ __le32 latency_bytes;
-+};
-+
-+/*******************************************************************************
-+ * CHANNEL MAP CONTROL MESSAGES
-+ */
-+struct virtio_snd_chmap_hdr {
-+ /* VIRTIO_SND_R_CHMAP_XXX */
-+ struct virtio_snd_hdr hdr;
-+ /* 0 ... virtio_snd_config::chmaps - 1 */
-+ __le32 chmap_id;
-+};
-+
-+/* standard channel position definition */
-+enum {
-+ VIRTIO_SND_CHMAP_NONE = 0, /* undefined */
-+ VIRTIO_SND_CHMAP_NA, /* silent */
-+ VIRTIO_SND_CHMAP_MONO, /* mono stream */
-+ VIRTIO_SND_CHMAP_FL, /* front left */
-+ VIRTIO_SND_CHMAP_FR, /* front right */
-+ VIRTIO_SND_CHMAP_RL, /* rear left */
-+ VIRTIO_SND_CHMAP_RR, /* rear right */
-+ VIRTIO_SND_CHMAP_FC, /* front center */
-+ VIRTIO_SND_CHMAP_LFE, /* low frequency (LFE) */
-+ VIRTIO_SND_CHMAP_SL, /* side left */
-+ VIRTIO_SND_CHMAP_SR, /* side right */
-+ VIRTIO_SND_CHMAP_RC, /* rear center */
-+ VIRTIO_SND_CHMAP_FLC, /* front left center */
-+ VIRTIO_SND_CHMAP_FRC, /* front right center */
-+ VIRTIO_SND_CHMAP_RLC, /* rear left center */
-+ VIRTIO_SND_CHMAP_RRC, /* rear right center */
-+ VIRTIO_SND_CHMAP_FLW, /* front left wide */
-+ VIRTIO_SND_CHMAP_FRW, /* front right wide */
-+ VIRTIO_SND_CHMAP_FLH, /* front left high */
-+ VIRTIO_SND_CHMAP_FCH, /* front center high */
-+ VIRTIO_SND_CHMAP_FRH, /* front right high */
-+ VIRTIO_SND_CHMAP_TC, /* top center */
-+ VIRTIO_SND_CHMAP_TFL, /* top front left */
-+ VIRTIO_SND_CHMAP_TFR, /* top front right */
-+ VIRTIO_SND_CHMAP_TFC, /* top front center */
-+ VIRTIO_SND_CHMAP_TRL, /* top rear left */
-+ VIRTIO_SND_CHMAP_TRR, /* top rear right */
-+ VIRTIO_SND_CHMAP_TRC, /* top rear center */
-+ VIRTIO_SND_CHMAP_TFLC, /* top front left center */
-+ VIRTIO_SND_CHMAP_TFRC, /* top front right center */
-+ VIRTIO_SND_CHMAP_TSL, /* top side left */
-+ VIRTIO_SND_CHMAP_TSR, /* top side right */
-+ VIRTIO_SND_CHMAP_LLFE, /* left LFE */
-+ VIRTIO_SND_CHMAP_RLFE, /* right LFE */
-+ VIRTIO_SND_CHMAP_BC, /* bottom center */
-+ VIRTIO_SND_CHMAP_BLC, /* bottom left center */
-+ VIRTIO_SND_CHMAP_BRC /* bottom right center */
-+};
-+
-+/* maximum possible number of channels */
-+#define VIRTIO_SND_CHMAP_MAX_SIZE 18
-+
-+struct virtio_snd_chmap_info {
-+ /* common header */
-+ struct virtio_snd_info hdr;
-+ /* dataflow direction (VIRTIO_SND_D_XXX) */
-+ __u8 direction;
-+ /* # of valid channel position values */
-+ __u8 channels;
-+ /* channel position values (VIRTIO_SND_CHMAP_XXX) */
-+ __u8 positions[VIRTIO_SND_CHMAP_MAX_SIZE];
-+};
-+
-+#endif /* VIRTIO_SND_IF_H */
-diff --git a/sound/Kconfig b/sound/Kconfig
-index 36785410fbe1..e56d96d2b11c 100644
---- a/sound/Kconfig
-+++ b/sound/Kconfig
-@@ -99,6 +99,8 @@ source "sound/synth/Kconfig"
-
- source "sound/xen/Kconfig"
-
-+source "sound/virtio/Kconfig"
-+
- endif # SND
-
- endif # !UML
-diff --git a/sound/Makefile b/sound/Makefile
-index 797ecdcd35e2..04ef04b1168f 100644
---- a/sound/Makefile
-+++ b/sound/Makefile
-@@ -5,7 +5,8 @@
- obj-$(CONFIG_SOUND) += soundcore.o
- obj-$(CONFIG_DMASOUND) += oss/dmasound/
- obj-$(CONFIG_SND) += core/ i2c/ drivers/ isa/ pci/ ppc/ arm/ sh/ synth/ usb/ \
-- firewire/ sparc/ spi/ parisc/ pcmcia/ mips/ soc/ atmel/ hda/ x86/ xen/
-+ firewire/ sparc/ spi/ parisc/ pcmcia/ mips/ soc/ atmel/ hda/ x86/ xen/ \
-+ virtio/
- obj-$(CONFIG_SND_AOA) += aoa/
-
- # This one must be compilable even if sound is configured out
-diff --git a/sound/virtio/Kconfig b/sound/virtio/Kconfig
-new file mode 100644
-index 000000000000..094cba24ee5b
---- /dev/null
-+++ b/sound/virtio/Kconfig
-@@ -0,0 +1,10 @@
-+# SPDX-License-Identifier: GPL-2.0+
-+# Sound card driver for virtio
-+
-+config SND_VIRTIO
-+ tristate "Virtio sound driver"
-+ depends on VIRTIO
-+ select SND_PCM
-+ select SND_JACK
-+ help
-+ This is the virtual sound driver for virtio. Say Y or M.
-diff --git a/sound/virtio/Makefile b/sound/virtio/Makefile
-new file mode 100644
-index 000000000000..8c87ebb9982b
---- /dev/null
-+++ b/sound/virtio/Makefile
-@@ -0,0 +1,7 @@
-+# SPDX-License-Identifier: GPL-2.0+
-+
-+obj-$(CONFIG_SND_VIRTIO) += virtio_snd.o
-+
-+virtio_snd-objs := \
-+ virtio_card.o
-+
-diff --git a/sound/virtio/virtio_card.c b/sound/virtio/virtio_card.c
-new file mode 100644
-index 000000000000..5a37056858e9
---- /dev/null
-+++ b/sound/virtio/virtio_card.c
-@@ -0,0 +1,324 @@
-+// SPDX-License-Identifier: GPL-2.0+
-+/*
-+ * virtio-snd: Virtio sound device
-+ * Copyright (C) 2021 OpenSynergy GmbH
-+ */
-+#include <linux/module.h>
-+#include <linux/moduleparam.h>
-+#include <linux/virtio_config.h>
-+#include <sound/initval.h>
-+#include <uapi/linux/virtio_ids.h>
-+
-+#include "virtio_card.h"
-+
-+static void virtsnd_remove(struct virtio_device *vdev);
-+
-+/**
-+ * virtsnd_event_send() - Add an event to the event queue.
-+ * @vqueue: Underlying event virtqueue.
-+ * @event: Event.
-+ * @notify: Indicates whether or not to send a notification to the device.
-+ * @gfp: Kernel flags for memory allocation.
-+ *
-+ * Context: Any context.
-+ */
-+static void virtsnd_event_send(struct virtqueue *vqueue,
-+ struct virtio_snd_event *event, bool notify,
-+ gfp_t gfp)
-+{
-+ struct scatterlist sg;
-+ struct scatterlist *psgs[1] = { &sg };
-+
-+ /* reset event content */
-+ memset(event, 0, sizeof(*event));
-+
-+ sg_init_one(&sg, event, sizeof(*event));
-+
-+ if (virtqueue_add_sgs(vqueue, psgs, 0, 1, event, gfp) || !notify)
-+ return;
-+
-+ if (virtqueue_kick_prepare(vqueue))
-+ virtqueue_notify(vqueue);
-+}
-+
-+/**
-+ * virtsnd_event_dispatch() - Dispatch an event from the device side.
-+ * @snd: VirtIO sound device.
-+ * @event: VirtIO sound event.
-+ *
-+ * Context: Any context.
-+ */
-+static void virtsnd_event_dispatch(struct virtio_snd *snd,
-+ struct virtio_snd_event *event)
-+{
-+}
-+
-+/**
-+ * virtsnd_event_notify_cb() - Dispatch all reported events from the event queue.
-+ * @vqueue: Underlying event virtqueue.
-+ *
-+ * This callback function is called upon a vring interrupt request from the
-+ * device.
-+ *
-+ * Context: Interrupt context.
-+ */
-+static void virtsnd_event_notify_cb(struct virtqueue *vqueue)
-+{
-+ struct virtio_snd *snd = vqueue->vdev->priv;
-+ struct virtio_snd_queue *queue = virtsnd_event_queue(snd);
-+ struct virtio_snd_event *event;
-+ u32 length;
-+ unsigned long flags;
-+
-+ spin_lock_irqsave(&queue->lock, flags);
-+ do {
-+ virtqueue_disable_cb(vqueue);
-+ while ((event = virtqueue_get_buf(vqueue, &length))) {
-+ virtsnd_event_dispatch(snd, event);
-+ virtsnd_event_send(vqueue, event, true, GFP_ATOMIC);
-+ }
-+ if (unlikely(virtqueue_is_broken(vqueue)))
-+ break;
-+ } while (!virtqueue_enable_cb(vqueue));
-+ spin_unlock_irqrestore(&queue->lock, flags);
-+}
-+
-+/**
-+ * virtsnd_find_vqs() - Enumerate and initialize all virtqueues.
-+ * @snd: VirtIO sound device.
-+ *
-+ * After calling this function, the event queue is disabled.
-+ *
-+ * Context: Any context.
-+ * Return: 0 on success, -errno on failure.
-+ */
-+static int virtsnd_find_vqs(struct virtio_snd *snd)
-+{
-+ struct virtio_device *vdev = snd->vdev;
-+ static vq_callback_t *callbacks[VIRTIO_SND_VQ_MAX] = {
-+ [VIRTIO_SND_VQ_EVENT] = virtsnd_event_notify_cb
-+ };
-+ static const char *names[VIRTIO_SND_VQ_MAX] = {
-+ [VIRTIO_SND_VQ_EVENT] = "virtsnd-event"
-+ };
-+ struct virtqueue *vqs[VIRTIO_SND_VQ_MAX] = { 0 };
-+ unsigned int i;
-+ unsigned int n;
-+ int rc;
-+
-+ rc = virtio_find_vqs(vdev, VIRTIO_SND_VQ_MAX, vqs, callbacks, names,
-+ NULL);
-+ if (rc) {
-+ dev_err(&vdev->dev, "failed to initialize virtqueues\n");
-+ return rc;
-+ }
-+
-+ for (i = 0; i < VIRTIO_SND_VQ_MAX; ++i)
-+ snd->queues[i].vqueue = vqs[i];
-+
-+ /* Allocate events and populate the event queue */
-+ virtqueue_disable_cb(vqs[VIRTIO_SND_VQ_EVENT]);
-+
-+ n = virtqueue_get_vring_size(vqs[VIRTIO_SND_VQ_EVENT]);
-+
-+ snd->event_msgs = kmalloc_array(n, sizeof(*snd->event_msgs),
-+ GFP_KERNEL);
-+ if (!snd->event_msgs)
-+ return -ENOMEM;
-+
-+ for (i = 0; i < n; ++i)
-+ virtsnd_event_send(vqs[VIRTIO_SND_VQ_EVENT],
-+ &snd->event_msgs[i], false, GFP_KERNEL);
-+
-+ return 0;
-+}
-+
-+/**
-+ * virtsnd_enable_event_vq() - Enable the event virtqueue.
-+ * @snd: VirtIO sound device.
-+ *
-+ * Context: Any context.
-+ */
-+static void virtsnd_enable_event_vq(struct virtio_snd *snd)
-+{
-+ struct virtio_snd_queue *queue = virtsnd_event_queue(snd);
-+
-+ if (!virtqueue_enable_cb(queue->vqueue))
-+ virtsnd_event_notify_cb(queue->vqueue);
-+}
-+
-+/**
-+ * virtsnd_disable_event_vq() - Disable the event virtqueue.
-+ * @snd: VirtIO sound device.
-+ *
-+ * Context: Any context.
-+ */
-+static void virtsnd_disable_event_vq(struct virtio_snd *snd)
-+{
-+ struct virtio_snd_queue *queue = virtsnd_event_queue(snd);
-+ struct virtio_snd_event *event;
-+ u32 length;
-+ unsigned long flags;
-+
-+ if (queue->vqueue) {
-+ spin_lock_irqsave(&queue->lock, flags);
-+ virtqueue_disable_cb(queue->vqueue);
-+ while ((event = virtqueue_get_buf(queue->vqueue, &length)))
-+ virtsnd_event_dispatch(snd, event);
-+ spin_unlock_irqrestore(&queue->lock, flags);
-+ }
-+}
-+
-+/**
-+ * virtsnd_build_devs() - Read configuration and build ALSA devices.
-+ * @snd: VirtIO sound device.
-+ *
-+ * Context: Any context that permits to sleep.
-+ * Return: 0 on success, -errno on failure.
-+ */
-+static int virtsnd_build_devs(struct virtio_snd *snd)
-+{
-+ struct virtio_device *vdev = snd->vdev;
-+ struct device *dev = &vdev->dev;
-+ int rc;
-+
-+ rc = snd_card_new(dev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
-+ THIS_MODULE, 0, &snd->card);
-+ if (rc < 0)
-+ return rc;
-+
-+ snd->card->private_data = snd;
-+
-+ strscpy(snd->card->driver, VIRTIO_SND_CARD_DRIVER,
-+ sizeof(snd->card->driver));
-+ strscpy(snd->card->shortname, VIRTIO_SND_CARD_NAME,
-+ sizeof(snd->card->shortname));
-+ if (dev->parent->bus)
-+ snprintf(snd->card->longname, sizeof(snd->card->longname),
-+ VIRTIO_SND_CARD_NAME " at %s/%s/%s",
-+ dev->parent->bus->name, dev_name(dev->parent),
-+ dev_name(dev));
-+ else
-+ snprintf(snd->card->longname, sizeof(snd->card->longname),
-+ VIRTIO_SND_CARD_NAME " at %s/%s",
-+ dev_name(dev->parent), dev_name(dev));
-+
-+ return snd_card_register(snd->card);
-+}
-+
-+/**
-+ * virtsnd_validate() - Validate if the device can be started.
-+ * @vdev: VirtIO parent device.
-+ *
-+ * Context: Any context.
-+ * Return: 0 on success, -EINVAL on failure.
-+ */
-+static int virtsnd_validate(struct virtio_device *vdev)
-+{
-+ if (!vdev->config->get) {
-+ dev_err(&vdev->dev, "configuration access disabled\n");
-+ return -EINVAL;
-+ }
-+
-+ if (!virtio_has_feature(vdev, VIRTIO_F_VERSION_1)) {
-+ dev_err(&vdev->dev,
-+ "device does not comply with spec version 1.x\n");
-+ return -EINVAL;
-+ }
-+
-+ return 0;
-+}
-+
-+/**
-+ * virtsnd_probe() - Create and initialize the device.
-+ * @vdev: VirtIO parent device.
-+ *
-+ * Context: Any context that permits to sleep.
-+ * Return: 0 on success, -errno on failure.
-+ */
-+static int virtsnd_probe(struct virtio_device *vdev)
-+{
-+ struct virtio_snd *snd;
-+ unsigned int i;
-+ int rc;
-+
-+ snd = devm_kzalloc(&vdev->dev, sizeof(*snd), GFP_KERNEL);
-+ if (!snd)
-+ return -ENOMEM;
-+
-+ snd->vdev = vdev;
-+
-+ vdev->priv = snd;
-+
-+ for (i = 0; i < VIRTIO_SND_VQ_MAX; ++i)
-+ spin_lock_init(&snd->queues[i].lock);
-+
-+ rc = virtsnd_find_vqs(snd);
-+ if (rc)
-+ goto on_exit;
-+
-+ virtio_device_ready(vdev);
-+
-+ rc = virtsnd_build_devs(snd);
-+ if (rc)
-+ goto on_exit;
-+
-+ virtsnd_enable_event_vq(snd);
-+
-+on_exit:
-+ if (rc)
-+ virtsnd_remove(vdev);
-+
-+ return rc;
-+}
-+
-+/**
-+ * virtsnd_remove() - Remove VirtIO and ALSA devices.
-+ * @vdev: VirtIO parent device.
-+ *
-+ * Context: Any context that permits to sleep.
-+ */
-+static void virtsnd_remove(struct virtio_device *vdev)
-+{
-+ struct virtio_snd *snd = vdev->priv;
-+
-+ virtsnd_disable_event_vq(snd);
-+
-+ if (snd->card)
-+ snd_card_free(snd->card);
-+
-+ vdev->config->del_vqs(vdev);
-+ vdev->config->reset(vdev);
-+
-+ kfree(snd->event_msgs);
-+}
-+
-+static const struct virtio_device_id id_table[] = {
-+ { VIRTIO_ID_SOUND, VIRTIO_DEV_ANY_ID },
-+ { 0 },
-+};
-+
-+static struct virtio_driver virtsnd_driver = {
-+ .driver.name = KBUILD_MODNAME,
-+ .driver.owner = THIS_MODULE,
-+ .id_table = id_table,
-+ .validate = virtsnd_validate,
-+ .probe = virtsnd_probe,
-+ .remove = virtsnd_remove,
-+};
-+
-+static int __init init(void)
-+{
-+ return register_virtio_driver(&virtsnd_driver);
-+}
-+module_init(init);
-+
-+static void __exit fini(void)
-+{
-+ unregister_virtio_driver(&virtsnd_driver);
-+}
-+module_exit(fini);
-+
-+MODULE_DEVICE_TABLE(virtio, id_table);
-+MODULE_DESCRIPTION("Virtio sound card driver");
-+MODULE_LICENSE("GPL");
-diff --git a/sound/virtio/virtio_card.h b/sound/virtio/virtio_card.h
-new file mode 100644
-index 000000000000..b903b1b12e90
---- /dev/null
-+++ b/sound/virtio/virtio_card.h
-@@ -0,0 +1,65 @@
-+/* SPDX-License-Identifier: GPL-2.0+ */
-+/*
-+ * virtio-snd: Virtio sound device
-+ * Copyright (C) 2021 OpenSynergy GmbH
-+ */
-+#ifndef VIRTIO_SND_CARD_H
-+#define VIRTIO_SND_CARD_H
-+
-+#include <linux/slab.h>
-+#include <linux/virtio.h>
-+#include <sound/core.h>
-+#include <uapi/linux/virtio_snd.h>
-+
-+#define VIRTIO_SND_CARD_DRIVER "virtio-snd"
-+#define VIRTIO_SND_CARD_NAME "VirtIO SoundCard"
-+
-+/**
-+ * struct virtio_snd_queue - Virtqueue wrapper structure.
-+ * @lock: Used to synchronize access to a virtqueue.
-+ * @vqueue: Underlying virtqueue.
-+ */
-+struct virtio_snd_queue {
-+ spinlock_t lock;
-+ struct virtqueue *vqueue;
-+};
-+
-+/**
-+ * struct virtio_snd - VirtIO sound card device.
-+ * @vdev: Underlying virtio device.
-+ * @queues: Virtqueue wrappers.
-+ * @card: ALSA sound card.
-+ * @event_msgs: Device events.
-+ */
-+struct virtio_snd {
-+ struct virtio_device *vdev;
-+ struct virtio_snd_queue queues[VIRTIO_SND_VQ_MAX];
-+ struct snd_card *card;
-+ struct virtio_snd_event *event_msgs;
-+};
-+
-+static inline struct virtio_snd_queue *
-+virtsnd_control_queue(struct virtio_snd *snd)
-+{
-+ return &snd->queues[VIRTIO_SND_VQ_CONTROL];
-+}
-+
-+static inline struct virtio_snd_queue *
-+virtsnd_event_queue(struct virtio_snd *snd)
-+{
-+ return &snd->queues[VIRTIO_SND_VQ_EVENT];
-+}
-+
-+static inline struct virtio_snd_queue *
-+virtsnd_tx_queue(struct virtio_snd *snd)
-+{
-+ return &snd->queues[VIRTIO_SND_VQ_TX];
-+}
-+
-+static inline struct virtio_snd_queue *
-+virtsnd_rx_queue(struct virtio_snd *snd)
-+{
-+ return &snd->queues[VIRTIO_SND_VQ_RX];
-+}
-+
-+#endif /* VIRTIO_SND_CARD_H */
diff --git a/meta-agl-bsp/virtualization-layer/recipes-kernel/linux/linux-yocto/virtio-kmeta/bsp/virtio/virtio-snd/0003-ALSA-virtio-handling-control-messages.patch b/meta-agl-bsp/virtualization-layer/recipes-kernel/linux/linux-yocto/virtio-kmeta/bsp/virtio/virtio-snd/0003-ALSA-virtio-handling-control-messages.patch
deleted file mode 100644
index 2ee988a4a..000000000
--- a/meta-agl-bsp/virtualization-layer/recipes-kernel/linux/linux-yocto/virtio-kmeta/bsp/virtio/virtio-snd/0003-ALSA-virtio-handling-control-messages.patch
+++ /dev/null
@@ -1,528 +0,0 @@
-From d4c8a3a4b9de5a25b6963f3ae1b8a5cb32081de5 Mon Sep 17 00:00:00 2001
-From: Anton Yakovlev <anton.yakovlev@opensynergy.com>
-Date: Tue, 2 Mar 2021 17:47:03 +0100
-Subject: [PATCH] ALSA: virtio: handling control messages
-
-The control queue can be used by different parts of the driver to send
-commands to the device. Control messages can be either synchronous or
-asynchronous. The lifetime of a message is controlled by a reference
-count.
-
-Introduce a module parameter to set the message completion timeout:
- msg_timeout_ms [=1000]
-
-Signed-off-by: Anton Yakovlev <anton.yakovlev@opensynergy.com>
-Link: https://lore.kernel.org/r/20210302164709.3142702-4-anton.yakovlev@opensynergy.com
-Signed-off-by: Takashi Iwai <tiwai@suse.de>
-Signed-off-by: Vasyl Vavrychuk <vasyl.vavrychuk@opensynergy.com>
----
- sound/virtio/Makefile | 3 +-
- sound/virtio/virtio_card.c | 13 ++
- sound/virtio/virtio_card.h | 7 +
- sound/virtio/virtio_ctl_msg.c | 310 ++++++++++++++++++++++++++++++++++
- sound/virtio/virtio_ctl_msg.h | 78 +++++++++
- 5 files changed, 410 insertions(+), 1 deletion(-)
- create mode 100644 sound/virtio/virtio_ctl_msg.c
- create mode 100644 sound/virtio/virtio_ctl_msg.h
-
-diff --git a/sound/virtio/Makefile b/sound/virtio/Makefile
-index 8c87ebb9982b..dc551e637441 100644
---- a/sound/virtio/Makefile
-+++ b/sound/virtio/Makefile
-@@ -3,5 +3,6 @@
- obj-$(CONFIG_SND_VIRTIO) += virtio_snd.o
-
- virtio_snd-objs := \
-- virtio_card.o
-+ virtio_card.o \
-+ virtio_ctl_msg.o
-
-diff --git a/sound/virtio/virtio_card.c b/sound/virtio/virtio_card.c
-index 5a37056858e9..b757b2444078 100644
---- a/sound/virtio/virtio_card.c
-+++ b/sound/virtio/virtio_card.c
-@@ -11,6 +11,10 @@
-
- #include "virtio_card.h"
-
-+u32 virtsnd_msg_timeout_ms = MSEC_PER_SEC;
-+module_param_named(msg_timeout_ms, virtsnd_msg_timeout_ms, uint, 0644);
-+MODULE_PARM_DESC(msg_timeout_ms, "Message completion timeout in milliseconds");
-+
- static void virtsnd_remove(struct virtio_device *vdev);
-
- /**
-@@ -96,9 +100,11 @@ static int virtsnd_find_vqs(struct virtio_snd *snd)
- {
- struct virtio_device *vdev = snd->vdev;
- static vq_callback_t *callbacks[VIRTIO_SND_VQ_MAX] = {
-+ [VIRTIO_SND_VQ_CONTROL] = virtsnd_ctl_notify_cb,
- [VIRTIO_SND_VQ_EVENT] = virtsnd_event_notify_cb
- };
- static const char *names[VIRTIO_SND_VQ_MAX] = {
-+ [VIRTIO_SND_VQ_CONTROL] = "virtsnd-ctl",
- [VIRTIO_SND_VQ_EVENT] = "virtsnd-event"
- };
- struct virtqueue *vqs[VIRTIO_SND_VQ_MAX] = { 0 };
-@@ -226,6 +232,11 @@ static int virtsnd_validate(struct virtio_device *vdev)
- return -EINVAL;
- }
-
-+ if (!virtsnd_msg_timeout_ms) {
-+ dev_err(&vdev->dev, "msg_timeout_ms value cannot be zero\n");
-+ return -EINVAL;
-+ }
-+
- return 0;
- }
-
-@@ -247,6 +258,7 @@ static int virtsnd_probe(struct virtio_device *vdev)
- return -ENOMEM;
-
- snd->vdev = vdev;
-+ INIT_LIST_HEAD(&snd->ctl_msgs);
-
- vdev->priv = snd;
-
-@@ -283,6 +295,7 @@ static void virtsnd_remove(struct virtio_device *vdev)
- struct virtio_snd *snd = vdev->priv;
-
- virtsnd_disable_event_vq(snd);
-+ virtsnd_ctl_msg_cancel_all(snd);
-
- if (snd->card)
- snd_card_free(snd->card);
-diff --git a/sound/virtio/virtio_card.h b/sound/virtio/virtio_card.h
-index b903b1b12e90..1e76eeff160f 100644
---- a/sound/virtio/virtio_card.h
-+++ b/sound/virtio/virtio_card.h
-@@ -11,6 +11,8 @@
- #include <sound/core.h>
- #include <uapi/linux/virtio_snd.h>
-
-+#include "virtio_ctl_msg.h"
-+
- #define VIRTIO_SND_CARD_DRIVER "virtio-snd"
- #define VIRTIO_SND_CARD_NAME "VirtIO SoundCard"
-
-@@ -29,15 +31,20 @@ struct virtio_snd_queue {
- * @vdev: Underlying virtio device.
- * @queues: Virtqueue wrappers.
- * @card: ALSA sound card.
-+ * @ctl_msgs: Pending control request list.
- * @event_msgs: Device events.
- */
- struct virtio_snd {
- struct virtio_device *vdev;
- struct virtio_snd_queue queues[VIRTIO_SND_VQ_MAX];
- struct snd_card *card;
-+ struct list_head ctl_msgs;
- struct virtio_snd_event *event_msgs;
- };
-
-+/* Message completion timeout in milliseconds (module parameter). */
-+extern u32 virtsnd_msg_timeout_ms;
-+
- static inline struct virtio_snd_queue *
- virtsnd_control_queue(struct virtio_snd *snd)
- {
-diff --git a/sound/virtio/virtio_ctl_msg.c b/sound/virtio/virtio_ctl_msg.c
-new file mode 100644
-index 000000000000..26ff7e7cc041
---- /dev/null
-+++ b/sound/virtio/virtio_ctl_msg.c
-@@ -0,0 +1,310 @@
-+// SPDX-License-Identifier: GPL-2.0+
-+/*
-+ * virtio-snd: Virtio sound device
-+ * Copyright (C) 2021 OpenSynergy GmbH
-+ */
-+#include <linux/moduleparam.h>
-+#include <linux/virtio_config.h>
-+
-+#include "virtio_card.h"
-+
-+/**
-+ * struct virtio_snd_msg - Control message.
-+ * @sg_request: Scattergather list containing a device request (header).
-+ * @sg_response: Scattergather list containing a device response (status).
-+ * @list: Pending message list entry.
-+ * @notify: Request completed notification.
-+ * @ref_count: Reference count used to manage a message lifetime.
-+ */
-+struct virtio_snd_msg {
-+ struct scatterlist sg_request;
-+ struct scatterlist sg_response;
-+ struct list_head list;
-+ struct completion notify;
-+ refcount_t ref_count;
-+};
-+
-+/**
-+ * virtsnd_ctl_msg_ref() - Increment reference counter for the message.
-+ * @msg: Control message.
-+ *
-+ * Context: Any context.
-+ */
-+void virtsnd_ctl_msg_ref(struct virtio_snd_msg *msg)
-+{
-+ refcount_inc(&msg->ref_count);
-+}
-+
-+/**
-+ * virtsnd_ctl_msg_unref() - Decrement reference counter for the message.
-+ * @msg: Control message.
-+ *
-+ * The message will be freed when the ref_count value is 0.
-+ *
-+ * Context: Any context.
-+ */
-+void virtsnd_ctl_msg_unref(struct virtio_snd_msg *msg)
-+{
-+ if (refcount_dec_and_test(&msg->ref_count))
-+ kfree(msg);
-+}
-+
-+/**
-+ * virtsnd_ctl_msg_request() - Get a pointer to the request header.
-+ * @msg: Control message.
-+ *
-+ * Context: Any context.
-+ */
-+void *virtsnd_ctl_msg_request(struct virtio_snd_msg *msg)
-+{
-+ return sg_virt(&msg->sg_request);
-+}
-+
-+/**
-+ * virtsnd_ctl_msg_request() - Get a pointer to the response header.
-+ * @msg: Control message.
-+ *
-+ * Context: Any context.
-+ */
-+void *virtsnd_ctl_msg_response(struct virtio_snd_msg *msg)
-+{
-+ return sg_virt(&msg->sg_response);
-+}
-+
-+/**
-+ * virtsnd_ctl_msg_alloc() - Allocate and initialize a control message.
-+ * @request_size: Size of request header.
-+ * @response_size: Size of response header.
-+ * @gfp: Kernel flags for memory allocation.
-+ *
-+ * The message will be automatically freed when the ref_count value is 0.
-+ *
-+ * Context: Any context. May sleep if @gfp flags permit.
-+ * Return: Allocated message on success, NULL on failure.
-+ */
-+struct virtio_snd_msg *virtsnd_ctl_msg_alloc(size_t request_size,
-+ size_t response_size, gfp_t gfp)
-+{
-+ struct virtio_snd_msg *msg;
-+
-+ if (!request_size || !response_size)
-+ return NULL;
-+
-+ msg = kzalloc(sizeof(*msg) + request_size + response_size, gfp);
-+ if (!msg)
-+ return NULL;
-+
-+ sg_init_one(&msg->sg_request, (u8 *)msg + sizeof(*msg), request_size);
-+ sg_init_one(&msg->sg_response, (u8 *)msg + sizeof(*msg) + request_size,
-+ response_size);
-+
-+ INIT_LIST_HEAD(&msg->list);
-+ init_completion(&msg->notify);
-+ /* This reference is dropped in virtsnd_ctl_msg_complete(). */
-+ refcount_set(&msg->ref_count, 1);
-+
-+ return msg;
-+}
-+
-+/**
-+ * virtsnd_ctl_msg_send() - Send a control message.
-+ * @snd: VirtIO sound device.
-+ * @msg: Control message.
-+ * @out_sgs: Additional sg-list to attach to the request header (may be NULL).
-+ * @in_sgs: Additional sg-list to attach to the response header (may be NULL).
-+ * @nowait: Flag indicating whether to wait for completion.
-+ *
-+ * Context: Any context. Takes and releases the control queue spinlock.
-+ * May sleep if @nowait is false.
-+ * Return: 0 on success, -errno on failure.
-+ */
-+int virtsnd_ctl_msg_send(struct virtio_snd *snd, struct virtio_snd_msg *msg,
-+ struct scatterlist *out_sgs,
-+ struct scatterlist *in_sgs, bool nowait)
-+{
-+ struct virtio_device *vdev = snd->vdev;
-+ struct virtio_snd_queue *queue = virtsnd_control_queue(snd);
-+ unsigned int js = msecs_to_jiffies(virtsnd_msg_timeout_ms);
-+ struct virtio_snd_hdr *request = virtsnd_ctl_msg_request(msg);
-+ struct virtio_snd_hdr *response = virtsnd_ctl_msg_response(msg);
-+ unsigned int nouts = 0;
-+ unsigned int nins = 0;
-+ struct scatterlist *psgs[4];
-+ bool notify = false;
-+ unsigned long flags;
-+ int rc;
-+
-+ virtsnd_ctl_msg_ref(msg);
-+
-+ /* Set the default status in case the message was canceled. */
-+ response->code = cpu_to_le32(VIRTIO_SND_S_IO_ERR);
-+
-+ psgs[nouts++] = &msg->sg_request;
-+ if (out_sgs)
-+ psgs[nouts++] = out_sgs;
-+
-+ psgs[nouts + nins++] = &msg->sg_response;
-+ if (in_sgs)
-+ psgs[nouts + nins++] = in_sgs;
-+
-+ spin_lock_irqsave(&queue->lock, flags);
-+ rc = virtqueue_add_sgs(queue->vqueue, psgs, nouts, nins, msg,
-+ GFP_ATOMIC);
-+ if (!rc) {
-+ notify = virtqueue_kick_prepare(queue->vqueue);
-+
-+ list_add_tail(&msg->list, &snd->ctl_msgs);
-+ }
-+ spin_unlock_irqrestore(&queue->lock, flags);
-+
-+ if (rc) {
-+ dev_err(&vdev->dev, "failed to send control message (0x%08x)\n",
-+ le32_to_cpu(request->code));
-+
-+ /*
-+ * Since in this case virtsnd_ctl_msg_complete() will not be
-+ * called, it is necessary to decrement the reference count.
-+ */
-+ virtsnd_ctl_msg_unref(msg);
-+
-+ goto on_exit;
-+ }
-+
-+ if (notify)
-+ virtqueue_notify(queue->vqueue);
-+
-+ if (nowait)
-+ goto on_exit;
-+
-+ rc = wait_for_completion_interruptible_timeout(&msg->notify, js);
-+ if (rc <= 0) {
-+ if (!rc) {
-+ dev_err(&vdev->dev,
-+ "control message (0x%08x) timeout\n",
-+ le32_to_cpu(request->code));
-+ rc = -ETIMEDOUT;
-+ }
-+
-+ goto on_exit;
-+ }
-+
-+ switch (le32_to_cpu(response->code)) {
-+ case VIRTIO_SND_S_OK:
-+ rc = 0;
-+ break;
-+ case VIRTIO_SND_S_NOT_SUPP:
-+ rc = -EOPNOTSUPP;
-+ break;
-+ case VIRTIO_SND_S_IO_ERR:
-+ rc = -EIO;
-+ break;
-+ default:
-+ rc = -EINVAL;
-+ break;
-+ }
-+
-+on_exit:
-+ virtsnd_ctl_msg_unref(msg);
-+
-+ return rc;
-+}
-+
-+/**
-+ * virtsnd_ctl_msg_complete() - Complete a control message.
-+ * @msg: Control message.
-+ *
-+ * Context: Any context. Expects the control queue spinlock to be held by
-+ * caller.
-+ */
-+void virtsnd_ctl_msg_complete(struct virtio_snd_msg *msg)
-+{
-+ list_del(&msg->list);
-+ complete(&msg->notify);
-+
-+ virtsnd_ctl_msg_unref(msg);
-+}
-+
-+/**
-+ * virtsnd_ctl_msg_cancel_all() - Cancel all pending control messages.
-+ * @snd: VirtIO sound device.
-+ *
-+ * Context: Any context.
-+ */
-+void virtsnd_ctl_msg_cancel_all(struct virtio_snd *snd)
-+{
-+ struct virtio_snd_queue *queue = virtsnd_control_queue(snd);
-+ unsigned long flags;
-+
-+ spin_lock_irqsave(&queue->lock, flags);
-+ while (!list_empty(&snd->ctl_msgs)) {
-+ struct virtio_snd_msg *msg =
-+ list_first_entry(&snd->ctl_msgs, struct virtio_snd_msg,
-+ list);
-+
-+ virtsnd_ctl_msg_complete(msg);
-+ }
-+ spin_unlock_irqrestore(&queue->lock, flags);
-+}
-+
-+/**
-+ * virtsnd_ctl_query_info() - Query the item configuration from the device.
-+ * @snd: VirtIO sound device.
-+ * @command: Control request code (VIRTIO_SND_R_XXX_INFO).
-+ * @start_id: Item start identifier.
-+ * @count: Item count to query.
-+ * @size: Item information size in bytes.
-+ * @info: Buffer for storing item information.
-+ *
-+ * Context: Any context that permits to sleep.
-+ * Return: 0 on success, -errno on failure.
-+ */
-+int virtsnd_ctl_query_info(struct virtio_snd *snd, int command, int start_id,
-+ int count, size_t size, void *info)
-+{
-+ struct virtio_snd_msg *msg;
-+ struct virtio_snd_query_info *query;
-+ struct scatterlist sg;
-+
-+ msg = virtsnd_ctl_msg_alloc(sizeof(*query),
-+ sizeof(struct virtio_snd_hdr), GFP_KERNEL);
-+ if (!msg)
-+ return -ENOMEM;
-+
-+ query = virtsnd_ctl_msg_request(msg);
-+ query->hdr.code = cpu_to_le32(command);
-+ query->start_id = cpu_to_le32(start_id);
-+ query->count = cpu_to_le32(count);
-+ query->size = cpu_to_le32(size);
-+
-+ sg_init_one(&sg, info, count * size);
-+
-+ return virtsnd_ctl_msg_send(snd, msg, NULL, &sg, false);
-+}
-+
-+/**
-+ * virtsnd_ctl_notify_cb() - Process all completed control messages.
-+ * @vqueue: Underlying control virtqueue.
-+ *
-+ * This callback function is called upon a vring interrupt request from the
-+ * device.
-+ *
-+ * Context: Interrupt context. Takes and releases the control queue spinlock.
-+ */
-+void virtsnd_ctl_notify_cb(struct virtqueue *vqueue)
-+{
-+ struct virtio_snd *snd = vqueue->vdev->priv;
-+ struct virtio_snd_queue *queue = virtsnd_control_queue(snd);
-+ struct virtio_snd_msg *msg;
-+ u32 length;
-+ unsigned long flags;
-+
-+ spin_lock_irqsave(&queue->lock, flags);
-+ do {
-+ virtqueue_disable_cb(vqueue);
-+ while ((msg = virtqueue_get_buf(vqueue, &length)))
-+ virtsnd_ctl_msg_complete(msg);
-+ if (unlikely(virtqueue_is_broken(vqueue)))
-+ break;
-+ } while (!virtqueue_enable_cb(vqueue));
-+ spin_unlock_irqrestore(&queue->lock, flags);
-+}
-diff --git a/sound/virtio/virtio_ctl_msg.h b/sound/virtio/virtio_ctl_msg.h
-new file mode 100644
-index 000000000000..7f4db044f28e
---- /dev/null
-+++ b/sound/virtio/virtio_ctl_msg.h
-@@ -0,0 +1,78 @@
-+/* SPDX-License-Identifier: GPL-2.0+ */
-+/*
-+ * virtio-snd: Virtio sound device
-+ * Copyright (C) 2021 OpenSynergy GmbH
-+ */
-+#ifndef VIRTIO_SND_MSG_H
-+#define VIRTIO_SND_MSG_H
-+
-+#include <linux/atomic.h>
-+#include <linux/virtio.h>
-+
-+struct virtio_snd;
-+struct virtio_snd_msg;
-+
-+void virtsnd_ctl_msg_ref(struct virtio_snd_msg *msg);
-+
-+void virtsnd_ctl_msg_unref(struct virtio_snd_msg *msg);
-+
-+void *virtsnd_ctl_msg_request(struct virtio_snd_msg *msg);
-+
-+void *virtsnd_ctl_msg_response(struct virtio_snd_msg *msg);
-+
-+struct virtio_snd_msg *virtsnd_ctl_msg_alloc(size_t request_size,
-+ size_t response_size, gfp_t gfp);
-+
-+int virtsnd_ctl_msg_send(struct virtio_snd *snd, struct virtio_snd_msg *msg,
-+ struct scatterlist *out_sgs,
-+ struct scatterlist *in_sgs, bool nowait);
-+
-+/**
-+ * virtsnd_ctl_msg_send_sync() - Simplified sending of synchronous message.
-+ * @snd: VirtIO sound device.
-+ * @msg: Control message.
-+ *
-+ * After returning from this function, the message will be deleted. If message
-+ * content is still needed, the caller must additionally to
-+ * virtsnd_ctl_msg_ref/unref() it.
-+ *
-+ * The msg_timeout_ms module parameter defines the message completion timeout.
-+ * If the message is not completed within this time, the function will return an
-+ * error.
-+ *
-+ * Context: Any context that permits to sleep.
-+ * Return: 0 on success, -errno on failure.
-+ *
-+ * The return value is a message status code (VIRTIO_SND_S_XXX) converted to an
-+ * appropriate -errno value.
-+ */
-+static inline int virtsnd_ctl_msg_send_sync(struct virtio_snd *snd,
-+ struct virtio_snd_msg *msg)
-+{
-+ return virtsnd_ctl_msg_send(snd, msg, NULL, NULL, false);
-+}
-+
-+/**
-+ * virtsnd_ctl_msg_send_async() - Simplified sending of asynchronous message.
-+ * @snd: VirtIO sound device.
-+ * @msg: Control message.
-+ *
-+ * Context: Any context.
-+ * Return: 0 on success, -errno on failure.
-+ */
-+static inline int virtsnd_ctl_msg_send_async(struct virtio_snd *snd,
-+ struct virtio_snd_msg *msg)
-+{
-+ return virtsnd_ctl_msg_send(snd, msg, NULL, NULL, true);
-+}
-+
-+void virtsnd_ctl_msg_cancel_all(struct virtio_snd *snd);
-+
-+void virtsnd_ctl_msg_complete(struct virtio_snd_msg *msg);
-+
-+int virtsnd_ctl_query_info(struct virtio_snd *snd, int command, int start_id,
-+ int count, size_t size, void *info);
-+
-+void virtsnd_ctl_notify_cb(struct virtqueue *vqueue);
-+
-+#endif /* VIRTIO_SND_MSG_H */
diff --git a/meta-agl-bsp/virtualization-layer/recipes-kernel/linux/linux-yocto/virtio-kmeta/bsp/virtio/virtio-snd/0004-ALSA-virtio-build-PCM-devices-and-substream-hardware.patch b/meta-agl-bsp/virtualization-layer/recipes-kernel/linux/linux-yocto/virtio-kmeta/bsp/virtio/virtio-snd/0004-ALSA-virtio-build-PCM-devices-and-substream-hardware.patch
deleted file mode 100644
index 27ae9a865..000000000
--- a/meta-agl-bsp/virtualization-layer/recipes-kernel/linux/linux-yocto/virtio-kmeta/bsp/virtio/virtio-snd/0004-ALSA-virtio-build-PCM-devices-and-substream-hardware.patch
+++ /dev/null
@@ -1,703 +0,0 @@
-From 12e4e501f9662a02e61acb5966fdceeffb0ff16d Mon Sep 17 00:00:00 2001
-From: Anton Yakovlev <anton.yakovlev@opensynergy.com>
-Date: Tue, 2 Mar 2021 17:47:04 +0100
-Subject: [PATCH] ALSA: virtio: build PCM devices and substream hardware
- descriptors
-
-Like the HDA specification, the virtio sound device specification links
-PCM substreams, jacks and PCM channel maps into functional groups. For
-each discovered group, a PCM device is created, the number of which
-coincides with the group number.
-
-Introduce the module parameters for setting the hardware buffer
-parameters:
- pcm_buffer_ms [=160]
- pcm_periods_min [=2]
- pcm_periods_max [=16]
- pcm_period_ms_min [=10]
- pcm_period_ms_max [=80]
-
-Signed-off-by: Anton Yakovlev <anton.yakovlev@opensynergy.com>
-Link: https://lore.kernel.org/r/20210302164709.3142702-5-anton.yakovlev@opensynergy.com
-Signed-off-by: Takashi Iwai <tiwai@suse.de>
-Signed-off-by: Vasyl Vavrychuk <vasyl.vavrychuk@opensynergy.com>
----
- sound/virtio/Makefile | 3 +-
- sound/virtio/virtio_card.c | 18 ++
- sound/virtio/virtio_card.h | 10 +
- sound/virtio/virtio_pcm.c | 479 +++++++++++++++++++++++++++++++++++++
- sound/virtio/virtio_pcm.h | 72 ++++++
- 5 files changed, 581 insertions(+), 1 deletion(-)
- create mode 100644 sound/virtio/virtio_pcm.c
- create mode 100644 sound/virtio/virtio_pcm.h
-
-diff --git a/sound/virtio/Makefile b/sound/virtio/Makefile
-index dc551e637441..69162a545a41 100644
---- a/sound/virtio/Makefile
-+++ b/sound/virtio/Makefile
-@@ -4,5 +4,6 @@ obj-$(CONFIG_SND_VIRTIO) += virtio_snd.o
-
- virtio_snd-objs := \
- virtio_card.o \
-- virtio_ctl_msg.o
-+ virtio_ctl_msg.o \
-+ virtio_pcm.o
-
-diff --git a/sound/virtio/virtio_card.c b/sound/virtio/virtio_card.c
-index b757b2444078..11c76ee311b7 100644
---- a/sound/virtio/virtio_card.c
-+++ b/sound/virtio/virtio_card.c
-@@ -209,6 +209,16 @@ static int virtsnd_build_devs(struct virtio_snd *snd)
- VIRTIO_SND_CARD_NAME " at %s/%s",
- dev_name(dev->parent), dev_name(dev));
-
-+ rc = virtsnd_pcm_parse_cfg(snd);
-+ if (rc)
-+ return rc;
-+
-+ if (snd->nsubstreams) {
-+ rc = virtsnd_pcm_build_devs(snd);
-+ if (rc)
-+ return rc;
-+ }
-+
- return snd_card_register(snd->card);
- }
-
-@@ -237,6 +247,9 @@ static int virtsnd_validate(struct virtio_device *vdev)
- return -EINVAL;
- }
-
-+ if (virtsnd_pcm_validate(vdev))
-+ return -EINVAL;
-+
- return 0;
- }
-
-@@ -259,6 +272,7 @@ static int virtsnd_probe(struct virtio_device *vdev)
-
- snd->vdev = vdev;
- INIT_LIST_HEAD(&snd->ctl_msgs);
-+ INIT_LIST_HEAD(&snd->pcm_list);
-
- vdev->priv = snd;
-
-@@ -293,6 +307,7 @@ static int virtsnd_probe(struct virtio_device *vdev)
- static void virtsnd_remove(struct virtio_device *vdev)
- {
- struct virtio_snd *snd = vdev->priv;
-+ unsigned int i;
-
- virtsnd_disable_event_vq(snd);
- virtsnd_ctl_msg_cancel_all(snd);
-@@ -303,6 +318,9 @@ static void virtsnd_remove(struct virtio_device *vdev)
- vdev->config->del_vqs(vdev);
- vdev->config->reset(vdev);
-
-+ for (i = 0; snd->substreams && i < snd->nsubstreams; ++i)
-+ cancel_work_sync(&snd->substreams[i].elapsed_period);
-+
- kfree(snd->event_msgs);
- }
-
-diff --git a/sound/virtio/virtio_card.h b/sound/virtio/virtio_card.h
-index 1e76eeff160f..77a1b7255370 100644
---- a/sound/virtio/virtio_card.h
-+++ b/sound/virtio/virtio_card.h
-@@ -12,9 +12,13 @@
- #include <uapi/linux/virtio_snd.h>
-
- #include "virtio_ctl_msg.h"
-+#include "virtio_pcm.h"
-
- #define VIRTIO_SND_CARD_DRIVER "virtio-snd"
- #define VIRTIO_SND_CARD_NAME "VirtIO SoundCard"
-+#define VIRTIO_SND_PCM_NAME "VirtIO PCM"
-+
-+struct virtio_pcm_substream;
-
- /**
- * struct virtio_snd_queue - Virtqueue wrapper structure.
-@@ -33,6 +37,9 @@ struct virtio_snd_queue {
- * @card: ALSA sound card.
- * @ctl_msgs: Pending control request list.
- * @event_msgs: Device events.
-+ * @pcm_list: VirtIO PCM device list.
-+ * @substreams: VirtIO PCM substreams.
-+ * @nsubstreams: Number of PCM substreams.
- */
- struct virtio_snd {
- struct virtio_device *vdev;
-@@ -40,6 +47,9 @@ struct virtio_snd {
- struct snd_card *card;
- struct list_head ctl_msgs;
- struct virtio_snd_event *event_msgs;
-+ struct list_head pcm_list;
-+ struct virtio_pcm_substream *substreams;
-+ u32 nsubstreams;
- };
-
- /* Message completion timeout in milliseconds (module parameter). */
-diff --git a/sound/virtio/virtio_pcm.c b/sound/virtio/virtio_pcm.c
-new file mode 100644
-index 000000000000..e16567e2e214
---- /dev/null
-+++ b/sound/virtio/virtio_pcm.c
-@@ -0,0 +1,479 @@
-+// SPDX-License-Identifier: GPL-2.0+
-+/*
-+ * virtio-snd: Virtio sound device
-+ * Copyright (C) 2021 OpenSynergy GmbH
-+ */
-+#include <linux/moduleparam.h>
-+#include <linux/virtio_config.h>
-+
-+#include "virtio_card.h"
-+
-+static u32 pcm_buffer_ms = 160;
-+module_param(pcm_buffer_ms, uint, 0644);
-+MODULE_PARM_DESC(pcm_buffer_ms, "PCM substream buffer time in milliseconds");
-+
-+static u32 pcm_periods_min = 2;
-+module_param(pcm_periods_min, uint, 0644);
-+MODULE_PARM_DESC(pcm_periods_min, "Minimum number of PCM periods");
-+
-+static u32 pcm_periods_max = 16;
-+module_param(pcm_periods_max, uint, 0644);
-+MODULE_PARM_DESC(pcm_periods_max, "Maximum number of PCM periods");
-+
-+static u32 pcm_period_ms_min = 10;
-+module_param(pcm_period_ms_min, uint, 0644);
-+MODULE_PARM_DESC(pcm_period_ms_min, "Minimum PCM period time in milliseconds");
-+
-+static u32 pcm_period_ms_max = 80;
-+module_param(pcm_period_ms_max, uint, 0644);
-+MODULE_PARM_DESC(pcm_period_ms_max, "Maximum PCM period time in milliseconds");
-+
-+/* Map for converting VirtIO format to ALSA format. */
-+static const snd_pcm_format_t g_v2a_format_map[] = {
-+ [VIRTIO_SND_PCM_FMT_IMA_ADPCM] = SNDRV_PCM_FORMAT_IMA_ADPCM,
-+ [VIRTIO_SND_PCM_FMT_MU_LAW] = SNDRV_PCM_FORMAT_MU_LAW,
-+ [VIRTIO_SND_PCM_FMT_A_LAW] = SNDRV_PCM_FORMAT_A_LAW,
-+ [VIRTIO_SND_PCM_FMT_S8] = SNDRV_PCM_FORMAT_S8,
-+ [VIRTIO_SND_PCM_FMT_U8] = SNDRV_PCM_FORMAT_U8,
-+ [VIRTIO_SND_PCM_FMT_S16] = SNDRV_PCM_FORMAT_S16_LE,
-+ [VIRTIO_SND_PCM_FMT_U16] = SNDRV_PCM_FORMAT_U16_LE,
-+ [VIRTIO_SND_PCM_FMT_S18_3] = SNDRV_PCM_FORMAT_S18_3LE,
-+ [VIRTIO_SND_PCM_FMT_U18_3] = SNDRV_PCM_FORMAT_U18_3LE,
-+ [VIRTIO_SND_PCM_FMT_S20_3] = SNDRV_PCM_FORMAT_S20_3LE,
-+ [VIRTIO_SND_PCM_FMT_U20_3] = SNDRV_PCM_FORMAT_U20_3LE,
-+ [VIRTIO_SND_PCM_FMT_S24_3] = SNDRV_PCM_FORMAT_S24_3LE,
-+ [VIRTIO_SND_PCM_FMT_U24_3] = SNDRV_PCM_FORMAT_U24_3LE,
-+ [VIRTIO_SND_PCM_FMT_S20] = SNDRV_PCM_FORMAT_S20_LE,
-+ [VIRTIO_SND_PCM_FMT_U20] = SNDRV_PCM_FORMAT_U20_LE,
-+ [VIRTIO_SND_PCM_FMT_S24] = SNDRV_PCM_FORMAT_S24_LE,
-+ [VIRTIO_SND_PCM_FMT_U24] = SNDRV_PCM_FORMAT_U24_LE,
-+ [VIRTIO_SND_PCM_FMT_S32] = SNDRV_PCM_FORMAT_S32_LE,
-+ [VIRTIO_SND_PCM_FMT_U32] = SNDRV_PCM_FORMAT_U32_LE,
-+ [VIRTIO_SND_PCM_FMT_FLOAT] = SNDRV_PCM_FORMAT_FLOAT_LE,
-+ [VIRTIO_SND_PCM_FMT_FLOAT64] = SNDRV_PCM_FORMAT_FLOAT64_LE,
-+ [VIRTIO_SND_PCM_FMT_DSD_U8] = SNDRV_PCM_FORMAT_DSD_U8,
-+ [VIRTIO_SND_PCM_FMT_DSD_U16] = SNDRV_PCM_FORMAT_DSD_U16_LE,
-+ [VIRTIO_SND_PCM_FMT_DSD_U32] = SNDRV_PCM_FORMAT_DSD_U32_LE,
-+ [VIRTIO_SND_PCM_FMT_IEC958_SUBFRAME] =
-+ SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE
-+};
-+
-+/* Map for converting VirtIO frame rate to ALSA frame rate. */
-+struct virtsnd_v2a_rate {
-+ unsigned int alsa_bit;
-+ unsigned int rate;
-+};
-+
-+static const struct virtsnd_v2a_rate g_v2a_rate_map[] = {
-+ [VIRTIO_SND_PCM_RATE_5512] = { SNDRV_PCM_RATE_5512, 5512 },
-+ [VIRTIO_SND_PCM_RATE_8000] = { SNDRV_PCM_RATE_8000, 8000 },
-+ [VIRTIO_SND_PCM_RATE_11025] = { SNDRV_PCM_RATE_11025, 11025 },
-+ [VIRTIO_SND_PCM_RATE_16000] = { SNDRV_PCM_RATE_16000, 16000 },
-+ [VIRTIO_SND_PCM_RATE_22050] = { SNDRV_PCM_RATE_22050, 22050 },
-+ [VIRTIO_SND_PCM_RATE_32000] = { SNDRV_PCM_RATE_32000, 32000 },
-+ [VIRTIO_SND_PCM_RATE_44100] = { SNDRV_PCM_RATE_44100, 44100 },
-+ [VIRTIO_SND_PCM_RATE_48000] = { SNDRV_PCM_RATE_48000, 48000 },
-+ [VIRTIO_SND_PCM_RATE_64000] = { SNDRV_PCM_RATE_64000, 64000 },
-+ [VIRTIO_SND_PCM_RATE_88200] = { SNDRV_PCM_RATE_88200, 88200 },
-+ [VIRTIO_SND_PCM_RATE_96000] = { SNDRV_PCM_RATE_96000, 96000 },
-+ [VIRTIO_SND_PCM_RATE_176400] = { SNDRV_PCM_RATE_176400, 176400 },
-+ [VIRTIO_SND_PCM_RATE_192000] = { SNDRV_PCM_RATE_192000, 192000 }
-+};
-+
-+/**
-+ * virtsnd_pcm_build_hw() - Parse substream config and build HW descriptor.
-+ * @vss: VirtIO substream.
-+ * @info: VirtIO substream information entry.
-+ *
-+ * Context: Any context.
-+ * Return: 0 on success, -EINVAL if configuration is invalid.
-+ */
-+static int virtsnd_pcm_build_hw(struct virtio_pcm_substream *vss,
-+ struct virtio_snd_pcm_info *info)
-+{
-+ struct virtio_device *vdev = vss->snd->vdev;
-+ unsigned int i;
-+ u64 values;
-+ size_t sample_max = 0;
-+ size_t sample_min = 0;
-+
-+ vss->features = le32_to_cpu(info->features);
-+
-+ /*
-+ * TODO: set SNDRV_PCM_INFO_{BATCH,BLOCK_TRANSFER} if device supports
-+ * only message-based transport.
-+ */
-+ vss->hw.info =
-+ SNDRV_PCM_INFO_MMAP |
-+ SNDRV_PCM_INFO_MMAP_VALID |
-+ SNDRV_PCM_INFO_BATCH |
-+ SNDRV_PCM_INFO_BLOCK_TRANSFER |
-+ SNDRV_PCM_INFO_INTERLEAVED |
-+ SNDRV_PCM_INFO_PAUSE;
-+
-+ if (!info->channels_min || info->channels_min > info->channels_max) {
-+ dev_err(&vdev->dev,
-+ "SID %u: invalid channel range [%u %u]\n",
-+ vss->sid, info->channels_min, info->channels_max);
-+ return -EINVAL;
-+ }
-+
-+ vss->hw.channels_min = info->channels_min;
-+ vss->hw.channels_max = info->channels_max;
-+
-+ values = le64_to_cpu(info->formats);
-+
-+ vss->hw.formats = 0;
-+
-+ for (i = 0; i < ARRAY_SIZE(g_v2a_format_map); ++i)
-+ if (values & (1ULL << i)) {
-+ snd_pcm_format_t alsa_fmt = g_v2a_format_map[i];
-+ int bytes = snd_pcm_format_physical_width(alsa_fmt) / 8;
-+
-+ if (!sample_min || sample_min > bytes)
-+ sample_min = bytes;
-+
-+ if (sample_max < bytes)
-+ sample_max = bytes;
-+
-+ vss->hw.formats |= pcm_format_to_bits(alsa_fmt);
-+ }
-+
-+ if (!vss->hw.formats) {
-+ dev_err(&vdev->dev,
-+ "SID %u: no supported PCM sample formats found\n",
-+ vss->sid);
-+ return -EINVAL;
-+ }
-+
-+ values = le64_to_cpu(info->rates);
-+
-+ vss->hw.rates = 0;
-+
-+ for (i = 0; i < ARRAY_SIZE(g_v2a_rate_map); ++i)
-+ if (values & (1ULL << i)) {
-+ if (!vss->hw.rate_min ||
-+ vss->hw.rate_min > g_v2a_rate_map[i].rate)
-+ vss->hw.rate_min = g_v2a_rate_map[i].rate;
-+
-+ if (vss->hw.rate_max < g_v2a_rate_map[i].rate)
-+ vss->hw.rate_max = g_v2a_rate_map[i].rate;
-+
-+ vss->hw.rates |= g_v2a_rate_map[i].alsa_bit;
-+ }
-+
-+ if (!vss->hw.rates) {
-+ dev_err(&vdev->dev,
-+ "SID %u: no supported PCM frame rates found\n",
-+ vss->sid);
-+ return -EINVAL;
-+ }
-+
-+ vss->hw.periods_min = pcm_periods_min;
-+ vss->hw.periods_max = pcm_periods_max;
-+
-+ /*
-+ * We must ensure that there is enough space in the buffer to store
-+ * pcm_buffer_ms ms for the combination (Cmax, Smax, Rmax), where:
-+ * Cmax = maximum supported number of channels,
-+ * Smax = maximum supported sample size in bytes,
-+ * Rmax = maximum supported frame rate.
-+ */
-+ vss->hw.buffer_bytes_max =
-+ PAGE_ALIGN(sample_max * vss->hw.channels_max * pcm_buffer_ms *
-+ (vss->hw.rate_max / MSEC_PER_SEC));
-+
-+ /*
-+ * We must ensure that the minimum period size is enough to store
-+ * pcm_period_ms_min ms for the combination (Cmin, Smin, Rmin), where:
-+ * Cmin = minimum supported number of channels,
-+ * Smin = minimum supported sample size in bytes,
-+ * Rmin = minimum supported frame rate.
-+ */
-+ vss->hw.period_bytes_min =
-+ sample_min * vss->hw.channels_min * pcm_period_ms_min *
-+ (vss->hw.rate_min / MSEC_PER_SEC);
-+
-+ /*
-+ * We must ensure that the maximum period size is enough to store
-+ * pcm_period_ms_max ms for the combination (Cmax, Smax, Rmax).
-+ */
-+ vss->hw.period_bytes_max =
-+ sample_max * vss->hw.channels_max * pcm_period_ms_max *
-+ (vss->hw.rate_max / MSEC_PER_SEC);
-+
-+ return 0;
-+}
-+
-+/**
-+ * virtsnd_pcm_find() - Find the PCM device for the specified node ID.
-+ * @snd: VirtIO sound device.
-+ * @nid: Function node ID.
-+ *
-+ * Context: Any context.
-+ * Return: a pointer to the PCM device or ERR_PTR(-ENOENT).
-+ */
-+struct virtio_pcm *virtsnd_pcm_find(struct virtio_snd *snd, u32 nid)
-+{
-+ struct virtio_pcm *vpcm;
-+
-+ list_for_each_entry(vpcm, &snd->pcm_list, list)
-+ if (vpcm->nid == nid)
-+ return vpcm;
-+
-+ return ERR_PTR(-ENOENT);
-+}
-+
-+/**
-+ * virtsnd_pcm_find_or_create() - Find or create the PCM device for the
-+ * specified node ID.
-+ * @snd: VirtIO sound device.
-+ * @nid: Function node ID.
-+ *
-+ * Context: Any context that permits to sleep.
-+ * Return: a pointer to the PCM device or ERR_PTR(-errno).
-+ */
-+struct virtio_pcm *virtsnd_pcm_find_or_create(struct virtio_snd *snd, u32 nid)
-+{
-+ struct virtio_device *vdev = snd->vdev;
-+ struct virtio_pcm *vpcm;
-+
-+ vpcm = virtsnd_pcm_find(snd, nid);
-+ if (!IS_ERR(vpcm))
-+ return vpcm;
-+
-+ vpcm = devm_kzalloc(&vdev->dev, sizeof(*vpcm), GFP_KERNEL);
-+ if (!vpcm)
-+ return ERR_PTR(-ENOMEM);
-+
-+ vpcm->nid = nid;
-+ list_add_tail(&vpcm->list, &snd->pcm_list);
-+
-+ return vpcm;
-+}
-+
-+/**
-+ * virtsnd_pcm_validate() - Validate if the device can be started.
-+ * @vdev: VirtIO parent device.
-+ *
-+ * Context: Any context.
-+ * Return: 0 on success, -EINVAL on failure.
-+ */
-+int virtsnd_pcm_validate(struct virtio_device *vdev)
-+{
-+ if (pcm_periods_min < 2 || pcm_periods_min > pcm_periods_max) {
-+ dev_err(&vdev->dev,
-+ "invalid range [%u %u] of the number of PCM periods\n",
-+ pcm_periods_min, pcm_periods_max);
-+ return -EINVAL;
-+ }
-+
-+ if (!pcm_period_ms_min || pcm_period_ms_min > pcm_period_ms_max) {
-+ dev_err(&vdev->dev,
-+ "invalid range [%u %u] of the size of the PCM period\n",
-+ pcm_period_ms_min, pcm_period_ms_max);
-+ return -EINVAL;
-+ }
-+
-+ if (pcm_buffer_ms < pcm_periods_min * pcm_period_ms_min) {
-+ dev_err(&vdev->dev,
-+ "pcm_buffer_ms(=%u) value cannot be < %u ms\n",
-+ pcm_buffer_ms, pcm_periods_min * pcm_period_ms_min);
-+ return -EINVAL;
-+ }
-+
-+ if (pcm_period_ms_max > pcm_buffer_ms / 2) {
-+ dev_err(&vdev->dev,
-+ "pcm_period_ms_max(=%u) value cannot be > %u ms\n",
-+ pcm_period_ms_max, pcm_buffer_ms / 2);
-+ return -EINVAL;
-+ }
-+
-+ return 0;
-+}
-+
-+/**
-+ * virtsnd_pcm_period_elapsed() - Kernel work function to handle the elapsed
-+ * period state.
-+ * @work: Elapsed period work.
-+ *
-+ * The main purpose of this function is to call snd_pcm_period_elapsed() in
-+ * a process context, not in an interrupt context. This is necessary because PCM
-+ * devices operate in non-atomic mode.
-+ *
-+ * Context: Process context.
-+ */
-+static void virtsnd_pcm_period_elapsed(struct work_struct *work)
-+{
-+ struct virtio_pcm_substream *vss =
-+ container_of(work, struct virtio_pcm_substream, elapsed_period);
-+
-+ snd_pcm_period_elapsed(vss->substream);
-+}
-+
-+/**
-+ * virtsnd_pcm_parse_cfg() - Parse the stream configuration.
-+ * @snd: VirtIO sound device.
-+ *
-+ * This function is called during initial device initialization.
-+ *
-+ * Context: Any context that permits to sleep.
-+ * Return: 0 on success, -errno on failure.
-+ */
-+int virtsnd_pcm_parse_cfg(struct virtio_snd *snd)
-+{
-+ struct virtio_device *vdev = snd->vdev;
-+ struct virtio_snd_pcm_info *info;
-+ u32 i;
-+ int rc;
-+
-+ virtio_cread_le(vdev, struct virtio_snd_config, streams,
-+ &snd->nsubstreams);
-+ if (!snd->nsubstreams)
-+ return 0;
-+
-+ snd->substreams = devm_kcalloc(&vdev->dev, snd->nsubstreams,
-+ sizeof(*snd->substreams), GFP_KERNEL);
-+ if (!snd->substreams)
-+ return -ENOMEM;
-+
-+ info = kcalloc(snd->nsubstreams, sizeof(*info), GFP_KERNEL);
-+ if (!info)
-+ return -ENOMEM;
-+
-+ rc = virtsnd_ctl_query_info(snd, VIRTIO_SND_R_PCM_INFO, 0,
-+ snd->nsubstreams, sizeof(*info), info);
-+ if (rc)
-+ goto on_exit;
-+
-+ for (i = 0; i < snd->nsubstreams; ++i) {
-+ struct virtio_pcm_substream *vss = &snd->substreams[i];
-+ struct virtio_pcm *vpcm;
-+
-+ vss->snd = snd;
-+ vss->sid = i;
-+ INIT_WORK(&vss->elapsed_period, virtsnd_pcm_period_elapsed);
-+
-+ rc = virtsnd_pcm_build_hw(vss, &info[i]);
-+ if (rc)
-+ goto on_exit;
-+
-+ vss->nid = le32_to_cpu(info[i].hdr.hda_fn_nid);
-+
-+ vpcm = virtsnd_pcm_find_or_create(snd, vss->nid);
-+ if (IS_ERR(vpcm)) {
-+ rc = PTR_ERR(vpcm);
-+ goto on_exit;
-+ }
-+
-+ switch (info[i].direction) {
-+ case VIRTIO_SND_D_OUTPUT:
-+ vss->direction = SNDRV_PCM_STREAM_PLAYBACK;
-+ break;
-+ case VIRTIO_SND_D_INPUT:
-+ vss->direction = SNDRV_PCM_STREAM_CAPTURE;
-+ break;
-+ default:
-+ dev_err(&vdev->dev, "SID %u: unknown direction (%u)\n",
-+ vss->sid, info[i].direction);
-+ rc = -EINVAL;
-+ goto on_exit;
-+ }
-+
-+ vpcm->streams[vss->direction].nsubstreams++;
-+ }
-+
-+on_exit:
-+ kfree(info);
-+
-+ return rc;
-+}
-+
-+/**
-+ * virtsnd_pcm_build_devs() - Build ALSA PCM devices.
-+ * @snd: VirtIO sound device.
-+ *
-+ * Context: Any context that permits to sleep.
-+ * Return: 0 on success, -errno on failure.
-+ */
-+int virtsnd_pcm_build_devs(struct virtio_snd *snd)
-+{
-+ struct virtio_device *vdev = snd->vdev;
-+ struct virtio_pcm *vpcm;
-+ u32 i;
-+ int rc;
-+
-+ list_for_each_entry(vpcm, &snd->pcm_list, list) {
-+ unsigned int npbs =
-+ vpcm->streams[SNDRV_PCM_STREAM_PLAYBACK].nsubstreams;
-+ unsigned int ncps =
-+ vpcm->streams[SNDRV_PCM_STREAM_CAPTURE].nsubstreams;
-+
-+ if (!npbs && !ncps)
-+ continue;
-+
-+ rc = snd_pcm_new(snd->card, VIRTIO_SND_CARD_DRIVER, vpcm->nid,
-+ npbs, ncps, &vpcm->pcm);
-+ if (rc) {
-+ dev_err(&vdev->dev, "snd_pcm_new[%u] failed: %d\n",
-+ vpcm->nid, rc);
-+ return rc;
-+ }
-+
-+ vpcm->pcm->info_flags = 0;
-+ vpcm->pcm->dev_class = SNDRV_PCM_CLASS_GENERIC;
-+ vpcm->pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX;
-+ snprintf(vpcm->pcm->name, sizeof(vpcm->pcm->name),
-+ VIRTIO_SND_PCM_NAME " %u", vpcm->pcm->device);
-+ vpcm->pcm->private_data = vpcm;
-+ vpcm->pcm->nonatomic = true;
-+
-+ for (i = 0; i < ARRAY_SIZE(vpcm->streams); ++i) {
-+ struct virtio_pcm_stream *stream = &vpcm->streams[i];
-+
-+ if (!stream->nsubstreams)
-+ continue;
-+
-+ stream->substreams =
-+ devm_kcalloc(&vdev->dev, stream->nsubstreams,
-+ sizeof(*stream->substreams),
-+ GFP_KERNEL);
-+ if (!stream->substreams)
-+ return -ENOMEM;
-+
-+ stream->nsubstreams = 0;
-+ }
-+ }
-+
-+ for (i = 0; i < snd->nsubstreams; ++i) {
-+ struct virtio_pcm_stream *vs;
-+ struct virtio_pcm_substream *vss = &snd->substreams[i];
-+
-+ vpcm = virtsnd_pcm_find(snd, vss->nid);
-+ if (IS_ERR(vpcm))
-+ return PTR_ERR(vpcm);
-+
-+ vs = &vpcm->streams[vss->direction];
-+ vs->substreams[vs->nsubstreams++] = vss;
-+ }
-+
-+ list_for_each_entry(vpcm, &snd->pcm_list, list) {
-+ for (i = 0; i < ARRAY_SIZE(vpcm->streams); ++i) {
-+ struct virtio_pcm_stream *vs = &vpcm->streams[i];
-+ struct snd_pcm_str *ks = &vpcm->pcm->streams[i];
-+ struct snd_pcm_substream *kss;
-+
-+ if (!vs->nsubstreams)
-+ continue;
-+
-+ for (kss = ks->substream; kss; kss = kss->next)
-+ vs->substreams[kss->number]->substream = kss;
-+ }
-+
-+ snd_pcm_set_managed_buffer_all(vpcm->pcm,
-+ SNDRV_DMA_TYPE_VMALLOC, NULL,
-+ 0, 0);
-+ }
-+
-+ return 0;
-+}
-diff --git a/sound/virtio/virtio_pcm.h b/sound/virtio/virtio_pcm.h
-new file mode 100644
-index 000000000000..84f2f3f14f48
---- /dev/null
-+++ b/sound/virtio/virtio_pcm.h
-@@ -0,0 +1,72 @@
-+/* SPDX-License-Identifier: GPL-2.0+ */
-+/*
-+ * virtio-snd: Virtio sound device
-+ * Copyright (C) 2021 OpenSynergy GmbH
-+ */
-+#ifndef VIRTIO_SND_PCM_H
-+#define VIRTIO_SND_PCM_H
-+
-+#include <linux/atomic.h>
-+#include <linux/virtio_config.h>
-+#include <sound/pcm.h>
-+
-+struct virtio_pcm;
-+struct virtio_pcm_msg;
-+
-+/**
-+ * struct virtio_pcm_substream - VirtIO PCM substream.
-+ * @snd: VirtIO sound device.
-+ * @nid: Function group node identifier.
-+ * @sid: Stream identifier.
-+ * @direction: Stream data flow direction (SNDRV_PCM_STREAM_XXX).
-+ * @features: Stream VirtIO feature bit map (1 << VIRTIO_SND_PCM_F_XXX).
-+ * @substream: Kernel ALSA substream.
-+ * @hw: Kernel ALSA substream hardware descriptor.
-+ * @elapsed_period: Kernel work to handle the elapsed period state.
-+ */
-+struct virtio_pcm_substream {
-+ struct virtio_snd *snd;
-+ u32 nid;
-+ u32 sid;
-+ u32 direction;
-+ u32 features;
-+ struct snd_pcm_substream *substream;
-+ struct snd_pcm_hardware hw;
-+ struct work_struct elapsed_period;
-+};
-+
-+/**
-+ * struct virtio_pcm_stream - VirtIO PCM stream.
-+ * @substreams: VirtIO substreams belonging to the stream.
-+ * @nsubstreams: Number of substreams.
-+ */
-+struct virtio_pcm_stream {
-+ struct virtio_pcm_substream **substreams;
-+ u32 nsubstreams;
-+};
-+
-+/**
-+ * struct virtio_pcm - VirtIO PCM device.
-+ * @list: VirtIO PCM list entry.
-+ * @nid: Function group node identifier.
-+ * @pcm: Kernel PCM device.
-+ * @streams: VirtIO PCM streams (playback and capture).
-+ */
-+struct virtio_pcm {
-+ struct list_head list;
-+ u32 nid;
-+ struct snd_pcm *pcm;
-+ struct virtio_pcm_stream streams[SNDRV_PCM_STREAM_LAST + 1];
-+};
-+
-+int virtsnd_pcm_validate(struct virtio_device *vdev);
-+
-+int virtsnd_pcm_parse_cfg(struct virtio_snd *snd);
-+
-+int virtsnd_pcm_build_devs(struct virtio_snd *snd);
-+
-+struct virtio_pcm *virtsnd_pcm_find(struct virtio_snd *snd, u32 nid);
-+
-+struct virtio_pcm *virtsnd_pcm_find_or_create(struct virtio_snd *snd, u32 nid);
-+
-+#endif /* VIRTIO_SND_PCM_H */
diff --git a/meta-agl-bsp/virtualization-layer/recipes-kernel/linux/linux-yocto/virtio-kmeta/bsp/virtio/virtio-snd/0005-ALSA-virtio-handling-control-and-I-O-messages-for-th.patch b/meta-agl-bsp/virtualization-layer/recipes-kernel/linux/linux-yocto/virtio-kmeta/bsp/virtio/virtio-snd/0005-ALSA-virtio-handling-control-and-I-O-messages-for-th.patch
deleted file mode 100644
index 3a63a530b..000000000
--- a/meta-agl-bsp/virtualization-layer/recipes-kernel/linux/linux-yocto/virtio-kmeta/bsp/virtio/virtio-snd/0005-ALSA-virtio-handling-control-and-I-O-messages-for-th.patch
+++ /dev/null
@@ -1,645 +0,0 @@
-From e60175c8c7a51861c6f31af4cf99b95f3da7a59f Mon Sep 17 00:00:00 2001
-From: Anton Yakovlev <anton.yakovlev@opensynergy.com>
-Date: Tue, 2 Mar 2021 17:47:05 +0100
-Subject: [PATCH] ALSA: virtio: handling control and I/O messages for the PCM
- device
-
-The driver implements a message-based transport for I/O substream
-operations. Before the start of the substream, the hardware buffer is
-sliced into I/O messages, the number of which is equal to the current
-number of periods. The size of each message is equal to the current
-size of one period.
-
-I/O messages are organized in an ordered queue. The completion of the
-I/O message indicates an elapsed period (the only exception is the end
-of the stream for the capture substream). Upon completion, the message
-is automatically re-added to the end of the queue.
-
-Signed-off-by: Anton Yakovlev <anton.yakovlev@opensynergy.com>
-Link: https://lore.kernel.org/r/20210302164709.3142702-6-anton.yakovlev@opensynergy.com
-Signed-off-by: Takashi Iwai <tiwai@suse.de>
-Signed-off-by: Vasyl Vavrychuk <vasyl.vavrychuk@opensynergy.com>
----
- sound/virtio/Makefile | 3 +-
- sound/virtio/virtio_card.c | 22 +-
- sound/virtio/virtio_card.h | 9 +
- sound/virtio/virtio_pcm.c | 32 +++
- sound/virtio/virtio_pcm.h | 40 ++++
- sound/virtio/virtio_pcm_msg.c | 414 ++++++++++++++++++++++++++++++++++
- 6 files changed, 515 insertions(+), 5 deletions(-)
- create mode 100644 sound/virtio/virtio_pcm_msg.c
-
-diff --git a/sound/virtio/Makefile b/sound/virtio/Makefile
-index 69162a545a41..626af3cc3ed7 100644
---- a/sound/virtio/Makefile
-+++ b/sound/virtio/Makefile
-@@ -5,5 +5,6 @@ obj-$(CONFIG_SND_VIRTIO) += virtio_snd.o
- virtio_snd-objs := \
- virtio_card.o \
- virtio_ctl_msg.o \
-- virtio_pcm.o
-+ virtio_pcm.o \
-+ virtio_pcm_msg.o
-
-diff --git a/sound/virtio/virtio_card.c b/sound/virtio/virtio_card.c
-index 11c76ee311b7..57b9b7f3a9c0 100644
---- a/sound/virtio/virtio_card.c
-+++ b/sound/virtio/virtio_card.c
-@@ -55,6 +55,12 @@ static void virtsnd_event_send(struct virtqueue *vqueue,
- static void virtsnd_event_dispatch(struct virtio_snd *snd,
- struct virtio_snd_event *event)
- {
-+ switch (le32_to_cpu(event->hdr.code)) {
-+ case VIRTIO_SND_EVT_PCM_PERIOD_ELAPSED:
-+ case VIRTIO_SND_EVT_PCM_XRUN:
-+ virtsnd_pcm_event(snd, event);
-+ break;
-+ }
- }
-
- /**
-@@ -101,11 +107,15 @@ static int virtsnd_find_vqs(struct virtio_snd *snd)
- struct virtio_device *vdev = snd->vdev;
- static vq_callback_t *callbacks[VIRTIO_SND_VQ_MAX] = {
- [VIRTIO_SND_VQ_CONTROL] = virtsnd_ctl_notify_cb,
-- [VIRTIO_SND_VQ_EVENT] = virtsnd_event_notify_cb
-+ [VIRTIO_SND_VQ_EVENT] = virtsnd_event_notify_cb,
-+ [VIRTIO_SND_VQ_TX] = virtsnd_pcm_tx_notify_cb,
-+ [VIRTIO_SND_VQ_RX] = virtsnd_pcm_rx_notify_cb
- };
- static const char *names[VIRTIO_SND_VQ_MAX] = {
- [VIRTIO_SND_VQ_CONTROL] = "virtsnd-ctl",
-- [VIRTIO_SND_VQ_EVENT] = "virtsnd-event"
-+ [VIRTIO_SND_VQ_EVENT] = "virtsnd-event",
-+ [VIRTIO_SND_VQ_TX] = "virtsnd-tx",
-+ [VIRTIO_SND_VQ_RX] = "virtsnd-rx"
- };
- struct virtqueue *vqs[VIRTIO_SND_VQ_MAX] = { 0 };
- unsigned int i;
-@@ -318,8 +328,12 @@ static void virtsnd_remove(struct virtio_device *vdev)
- vdev->config->del_vqs(vdev);
- vdev->config->reset(vdev);
-
-- for (i = 0; snd->substreams && i < snd->nsubstreams; ++i)
-- cancel_work_sync(&snd->substreams[i].elapsed_period);
-+ for (i = 0; snd->substreams && i < snd->nsubstreams; ++i) {
-+ struct virtio_pcm_substream *vss = &snd->substreams[i];
-+
-+ cancel_work_sync(&vss->elapsed_period);
-+ virtsnd_pcm_msg_free(vss);
-+ }
-
- kfree(snd->event_msgs);
- }
-diff --git a/sound/virtio/virtio_card.h b/sound/virtio/virtio_card.h
-index 77a1b7255370..c43f9744d362 100644
---- a/sound/virtio/virtio_card.h
-+++ b/sound/virtio/virtio_card.h
-@@ -79,4 +79,13 @@ virtsnd_rx_queue(struct virtio_snd *snd)
- return &snd->queues[VIRTIO_SND_VQ_RX];
- }
-
-+static inline struct virtio_snd_queue *
-+virtsnd_pcm_queue(struct virtio_pcm_substream *vss)
-+{
-+ if (vss->direction == SNDRV_PCM_STREAM_PLAYBACK)
-+ return virtsnd_tx_queue(vss->snd);
-+ else
-+ return virtsnd_rx_queue(vss->snd);
-+}
-+
- #endif /* VIRTIO_SND_CARD_H */
-diff --git a/sound/virtio/virtio_pcm.c b/sound/virtio/virtio_pcm.c
-index e16567e2e214..2dcd763efa29 100644
---- a/sound/virtio/virtio_pcm.c
-+++ b/sound/virtio/virtio_pcm.c
-@@ -353,6 +353,8 @@ int virtsnd_pcm_parse_cfg(struct virtio_snd *snd)
- vss->snd = snd;
- vss->sid = i;
- INIT_WORK(&vss->elapsed_period, virtsnd_pcm_period_elapsed);
-+ init_waitqueue_head(&vss->msg_empty);
-+ spin_lock_init(&vss->lock);
-
- rc = virtsnd_pcm_build_hw(vss, &info[i]);
- if (rc)
-@@ -477,3 +479,33 @@ int virtsnd_pcm_build_devs(struct virtio_snd *snd)
-
- return 0;
- }
-+
-+/**
-+ * virtsnd_pcm_event() - Handle the PCM device event notification.
-+ * @snd: VirtIO sound device.
-+ * @event: VirtIO sound event.
-+ *
-+ * Context: Interrupt context.
-+ */
-+void virtsnd_pcm_event(struct virtio_snd *snd, struct virtio_snd_event *event)
-+{
-+ struct virtio_pcm_substream *vss;
-+ u32 sid = le32_to_cpu(event->data);
-+
-+ if (sid >= snd->nsubstreams)
-+ return;
-+
-+ vss = &snd->substreams[sid];
-+
-+ switch (le32_to_cpu(event->hdr.code)) {
-+ case VIRTIO_SND_EVT_PCM_PERIOD_ELAPSED:
-+ /* TODO: deal with shmem elapsed period */
-+ break;
-+ case VIRTIO_SND_EVT_PCM_XRUN:
-+ spin_lock(&vss->lock);
-+ if (vss->xfer_enabled)
-+ vss->xfer_xrun = true;
-+ spin_unlock(&vss->lock);
-+ break;
-+ }
-+}
-diff --git a/sound/virtio/virtio_pcm.h b/sound/virtio/virtio_pcm.h
-index 84f2f3f14f48..6722f1139666 100644
---- a/sound/virtio/virtio_pcm.h
-+++ b/sound/virtio/virtio_pcm.h
-@@ -23,6 +23,17 @@ struct virtio_pcm_msg;
- * @substream: Kernel ALSA substream.
- * @hw: Kernel ALSA substream hardware descriptor.
- * @elapsed_period: Kernel work to handle the elapsed period state.
-+ * @lock: Spinlock that protects fields shared by interrupt handlers and
-+ * substream operators.
-+ * @buffer_bytes: Current buffer size in bytes.
-+ * @hw_ptr: Substream hardware pointer value in bytes [0 ... buffer_bytes).
-+ * @xfer_enabled: Data transfer state (0 - off, 1 - on).
-+ * @xfer_xrun: Data underflow/overflow state (0 - no xrun, 1 - xrun).
-+ * @msgs: Allocated I/O messages.
-+ * @nmsgs: Number of allocated I/O messages.
-+ * @msg_last_enqueued: Index of the last I/O message added to the virtqueue.
-+ * @msg_count: Number of pending I/O messages in the virtqueue.
-+ * @msg_empty: Notify when msg_count is zero.
- */
- struct virtio_pcm_substream {
- struct virtio_snd *snd;
-@@ -33,6 +44,16 @@ struct virtio_pcm_substream {
- struct snd_pcm_substream *substream;
- struct snd_pcm_hardware hw;
- struct work_struct elapsed_period;
-+ spinlock_t lock;
-+ size_t buffer_bytes;
-+ size_t hw_ptr;
-+ bool xfer_enabled;
-+ bool xfer_xrun;
-+ struct virtio_pcm_msg **msgs;
-+ unsigned int nmsgs;
-+ int msg_last_enqueued;
-+ unsigned int msg_count;
-+ wait_queue_head_t msg_empty;
- };
-
- /**
-@@ -65,8 +86,27 @@ int virtsnd_pcm_parse_cfg(struct virtio_snd *snd);
-
- int virtsnd_pcm_build_devs(struct virtio_snd *snd);
-
-+void virtsnd_pcm_event(struct virtio_snd *snd, struct virtio_snd_event *event);
-+
-+void virtsnd_pcm_tx_notify_cb(struct virtqueue *vqueue);
-+
-+void virtsnd_pcm_rx_notify_cb(struct virtqueue *vqueue);
-+
- struct virtio_pcm *virtsnd_pcm_find(struct virtio_snd *snd, u32 nid);
-
- struct virtio_pcm *virtsnd_pcm_find_or_create(struct virtio_snd *snd, u32 nid);
-
-+struct virtio_snd_msg *
-+virtsnd_pcm_ctl_msg_alloc(struct virtio_pcm_substream *vss,
-+ unsigned int command, gfp_t gfp);
-+
-+int virtsnd_pcm_msg_alloc(struct virtio_pcm_substream *vss,
-+ unsigned int periods, unsigned int period_bytes);
-+
-+void virtsnd_pcm_msg_free(struct virtio_pcm_substream *vss);
-+
-+int virtsnd_pcm_msg_send(struct virtio_pcm_substream *vss);
-+
-+unsigned int virtsnd_pcm_msg_pending_num(struct virtio_pcm_substream *vss);
-+
- #endif /* VIRTIO_SND_PCM_H */
-diff --git a/sound/virtio/virtio_pcm_msg.c b/sound/virtio/virtio_pcm_msg.c
-new file mode 100644
-index 000000000000..f88c8f29cbd8
---- /dev/null
-+++ b/sound/virtio/virtio_pcm_msg.c
-@@ -0,0 +1,414 @@
-+// SPDX-License-Identifier: GPL-2.0+
-+/*
-+ * virtio-snd: Virtio sound device
-+ * Copyright (C) 2021 OpenSynergy GmbH
-+ */
-+#include <sound/pcm_params.h>
-+
-+#include "virtio_card.h"
-+
-+/**
-+ * struct virtio_pcm_msg - VirtIO I/O message.
-+ * @substream: VirtIO PCM substream.
-+ * @xfer: Request header payload.
-+ * @status: Response header payload.
-+ * @length: Data length in bytes.
-+ * @sgs: Payload scatter-gather table.
-+ */
-+struct virtio_pcm_msg {
-+ struct virtio_pcm_substream *substream;
-+ struct virtio_snd_pcm_xfer xfer;
-+ struct virtio_snd_pcm_status status;
-+ size_t length;
-+ struct scatterlist sgs[0];
-+};
-+
-+/**
-+ * enum pcm_msg_sg_index - Index values for the virtio_pcm_msg->sgs field in
-+ * an I/O message.
-+ * @PCM_MSG_SG_XFER: Element containing a virtio_snd_pcm_xfer structure.
-+ * @PCM_MSG_SG_STATUS: Element containing a virtio_snd_pcm_status structure.
-+ * @PCM_MSG_SG_DATA: The first element containing a data buffer.
-+ */
-+enum pcm_msg_sg_index {
-+ PCM_MSG_SG_XFER = 0,
-+ PCM_MSG_SG_STATUS,
-+ PCM_MSG_SG_DATA
-+};
-+
-+/**
-+ * virtsnd_pcm_sg_num() - Count the number of sg-elements required to represent
-+ * vmalloc'ed buffer.
-+ * @data: Pointer to vmalloc'ed buffer.
-+ * @length: Buffer size.
-+ *
-+ * Context: Any context.
-+ * Return: Number of physically contiguous parts in the @data.
-+ */
-+static int virtsnd_pcm_sg_num(u8 *data, unsigned int length)
-+{
-+ phys_addr_t sg_address;
-+ unsigned int sg_length;
-+ int num = 0;
-+
-+ while (length) {
-+ struct page *pg = vmalloc_to_page(data);
-+ phys_addr_t pg_address = page_to_phys(pg);
-+ size_t pg_length;
-+
-+ pg_length = PAGE_SIZE - offset_in_page(data);
-+ if (pg_length > length)
-+ pg_length = length;
-+
-+ if (!num || sg_address + sg_length != pg_address) {
-+ sg_address = pg_address;
-+ sg_length = pg_length;
-+ num++;
-+ } else {
-+ sg_length += pg_length;
-+ }
-+
-+ data += pg_length;
-+ length -= pg_length;
-+ }
-+
-+ return num;
-+}
-+
-+/**
-+ * virtsnd_pcm_sg_from() - Build sg-list from vmalloc'ed buffer.
-+ * @sgs: Preallocated sg-list to populate.
-+ * @nsgs: The maximum number of elements in the @sgs.
-+ * @data: Pointer to vmalloc'ed buffer.
-+ * @length: Buffer size.
-+ *
-+ * Splits the buffer into physically contiguous parts and makes an sg-list of
-+ * such parts.
-+ *
-+ * Context: Any context.
-+ */
-+static void virtsnd_pcm_sg_from(struct scatterlist *sgs, int nsgs, u8 *data,
-+ unsigned int length)
-+{
-+ int idx = -1;
-+
-+ while (length) {
-+ struct page *pg = vmalloc_to_page(data);
-+ size_t pg_length;
-+
-+ pg_length = PAGE_SIZE - offset_in_page(data);
-+ if (pg_length > length)
-+ pg_length = length;
-+
-+ if (idx == -1 ||
-+ sg_phys(&sgs[idx]) + sgs[idx].length != page_to_phys(pg)) {
-+ if (idx + 1 == nsgs)
-+ break;
-+ sg_set_page(&sgs[++idx], pg, pg_length,
-+ offset_in_page(data));
-+ } else {
-+ sgs[idx].length += pg_length;
-+ }
-+
-+ data += pg_length;
-+ length -= pg_length;
-+ }
-+
-+ sg_mark_end(&sgs[idx]);
-+}
-+
-+/**
-+ * virtsnd_pcm_msg_alloc() - Allocate I/O messages.
-+ * @vss: VirtIO PCM substream.
-+ * @periods: Current number of periods.
-+ * @period_bytes: Current period size in bytes.
-+ *
-+ * The function slices the buffer into @periods parts (each with the size of
-+ * @period_bytes), and creates @periods corresponding I/O messages.
-+ *
-+ * Context: Any context that permits to sleep.
-+ * Return: 0 on success, -ENOMEM on failure.
-+ */
-+int virtsnd_pcm_msg_alloc(struct virtio_pcm_substream *vss,
-+ unsigned int periods, unsigned int period_bytes)
-+{
-+ struct snd_pcm_runtime *runtime = vss->substream->runtime;
-+ unsigned int i;
-+
-+ vss->msgs = kcalloc(periods, sizeof(*vss->msgs), GFP_KERNEL);
-+ if (!vss->msgs)
-+ return -ENOMEM;
-+
-+ vss->nmsgs = periods;
-+
-+ for (i = 0; i < periods; ++i) {
-+ u8 *data = runtime->dma_area + period_bytes * i;
-+ int sg_num = virtsnd_pcm_sg_num(data, period_bytes);
-+ struct virtio_pcm_msg *msg;
-+
-+ msg = kzalloc(sizeof(*msg) + sizeof(*msg->sgs) * (sg_num + 2),
-+ GFP_KERNEL);
-+ if (!msg)
-+ return -ENOMEM;
-+
-+ msg->substream = vss;
-+ sg_init_one(&msg->sgs[PCM_MSG_SG_XFER], &msg->xfer,
-+ sizeof(msg->xfer));
-+ sg_init_one(&msg->sgs[PCM_MSG_SG_STATUS], &msg->status,
-+ sizeof(msg->status));
-+ msg->length = period_bytes;
-+ virtsnd_pcm_sg_from(&msg->sgs[PCM_MSG_SG_DATA], sg_num, data,
-+ period_bytes);
-+
-+ vss->msgs[i] = msg;
-+ }
-+
-+ return 0;
-+}
-+
-+/**
-+ * virtsnd_pcm_msg_free() - Free all allocated I/O messages.
-+ * @vss: VirtIO PCM substream.
-+ *
-+ * Context: Any context.
-+ */
-+void virtsnd_pcm_msg_free(struct virtio_pcm_substream *vss)
-+{
-+ unsigned int i;
-+
-+ for (i = 0; vss->msgs && i < vss->nmsgs; ++i)
-+ kfree(vss->msgs[i]);
-+ kfree(vss->msgs);
-+
-+ vss->msgs = NULL;
-+ vss->nmsgs = 0;
-+}
-+
-+/**
-+ * virtsnd_pcm_msg_send() - Send asynchronous I/O messages.
-+ * @vss: VirtIO PCM substream.
-+ *
-+ * All messages are organized in an ordered circular list. Each time the
-+ * function is called, all currently non-enqueued messages are added to the
-+ * virtqueue. For this, the function keeps track of two values:
-+ *
-+ * msg_last_enqueued = index of the last enqueued message,
-+ * msg_count = # of pending messages in the virtqueue.
-+ *
-+ * Context: Any context. Expects the tx/rx queue and the VirtIO substream
-+ * spinlocks to be held by caller.
-+ * Return: 0 on success, -errno on failure.
-+ */
-+int virtsnd_pcm_msg_send(struct virtio_pcm_substream *vss)
-+{
-+ struct snd_pcm_runtime *runtime = vss->substream->runtime;
-+ struct virtio_snd *snd = vss->snd;
-+ struct virtio_device *vdev = snd->vdev;
-+ struct virtqueue *vqueue = virtsnd_pcm_queue(vss)->vqueue;
-+ int i;
-+ int n;
-+ bool notify = false;
-+
-+ i = (vss->msg_last_enqueued + 1) % runtime->periods;
-+ n = runtime->periods - vss->msg_count;
-+
-+ for (; n; --n, i = (i + 1) % runtime->periods) {
-+ struct virtio_pcm_msg *msg = vss->msgs[i];
-+ struct scatterlist *psgs[] = {
-+ &msg->sgs[PCM_MSG_SG_XFER],
-+ &msg->sgs[PCM_MSG_SG_DATA],
-+ &msg->sgs[PCM_MSG_SG_STATUS]
-+ };
-+ int rc;
-+
-+ msg->xfer.stream_id = cpu_to_le32(vss->sid);
-+ memset(&msg->status, 0, sizeof(msg->status));
-+
-+ if (vss->direction == SNDRV_PCM_STREAM_PLAYBACK)
-+ rc = virtqueue_add_sgs(vqueue, psgs, 2, 1, msg,
-+ GFP_ATOMIC);
-+ else
-+ rc = virtqueue_add_sgs(vqueue, psgs, 1, 2, msg,
-+ GFP_ATOMIC);
-+
-+ if (rc) {
-+ dev_err(&vdev->dev,
-+ "SID %u: failed to send I/O message\n",
-+ vss->sid);
-+ return rc;
-+ }
-+
-+ vss->msg_last_enqueued = i;
-+ vss->msg_count++;
-+ }
-+
-+ if (!(vss->features & (1U << VIRTIO_SND_PCM_F_MSG_POLLING)))
-+ notify = virtqueue_kick_prepare(vqueue);
-+
-+ if (notify)
-+ virtqueue_notify(vqueue);
-+
-+ return 0;
-+}
-+
-+/**
-+ * virtsnd_pcm_msg_pending_num() - Returns the number of pending I/O messages.
-+ * @vss: VirtIO substream.
-+ *
-+ * Context: Any context.
-+ * Return: Number of messages.
-+ */
-+unsigned int virtsnd_pcm_msg_pending_num(struct virtio_pcm_substream *vss)
-+{
-+ unsigned int num;
-+ unsigned long flags;
-+
-+ spin_lock_irqsave(&vss->lock, flags);
-+ num = vss->msg_count;
-+ spin_unlock_irqrestore(&vss->lock, flags);
-+
-+ return num;
-+}
-+
-+/**
-+ * virtsnd_pcm_msg_complete() - Complete an I/O message.
-+ * @msg: I/O message.
-+ * @written_bytes: Number of bytes written to the message.
-+ *
-+ * Completion of the message means the elapsed period. If transmission is
-+ * allowed, then each completed message is immediately placed back at the end
-+ * of the queue.
-+ *
-+ * For the playback substream, @written_bytes is equal to sizeof(msg->status).
-+ *
-+ * For the capture substream, @written_bytes is equal to sizeof(msg->status)
-+ * plus the number of captured bytes.
-+ *
-+ * Context: Interrupt context. Takes and releases the VirtIO substream spinlock.
-+ */
-+static void virtsnd_pcm_msg_complete(struct virtio_pcm_msg *msg,
-+ size_t written_bytes)
-+{
-+ struct virtio_pcm_substream *vss = msg->substream;
-+
-+ /*
-+ * hw_ptr always indicates the buffer position of the first I/O message
-+ * in the virtqueue. Therefore, on each completion of an I/O message,
-+ * the hw_ptr value is unconditionally advanced.
-+ */
-+ spin_lock(&vss->lock);
-+ /*
-+ * If the capture substream returned an incorrect status, then just
-+ * increase the hw_ptr by the message size.
-+ */
-+ if (vss->direction == SNDRV_PCM_STREAM_PLAYBACK ||
-+ written_bytes <= sizeof(msg->status))
-+ vss->hw_ptr += msg->length;
-+ else
-+ vss->hw_ptr += written_bytes - sizeof(msg->status);
-+
-+ if (vss->hw_ptr >= vss->buffer_bytes)
-+ vss->hw_ptr -= vss->buffer_bytes;
-+
-+ vss->xfer_xrun = false;
-+ vss->msg_count--;
-+
-+ if (vss->xfer_enabled) {
-+ struct snd_pcm_runtime *runtime = vss->substream->runtime;
-+
-+ runtime->delay =
-+ bytes_to_frames(runtime,
-+ le32_to_cpu(msg->status.latency_bytes));
-+
-+ schedule_work(&vss->elapsed_period);
-+
-+ virtsnd_pcm_msg_send(vss);
-+ } else if (!vss->msg_count) {
-+ wake_up_all(&vss->msg_empty);
-+ }
-+ spin_unlock(&vss->lock);
-+}
-+
-+/**
-+ * virtsnd_pcm_notify_cb() - Process all completed I/O messages.
-+ * @queue: Underlying tx/rx virtqueue.
-+ *
-+ * Context: Interrupt context. Takes and releases the tx/rx queue spinlock.
-+ */
-+static inline void virtsnd_pcm_notify_cb(struct virtio_snd_queue *queue)
-+{
-+ struct virtio_pcm_msg *msg;
-+ u32 written_bytes;
-+ unsigned long flags;
-+
-+ spin_lock_irqsave(&queue->lock, flags);
-+ do {
-+ virtqueue_disable_cb(queue->vqueue);
-+ while ((msg = virtqueue_get_buf(queue->vqueue, &written_bytes)))
-+ virtsnd_pcm_msg_complete(msg, written_bytes);
-+ if (unlikely(virtqueue_is_broken(queue->vqueue)))
-+ break;
-+ } while (!virtqueue_enable_cb(queue->vqueue));
-+ spin_unlock_irqrestore(&queue->lock, flags);
-+}
-+
-+/**
-+ * virtsnd_pcm_tx_notify_cb() - Process all completed TX messages.
-+ * @vqueue: Underlying tx virtqueue.
-+ *
-+ * Context: Interrupt context.
-+ */
-+void virtsnd_pcm_tx_notify_cb(struct virtqueue *vqueue)
-+{
-+ struct virtio_snd *snd = vqueue->vdev->priv;
-+
-+ virtsnd_pcm_notify_cb(virtsnd_tx_queue(snd));
-+}
-+
-+/**
-+ * virtsnd_pcm_rx_notify_cb() - Process all completed RX messages.
-+ * @vqueue: Underlying rx virtqueue.
-+ *
-+ * Context: Interrupt context.
-+ */
-+void virtsnd_pcm_rx_notify_cb(struct virtqueue *vqueue)
-+{
-+ struct virtio_snd *snd = vqueue->vdev->priv;
-+
-+ virtsnd_pcm_notify_cb(virtsnd_rx_queue(snd));
-+}
-+
-+/**
-+ * virtsnd_pcm_ctl_msg_alloc() - Allocate and initialize the PCM device control
-+ * message for the specified substream.
-+ * @vss: VirtIO PCM substream.
-+ * @command: Control request code (VIRTIO_SND_R_PCM_XXX).
-+ * @gfp: Kernel flags for memory allocation.
-+ *
-+ * Context: Any context. May sleep if @gfp flags permit.
-+ * Return: Allocated message on success, NULL on failure.
-+ */
-+struct virtio_snd_msg *
-+virtsnd_pcm_ctl_msg_alloc(struct virtio_pcm_substream *vss,
-+ unsigned int command, gfp_t gfp)
-+{
-+ size_t request_size = sizeof(struct virtio_snd_pcm_hdr);
-+ size_t response_size = sizeof(struct virtio_snd_hdr);
-+ struct virtio_snd_msg *msg;
-+
-+ switch (command) {
-+ case VIRTIO_SND_R_PCM_SET_PARAMS:
-+ request_size = sizeof(struct virtio_snd_pcm_set_params);
-+ break;
-+ }
-+
-+ msg = virtsnd_ctl_msg_alloc(request_size, response_size, gfp);
-+ if (msg) {
-+ struct virtio_snd_pcm_hdr *hdr = virtsnd_ctl_msg_request(msg);
-+
-+ hdr->hdr.code = cpu_to_le32(command);
-+ hdr->stream_id = cpu_to_le32(vss->sid);
-+ }
-+
-+ return msg;
-+}
diff --git a/meta-agl-bsp/virtualization-layer/recipes-kernel/linux/linux-yocto/virtio-kmeta/bsp/virtio/virtio-snd/0006-ALSA-virtio-PCM-substream-operators.patch b/meta-agl-bsp/virtualization-layer/recipes-kernel/linux/linux-yocto/virtio-kmeta/bsp/virtio/virtio-snd/0006-ALSA-virtio-PCM-substream-operators.patch
deleted file mode 100644
index 9196b34e4..000000000
--- a/meta-agl-bsp/virtualization-layer/recipes-kernel/linux/linux-yocto/virtio-kmeta/bsp/virtio/virtio-snd/0006-ALSA-virtio-PCM-substream-operators.patch
+++ /dev/null
@@ -1,525 +0,0 @@
-From 93c313dc4fc78b077bb0911afe3a77ffa845ad58 Mon Sep 17 00:00:00 2001
-From: Anton Yakovlev <anton.yakovlev@opensynergy.com>
-Date: Tue, 2 Mar 2021 17:47:06 +0100
-Subject: [PATCH] ALSA: virtio: PCM substream operators
-
-Introduce the operators required for the operation of substreams.
-
-Signed-off-by: Anton Yakovlev <anton.yakovlev@opensynergy.com>
-Link: https://lore.kernel.org/r/20210302164709.3142702-7-anton.yakovlev@opensynergy.com
-Signed-off-by: Takashi Iwai <tiwai@suse.de>
-Signed-off-by: Vasyl Vavrychuk <vasyl.vavrychuk@opensynergy.com>
----
- sound/virtio/Makefile | 3 +-
- sound/virtio/virtio_pcm.c | 2 +
- sound/virtio/virtio_pcm.h | 5 +
- sound/virtio/virtio_pcm_ops.c | 445 ++++++++++++++++++++++++++++++++++
- 4 files changed, 454 insertions(+), 1 deletion(-)
- create mode 100644 sound/virtio/virtio_pcm_ops.c
-
-diff --git a/sound/virtio/Makefile b/sound/virtio/Makefile
-index 626af3cc3ed7..34493226793f 100644
---- a/sound/virtio/Makefile
-+++ b/sound/virtio/Makefile
-@@ -6,5 +6,6 @@ virtio_snd-objs := \
- virtio_card.o \
- virtio_ctl_msg.o \
- virtio_pcm.o \
-- virtio_pcm_msg.o
-+ virtio_pcm_msg.o \
-+ virtio_pcm_ops.o
-
-diff --git a/sound/virtio/virtio_pcm.c b/sound/virtio/virtio_pcm.c
-index 2dcd763efa29..c10d91fff2fb 100644
---- a/sound/virtio/virtio_pcm.c
-+++ b/sound/virtio/virtio_pcm.c
-@@ -470,6 +470,8 @@ int virtsnd_pcm_build_devs(struct virtio_snd *snd)
-
- for (kss = ks->substream; kss; kss = kss->next)
- vs->substreams[kss->number]->substream = kss;
-+
-+ snd_pcm_set_ops(vpcm->pcm, i, &virtsnd_pcm_ops);
- }
-
- snd_pcm_set_managed_buffer_all(vpcm->pcm,
-diff --git a/sound/virtio/virtio_pcm.h b/sound/virtio/virtio_pcm.h
-index 6722f1139666..efd0228746cf 100644
---- a/sound/virtio/virtio_pcm.h
-+++ b/sound/virtio/virtio_pcm.h
-@@ -29,6 +29,8 @@ struct virtio_pcm_msg;
- * @hw_ptr: Substream hardware pointer value in bytes [0 ... buffer_bytes).
- * @xfer_enabled: Data transfer state (0 - off, 1 - on).
- * @xfer_xrun: Data underflow/overflow state (0 - no xrun, 1 - xrun).
-+ * @stopped: True if the substream is stopped and must be released on the device
-+ * side.
- * @msgs: Allocated I/O messages.
- * @nmsgs: Number of allocated I/O messages.
- * @msg_last_enqueued: Index of the last I/O message added to the virtqueue.
-@@ -49,6 +51,7 @@ struct virtio_pcm_substream {
- size_t hw_ptr;
- bool xfer_enabled;
- bool xfer_xrun;
-+ bool stopped;
- struct virtio_pcm_msg **msgs;
- unsigned int nmsgs;
- int msg_last_enqueued;
-@@ -80,6 +83,8 @@ struct virtio_pcm {
- struct virtio_pcm_stream streams[SNDRV_PCM_STREAM_LAST + 1];
- };
-
-+extern const struct snd_pcm_ops virtsnd_pcm_ops;
-+
- int virtsnd_pcm_validate(struct virtio_device *vdev);
-
- int virtsnd_pcm_parse_cfg(struct virtio_snd *snd);
-diff --git a/sound/virtio/virtio_pcm_ops.c b/sound/virtio/virtio_pcm_ops.c
-new file mode 100644
-index 000000000000..0682a2df6c8c
---- /dev/null
-+++ b/sound/virtio/virtio_pcm_ops.c
-@@ -0,0 +1,445 @@
-+// SPDX-License-Identifier: GPL-2.0+
-+/*
-+ * virtio-snd: Virtio sound device
-+ * Copyright (C) 2021 OpenSynergy GmbH
-+ */
-+#include <sound/pcm_params.h>
-+
-+#include "virtio_card.h"
-+
-+/*
-+ * I/O messages lifetime
-+ * ---------------------
-+ *
-+ * Allocation:
-+ * Messages are initially allocated in the ops->hw_params() after the size and
-+ * number of periods have been successfully negotiated.
-+ *
-+ * Freeing:
-+ * Messages can be safely freed after the queue has been successfully flushed
-+ * (RELEASE command in the ops->sync_stop()) and the ops->hw_free() has been
-+ * called.
-+ *
-+ * When the substream stops, the ops->sync_stop() waits until the device has
-+ * completed all pending messages. This wait can be interrupted either by a
-+ * signal or due to a timeout. In this case, the device can still access
-+ * messages even after calling ops->hw_free(). It can also issue an interrupt,
-+ * and the interrupt handler will also try to access message structures.
-+ *
-+ * Therefore, freeing of already allocated messages occurs:
-+ *
-+ * - in ops->hw_params(), if this operator was called several times in a row,
-+ * or if ops->hw_free() failed to free messages previously;
-+ *
-+ * - in ops->hw_free(), if the queue has been successfully flushed;
-+ *
-+ * - in dev->release().
-+ */
-+
-+/* Map for converting ALSA format to VirtIO format. */
-+struct virtsnd_a2v_format {
-+ snd_pcm_format_t alsa_bit;
-+ unsigned int vio_bit;
-+};
-+
-+static const struct virtsnd_a2v_format g_a2v_format_map[] = {
-+ { SNDRV_PCM_FORMAT_IMA_ADPCM, VIRTIO_SND_PCM_FMT_IMA_ADPCM },
-+ { SNDRV_PCM_FORMAT_MU_LAW, VIRTIO_SND_PCM_FMT_MU_LAW },
-+ { SNDRV_PCM_FORMAT_A_LAW, VIRTIO_SND_PCM_FMT_A_LAW },
-+ { SNDRV_PCM_FORMAT_S8, VIRTIO_SND_PCM_FMT_S8 },
-+ { SNDRV_PCM_FORMAT_U8, VIRTIO_SND_PCM_FMT_U8 },
-+ { SNDRV_PCM_FORMAT_S16_LE, VIRTIO_SND_PCM_FMT_S16 },
-+ { SNDRV_PCM_FORMAT_U16_LE, VIRTIO_SND_PCM_FMT_U16 },
-+ { SNDRV_PCM_FORMAT_S18_3LE, VIRTIO_SND_PCM_FMT_S18_3 },
-+ { SNDRV_PCM_FORMAT_U18_3LE, VIRTIO_SND_PCM_FMT_U18_3 },
-+ { SNDRV_PCM_FORMAT_S20_3LE, VIRTIO_SND_PCM_FMT_S20_3 },
-+ { SNDRV_PCM_FORMAT_U20_3LE, VIRTIO_SND_PCM_FMT_U20_3 },
-+ { SNDRV_PCM_FORMAT_S24_3LE, VIRTIO_SND_PCM_FMT_S24_3 },
-+ { SNDRV_PCM_FORMAT_U24_3LE, VIRTIO_SND_PCM_FMT_U24_3 },
-+ { SNDRV_PCM_FORMAT_S20_LE, VIRTIO_SND_PCM_FMT_S20 },
-+ { SNDRV_PCM_FORMAT_U20_LE, VIRTIO_SND_PCM_FMT_U20 },
-+ { SNDRV_PCM_FORMAT_S24_LE, VIRTIO_SND_PCM_FMT_S24 },
-+ { SNDRV_PCM_FORMAT_U24_LE, VIRTIO_SND_PCM_FMT_U24 },
-+ { SNDRV_PCM_FORMAT_S32_LE, VIRTIO_SND_PCM_FMT_S32 },
-+ { SNDRV_PCM_FORMAT_U32_LE, VIRTIO_SND_PCM_FMT_U32 },
-+ { SNDRV_PCM_FORMAT_FLOAT_LE, VIRTIO_SND_PCM_FMT_FLOAT },
-+ { SNDRV_PCM_FORMAT_FLOAT64_LE, VIRTIO_SND_PCM_FMT_FLOAT64 },
-+ { SNDRV_PCM_FORMAT_DSD_U8, VIRTIO_SND_PCM_FMT_DSD_U8 },
-+ { SNDRV_PCM_FORMAT_DSD_U16_LE, VIRTIO_SND_PCM_FMT_DSD_U16 },
-+ { SNDRV_PCM_FORMAT_DSD_U32_LE, VIRTIO_SND_PCM_FMT_DSD_U32 },
-+ { SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE,
-+ VIRTIO_SND_PCM_FMT_IEC958_SUBFRAME }
-+};
-+
-+/* Map for converting ALSA frame rate to VirtIO frame rate. */
-+struct virtsnd_a2v_rate {
-+ unsigned int rate;
-+ unsigned int vio_bit;
-+};
-+
-+static const struct virtsnd_a2v_rate g_a2v_rate_map[] = {
-+ { 5512, VIRTIO_SND_PCM_RATE_5512 },
-+ { 8000, VIRTIO_SND_PCM_RATE_8000 },
-+ { 11025, VIRTIO_SND_PCM_RATE_11025 },
-+ { 16000, VIRTIO_SND_PCM_RATE_16000 },
-+ { 22050, VIRTIO_SND_PCM_RATE_22050 },
-+ { 32000, VIRTIO_SND_PCM_RATE_32000 },
-+ { 44100, VIRTIO_SND_PCM_RATE_44100 },
-+ { 48000, VIRTIO_SND_PCM_RATE_48000 },
-+ { 64000, VIRTIO_SND_PCM_RATE_64000 },
-+ { 88200, VIRTIO_SND_PCM_RATE_88200 },
-+ { 96000, VIRTIO_SND_PCM_RATE_96000 },
-+ { 176400, VIRTIO_SND_PCM_RATE_176400 },
-+ { 192000, VIRTIO_SND_PCM_RATE_192000 }
-+};
-+
-+static int virtsnd_pcm_sync_stop(struct snd_pcm_substream *substream);
-+
-+/**
-+ * virtsnd_pcm_open() - Open the PCM substream.
-+ * @substream: Kernel ALSA substream.
-+ *
-+ * Context: Process context.
-+ * Return: 0 on success, -errno on failure.
-+ */
-+static int virtsnd_pcm_open(struct snd_pcm_substream *substream)
-+{
-+ struct virtio_pcm *vpcm = snd_pcm_substream_chip(substream);
-+ struct virtio_pcm_stream *vs = &vpcm->streams[substream->stream];
-+ struct virtio_pcm_substream *vss = vs->substreams[substream->number];
-+
-+ substream->runtime->hw = vss->hw;
-+ substream->private_data = vss;
-+
-+ snd_pcm_hw_constraint_integer(substream->runtime,
-+ SNDRV_PCM_HW_PARAM_PERIODS);
-+
-+ vss->stopped = !!virtsnd_pcm_msg_pending_num(vss);
-+
-+ /*
-+ * If the substream has already been used, then the I/O queue may be in
-+ * an invalid state. Just in case, we do a check and try to return the
-+ * queue to its original state, if necessary.
-+ */
-+ return virtsnd_pcm_sync_stop(substream);
-+}
-+
-+/**
-+ * virtsnd_pcm_close() - Close the PCM substream.
-+ * @substream: Kernel ALSA substream.
-+ *
-+ * Context: Process context.
-+ * Return: 0.
-+ */
-+static int virtsnd_pcm_close(struct snd_pcm_substream *substream)
-+{
-+ return 0;
-+}
-+
-+/**
-+ * virtsnd_pcm_dev_set_params() - Set the parameters of the PCM substream on
-+ * the device side.
-+ * @vss: VirtIO PCM substream.
-+ * @buffer_bytes: Size of the hardware buffer.
-+ * @period_bytes: Size of the hardware period.
-+ * @channels: Selected number of channels.
-+ * @format: Selected sample format (SNDRV_PCM_FORMAT_XXX).
-+ * @rate: Selected frame rate.
-+ *
-+ * Context: Any context that permits to sleep.
-+ * Return: 0 on success, -errno on failure.
-+ */
-+static int virtsnd_pcm_dev_set_params(struct virtio_pcm_substream *vss,
-+ unsigned int buffer_bytes,
-+ unsigned int period_bytes,
-+ unsigned int channels,
-+ snd_pcm_format_t format,
-+ unsigned int rate)
-+{
-+ struct virtio_snd_msg *msg;
-+ struct virtio_snd_pcm_set_params *request;
-+ unsigned int i;
-+ int vformat = -1;
-+ int vrate = -1;
-+
-+ for (i = 0; i < ARRAY_SIZE(g_a2v_format_map); ++i)
-+ if (g_a2v_format_map[i].alsa_bit == format) {
-+ vformat = g_a2v_format_map[i].vio_bit;
-+
-+ break;
-+ }
-+
-+ for (i = 0; i < ARRAY_SIZE(g_a2v_rate_map); ++i)
-+ if (g_a2v_rate_map[i].rate == rate) {
-+ vrate = g_a2v_rate_map[i].vio_bit;
-+
-+ break;
-+ }
-+
-+ if (vformat == -1 || vrate == -1)
-+ return -EINVAL;
-+
-+ msg = virtsnd_pcm_ctl_msg_alloc(vss, VIRTIO_SND_R_PCM_SET_PARAMS,
-+ GFP_KERNEL);
-+ if (!msg)
-+ return -ENOMEM;
-+
-+ request = virtsnd_ctl_msg_request(msg);
-+ request->buffer_bytes = cpu_to_le32(buffer_bytes);
-+ request->period_bytes = cpu_to_le32(period_bytes);
-+ request->channels = channels;
-+ request->format = vformat;
-+ request->rate = vrate;
-+
-+ if (vss->features & (1U << VIRTIO_SND_PCM_F_MSG_POLLING))
-+ request->features |=
-+ cpu_to_le32(1U << VIRTIO_SND_PCM_F_MSG_POLLING);
-+
-+ if (vss->features & (1U << VIRTIO_SND_PCM_F_EVT_XRUNS))
-+ request->features |=
-+ cpu_to_le32(1U << VIRTIO_SND_PCM_F_EVT_XRUNS);
-+
-+ return virtsnd_ctl_msg_send_sync(vss->snd, msg);
-+}
-+
-+/**
-+ * virtsnd_pcm_hw_params() - Set the parameters of the PCM substream.
-+ * @substream: Kernel ALSA substream.
-+ * @hw_params: Hardware parameters.
-+ *
-+ * Context: Process context.
-+ * Return: 0 on success, -errno on failure.
-+ */
-+static int virtsnd_pcm_hw_params(struct snd_pcm_substream *substream,
-+ struct snd_pcm_hw_params *hw_params)
-+{
-+ struct virtio_pcm_substream *vss = snd_pcm_substream_chip(substream);
-+ struct virtio_device *vdev = vss->snd->vdev;
-+ int rc;
-+
-+ if (virtsnd_pcm_msg_pending_num(vss)) {
-+ dev_err(&vdev->dev, "SID %u: invalid I/O queue state\n",
-+ vss->sid);
-+ return -EBADFD;
-+ }
-+
-+ rc = virtsnd_pcm_dev_set_params(vss, params_buffer_bytes(hw_params),
-+ params_period_bytes(hw_params),
-+ params_channels(hw_params),
-+ params_format(hw_params),
-+ params_rate(hw_params));
-+ if (rc)
-+ return rc;
-+
-+ /*
-+ * Free previously allocated messages if ops->hw_params() is called
-+ * several times in a row, or if ops->hw_free() failed to free messages.
-+ */
-+ virtsnd_pcm_msg_free(vss);
-+
-+ return virtsnd_pcm_msg_alloc(vss, params_periods(hw_params),
-+ params_period_bytes(hw_params));
-+}
-+
-+/**
-+ * virtsnd_pcm_hw_free() - Reset the parameters of the PCM substream.
-+ * @substream: Kernel ALSA substream.
-+ *
-+ * Context: Process context.
-+ * Return: 0
-+ */
-+static int virtsnd_pcm_hw_free(struct snd_pcm_substream *substream)
-+{
-+ struct virtio_pcm_substream *vss = snd_pcm_substream_chip(substream);
-+
-+ /* If the queue is flushed, we can safely free the messages here. */
-+ if (!virtsnd_pcm_msg_pending_num(vss))
-+ virtsnd_pcm_msg_free(vss);
-+
-+ return 0;
-+}
-+
-+/**
-+ * virtsnd_pcm_prepare() - Prepare the PCM substream.
-+ * @substream: Kernel ALSA substream.
-+ *
-+ * Context: Process context.
-+ * Return: 0 on success, -errno on failure.
-+ */
-+static int virtsnd_pcm_prepare(struct snd_pcm_substream *substream)
-+{
-+ struct virtio_pcm_substream *vss = snd_pcm_substream_chip(substream);
-+ struct virtio_device *vdev = vss->snd->vdev;
-+ struct virtio_snd_msg *msg;
-+
-+ if (virtsnd_pcm_msg_pending_num(vss)) {
-+ dev_err(&vdev->dev, "SID %u: invalid I/O queue state\n",
-+ vss->sid);
-+ return -EBADFD;
-+ }
-+
-+ vss->buffer_bytes = snd_pcm_lib_buffer_bytes(substream);
-+ vss->hw_ptr = 0;
-+ vss->xfer_xrun = false;
-+ vss->msg_last_enqueued = -1;
-+ vss->msg_count = 0;
-+
-+ msg = virtsnd_pcm_ctl_msg_alloc(vss, VIRTIO_SND_R_PCM_PREPARE,
-+ GFP_KERNEL);
-+ if (!msg)
-+ return -ENOMEM;
-+
-+ return virtsnd_ctl_msg_send_sync(vss->snd, msg);
-+}
-+
-+/**
-+ * virtsnd_pcm_trigger() - Process command for the PCM substream.
-+ * @substream: Kernel ALSA substream.
-+ * @command: Substream command (SNDRV_PCM_TRIGGER_XXX).
-+ *
-+ * Context: Any context. Takes and releases the VirtIO substream spinlock.
-+ * May take and release the tx/rx queue spinlock.
-+ * Return: 0 on success, -errno on failure.
-+ */
-+static int virtsnd_pcm_trigger(struct snd_pcm_substream *substream, int command)
-+{
-+ struct virtio_pcm_substream *vss = snd_pcm_substream_chip(substream);
-+ struct virtio_snd *snd = vss->snd;
-+ struct virtio_snd_queue *queue;
-+ struct virtio_snd_msg *msg;
-+ unsigned long flags;
-+ int rc;
-+
-+ switch (command) {
-+ case SNDRV_PCM_TRIGGER_START:
-+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
-+ queue = virtsnd_pcm_queue(vss);
-+
-+ spin_lock_irqsave(&queue->lock, flags);
-+ spin_lock(&vss->lock);
-+ rc = virtsnd_pcm_msg_send(vss);
-+ if (!rc)
-+ vss->xfer_enabled = true;
-+ spin_unlock(&vss->lock);
-+ spin_unlock_irqrestore(&queue->lock, flags);
-+ if (rc)
-+ return rc;
-+
-+ msg = virtsnd_pcm_ctl_msg_alloc(vss, VIRTIO_SND_R_PCM_START,
-+ GFP_KERNEL);
-+ if (!msg) {
-+ spin_lock_irqsave(&vss->lock, flags);
-+ vss->xfer_enabled = false;
-+ spin_unlock_irqrestore(&vss->lock, flags);
-+
-+ return -ENOMEM;
-+ }
-+
-+ return virtsnd_ctl_msg_send_sync(snd, msg);
-+ case SNDRV_PCM_TRIGGER_STOP:
-+ vss->stopped = true;
-+ fallthrough;
-+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
-+ spin_lock_irqsave(&vss->lock, flags);
-+ vss->xfer_enabled = false;
-+ spin_unlock_irqrestore(&vss->lock, flags);
-+
-+ msg = virtsnd_pcm_ctl_msg_alloc(vss, VIRTIO_SND_R_PCM_STOP,
-+ GFP_KERNEL);
-+ if (!msg)
-+ return -ENOMEM;
-+
-+ return virtsnd_ctl_msg_send_sync(snd, msg);
-+ default:
-+ return -EINVAL;
-+ }
-+}
-+
-+/**
-+ * virtsnd_pcm_sync_stop() - Synchronous PCM substream stop.
-+ * @substream: Kernel ALSA substream.
-+ *
-+ * The function can be called both from the upper level or from the driver
-+ * itself.
-+ *
-+ * Context: Process context. Takes and releases the VirtIO substream spinlock.
-+ * Return: 0 on success, -errno on failure.
-+ */
-+static int virtsnd_pcm_sync_stop(struct snd_pcm_substream *substream)
-+{
-+ struct virtio_pcm_substream *vss = snd_pcm_substream_chip(substream);
-+ struct virtio_snd *snd = vss->snd;
-+ struct virtio_snd_msg *msg;
-+ unsigned int js = msecs_to_jiffies(virtsnd_msg_timeout_ms);
-+ int rc;
-+
-+ cancel_work_sync(&vss->elapsed_period);
-+
-+ if (!vss->stopped)
-+ return 0;
-+
-+ msg = virtsnd_pcm_ctl_msg_alloc(vss, VIRTIO_SND_R_PCM_RELEASE,
-+ GFP_KERNEL);
-+ if (!msg)
-+ return -ENOMEM;
-+
-+ rc = virtsnd_ctl_msg_send_sync(snd, msg);
-+ if (rc)
-+ return rc;
-+
-+ /*
-+ * The spec states that upon receipt of the RELEASE command "the device
-+ * MUST complete all pending I/O messages for the specified stream ID".
-+ * Thus, we consider the absence of I/O messages in the queue as an
-+ * indication that the substream has been released.
-+ */
-+ rc = wait_event_interruptible_timeout(vss->msg_empty,
-+ !virtsnd_pcm_msg_pending_num(vss),
-+ js);
-+ if (rc <= 0) {
-+ dev_warn(&snd->vdev->dev, "SID %u: failed to flush I/O queue\n",
-+ vss->sid);
-+
-+ return !rc ? -ETIMEDOUT : rc;
-+ }
-+
-+ vss->stopped = false;
-+
-+ return 0;
-+}
-+
-+/**
-+ * virtsnd_pcm_pointer() - Get the current hardware position for the PCM
-+ * substream.
-+ * @substream: Kernel ALSA substream.
-+ *
-+ * Context: Any context. Takes and releases the VirtIO substream spinlock.
-+ * Return: Hardware position in frames inside [0 ... buffer_size) range.
-+ */
-+static snd_pcm_uframes_t
-+virtsnd_pcm_pointer(struct snd_pcm_substream *substream)
-+{
-+ struct virtio_pcm_substream *vss = snd_pcm_substream_chip(substream);
-+ snd_pcm_uframes_t hw_ptr = SNDRV_PCM_POS_XRUN;
-+ unsigned long flags;
-+
-+ spin_lock_irqsave(&vss->lock, flags);
-+ if (!vss->xfer_xrun)
-+ hw_ptr = bytes_to_frames(substream->runtime, vss->hw_ptr);
-+ spin_unlock_irqrestore(&vss->lock, flags);
-+
-+ return hw_ptr;
-+}
-+
-+/* PCM substream operators map. */
-+const struct snd_pcm_ops virtsnd_pcm_ops = {
-+ .open = virtsnd_pcm_open,
-+ .close = virtsnd_pcm_close,
-+ .ioctl = snd_pcm_lib_ioctl,
-+ .hw_params = virtsnd_pcm_hw_params,
-+ .hw_free = virtsnd_pcm_hw_free,
-+ .prepare = virtsnd_pcm_prepare,
-+ .trigger = virtsnd_pcm_trigger,
-+ .sync_stop = virtsnd_pcm_sync_stop,
-+ .pointer = virtsnd_pcm_pointer,
-+};
diff --git a/meta-agl-bsp/virtualization-layer/recipes-kernel/linux/linux-yocto/virtio-kmeta/bsp/virtio/virtio-snd/0007-ALSA-virtio-introduce-jack-support.patch b/meta-agl-bsp/virtualization-layer/recipes-kernel/linux/linux-yocto/virtio-kmeta/bsp/virtio/virtio-snd/0007-ALSA-virtio-introduce-jack-support.patch
deleted file mode 100644
index af30421e0..000000000
--- a/meta-agl-bsp/virtualization-layer/recipes-kernel/linux/linux-yocto/virtio-kmeta/bsp/virtio/virtio-snd/0007-ALSA-virtio-introduce-jack-support.patch
+++ /dev/null
@@ -1,351 +0,0 @@
-From 07692f250a96382b38daa2b7e2b96689f64d7a40 Mon Sep 17 00:00:00 2001
-From: Anton Yakovlev <anton.yakovlev@opensynergy.com>
-Date: Tue, 2 Mar 2021 17:47:07 +0100
-Subject: [PATCH] ALSA: virtio: introduce jack support
-
-Enumerate all available jacks and create ALSA controls.
-
-At the moment jacks have a simple implementation and can only be used
-to receive notifications about a plugged in/out device.
-
-Signed-off-by: Anton Yakovlev <anton.yakovlev@opensynergy.com>
-Link: https://lore.kernel.org/r/20210302164709.3142702-8-anton.yakovlev@opensynergy.com
-Signed-off-by: Takashi Iwai <tiwai@suse.de>
-Signed-off-by: Vasyl Vavrychuk <vasyl.vavrychuk@opensynergy.com>
----
- sound/virtio/Makefile | 1 +
- sound/virtio/virtio_card.c | 14 +++
- sound/virtio/virtio_card.h | 12 ++
- sound/virtio/virtio_jack.c | 233 +++++++++++++++++++++++++++++++++++++
- 4 files changed, 260 insertions(+)
- create mode 100644 sound/virtio/virtio_jack.c
-
-diff --git a/sound/virtio/Makefile b/sound/virtio/Makefile
-index 34493226793f..09f485291285 100644
---- a/sound/virtio/Makefile
-+++ b/sound/virtio/Makefile
-@@ -5,6 +5,7 @@ obj-$(CONFIG_SND_VIRTIO) += virtio_snd.o
- virtio_snd-objs := \
- virtio_card.o \
- virtio_ctl_msg.o \
-+ virtio_jack.o \
- virtio_pcm.o \
- virtio_pcm_msg.o \
- virtio_pcm_ops.o
-diff --git a/sound/virtio/virtio_card.c b/sound/virtio/virtio_card.c
-index 57b9b7f3a9c0..89bd66c1256e 100644
---- a/sound/virtio/virtio_card.c
-+++ b/sound/virtio/virtio_card.c
-@@ -56,6 +56,10 @@ static void virtsnd_event_dispatch(struct virtio_snd *snd,
- struct virtio_snd_event *event)
- {
- switch (le32_to_cpu(event->hdr.code)) {
-+ case VIRTIO_SND_EVT_JACK_CONNECTED:
-+ case VIRTIO_SND_EVT_JACK_DISCONNECTED:
-+ virtsnd_jack_event(snd, event);
-+ break;
- case VIRTIO_SND_EVT_PCM_PERIOD_ELAPSED:
- case VIRTIO_SND_EVT_PCM_XRUN:
- virtsnd_pcm_event(snd, event);
-@@ -219,10 +223,20 @@ static int virtsnd_build_devs(struct virtio_snd *snd)
- VIRTIO_SND_CARD_NAME " at %s/%s",
- dev_name(dev->parent), dev_name(dev));
-
-+ rc = virtsnd_jack_parse_cfg(snd);
-+ if (rc)
-+ return rc;
-+
- rc = virtsnd_pcm_parse_cfg(snd);
- if (rc)
- return rc;
-
-+ if (snd->njacks) {
-+ rc = virtsnd_jack_build_devs(snd);
-+ if (rc)
-+ return rc;
-+ }
-+
- if (snd->nsubstreams) {
- rc = virtsnd_pcm_build_devs(snd);
- if (rc)
-diff --git a/sound/virtio/virtio_card.h b/sound/virtio/virtio_card.h
-index c43f9744d362..f154313c79fd 100644
---- a/sound/virtio/virtio_card.h
-+++ b/sound/virtio/virtio_card.h
-@@ -18,6 +18,7 @@
- #define VIRTIO_SND_CARD_NAME "VirtIO SoundCard"
- #define VIRTIO_SND_PCM_NAME "VirtIO PCM"
-
-+struct virtio_jack;
- struct virtio_pcm_substream;
-
- /**
-@@ -38,6 +39,8 @@ struct virtio_snd_queue {
- * @ctl_msgs: Pending control request list.
- * @event_msgs: Device events.
- * @pcm_list: VirtIO PCM device list.
-+ * @jacks: VirtIO jacks.
-+ * @njacks: Number of jacks.
- * @substreams: VirtIO PCM substreams.
- * @nsubstreams: Number of PCM substreams.
- */
-@@ -48,6 +51,8 @@ struct virtio_snd {
- struct list_head ctl_msgs;
- struct virtio_snd_event *event_msgs;
- struct list_head pcm_list;
-+ struct virtio_jack *jacks;
-+ u32 njacks;
- struct virtio_pcm_substream *substreams;
- u32 nsubstreams;
- };
-@@ -88,4 +93,11 @@ virtsnd_pcm_queue(struct virtio_pcm_substream *vss)
- return virtsnd_rx_queue(vss->snd);
- }
-
-+int virtsnd_jack_parse_cfg(struct virtio_snd *snd);
-+
-+int virtsnd_jack_build_devs(struct virtio_snd *snd);
-+
-+void virtsnd_jack_event(struct virtio_snd *snd,
-+ struct virtio_snd_event *event);
-+
- #endif /* VIRTIO_SND_CARD_H */
-diff --git a/sound/virtio/virtio_jack.c b/sound/virtio/virtio_jack.c
-new file mode 100644
-index 000000000000..c69f1dcdcc84
---- /dev/null
-+++ b/sound/virtio/virtio_jack.c
-@@ -0,0 +1,233 @@
-+// SPDX-License-Identifier: GPL-2.0+
-+/*
-+ * virtio-snd: Virtio sound device
-+ * Copyright (C) 2021 OpenSynergy GmbH
-+ */
-+#include <linux/virtio_config.h>
-+#include <sound/jack.h>
-+#include <sound/hda_verbs.h>
-+
-+#include "virtio_card.h"
-+
-+/**
-+ * DOC: Implementation Status
-+ *
-+ * At the moment jacks have a simple implementation and can only be used to
-+ * receive notifications about a plugged in/out device.
-+ *
-+ * VIRTIO_SND_R_JACK_REMAP
-+ * is not supported
-+ */
-+
-+/**
-+ * struct virtio_jack - VirtIO jack.
-+ * @jack: Kernel jack control.
-+ * @nid: Functional group node identifier.
-+ * @features: Jack virtio feature bit map (1 << VIRTIO_SND_JACK_F_XXX).
-+ * @defconf: Pin default configuration value.
-+ * @caps: Pin capabilities value.
-+ * @connected: Current jack connection status.
-+ * @type: Kernel jack type (SND_JACK_XXX).
-+ */
-+struct virtio_jack {
-+ struct snd_jack *jack;
-+ u32 nid;
-+ u32 features;
-+ u32 defconf;
-+ u32 caps;
-+ bool connected;
-+ int type;
-+};
-+
-+/**
-+ * virtsnd_jack_get_label() - Get the name string for the jack.
-+ * @vjack: VirtIO jack.
-+ *
-+ * Returns the jack name based on the default pin configuration value (see HDA
-+ * specification).
-+ *
-+ * Context: Any context.
-+ * Return: Name string.
-+ */
-+static const char *virtsnd_jack_get_label(struct virtio_jack *vjack)
-+{
-+ unsigned int defconf = vjack->defconf;
-+ unsigned int device =
-+ (defconf & AC_DEFCFG_DEVICE) >> AC_DEFCFG_DEVICE_SHIFT;
-+ unsigned int location =
-+ (defconf & AC_DEFCFG_LOCATION) >> AC_DEFCFG_LOCATION_SHIFT;
-+
-+ switch (device) {
-+ case AC_JACK_LINE_OUT:
-+ return "Line Out";
-+ case AC_JACK_SPEAKER:
-+ return "Speaker";
-+ case AC_JACK_HP_OUT:
-+ return "Headphone";
-+ case AC_JACK_CD:
-+ return "CD";
-+ case AC_JACK_SPDIF_OUT:
-+ case AC_JACK_DIG_OTHER_OUT:
-+ if (location == AC_JACK_LOC_HDMI)
-+ return "HDMI Out";
-+ else
-+ return "SPDIF Out";
-+ case AC_JACK_LINE_IN:
-+ return "Line";
-+ case AC_JACK_AUX:
-+ return "Aux";
-+ case AC_JACK_MIC_IN:
-+ return "Mic";
-+ case AC_JACK_SPDIF_IN:
-+ return "SPDIF In";
-+ case AC_JACK_DIG_OTHER_IN:
-+ return "Digital In";
-+ default:
-+ return "Misc";
-+ }
-+}
-+
-+/**
-+ * virtsnd_jack_get_type() - Get the type for the jack.
-+ * @vjack: VirtIO jack.
-+ *
-+ * Returns the jack type based on the default pin configuration value (see HDA
-+ * specification).
-+ *
-+ * Context: Any context.
-+ * Return: SND_JACK_XXX value.
-+ */
-+static int virtsnd_jack_get_type(struct virtio_jack *vjack)
-+{
-+ unsigned int defconf = vjack->defconf;
-+ unsigned int device =
-+ (defconf & AC_DEFCFG_DEVICE) >> AC_DEFCFG_DEVICE_SHIFT;
-+
-+ switch (device) {
-+ case AC_JACK_LINE_OUT:
-+ case AC_JACK_SPEAKER:
-+ return SND_JACK_LINEOUT;
-+ case AC_JACK_HP_OUT:
-+ return SND_JACK_HEADPHONE;
-+ case AC_JACK_SPDIF_OUT:
-+ case AC_JACK_DIG_OTHER_OUT:
-+ return SND_JACK_AVOUT;
-+ case AC_JACK_MIC_IN:
-+ return SND_JACK_MICROPHONE;
-+ default:
-+ return SND_JACK_LINEIN;
-+ }
-+}
-+
-+/**
-+ * virtsnd_jack_parse_cfg() - Parse the jack configuration.
-+ * @snd: VirtIO sound device.
-+ *
-+ * This function is called during initial device initialization.
-+ *
-+ * Context: Any context that permits to sleep.
-+ * Return: 0 on success, -errno on failure.
-+ */
-+int virtsnd_jack_parse_cfg(struct virtio_snd *snd)
-+{
-+ struct virtio_device *vdev = snd->vdev;
-+ struct virtio_snd_jack_info *info;
-+ u32 i;
-+ int rc;
-+
-+ virtio_cread_le(vdev, struct virtio_snd_config, jacks, &snd->njacks);
-+ if (!snd->njacks)
-+ return 0;
-+
-+ snd->jacks = devm_kcalloc(&vdev->dev, snd->njacks, sizeof(*snd->jacks),
-+ GFP_KERNEL);
-+ if (!snd->jacks)
-+ return -ENOMEM;
-+
-+ info = kcalloc(snd->njacks, sizeof(*info), GFP_KERNEL);
-+ if (!info)
-+ return -ENOMEM;
-+
-+ rc = virtsnd_ctl_query_info(snd, VIRTIO_SND_R_JACK_INFO, 0, snd->njacks,
-+ sizeof(*info), info);
-+ if (rc)
-+ goto on_exit;
-+
-+ for (i = 0; i < snd->njacks; ++i) {
-+ struct virtio_jack *vjack = &snd->jacks[i];
-+
-+ vjack->nid = le32_to_cpu(info[i].hdr.hda_fn_nid);
-+ vjack->features = le32_to_cpu(info[i].features);
-+ vjack->defconf = le32_to_cpu(info[i].hda_reg_defconf);
-+ vjack->caps = le32_to_cpu(info[i].hda_reg_caps);
-+ vjack->connected = info[i].connected;
-+ }
-+
-+on_exit:
-+ kfree(info);
-+
-+ return rc;
-+}
-+
-+/**
-+ * virtsnd_jack_build_devs() - Build ALSA controls for jacks.
-+ * @snd: VirtIO sound device.
-+ *
-+ * Context: Any context that permits to sleep.
-+ * Return: 0 on success, -errno on failure.
-+ */
-+int virtsnd_jack_build_devs(struct virtio_snd *snd)
-+{
-+ u32 i;
-+ int rc;
-+
-+ for (i = 0; i < snd->njacks; ++i) {
-+ struct virtio_jack *vjack = &snd->jacks[i];
-+
-+ vjack->type = virtsnd_jack_get_type(vjack);
-+
-+ rc = snd_jack_new(snd->card, virtsnd_jack_get_label(vjack),
-+ vjack->type, &vjack->jack, true, true);
-+ if (rc)
-+ return rc;
-+
-+ if (vjack->jack)
-+ vjack->jack->private_data = vjack;
-+
-+ snd_jack_report(vjack->jack,
-+ vjack->connected ? vjack->type : 0);
-+ }
-+
-+ return 0;
-+}
-+
-+/**
-+ * virtsnd_jack_event() - Handle the jack event notification.
-+ * @snd: VirtIO sound device.
-+ * @event: VirtIO sound event.
-+ *
-+ * Context: Interrupt context.
-+ */
-+void virtsnd_jack_event(struct virtio_snd *snd, struct virtio_snd_event *event)
-+{
-+ u32 jack_id = le32_to_cpu(event->data);
-+ struct virtio_jack *vjack;
-+
-+ if (jack_id >= snd->njacks)
-+ return;
-+
-+ vjack = &snd->jacks[jack_id];
-+
-+ switch (le32_to_cpu(event->hdr.code)) {
-+ case VIRTIO_SND_EVT_JACK_CONNECTED:
-+ vjack->connected = true;
-+ break;
-+ case VIRTIO_SND_EVT_JACK_DISCONNECTED:
-+ vjack->connected = false;
-+ break;
-+ default:
-+ return;
-+ }
-+
-+ snd_jack_report(vjack->jack, vjack->connected ? vjack->type : 0);
-+}
diff --git a/meta-agl-bsp/virtualization-layer/recipes-kernel/linux/linux-yocto/virtio-kmeta/bsp/virtio/virtio-snd/0008-ALSA-virtio-introduce-PCM-channel-map-support.patch b/meta-agl-bsp/virtualization-layer/recipes-kernel/linux/linux-yocto/virtio-kmeta/bsp/virtio/virtio-snd/0008-ALSA-virtio-introduce-PCM-channel-map-support.patch
deleted file mode 100644
index d27ddb435..000000000
--- a/meta-agl-bsp/virtualization-layer/recipes-kernel/linux/linux-yocto/virtio-kmeta/bsp/virtio/virtio-snd/0008-ALSA-virtio-introduce-PCM-channel-map-support.patch
+++ /dev/null
@@ -1,335 +0,0 @@
-From 861932797d59b807b4fcc8a2e12dafbddd5ca4d9 Mon Sep 17 00:00:00 2001
-From: Anton Yakovlev <anton.yakovlev@opensynergy.com>
-Date: Tue, 2 Mar 2021 17:47:08 +0100
-Subject: [PATCH] ALSA: virtio: introduce PCM channel map support
-
-Enumerate all available PCM channel maps and create ALSA controls.
-
-Signed-off-by: Anton Yakovlev <anton.yakovlev@opensynergy.com>
-Link: https://lore.kernel.org/r/20210302164709.3142702-9-anton.yakovlev@opensynergy.com
-Signed-off-by: Takashi Iwai <tiwai@suse.de>
-Signed-off-by: Vasyl Vavrychuk <vasyl.vavrychuk@opensynergy.com>
----
- sound/virtio/Makefile | 1 +
- sound/virtio/virtio_card.c | 10 ++
- sound/virtio/virtio_card.h | 8 ++
- sound/virtio/virtio_chmap.c | 219 ++++++++++++++++++++++++++++++++++++
- sound/virtio/virtio_pcm.h | 4 +
- 5 files changed, 242 insertions(+)
- create mode 100644 sound/virtio/virtio_chmap.c
-
-diff --git a/sound/virtio/Makefile b/sound/virtio/Makefile
-index 09f485291285..2742bddb8874 100644
---- a/sound/virtio/Makefile
-+++ b/sound/virtio/Makefile
-@@ -4,6 +4,7 @@ obj-$(CONFIG_SND_VIRTIO) += virtio_snd.o
-
- virtio_snd-objs := \
- virtio_card.o \
-+ virtio_chmap.o \
- virtio_ctl_msg.o \
- virtio_jack.o \
- virtio_pcm.o \
-diff --git a/sound/virtio/virtio_card.c b/sound/virtio/virtio_card.c
-index 89bd66c1256e..1c03fcc41c3b 100644
---- a/sound/virtio/virtio_card.c
-+++ b/sound/virtio/virtio_card.c
-@@ -231,6 +231,10 @@ static int virtsnd_build_devs(struct virtio_snd *snd)
- if (rc)
- return rc;
-
-+ rc = virtsnd_chmap_parse_cfg(snd);
-+ if (rc)
-+ return rc;
-+
- if (snd->njacks) {
- rc = virtsnd_jack_build_devs(snd);
- if (rc)
-@@ -243,6 +247,12 @@ static int virtsnd_build_devs(struct virtio_snd *snd)
- return rc;
- }
-
-+ if (snd->nchmaps) {
-+ rc = virtsnd_chmap_build_devs(snd);
-+ if (rc)
-+ return rc;
-+ }
-+
- return snd_card_register(snd->card);
- }
-
-diff --git a/sound/virtio/virtio_card.h b/sound/virtio/virtio_card.h
-index f154313c79fd..86ef3941895e 100644
---- a/sound/virtio/virtio_card.h
-+++ b/sound/virtio/virtio_card.h
-@@ -43,6 +43,8 @@ struct virtio_snd_queue {
- * @njacks: Number of jacks.
- * @substreams: VirtIO PCM substreams.
- * @nsubstreams: Number of PCM substreams.
-+ * @chmaps: VirtIO channel maps.
-+ * @nchmaps: Number of channel maps.
- */
- struct virtio_snd {
- struct virtio_device *vdev;
-@@ -55,6 +57,8 @@ struct virtio_snd {
- u32 njacks;
- struct virtio_pcm_substream *substreams;
- u32 nsubstreams;
-+ struct virtio_snd_chmap_info *chmaps;
-+ u32 nchmaps;
- };
-
- /* Message completion timeout in milliseconds (module parameter). */
-@@ -100,4 +104,8 @@ int virtsnd_jack_build_devs(struct virtio_snd *snd);
- void virtsnd_jack_event(struct virtio_snd *snd,
- struct virtio_snd_event *event);
-
-+int virtsnd_chmap_parse_cfg(struct virtio_snd *snd);
-+
-+int virtsnd_chmap_build_devs(struct virtio_snd *snd);
-+
- #endif /* VIRTIO_SND_CARD_H */
-diff --git a/sound/virtio/virtio_chmap.c b/sound/virtio/virtio_chmap.c
-new file mode 100644
-index 000000000000..5bc924933a59
---- /dev/null
-+++ b/sound/virtio/virtio_chmap.c
-@@ -0,0 +1,219 @@
-+// SPDX-License-Identifier: GPL-2.0+
-+/*
-+ * virtio-snd: Virtio sound device
-+ * Copyright (C) 2021 OpenSynergy GmbH
-+ */
-+#include <linux/virtio_config.h>
-+
-+#include "virtio_card.h"
-+
-+/* VirtIO->ALSA channel position map */
-+static const u8 g_v2a_position_map[] = {
-+ [VIRTIO_SND_CHMAP_NONE] = SNDRV_CHMAP_UNKNOWN,
-+ [VIRTIO_SND_CHMAP_NA] = SNDRV_CHMAP_NA,
-+ [VIRTIO_SND_CHMAP_MONO] = SNDRV_CHMAP_MONO,
-+ [VIRTIO_SND_CHMAP_FL] = SNDRV_CHMAP_FL,
-+ [VIRTIO_SND_CHMAP_FR] = SNDRV_CHMAP_FR,
-+ [VIRTIO_SND_CHMAP_RL] = SNDRV_CHMAP_RL,
-+ [VIRTIO_SND_CHMAP_RR] = SNDRV_CHMAP_RR,
-+ [VIRTIO_SND_CHMAP_FC] = SNDRV_CHMAP_FC,
-+ [VIRTIO_SND_CHMAP_LFE] = SNDRV_CHMAP_LFE,
-+ [VIRTIO_SND_CHMAP_SL] = SNDRV_CHMAP_SL,
-+ [VIRTIO_SND_CHMAP_SR] = SNDRV_CHMAP_SR,
-+ [VIRTIO_SND_CHMAP_RC] = SNDRV_CHMAP_RC,
-+ [VIRTIO_SND_CHMAP_FLC] = SNDRV_CHMAP_FLC,
-+ [VIRTIO_SND_CHMAP_FRC] = SNDRV_CHMAP_FRC,
-+ [VIRTIO_SND_CHMAP_RLC] = SNDRV_CHMAP_RLC,
-+ [VIRTIO_SND_CHMAP_RRC] = SNDRV_CHMAP_RRC,
-+ [VIRTIO_SND_CHMAP_FLW] = SNDRV_CHMAP_FLW,
-+ [VIRTIO_SND_CHMAP_FRW] = SNDRV_CHMAP_FRW,
-+ [VIRTIO_SND_CHMAP_FLH] = SNDRV_CHMAP_FLH,
-+ [VIRTIO_SND_CHMAP_FCH] = SNDRV_CHMAP_FCH,
-+ [VIRTIO_SND_CHMAP_FRH] = SNDRV_CHMAP_FRH,
-+ [VIRTIO_SND_CHMAP_TC] = SNDRV_CHMAP_TC,
-+ [VIRTIO_SND_CHMAP_TFL] = SNDRV_CHMAP_TFL,
-+ [VIRTIO_SND_CHMAP_TFR] = SNDRV_CHMAP_TFR,
-+ [VIRTIO_SND_CHMAP_TFC] = SNDRV_CHMAP_TFC,
-+ [VIRTIO_SND_CHMAP_TRL] = SNDRV_CHMAP_TRL,
-+ [VIRTIO_SND_CHMAP_TRR] = SNDRV_CHMAP_TRR,
-+ [VIRTIO_SND_CHMAP_TRC] = SNDRV_CHMAP_TRC,
-+ [VIRTIO_SND_CHMAP_TFLC] = SNDRV_CHMAP_TFLC,
-+ [VIRTIO_SND_CHMAP_TFRC] = SNDRV_CHMAP_TFRC,
-+ [VIRTIO_SND_CHMAP_TSL] = SNDRV_CHMAP_TSL,
-+ [VIRTIO_SND_CHMAP_TSR] = SNDRV_CHMAP_TSR,
-+ [VIRTIO_SND_CHMAP_LLFE] = SNDRV_CHMAP_LLFE,
-+ [VIRTIO_SND_CHMAP_RLFE] = SNDRV_CHMAP_RLFE,
-+ [VIRTIO_SND_CHMAP_BC] = SNDRV_CHMAP_BC,
-+ [VIRTIO_SND_CHMAP_BLC] = SNDRV_CHMAP_BLC,
-+ [VIRTIO_SND_CHMAP_BRC] = SNDRV_CHMAP_BRC
-+};
-+
-+/**
-+ * virtsnd_chmap_parse_cfg() - Parse the channel map configuration.
-+ * @snd: VirtIO sound device.
-+ *
-+ * This function is called during initial device initialization.
-+ *
-+ * Context: Any context that permits to sleep.
-+ * Return: 0 on success, -errno on failure.
-+ */
-+int virtsnd_chmap_parse_cfg(struct virtio_snd *snd)
-+{
-+ struct virtio_device *vdev = snd->vdev;
-+ u32 i;
-+ int rc;
-+
-+ virtio_cread_le(vdev, struct virtio_snd_config, chmaps, &snd->nchmaps);
-+ if (!snd->nchmaps)
-+ return 0;
-+
-+ snd->chmaps = devm_kcalloc(&vdev->dev, snd->nchmaps,
-+ sizeof(*snd->chmaps), GFP_KERNEL);
-+ if (!snd->chmaps)
-+ return -ENOMEM;
-+
-+ rc = virtsnd_ctl_query_info(snd, VIRTIO_SND_R_CHMAP_INFO, 0,
-+ snd->nchmaps, sizeof(*snd->chmaps),
-+ snd->chmaps);
-+ if (rc)
-+ return rc;
-+
-+ /* Count the number of channel maps per each PCM device/stream. */
-+ for (i = 0; i < snd->nchmaps; ++i) {
-+ struct virtio_snd_chmap_info *info = &snd->chmaps[i];
-+ u32 nid = le32_to_cpu(info->hdr.hda_fn_nid);
-+ struct virtio_pcm *vpcm;
-+ struct virtio_pcm_stream *vs;
-+
-+ vpcm = virtsnd_pcm_find_or_create(snd, nid);
-+ if (IS_ERR(vpcm))
-+ return PTR_ERR(vpcm);
-+
-+ switch (info->direction) {
-+ case VIRTIO_SND_D_OUTPUT:
-+ vs = &vpcm->streams[SNDRV_PCM_STREAM_PLAYBACK];
-+ break;
-+ case VIRTIO_SND_D_INPUT:
-+ vs = &vpcm->streams[SNDRV_PCM_STREAM_CAPTURE];
-+ break;
-+ default:
-+ dev_err(&vdev->dev,
-+ "chmap #%u: unknown direction (%u)\n", i,
-+ info->direction);
-+ return -EINVAL;
-+ }
-+
-+ vs->nchmaps++;
-+ }
-+
-+ return 0;
-+}
-+
-+/**
-+ * virtsnd_chmap_add_ctls() - Create an ALSA control for channel maps.
-+ * @pcm: ALSA PCM device.
-+ * @direction: PCM stream direction (SNDRV_PCM_STREAM_XXX).
-+ * @vs: VirtIO PCM stream.
-+ *
-+ * Context: Any context.
-+ * Return: 0 on success, -errno on failure.
-+ */
-+static int virtsnd_chmap_add_ctls(struct snd_pcm *pcm, int direction,
-+ struct virtio_pcm_stream *vs)
-+{
-+ u32 i;
-+ int max_channels = 0;
-+
-+ for (i = 0; i < vs->nchmaps; i++)
-+ if (max_channels < vs->chmaps[i].channels)
-+ max_channels = vs->chmaps[i].channels;
-+
-+ return snd_pcm_add_chmap_ctls(pcm, direction, vs->chmaps, max_channels,
-+ 0, NULL);
-+}
-+
-+/**
-+ * virtsnd_chmap_build_devs() - Build ALSA controls for channel maps.
-+ * @snd: VirtIO sound device.
-+ *
-+ * Context: Any context.
-+ * Return: 0 on success, -errno on failure.
-+ */
-+int virtsnd_chmap_build_devs(struct virtio_snd *snd)
-+{
-+ struct virtio_device *vdev = snd->vdev;
-+ struct virtio_pcm *vpcm;
-+ struct virtio_pcm_stream *vs;
-+ u32 i;
-+ int rc;
-+
-+ /* Allocate channel map elements per each PCM device/stream. */
-+ list_for_each_entry(vpcm, &snd->pcm_list, list) {
-+ for (i = 0; i < ARRAY_SIZE(vpcm->streams); ++i) {
-+ vs = &vpcm->streams[i];
-+
-+ if (!vs->nchmaps)
-+ continue;
-+
-+ vs->chmaps = devm_kcalloc(&vdev->dev, vs->nchmaps + 1,
-+ sizeof(*vs->chmaps),
-+ GFP_KERNEL);
-+ if (!vs->chmaps)
-+ return -ENOMEM;
-+
-+ vs->nchmaps = 0;
-+ }
-+ }
-+
-+ /* Initialize channel maps per each PCM device/stream. */
-+ for (i = 0; i < snd->nchmaps; ++i) {
-+ struct virtio_snd_chmap_info *info = &snd->chmaps[i];
-+ unsigned int channels = info->channels;
-+ unsigned int ch;
-+ struct snd_pcm_chmap_elem *chmap;
-+
-+ vpcm = virtsnd_pcm_find(snd, le32_to_cpu(info->hdr.hda_fn_nid));
-+ if (IS_ERR(vpcm))
-+ return PTR_ERR(vpcm);
-+
-+ if (info->direction == VIRTIO_SND_D_OUTPUT)
-+ vs = &vpcm->streams[SNDRV_PCM_STREAM_PLAYBACK];
-+ else
-+ vs = &vpcm->streams[SNDRV_PCM_STREAM_CAPTURE];
-+
-+ chmap = &vs->chmaps[vs->nchmaps++];
-+
-+ if (channels > ARRAY_SIZE(chmap->map))
-+ channels = ARRAY_SIZE(chmap->map);
-+
-+ chmap->channels = channels;
-+
-+ for (ch = 0; ch < channels; ++ch) {
-+ u8 position = info->positions[ch];
-+
-+ if (position >= ARRAY_SIZE(g_v2a_position_map))
-+ return -EINVAL;
-+
-+ chmap->map[ch] = g_v2a_position_map[position];
-+ }
-+ }
-+
-+ /* Create an ALSA control per each PCM device/stream. */
-+ list_for_each_entry(vpcm, &snd->pcm_list, list) {
-+ if (!vpcm->pcm)
-+ continue;
-+
-+ for (i = 0; i < ARRAY_SIZE(vpcm->streams); ++i) {
-+ vs = &vpcm->streams[i];
-+
-+ if (!vs->nchmaps)
-+ continue;
-+
-+ rc = virtsnd_chmap_add_ctls(vpcm->pcm, i, vs);
-+ if (rc)
-+ return rc;
-+ }
-+ }
-+
-+ return 0;
-+}
-diff --git a/sound/virtio/virtio_pcm.h b/sound/virtio/virtio_pcm.h
-index efd0228746cf..1353fdc9bd69 100644
---- a/sound/virtio/virtio_pcm.h
-+++ b/sound/virtio/virtio_pcm.h
-@@ -63,10 +63,14 @@ struct virtio_pcm_substream {
- * struct virtio_pcm_stream - VirtIO PCM stream.
- * @substreams: VirtIO substreams belonging to the stream.
- * @nsubstreams: Number of substreams.
-+ * @chmaps: Kernel channel maps belonging to the stream.
-+ * @nchmaps: Number of channel maps.
- */
- struct virtio_pcm_stream {
- struct virtio_pcm_substream **substreams;
- u32 nsubstreams;
-+ struct snd_pcm_chmap_elem *chmaps;
-+ u32 nchmaps;
- };
-
- /**
diff --git a/meta-agl-bsp/virtualization-layer/recipes-kernel/linux/linux-yocto/virtio-kmeta/bsp/virtio/virtio-snd/0009-ALSA-virtio-introduce-device-suspend-resume-support.patch b/meta-agl-bsp/virtualization-layer/recipes-kernel/linux/linux-yocto/virtio-kmeta/bsp/virtio/virtio-snd/0009-ALSA-virtio-introduce-device-suspend-resume-support.patch
deleted file mode 100644
index b7d278fd0..000000000
--- a/meta-agl-bsp/virtualization-layer/recipes-kernel/linux/linux-yocto/virtio-kmeta/bsp/virtio/virtio-snd/0009-ALSA-virtio-introduce-device-suspend-resume-support.patch
+++ /dev/null
@@ -1,174 +0,0 @@
-From b173fb2a0eb0067fc665ba48f9b2b8b5f991c078 Mon Sep 17 00:00:00 2001
-From: Anton Yakovlev <anton.yakovlev@opensynergy.com>
-Date: Tue, 2 Mar 2021 17:47:09 +0100
-Subject: [PATCH] ALSA: virtio: introduce device suspend/resume support
-
-All running PCM substreams are stopped on device suspend and restarted
-on device resume.
-
-Signed-off-by: Anton Yakovlev <anton.yakovlev@opensynergy.com>
-Link: https://lore.kernel.org/r/20210302164709.3142702-10-anton.yakovlev@opensynergy.com
-Signed-off-by: Takashi Iwai <tiwai@suse.de>
-Signed-off-by: Vasyl Vavrychuk <vasyl.vavrychuk@opensynergy.com>
----
- sound/virtio/virtio_card.c | 56 +++++++++++++++++++++++++++++++++++
- sound/virtio/virtio_pcm.h | 3 ++
- sound/virtio/virtio_pcm_ops.c | 33 ++++++++++++++++-----
- 3 files changed, 85 insertions(+), 7 deletions(-)
-
-diff --git a/sound/virtio/virtio_card.c b/sound/virtio/virtio_card.c
-index 1c03fcc41c3b..ae9128063917 100644
---- a/sound/virtio/virtio_card.c
-+++ b/sound/virtio/virtio_card.c
-@@ -362,6 +362,58 @@ static void virtsnd_remove(struct virtio_device *vdev)
- kfree(snd->event_msgs);
- }
-
-+#ifdef CONFIG_PM_SLEEP
-+/**
-+ * virtsnd_freeze() - Suspend device.
-+ * @vdev: VirtIO parent device.
-+ *
-+ * Context: Any context.
-+ * Return: 0 on success, -errno on failure.
-+ */
-+static int virtsnd_freeze(struct virtio_device *vdev)
-+{
-+ struct virtio_snd *snd = vdev->priv;
-+ unsigned int i;
-+
-+ virtsnd_disable_event_vq(snd);
-+ virtsnd_ctl_msg_cancel_all(snd);
-+
-+ vdev->config->del_vqs(vdev);
-+ vdev->config->reset(vdev);
-+
-+ for (i = 0; i < snd->nsubstreams; ++i)
-+ cancel_work_sync(&snd->substreams[i].elapsed_period);
-+
-+ kfree(snd->event_msgs);
-+ snd->event_msgs = NULL;
-+
-+ return 0;
-+}
-+
-+/**
-+ * virtsnd_restore() - Resume device.
-+ * @vdev: VirtIO parent device.
-+ *
-+ * Context: Any context.
-+ * Return: 0 on success, -errno on failure.
-+ */
-+static int virtsnd_restore(struct virtio_device *vdev)
-+{
-+ struct virtio_snd *snd = vdev->priv;
-+ int rc;
-+
-+ rc = virtsnd_find_vqs(snd);
-+ if (rc)
-+ return rc;
-+
-+ virtio_device_ready(vdev);
-+
-+ virtsnd_enable_event_vq(snd);
-+
-+ return 0;
-+}
-+#endif /* CONFIG_PM_SLEEP */
-+
- static const struct virtio_device_id id_table[] = {
- { VIRTIO_ID_SOUND, VIRTIO_DEV_ANY_ID },
- { 0 },
-@@ -374,6 +426,10 @@ static struct virtio_driver virtsnd_driver = {
- .validate = virtsnd_validate,
- .probe = virtsnd_probe,
- .remove = virtsnd_remove,
-+#ifdef CONFIG_PM_SLEEP
-+ .freeze = virtsnd_freeze,
-+ .restore = virtsnd_restore,
-+#endif
- };
-
- static int __init init(void)
-diff --git a/sound/virtio/virtio_pcm.h b/sound/virtio/virtio_pcm.h
-index 1353fdc9bd69..062eb8e8f2cf 100644
---- a/sound/virtio/virtio_pcm.h
-+++ b/sound/virtio/virtio_pcm.h
-@@ -31,6 +31,8 @@ struct virtio_pcm_msg;
- * @xfer_xrun: Data underflow/overflow state (0 - no xrun, 1 - xrun).
- * @stopped: True if the substream is stopped and must be released on the device
- * side.
-+ * @suspended: True if the substream is suspended and must be reconfigured on
-+ * the device side at resume.
- * @msgs: Allocated I/O messages.
- * @nmsgs: Number of allocated I/O messages.
- * @msg_last_enqueued: Index of the last I/O message added to the virtqueue.
-@@ -52,6 +54,7 @@ struct virtio_pcm_substream {
- bool xfer_enabled;
- bool xfer_xrun;
- bool stopped;
-+ bool suspended;
- struct virtio_pcm_msg **msgs;
- unsigned int nmsgs;
- int msg_last_enqueued;
-diff --git a/sound/virtio/virtio_pcm_ops.c b/sound/virtio/virtio_pcm_ops.c
-index 0682a2df6c8c..f8bfb87624be 100644
---- a/sound/virtio/virtio_pcm_ops.c
-+++ b/sound/virtio/virtio_pcm_ops.c
-@@ -115,6 +115,7 @@ static int virtsnd_pcm_open(struct snd_pcm_substream *substream)
- SNDRV_PCM_HW_PARAM_PERIODS);
-
- vss->stopped = !!virtsnd_pcm_msg_pending_num(vss);
-+ vss->suspended = false;
-
- /*
- * If the substream has already been used, then the I/O queue may be in
-@@ -272,16 +273,31 @@ static int virtsnd_pcm_prepare(struct snd_pcm_substream *substream)
- struct virtio_device *vdev = vss->snd->vdev;
- struct virtio_snd_msg *msg;
-
-- if (virtsnd_pcm_msg_pending_num(vss)) {
-- dev_err(&vdev->dev, "SID %u: invalid I/O queue state\n",
-- vss->sid);
-- return -EBADFD;
-+ if (!vss->suspended) {
-+ if (virtsnd_pcm_msg_pending_num(vss)) {
-+ dev_err(&vdev->dev, "SID %u: invalid I/O queue state\n",
-+ vss->sid);
-+ return -EBADFD;
-+ }
-+
-+ vss->buffer_bytes = snd_pcm_lib_buffer_bytes(substream);
-+ vss->hw_ptr = 0;
-+ vss->msg_last_enqueued = -1;
-+ } else {
-+ struct snd_pcm_runtime *runtime = substream->runtime;
-+ unsigned int buffer_bytes = snd_pcm_lib_buffer_bytes(substream);
-+ unsigned int period_bytes = snd_pcm_lib_period_bytes(substream);
-+ int rc;
-+
-+ rc = virtsnd_pcm_dev_set_params(vss, buffer_bytes, period_bytes,
-+ runtime->channels,
-+ runtime->format, runtime->rate);
-+ if (rc)
-+ return rc;
- }
-
-- vss->buffer_bytes = snd_pcm_lib_buffer_bytes(substream);
-- vss->hw_ptr = 0;
- vss->xfer_xrun = false;
-- vss->msg_last_enqueued = -1;
-+ vss->suspended = false;
- vss->msg_count = 0;
-
- msg = virtsnd_pcm_ctl_msg_alloc(vss, VIRTIO_SND_R_PCM_PREPARE,
-@@ -336,6 +352,9 @@ static int virtsnd_pcm_trigger(struct snd_pcm_substream *substream, int command)
- }
-
- return virtsnd_ctl_msg_send_sync(snd, msg);
-+ case SNDRV_PCM_TRIGGER_SUSPEND:
-+ vss->suspended = true;
-+ fallthrough;
- case SNDRV_PCM_TRIGGER_STOP:
- vss->stopped = true;
- fallthrough;
diff --git a/meta-agl-bsp/virtualization-layer/recipes-kernel/linux/linux-yocto/virtio-kmeta/bsp/virtio/virtio-snd/virtio-snd.scc b/meta-agl-bsp/virtualization-layer/recipes-kernel/linux/linux-yocto/virtio-kmeta/bsp/virtio/virtio-snd/virtio-snd.scc
index ba7b4ceb6..a1fc8bb7d 100644
--- a/meta-agl-bsp/virtualization-layer/recipes-kernel/linux/linux-yocto/virtio-kmeta/bsp/virtio/virtio-snd/virtio-snd.scc
+++ b/meta-agl-bsp/virtualization-layer/recipes-kernel/linux/linux-yocto/virtio-kmeta/bsp/virtio/virtio-snd/virtio-snd.scc
@@ -1,11 +1,2 @@
# SPDX-License-Identifier: MIT
kconf hardware virtio-snd.cfg
-patch 0001-uapi-virtio_ids-add-a-sound-device-type-ID-from-OASI.patch
-patch 0002-ALSA-virtio-add-virtio-sound-driver.patch
-patch 0003-ALSA-virtio-handling-control-messages.patch
-patch 0004-ALSA-virtio-build-PCM-devices-and-substream-hardware.patch
-patch 0005-ALSA-virtio-handling-control-and-I-O-messages-for-th.patch
-patch 0006-ALSA-virtio-PCM-substream-operators.patch
-patch 0007-ALSA-virtio-introduce-jack-support.patch
-patch 0008-ALSA-virtio-introduce-PCM-channel-map-support.patch
-patch 0009-ALSA-virtio-introduce-device-suspend-resume-support.patch
diff --git a/meta-agl-bsp/virtualization-layer/recipes-kernel/linux/linux-yocto/virtio-kmeta/bsp/virtio/virtio.scc b/meta-agl-bsp/virtualization-layer/recipes-kernel/linux/linux-yocto/virtio-kmeta/bsp/virtio/virtio.scc
index 755cde94e..c48cadbd9 100644
--- a/meta-agl-bsp/virtualization-layer/recipes-kernel/linux/linux-yocto/virtio-kmeta/bsp/virtio/virtio.scc
+++ b/meta-agl-bsp/virtualization-layer/recipes-kernel/linux/linux-yocto/virtio-kmeta/bsp/virtio/virtio.scc
@@ -1,5 +1,4 @@
# SPDX-License-Identifier: MIT
kconf hardware virtio.cfg
-patch virtio-input-add-multi-touch-support.patch
include virtio-snd/virtio-snd.scc
diff --git a/meta-agl-bsp/virtualization-layer/recipes-kernel/linux/linux-yocto_%.bbappend b/meta-agl-bsp/virtualization-layer/recipes-kernel/linux/linux-yocto_%.bbappend
index 0f255cddb..8b5e92a20 100644
--- a/meta-agl-bsp/virtualization-layer/recipes-kernel/linux/linux-yocto_%.bbappend
+++ b/meta-agl-bsp/virtualization-layer/recipes-kernel/linux/linux-yocto_%.bbappend
@@ -5,4 +5,4 @@ SRC_URI:append:virtio-all = " \
file://virtio-kmeta/bsp/virtio/virtio-aarch64-${LINUX_KERNEL_TYPE}.scc \
"
-COMPATIBLE_MACHINE_virtio-aarch64 = "virtio-aarch64"
+COMPATIBLE_MACHINE:virtio-aarch64 = "virtio-aarch64"
diff --git a/meta-agl-bsp/virtualization-layer/recipes-kernel/linux/linux-yocto_5.10.bb b/meta-agl-bsp/virtualization-layer/recipes-kernel/linux/linux-yocto_5.10.bb
deleted file mode 100644
index 322ae51ea..000000000
--- a/meta-agl-bsp/virtualization-layer/recipes-kernel/linux/linux-yocto_5.10.bb
+++ /dev/null
@@ -1,58 +0,0 @@
-KBRANCH ?= "v5.10/standard/base"
-
-require recipes-kernel/linux/linux-yocto.inc
-
-# board specific branches
-KBRANCH:qemuarm ?= "v5.10/standard/arm-versatile-926ejs"
-KBRANCH:qemuarm64 ?= "v5.10/standard/qemuarm64"
-KBRANCH:qemumips ?= "v5.10/standard/mti-malta32"
-KBRANCH:qemuppc ?= "v5.10/standard/qemuppc"
-KBRANCH:qemuriscv64 ?= "v5.10/standard/base"
-KBRANCH:qemuriscv32 ?= "v5.10/standard/base"
-KBRANCH:qemux86 ?= "v5.10/standard/base"
-KBRANCH:qemux86-64 ?= "v5.10/standard/base"
-KBRANCH:qemumips64 ?= "v5.10/standard/mti-malta64"
-
-SRCREV_machine:qemuarm ?= "d8551cae1ccdbe062a5c6068ce39ea8f4e1c72db"
-SRCREV_machine:qemuarm64 ?= "cf5b0320cf4544d3db9ce3ddd6ddb7553a610651"
-SRCREV_machine:qemumips ?= "7f1f1ad2f2d90b1b070c6b0a82f0add9aa492e37"
-SRCREV_machine:qemuppc ?= "cf5b0320cf4544d3db9ce3ddd6ddb7553a610651"
-SRCREV_machine:qemuriscv64 ?= "cf5b0320cf4544d3db9ce3ddd6ddb7553a610651"
-SRCREV_machine:qemuriscv32 ?= "cf5b0320cf4544d3db9ce3ddd6ddb7553a610651"
-SRCREV_machine:qemux86 ?= "cf5b0320cf4544d3db9ce3ddd6ddb7553a610651"
-SRCREV_machine:qemux86-64 ?= "cf5b0320cf4544d3db9ce3ddd6ddb7553a610651"
-SRCREV_machine:qemumips64 ?= "fd5ac097b891642eea13659bea536f3ec5910d6d"
-SRCREV_machine ?= "cf5b0320cf4544d3db9ce3ddd6ddb7553a610651"
-SRCREV_meta ?= "031f6c76e488a3563f35258c72ff1de3e25a512e"
-
-# remap qemuarm to qemuarma15 for the 5.8 kernel
-# KMACHINE:qemuarm ?= "qemuarma15"
-
-SRC_URI = "git://git.yoctoproject.org/linux-yocto.git;name=machine;branch=${KBRANCH}; \
- git://git.yoctoproject.org/yocto-kernel-cache;type=kmeta;name=meta;branch=yocto-5.10;destsuffix=${KMETA}"
-
-LIC_FILES_CHKSUM = "file://COPYING;md5=6bc538ed5bd9a7fc9398086aedcd7e46"
-LINUX_VERSION ?= "5.10.25"
-
-DEPENDS += "${@bb.utils.contains('ARCH', 'x86', 'elfutils-native', '', d)}"
-DEPENDS += "openssl-native util-linux-native"
-DEPENDS += "gmp-native"
-
-PV = "${LINUX_VERSION}+git${SRCPV}"
-
-KMETA = "kernel-meta"
-KCONF_BSP_AUDIT_LEVEL = "1"
-
-KERNEL_DEVICETREE:qemuarmv5 = "versatile-pb.dtb"
-
-COMPATIBLE_MACHINE = "qemuarm|qemuarmv5|qemuarm64|qemux86|qemuppc|qemuppc64|qemumips|qemumips64|qemux86-64|qemuriscv64|qemuriscv32"
-
-# Functionality flags
-KERNEL_EXTRA_FEATURES ?= "features/netfilter/netfilter.scc"
-KERNEL_FEATURES:append = " ${KERNEL_EXTRA_FEATURES}"
-KERNEL_FEATURES:append:qemuall=" cfg/virtio.scc features/drm-bochs/drm-bochs.scc"
-KERNEL_FEATURES:append:qemux86=" cfg/sound.scc cfg/paravirt_kvm.scc"
-KERNEL_FEATURES:append:qemux86-64=" cfg/sound.scc cfg/paravirt_kvm.scc"
-KERNEL_FEATURES:append = " ${@bb.utils.contains("TUNE_FEATURES", "mx32", " cfg/x32.scc", "", d)}"
-KERNEL_FEATURES:append = " ${@bb.utils.contains("DISTRO_FEATURES", "ptest", " features/scsi/scsi-debug.scc", "", d)}"
-KERNEL_FEATURES:append = " ${@bb.utils.contains("DISTRO_FEATURES", "ptest", " features/gpio/mockup.scc", "", d)}" \ No newline at end of file