[PATCH 6.12 0192/1376] media: go7007: defer the ALSA v4l2 put until card release
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Date: 2026-09-12 11:53:14
Also in:
linux-patches
6.12-stable review patch. If anyone has any objections, please let me know. ------------------ From: Shuangpeng Bai <redacted> commit 1bd456afeb8a515137e567967069fce6f8fcd23e upstream. go7007_snd_init() already takes a v4l2_device reference for the ALSA side, but go7007_snd_remove() drops it immediately after calling snd_card_free_when_closed(). That is too early when a userspace process still has the capture PCM open. The ALSA card and its PCM callbacks remain alive until the last file is closed, so the release path can still reach struct go7007 through pcm->private_data and call go7007_snd_hw_free() after the V4L2 release path has freed the object. Move the matching v4l2_device_put() to the ALSA card private_free callback so the existing ALSA reference covers the whole deferred card lifetime. Closes: https://lore.kernel.org/r/178144969601.60470.6005237146425573205@gmail.com (local) Fixes: d5d3a7cc127d ("[media] go7007: fix unregister/disconnect handling") Cc: stable@vger.kernel.org Signed-off-by: Shuangpeng Bai <redacted> Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> --- drivers/media/usb/go7007/snd-go7007.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-)
--- a/drivers/media/usb/go7007/snd-go7007.c
+++ b/drivers/media/usb/go7007/snd-go7007.c@@ -195,6 +195,13 @@ static const struct snd_device_ops go700 .dev_free = go7007_snd_free, }; +static void go7007_snd_card_free(struct snd_card *card) +{ + struct go7007 *go = card->private_data; + + v4l2_device_put(&go->v4l2_dev); +} + int go7007_snd_init(struct go7007 *go) { static int dev;
@@ -245,6 +252,8 @@ int go7007_snd_init(struct go7007 *go) gosnd->substream = NULL; go->snd_context = gosnd; v4l2_device_get(&go->v4l2_dev); + gosnd->card->private_data = go; + gosnd->card->private_free = go7007_snd_card_free; ++dev; return 0;
@@ -263,7 +272,6 @@ int go7007_snd_remove(struct go7007 *go) snd_card_disconnect(gosnd->card); snd_card_free_when_closed(gosnd->card); - v4l2_device_put(&go->v4l2_dev); return 0; } EXPORT_SYMBOL(go7007_snd_remove);