diff options
author | Anton Yakovlev <anton.yakovlev@opensynergy.com> | 2021-03-02 17:47:09 +0100 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2021-03-07 09:08:39 +0100 |
commit | 575483e90a3292c2afceb7161732046e411d6fdd (patch) | |
tree | 1cea631e4a3270130fcef89494e47ff9a05d7e03 /sound/virtio/virtio_card.c | |
parent | 19325fedf245ca932c58a629d3888a9a393534ab (diff) |
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>
Diffstat (limited to 'sound/virtio/virtio_card.c')
-rw-r--r-- | sound/virtio/virtio_card.c | 56 |
1 files changed, 56 insertions, 0 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) |