======== 8< --------
From 74bb5c45f0bf36e6487538088c654b88e1efb5b5 Mon Sep 17 00:00:00 2001
From: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Date: Tue, 17 Oct 2017 17:58:47 +0900
Subject: [PATCH] ALSA: dummy: support unbind operation to shift state of sound
devices to disconnected
---
sound/drivers/dummy.c | 39 ++++++++++++++++++++++++++++++++++++---
1 file changed, 36 insertions(+), 3 deletions(-)
@@ -92,6 +92,7 @@ MODULE_PARM_DESC(hrtimer, "Use hrtimer as the timer source.");
#endif
static struct platform_device *devices[SNDRV_CARDS];
+static struct snd_card *cards[SNDRV_CARDS];
#define MIXER_ADDR_MASTER 0
#define MIXER_ADDR_LINE 1
@@ -1134,7 +1135,24 @@ static int snd_dummy_probe(struct platform_device *devptr)
static int snd_dummy_remove(struct platform_device *devptr)
{
- snd_card_free(platform_get_drvdata(devptr));
+ struct snd_card *card = platform_get_drvdata(devptr);
+ struct snd_device *dev;
+ int i;
+
+ for (i = 0; i < SNDRV_CARDS; ++i) {
+ /* Temporary for module removal. */
+ if (devices[i] == devptr)
+ cards[i] = card;
+ }
+
+ /*
+ * This shifts state of an instance of sound card into disconnected, but
+ * don't wait till all of references to instances of sound devices are
+ * released.
+ */
+ list_for_each_entry_reverse(dev, &card->devices, list)
+ snd_device_disconnect(card, dev->device_data);
+
return 0;
}
@@ -1178,8 +1196,23 @@ static void snd_dummy_unregister_all(void)
{
int i;
- for (i = 0; i < ARRAY_SIZE(devices); ++i)
- platform_device_unregister(devices[i]);
+ for (i = 0; i < ARRAY_SIZE(devices); ++i) {
+ struct platform_device *devptr = devices[i];
+ struct snd_card *card = cards[i];
+
+ if (devptr == NULL)
+ continue;
+ if (card) {
+ /*
+ * This can wait till the final reference to an
+ * instance of sound card is released.
+ */
+ snd_card_free(card);
+ }
+
+ platform_device_unregister(devptr);
+ }
+
platform_driver_unregister(&snd_dummy_driver);
free_fake_buffer();
}