[PATCH master] input: virtio_input: don't free poller-enabled beeper on remove

Ahmad Fatoum a.fatoum at barebox.org
Sun Nov 8 02:45:42 PST 2026


The sound card of a virtio keyboard is embedded in the driver's private
data, which virtinput_remove() frees.

Drop the free and instead just disable the soundcard, so it can no
longer beep. A proper fix would be to add support for unregistering
sound cards, but that can follow after devm support lands.

Fixes: deb9d7c18b07 ("input: virtio_input: add sound support")
Signed-off-by: Ahmad Fatoum <a.fatoum at barebox.org>
---
 drivers/input/virtio_input.c | 12 ++++++++----
 drivers/sound/core.c         | 11 ++++++++++-
 include/sound.h              |  6 ++++++
 3 files changed, 24 insertions(+), 5 deletions(-)

diff --git a/drivers/input/virtio_input.c b/drivers/input/virtio_input.c
index 6e73e7873986..48a3aef2522c 100644
--- a/drivers/input/virtio_input.c
+++ b/drivers/input/virtio_input.c
@@ -19,6 +19,7 @@ struct virtio_input {
 	struct virtio_input_event  evts[64];
 	struct poller_struct       poller;
 	struct sound_card          beeper;
+	bool                       beeper_registered;
 	unsigned long              sndbit[BITS_TO_LONGS(SND_CNT)];
 };
 
@@ -239,10 +240,12 @@ static int virtinput_probe(struct virtio_device *vdev)
 		beeper->beep = virtinput_send_status;
 
 		err = sound_card_register(&vi->beeper);
-		if (err)
+		if (err) {
 			dev_warn(&vdev->dev, "bell registration failed: %pe\n", ERR_PTR(err));
-		else
+		} else {
+			vi->beeper_registered = true;
 			dev_info(&vdev->dev, "bell registered\n");
+		}
 	}
 
 	return 0;
@@ -260,12 +263,13 @@ static void virtinput_remove(struct virtio_device *vdev)
 {
 	struct virtio_input *vi = vdev->priv;
 
+	if (vi->beeper_registered)
+		sound_card_disable(&vi->beeper);
+
 	vdev->config->reset(vdev);
 	poller_unregister(&vi->poller);
 	input_device_unregister(&vi->idev);
 	vdev->config->del_vqs(vdev);
-
-	kfree(vi);
 }
 
 static const struct virtio_device_id id_table[] = {
diff --git a/drivers/sound/core.c b/drivers/sound/core.c
index 801b1fade552..aabcfee2822f 100644
--- a/drivers/sound/core.c
+++ b/drivers/sound/core.c
@@ -18,6 +18,9 @@ struct beep {
 static int sound_card_do_beep(struct sound_card *card,
 			      int freq, unsigned int us)
 {
+	if (!card->beep)
+		return -ENODEV;
+
 	if (freq == -1)
 		freq = card->bell_frequency;
 
@@ -110,7 +113,7 @@ int sound_card_beep_cancel(struct sound_card *card)
 
 	poller_async_cancel(&card->poller);
 
-	ret = card->beep(card, 0, 0);
+	ret = sound_card_do_beep(card, 0, 0);
 
 	list_for_each_entry_safe(beep, tmp, &card->tune, list) {
 		list_del(&beep->list);
@@ -119,3 +122,9 @@ int sound_card_beep_cancel(struct sound_card *card)
 
 	return ret;
 }
+
+void sound_card_disable(struct sound_card *card)
+{
+	sound_card_beep_cancel(card);
+	card->beep = NULL;
+}
diff --git a/include/sound.h b/include/sound.h
index 62fef106ee73..56c3c328d081 100644
--- a/include/sound.h
+++ b/include/sound.h
@@ -25,6 +25,12 @@ int sound_card_beep_wait(struct sound_card *card, unsigned timeout_us);
 int sound_card_beep(struct sound_card *card, int freq, unsigned int us);
 int sound_card_beep_cancel(struct sound_card *card);
 
+#ifdef CONFIG_SOUND
+void sound_card_disable(struct sound_card *card);
+#else
+static inline void sound_card_disable(struct sound_card *card) {}
+#endif
+
 struct sound_card *sound_card_get_default(void);
 
 static inline int beep(int freq, unsigned us)
-- 
2.47.3




More information about the barebox mailing list