clear-pkgs-linux-iot-lts2018/0974-ASoC-Intel-Skylake-Vir...

153 lines
4.2 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Pawel Furtak <pawel.furtak@intel.com>
Date: Fri, 18 Jan 2019 17:49:19 +0100
Subject: [PATCH] ASoC: Intel: Skylake: Virt: Support for entering/exiting S3
In order to handle suspend/resume operations on GOS,
two additional operations have to be implemented.
Change-Id: I9a22ed8d2d219afbff1c7e999d836402756717b5
Tracked-On: OAM-74846
Signed-off-by: Pawel Furtak <pawel.furtak@intel.com>
Reviewed-by: Janca, Grzegorz <grzegorz.janca@intel.com>
Reviewed-by: Rojewski, Cezary <cezary.rojewski@intel.com>
Tested-by: Rojewski, Cezary <cezary.rojewski@intel.com>
---
.../soc/intel/skylake/virtio/skl-virtio-fe.c | 87 +++++++++++++------
1 file changed, 62 insertions(+), 25 deletions(-)
diff --git a/sound/soc/intel/skylake/virtio/skl-virtio-fe.c b/sound/soc/intel/skylake/virtio/skl-virtio-fe.c
index 8b27ebb8c812..0ae0bba2b376 100644
--- a/sound/soc/intel/skylake/virtio/skl-virtio-fe.c
+++ b/sound/soc/intel/skylake/virtio/skl-virtio-fe.c
@@ -942,17 +942,40 @@ static int vfe_skl_init(struct virtio_device *vdev)
return err;
}
+static int vfe_init_vqs(struct snd_skl_vfe *vfe)
+{
+ struct virtqueue *vqs[SKL_VIRTIO_NUM_OF_VQS];
+ int ret;
+ struct virtio_device *vdev = vfe->vdev;
+ vq_callback_t *cbs[SKL_VIRTIO_NUM_OF_VQS] = {
+ vfe_cmd_tx_done,
+ vfe_cmd_handle_rx,
+ vfe_not_tx_done,
+ vfe_not_handle_rx
+ };
+
+ /* find virt queue for vfe to send/receive IPC message. */
+ ret = virtio_find_vqs(vfe->vdev, SKL_VIRTIO_NUM_OF_VQS,
+ vqs, cbs, vfe_skl_vq_names, NULL);
+ if (ret) {
+ dev_err(&vdev->dev, "error: find vqs fail with %d\n", ret);
+ return ret;
+ }
+ /* virtques */
+ vfe->ipc_cmd_tx_vq = vqs[SKL_VIRTIO_IPC_CMD_TX_VQ];
+ vfe->ipc_cmd_rx_vq = vqs[SKL_VIRTIO_IPC_CMD_RX_VQ];
+ vfe->ipc_not_tx_vq = vqs[SKL_VIRTIO_IPC_NOT_TX_VQ];
+ vfe->ipc_not_rx_vq = vqs[SKL_VIRTIO_IPC_NOT_RX_VQ];
+
+ virtio_device_ready(vdev);
+
+ return 0;
+}
+
static int vfe_init(struct virtio_device *vdev)
{
struct snd_skl_vfe *vfe;
int ret;
- struct virtqueue *vqs[SKL_VIRTIO_NUM_OF_VQS];
- vq_callback_t *cbs[SKL_VIRTIO_NUM_OF_VQS] = {
- vfe_cmd_tx_done,
- vfe_cmd_handle_rx,
- vfe_not_tx_done,
- vfe_not_handle_rx
- };
vfe = devm_kzalloc(&vdev->dev, sizeof(*vfe), GFP_KERNEL);
if (!vfe)
@@ -963,32 +986,18 @@ static int vfe_init(struct virtio_device *vdev)
vdev->priv = vfe;
INIT_LIST_HEAD(&vfe->kcontrols_list);
-
spin_lock_init(&vfe->substream_info_lock);
INIT_LIST_HEAD(&vfe->substr_info_list);
-
- /* find virt queue for vfe to send/receive IPC message. */
- ret = virtio_find_vqs(vfe->vdev, SKL_VIRTIO_NUM_OF_VQS,
- vqs, cbs, vfe_skl_vq_names, NULL);
- if (ret) {
- dev_err(&vdev->dev, "error: find vqs fail with %d\n", ret);
- goto err;
- }
-
spin_lock_init(&vfe->ipc_vq_lock);
- /* virtques */
- vfe->ipc_cmd_tx_vq = vqs[SKL_VIRTIO_IPC_CMD_TX_VQ];
- vfe->ipc_cmd_rx_vq = vqs[SKL_VIRTIO_IPC_CMD_RX_VQ];
- vfe->ipc_not_tx_vq = vqs[SKL_VIRTIO_IPC_NOT_TX_VQ];
- vfe->ipc_not_rx_vq = vqs[SKL_VIRTIO_IPC_NOT_RX_VQ];
-
INIT_WORK(&vfe->posn_update_work, vfe_posn_update);
- virtio_device_ready(vdev);
-
vfe->send_dsp_ipc_msg = vfe_send_dsp_ipc_msg;
vfe->notify_machine_probe = vfe_wrap_native_driver;
+ ret = vfe_init_vqs(vfe);
+ if (ret < 0)
+ goto err;
+
vfe->pos_not = devm_kmalloc(&vdev->dev,
sizeof(*vfe->pos_not), GFP_KERNEL);
if (!vfe->pos_not)
@@ -1046,6 +1055,30 @@ static void virtaudio_config_changed(struct virtio_device *vdev)
{
}
+#ifdef CONFIG_PM_SLEEP
+static int vfe_freeze(struct virtio_device *vdev)
+{
+ vdev->config->reset(vdev);
+ vdev->config->del_vqs(vdev);
+
+ return 0;
+}
+
+static int vfe_restore(struct virtio_device *vdev)
+{
+ int ret;
+ struct snd_skl_vfe *vfe = vdev->priv;
+
+ ret = vfe_init_vqs(vfe);
+ if (ret < 0)
+ return ret;
+
+ vfe_send_pos_request(vfe, vfe->pos_not);
+
+ return 0;
+}
+#endif
+
const struct virtio_device_id id_table[] = {
{VIRTIO_ID_AUDIO, VIRTIO_DEV_ANY_ID},
{0},
@@ -1060,6 +1093,10 @@ static struct virtio_driver vfe_audio_driver = {
.probe = vfe_probe,
.remove = vfe_remove,
.config_changed = virtaudio_config_changed,
+#ifdef CONFIG_PM_SLEEP
+ .freeze = vfe_freeze,
+ .restore = vfe_restore,
+#endif
};
module_virtio_driver(vfe_audio_driver);
--
https://clearlinux.org