From c3e6f7d8763fa0400d28c57633eb323515ba05fc Mon Sep 17 00:00:00 2001
From: Takashi Iwai <tiwai@suse.de>
Date: Wed, 16 Nov 2005 18:43:35 +0100
Subject: [ALSA] Remove superfluous pcm_free callbacks

Remove superflous pcm_free callbacks.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 sound/isa/cmi8330.c | 6 ------
 1 file changed, 6 deletions(-)

(limited to 'sound/isa/cmi8330.c')

diff --git a/sound/isa/cmi8330.c b/sound/isa/cmi8330.c
index 5252206ea388..6038529d5af2 100644
--- a/sound/isa/cmi8330.c
+++ b/sound/isa/cmi8330.c
@@ -388,11 +388,6 @@ static int snd_cmi8330_capture_open(snd_pcm_substream_t * substream)
 	return chip->streams[SNDRV_PCM_STREAM_CAPTURE].open(substream);
 }
 
-static void snd_cmi8330_pcm_free(snd_pcm_t *pcm)
-{
-	snd_pcm_lib_preallocate_free_for_all(pcm);
-}
-
 static int __devinit snd_cmi8330_pcm(snd_card_t *card, struct snd_cmi8330 *chip)
 {
 	snd_pcm_t *pcm;
@@ -407,7 +402,6 @@ static int __devinit snd_cmi8330_pcm(snd_card_t *card, struct snd_cmi8330 *chip)
 		return err;
 	strcpy(pcm->name, "CMI8330");
 	pcm->private_data = chip;
-	pcm->private_free = snd_cmi8330_pcm_free;
 	
 	/* SB16 */
 	ops = snd_sb16dsp_get_pcm_ops(CMI_SB_STREAM);
-- 
cgit v1.2.3


From e3561703723fcc2315f852cb85e80533a2c58e3e Mon Sep 17 00:00:00 2001
From: Takashi Iwai <tiwai@suse.de>
Date: Thu, 17 Nov 2005 14:41:02 +0100
Subject: [ALSA] Remove xxx_t typedefs: ISA CMI8330

Modules: CMI8330 driver

Remove xxx_t typedefs from the ISA CMI8330 driver.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 sound/isa/cmi8330.c | 32 ++++++++++++++++----------------
 1 file changed, 16 insertions(+), 16 deletions(-)

(limited to 'sound/isa/cmi8330.c')

diff --git a/sound/isa/cmi8330.c b/sound/isa/cmi8330.c
index 6038529d5af2..cf160062beb0 100644
--- a/sound/isa/cmi8330.c
+++ b/sound/isa/cmi8330.c
@@ -137,26 +137,26 @@ static unsigned char snd_cmi8330_image[((CMI8330_CDINGAIN)-16) + 1] =
 	0x0			/* 26 - cd-in rec gain */
 };
 
-typedef int (*snd_pcm_open_callback_t)(snd_pcm_substream_t *);
+typedef int (*snd_pcm_open_callback_t)(struct snd_pcm_substream *);
 
 struct snd_cmi8330 {
 #ifdef CONFIG_PNP
 	struct pnp_dev *cap;
 	struct pnp_dev *play;
 #endif
-	snd_card_t *card;
-	ad1848_t *wss;
-	sb_t *sb;
+	struct snd_card *card;
+	struct snd_ad1848 *wss;
+	struct snd_sb *sb;
 
-	snd_pcm_t *pcm;
+	struct snd_pcm *pcm;
 	struct snd_cmi8330_stream {
-		snd_pcm_ops_t ops;
+		struct snd_pcm_ops ops;
 		snd_pcm_open_callback_t open;
 		void *private_data; /* sb or wss */
 	} streams[2];
 };
 
-static snd_card_t *snd_cmi8330_legacy[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
+static struct snd_card *snd_cmi8330_legacy[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
 
 #ifdef CONFIG_PNP
 
@@ -231,7 +231,7 @@ static unsigned char cmi8330_sb_init_values[][2] __initdata = {
 };
 
 
-static int __devinit cmi8330_add_sb_mixers(sb_t *chip)
+static int __devinit cmi8330_add_sb_mixers(struct snd_sb *chip)
 {
 	int idx, err;
 	unsigned long flags;
@@ -256,7 +256,7 @@ static int __devinit cmi8330_add_sb_mixers(sb_t *chip)
 }
 #endif
 
-static int __devinit snd_cmi8330_mixer(snd_card_t *card, struct snd_cmi8330 *acard)
+static int __devinit snd_cmi8330_mixer(struct snd_card *card, struct snd_cmi8330 *acard)
 {
 	unsigned int idx;
 	int err;
@@ -370,7 +370,7 @@ static int __devinit snd_cmi8330_pnp(int dev, struct snd_cmi8330 *acard,
 #define CMI_AD_STREAM	SNDRV_PCM_STREAM_PLAYBACK
 #endif
 
-static int snd_cmi8330_playback_open(snd_pcm_substream_t * substream)
+static int snd_cmi8330_playback_open(struct snd_pcm_substream *substream)
 {
 	struct snd_cmi8330 *chip = snd_pcm_substream_chip(substream);
 
@@ -379,7 +379,7 @@ static int snd_cmi8330_playback_open(snd_pcm_substream_t * substream)
 	return chip->streams[SNDRV_PCM_STREAM_PLAYBACK].open(substream);
 }
 
-static int snd_cmi8330_capture_open(snd_pcm_substream_t * substream)
+static int snd_cmi8330_capture_open(struct snd_pcm_substream *substream)
 {
 	struct snd_cmi8330 *chip = snd_pcm_substream_chip(substream);
 
@@ -388,10 +388,10 @@ static int snd_cmi8330_capture_open(snd_pcm_substream_t * substream)
 	return chip->streams[SNDRV_PCM_STREAM_CAPTURE].open(substream);
 }
 
-static int __devinit snd_cmi8330_pcm(snd_card_t *card, struct snd_cmi8330 *chip)
+static int __devinit snd_cmi8330_pcm(struct snd_card *card, struct snd_cmi8330 *chip)
 {
-	snd_pcm_t *pcm;
-	const snd_pcm_ops_t *ops;
+	struct snd_pcm *pcm;
+	const struct snd_pcm_ops *ops;
 	int err;
 	static snd_pcm_open_callback_t cmi_open_callbacks[2] = {
 		snd_cmi8330_playback_open,
@@ -444,7 +444,7 @@ static int __devinit snd_cmi8330_probe(int dev,
 				       struct pnp_card_link *pcard,
 				       const struct pnp_card_device_id *pid)
 {
-	snd_card_t *card;
+	struct snd_card *card;
 	struct snd_cmi8330 *acard;
 	int i, err;
 
@@ -567,7 +567,7 @@ static int __devinit snd_cmi8330_pnp_detect(struct pnp_card_link *card,
 
 static void __devexit snd_cmi8330_pnp_remove(struct pnp_card_link * pcard)
 {
-	snd_card_t *card = (snd_card_t *) pnp_get_card_drvdata(pcard);
+	struct snd_card *card = (struct snd_card *) pnp_get_card_drvdata(pcard);
 
 	snd_card_disconnect(card);
 	snd_card_free_in_thread(card);
-- 
cgit v1.2.3


From acdcbc15426b91b0041756a92ea4932c60def189 Mon Sep 17 00:00:00 2001
From: Takashi Iwai <tiwai@suse.de>
Date: Thu, 17 Nov 2005 17:11:35 +0100
Subject: [ALSA] cmi8330 - Use platform_device, add PM support

Modules: CMI8330 driver

Rewrite the probe/remove with platform_device.
Also, add the PM support.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 sound/isa/cmi8330.c | 241 +++++++++++++++++++++++++++++++++++-----------------
 1 file changed, 163 insertions(+), 78 deletions(-)

(limited to 'sound/isa/cmi8330.c')

diff --git a/sound/isa/cmi8330.c b/sound/isa/cmi8330.c
index cf160062beb0..ba0114ebafde 100644
--- a/sound/isa/cmi8330.c
+++ b/sound/isa/cmi8330.c
@@ -45,6 +45,8 @@
 
 #include <sound/driver.h>
 #include <linux/init.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/pnp.h>
 #include <linux/moduleparam.h>
@@ -156,8 +158,6 @@ struct snd_cmi8330 {
 	} streams[2];
 };
 
-static struct snd_card *snd_cmi8330_legacy[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
-
 #ifdef CONFIG_PNP
 
 static struct pnp_card_device_id snd_cmi8330_pnpids[] = {
@@ -429,6 +429,31 @@ static int __devinit snd_cmi8330_pcm(struct snd_card *card, struct snd_cmi8330 *
 }
 
 
+#ifdef CONFIG_PM
+static int snd_cmi8330_suspend(struct snd_card *card)
+{
+	struct snd_cmi8330 *acard = card->private_data;
+
+	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
+	snd_pcm_suspend_all(acard->pcm);
+	acard->wss->suspend(acard->wss);
+	snd_sbmixer_suspend(acard->sb);
+	return 0;
+}
+
+static int snd_cmi8330_resume(struct snd_card *card)
+{
+	struct snd_cmi8330 *acard = card->private_data;
+
+	snd_sbdsp_reset(acard->sb);
+	snd_sbmixer_suspend(acard->sb);
+	acard->wss->resume(acard->wss);
+	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
+	return 0;
+}
+#endif
+
+
 /*
  */
 
@@ -440,44 +465,28 @@ static int __devinit snd_cmi8330_pcm(struct snd_card *card, struct snd_cmi8330 *
 
 #define PFX	"cmi8330: "
 
-static int __devinit snd_cmi8330_probe(int dev,
-				       struct pnp_card_link *pcard,
-				       const struct pnp_card_device_id *pid)
+static struct snd_card *snd_cmi8330_card_new(int dev)
 {
 	struct snd_card *card;
 	struct snd_cmi8330 *acard;
-	int i, err;
-
-	if (! is_isapnp_selected(dev)) {
-		if (wssport[dev] == SNDRV_AUTO_PORT) {
-			snd_printk(KERN_ERR PFX "specify wssport\n");
-			return -EINVAL;
-		}
-		if (sbport[dev] == SNDRV_AUTO_PORT) {
-			snd_printk(KERN_ERR PFX "specify sbport\n");
-			return -EINVAL;
-		}
-	}
 
 	card = snd_card_new(index[dev], id[dev], THIS_MODULE,
 			    sizeof(struct snd_cmi8330));
 	if (card == NULL) {
 		snd_printk(KERN_ERR PFX "could not get a new card\n");
-		return -ENOMEM;
+		return NULL;
 	}
-	acard = (struct snd_cmi8330 *)card->private_data;
+	acard = card->private_data;
 	acard->card = card;
+	return card;
+}
 
-#ifdef CONFIG_PNP
-	if (isapnp[dev]) {
-		if ((err = snd_cmi8330_pnp(dev, acard, pcard, pid)) < 0) {
-			snd_printk(KERN_ERR PFX "PnP detection failed\n");
-			goto _err;
-		}
-		snd_card_set_dev(card, &pcard->card->dev);
-	}
-#endif
+static int __devinit snd_cmi8330_probe(struct snd_card *card, int dev)
+{
+	struct snd_cmi8330 *acard;
+	int i, err;
 
+	acard = card->private_data;
 	if ((err = snd_ad1848_create(card,
 				     wssport[dev] + 4,
 				     wssirq[dev],
@@ -485,12 +494,11 @@ static int __devinit snd_cmi8330_probe(int dev,
 				     AD1848_HW_DETECT,
 				     &acard->wss)) < 0) {
 		snd_printk(KERN_ERR PFX "(AD1848) device busy??\n");
-		goto _err;
+		return err;
 	}
 	if (acard->wss->hardware != AD1848_HW_CMI8330) {
 		snd_printk(KERN_ERR PFX "(AD1848) not found during probe\n");
-		err = -ENODEV;
-		goto _err;
+		return -ENODEV;
 	}
 
 	if ((err = snd_sbdsp_create(card, sbport[dev],
@@ -500,11 +508,11 @@ static int __devinit snd_cmi8330_probe(int dev,
 				    sbdma16[dev],
 				    SB_HW_AUTO, &acard->sb)) < 0) {
 		snd_printk(KERN_ERR PFX "(SB16) device busy??\n");
-		goto _err;
+		return err;
 	}
 	if (acard->sb->hardware != SB_HW_16) {
 		snd_printk(KERN_ERR PFX "(SB16) not found during probe\n");
-		goto _err;
+		return err;
 	}
 
 	snd_ad1848_out(acard->wss, AD1848_MISC_INFO, 0x40); /* switch on MODE2 */
@@ -513,12 +521,12 @@ static int __devinit snd_cmi8330_probe(int dev,
 
 	if ((err = snd_cmi8330_mixer(card, acard)) < 0) {
 		snd_printk(KERN_ERR PFX "failed to create mixers\n");
-		goto _err;
+		return err;
 	}
 
 	if ((err = snd_cmi8330_pcm(card, acard)) < 0) {
 		snd_printk(KERN_ERR PFX "failed to create pcms\n");
-		goto _err;
+		return err;
 	}
 
 	strcpy(card->driver, "CMI8330/C3D");
@@ -529,79 +537,162 @@ static int __devinit snd_cmi8330_probe(int dev,
 		wssirq[dev],
 		wssdma[dev]);
 
-	if ((err = snd_card_set_generic_dev(card)) < 0)
-		goto _err;
+	return snd_card_register(card);
+}
+
+static int __init snd_cmi8330_nonpnp_probe(struct platform_device *pdev)
+{
+	struct snd_card *card;
+	int err;
+	int dev = pdev->id;
 
-	if ((err = snd_card_register(card)) < 0)
-		goto _err;
+	if (wssport[dev] == SNDRV_AUTO_PORT) {
+		snd_printk(KERN_ERR PFX "specify wssport\n");
+		return -EINVAL;
+	}
+	if (sbport[dev] == SNDRV_AUTO_PORT) {
+		snd_printk(KERN_ERR PFX "specify sbport\n");
+		return -EINVAL;
+	}
 
-	if (pcard)
-		pnp_set_card_drvdata(pcard, card);
-	else
-		snd_cmi8330_legacy[dev] = card;
+	card = snd_cmi8330_card_new(dev);
+	if (! card)
+		return -ENOMEM;
+	snd_card_set_dev(card, &pdev->dev);
+	if ((err = snd_cmi8330_probe(card, dev)) < 0) {
+		snd_card_free(card);
+		return err;
+	}
+	platform_set_drvdata(pdev, card);
 	return 0;
+}
+
+static int snd_cmi8330_nonpnp_remove(struct platform_device *devptr)
+{
+	snd_card_free(platform_get_drvdata(devptr));
+	platform_set_drvdata(devptr, NULL);
+	return 0;
+}
 
- _err:
-	snd_card_free(card);
-	return err;
+#ifdef CONFIG_PM
+static int snd_cmi8330_nonpnp_suspend(struct platform_device *dev, pm_message_t state)
+{
+	return snd_cmi8330_suspend(platform_get_drvdata(dev));
 }
 
+static int snd_cmi8330_nonpnp_resume(struct platform_device *dev)
+{
+	return snd_cmi8330_resume(platform_get_drvdata(dev));
+}
+#endif
+
+#define CMI8330_DRIVER	"snd_cmi8330"
+
+static struct platform_driver snd_cmi8330_driver = {
+	.probe		= snd_cmi8330_nonpnp_probe,
+	.remove		= snd_cmi8330_nonpnp_remove,
+#ifdef CONFIG_PM
+	.suspend	= snd_cmi8330_nonpnp_suspend,
+	.resume		= snd_cmi8330_nonpnp_resume,
+#endif
+	.driver		= {
+		.name	= CMI8330_DRIVER
+	},
+};
+
+
 #ifdef CONFIG_PNP
-static int __devinit snd_cmi8330_pnp_detect(struct pnp_card_link *card,
-					    const struct pnp_card_device_id *id)
+static int __devinit snd_cmi8330_pnp_detect(struct pnp_card_link *pcard,
+					    const struct pnp_card_device_id *pid)
 {
 	static int dev;
+	struct snd_card *card;
 	int res;
 
 	for ( ; dev < SNDRV_CARDS; dev++) {
-		if (!enable[dev] || !isapnp[dev])
-			continue;
-		res = snd_cmi8330_probe(dev, card, id);
-		if (res < 0)
-			return res;
-		dev++;
-		return 0;
+		if (enable[dev] && isapnp[dev])
+			break;
+	}
+	if (dev >= SNDRV_CARDS)
+		return -ENODEV;
+			       
+	card = snd_cmi8330_card_new(dev);
+	if (! card)
+		return -ENOMEM;
+	if ((res = snd_cmi8330_pnp(dev, card->private_data, pcard, pid)) < 0) {
+		snd_printk(KERN_ERR PFX "PnP detection failed\n");
+		snd_card_free(card);
+		return res;
+	}
+	snd_card_set_dev(card, &pcard->card->dev);
+	if ((res = snd_cmi8330_probe(card, dev)) < 0) {
+		snd_card_free(card);
+		return res;
 	}
-	return -ENODEV;
+	pnp_set_card_drvdata(pcard, card);
+	dev++;
+	return 0;
 }
 
 static void __devexit snd_cmi8330_pnp_remove(struct pnp_card_link * pcard)
 {
-	struct snd_card *card = (struct snd_card *) pnp_get_card_drvdata(pcard);
+	snd_card_free(pnp_get_card_drvdata(pcard));
+	pnp_set_card_drvdata(pcard, NULL);
+}
 
-	snd_card_disconnect(card);
-	snd_card_free_in_thread(card);
+#ifdef CONFIG_PM
+static int snd_cmi8330_pnp_suspend(struct pnp_card_link *pcard, pm_message_t state)
+{
+	return snd_cmi8330_suspend(pnp_get_card_drvdata(pcard));
 }
 
+static int snd_cmi8330_pnp_resume(struct pnp_card_link *pcard)
+{
+	return snd_cmi8330_resume(pnp_get_card_drvdata(pcard));
+}
+#endif
+
 static struct pnp_card_driver cmi8330_pnpc_driver = {
 	.flags = PNP_DRIVER_RES_DISABLE,
 	.name = "cmi8330",
 	.id_table = snd_cmi8330_pnpids,
 	.probe = snd_cmi8330_pnp_detect,
 	.remove = __devexit_p(snd_cmi8330_pnp_remove),
+#ifdef CONFIG_PM
+	.suspend	= snd_cmi8330_pnp_suspend,
+	.resume		= snd_cmi8330_pnp_resume,
+#endif
 };
 #endif /* CONFIG_PNP */
 
 static int __init alsa_card_cmi8330_init(void)
 {
-	int dev, cards = 0;
+	int i, err, cards = 0;
 
-	for (dev = 0; dev < SNDRV_CARDS; dev++) {
-		if (!enable[dev])
-			continue;
-		if (is_isapnp_selected(dev))
+	if ((err = platform_driver_register(&snd_cmi8330_driver)) < 0)
+		return err;
+
+	for (i = 0; i < SNDRV_CARDS && enable[i]; i++) {
+		struct platform_device *device;
+		if (is_isapnp_selected(i))
 			continue;
-		if (snd_cmi8330_probe(dev, NULL, NULL) >= 0)
-			cards++;
+		device = platform_device_register_simple(CMI8330_DRIVER,
+							 i, NULL, 0);
+		if (IS_ERR(device)) {
+			err = PTR_ERR(device);
+			platform_driver_unregister(&snd_cmi8330_driver);
+			return err;
+		}
+		cards++;
 	}
-#ifdef CONFIG_PNP
-	cards += pnp_register_card_driver(&cmi8330_pnpc_driver);
-#endif
+
+	err = pnp_register_card_driver(&cmi8330_pnpc_driver);
+	if (err > 0)
+		cards += err;
 
 	if (!cards) {
-#ifdef CONFIG_PNP
 		pnp_unregister_card_driver(&cmi8330_pnpc_driver);
-#endif
+		platform_driver_unregister(&snd_cmi8330_driver);
 #ifdef MODULE
 		snd_printk(KERN_ERR "CMI8330 not found or device busy\n");
 #endif
@@ -612,14 +703,8 @@ static int __init alsa_card_cmi8330_init(void)
 
 static void __exit alsa_card_cmi8330_exit(void)
 {
-	int i;
-
-#ifdef CONFIG_PNP
-	/* PnP cards first */
 	pnp_unregister_card_driver(&cmi8330_pnpc_driver);
-#endif
-	for (i = 0; i < SNDRV_CARDS; i++)
-		snd_card_free(snd_cmi8330_legacy[i]);
+	platform_driver_unregister(&snd_cmi8330_driver);
 }
 
 module_init(alsa_card_cmi8330_init)
-- 
cgit v1.2.3


From f7a9275d949cb0bf1f259a1546e52a0bf518151c Mon Sep 17 00:00:00 2001
From: Clemens Ladisch <clemens@ladisch.de>
Date: Wed, 7 Dec 2005 09:13:42 +0100
Subject: [ALSA] unregister platform devices

Call platform_device_unregister() for all platform devices that we've
registered.

Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
---
 sound/arm/sa11xx-uda1341.c         |  6 +++--
 sound/drivers/dummy.c              | 16 ++++++++++--
 sound/drivers/mpu401/mpu401.c      | 21 +++++++++++-----
 sound/drivers/mtpav.c              |  4 ++-
 sound/drivers/serial-u16550.c      | 16 ++++++++++--
 sound/drivers/virmidi.c            | 16 ++++++++++--
 sound/isa/ad1848/ad1848.c          | 16 ++++++++++--
 sound/isa/cmi8330.c                | 34 +++++++++++++++++++------
 sound/isa/cs423x/cs4231.c          | 16 ++++++++++--
 sound/isa/cs423x/cs4236.c          | 51 +++++++++++++++++++++++++++-----------
 sound/isa/es1688/es1688.c          | 16 ++++++++++--
 sound/isa/es18xx.c                 | 34 +++++++++++++++++++------
 sound/isa/gus/gusclassic.c         | 16 ++++++++++--
 sound/isa/gus/gusextreme.c         | 16 ++++++++++--
 sound/isa/gus/gusmax.c             | 16 ++++++++++--
 sound/isa/gus/interwave.c          | 34 +++++++++++++++++++------
 sound/isa/opl3sa2.c                | 43 ++++++++++++++++++++++++--------
 sound/isa/opti9xx/opti92x-ad1848.c |  9 +++++--
 sound/isa/sb/sb16.c                | 42 ++++++++++++++++++++++---------
 sound/isa/sb/sb8.c                 | 16 ++++++++++--
 sound/isa/sgalaxy.c                | 16 ++++++++++--
 sound/isa/sscape.c                 | 33 ++++++++++++++++++------
 sound/isa/wavefront/wavefront.c    | 35 ++++++++++++++++++++------
 sound/ppc/powermac.c               |  4 ++-
 24 files changed, 415 insertions(+), 111 deletions(-)

(limited to 'sound/isa/cmi8330.c')

diff --git a/sound/arm/sa11xx-uda1341.c b/sound/arm/sa11xx-uda1341.c
index 3c342c1a7c80..13057d92f08a 100644
--- a/sound/arm/sa11xx-uda1341.c
+++ b/sound/arm/sa11xx-uda1341.c
@@ -21,7 +21,7 @@
  *                              merged HAL layer (patches from Brian)
  */
 
-/* $Id: sa11xx-uda1341.c,v 1.26 2005/11/17 17:19:50 tiwai Exp $ */
+/* $Id: sa11xx-uda1341.c,v 1.27 2005/12/07 09:13:42 cladisch Exp $ */
 
 /***************************************************************************************************
 *
@@ -155,6 +155,8 @@ static struct snd_pcm_hw_constraint_list hw_constraints_rates = {
 	.mask	= 0,
 };
 
+static struct platform_device *device;
+
 /* }}} */
 
 /* {{{ Clock and sample rate stuff */
@@ -976,7 +978,6 @@ static struct platform_driver sa11xx_uda1341_driver = {
 static int __init sa11xx_uda1341_init(void)
 {
 	int err;
-	struct platform_device *device;
 
 	if (!machine_is_h3xxx())
 		return -ENODEV;
@@ -992,6 +993,7 @@ static int __init sa11xx_uda1341_init(void)
 
 static void __exit sa11xx_uda1341_exit(void)
 {
+	platform_device_unregister(device);
 	platform_driver_unregister(&sa11xx_uda1341_driver);
 }
 
diff --git a/sound/drivers/dummy.c b/sound/drivers/dummy.c
index 186117571745..96d207051628 100644
--- a/sound/drivers/dummy.c
+++ b/sound/drivers/dummy.c
@@ -144,6 +144,8 @@ MODULE_PARM_DESC(pcm_substreams, "PCM substreams # (1-16) for dummy driver.");
 //module_param_array(midi_devs, int, NULL, 0444);
 //MODULE_PARM_DESC(midi_devs, "MIDI devices # (0-2) for dummy driver.");
 
+static struct platform_device *devices[SNDRV_CARDS];
+
 #define MIXER_ADDR_MASTER	0
 #define MIXER_ADDR_LINE		1
 #define MIXER_ADDR_MIC		2
@@ -634,6 +636,15 @@ static struct platform_driver snd_dummy_driver = {
 	},
 };
 
+static void __init_or_module snd_dummy_unregister_all(void)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(devices); ++i)
+		platform_device_unregister(devices[i]);
+	platform_driver_unregister(&snd_dummy_driver);
+}
+
 static int __init alsa_card_dummy_init(void)
 {
 	int i, cards, err;
@@ -650,6 +661,7 @@ static int __init alsa_card_dummy_init(void)
 			err = PTR_ERR(device);
 			goto errout;
 		}
+		devices[i] = device;
 		cards++;
 	}
 	if (!cards) {
@@ -662,13 +674,13 @@ static int __init alsa_card_dummy_init(void)
 	return 0;
 
  errout:
-	platform_driver_unregister(&snd_dummy_driver);
+	snd_dummy_unregister_all();
 	return err;
 }
 
 static void __exit alsa_card_dummy_exit(void)
 {
-	platform_driver_unregister(&snd_dummy_driver);
+	snd_dummy_unregister_all();
 }
 
 module_init(alsa_card_dummy_init)
diff --git a/sound/drivers/mpu401/mpu401.c b/sound/drivers/mpu401/mpu401.c
index ec817a86d3dd..915589a402ab 100644
--- a/sound/drivers/mpu401/mpu401.c
+++ b/sound/drivers/mpu401/mpu401.c
@@ -58,6 +58,7 @@ MODULE_PARM_DESC(port, "Port # for MPU-401 device.");
 module_param_array(irq, int, NULL, 0444);
 MODULE_PARM_DESC(irq, "IRQ # for MPU-401 device.");
 
+static struct platform_device *platform_devices[SNDRV_CARDS];
 static int pnp_registered = 0;
 
 static int snd_mpu401_create(int dev, struct snd_card **rcard)
@@ -220,6 +221,17 @@ static struct pnp_driver snd_mpu401_pnp_driver = {
 static struct pnp_driver snd_mpu401_pnp_driver;
 #endif
 
+static void __init_or_module snd_mpu401_unregister_all(void)
+{
+	int i;
+
+	if (pnp_registered)
+		pnp_unregister_driver(&snd_mpu401_pnp_driver);
+	for (i = 0; i < ARRAY_SIZE(platform_devices); ++i)
+		platform_device_unregister(platform_devices[i]);
+	platform_driver_unregister(&snd_mpu401_driver);
+}
+
 static int __init alsa_card_mpu401_init(void)
 {
 	int i, err, devices;
@@ -240,6 +252,7 @@ static int __init alsa_card_mpu401_init(void)
 			err = PTR_ERR(device);
 			goto errout;
 		}
+		platform_devices[i] = device;
 		devices++;
 	}
 	if ((err = pnp_register_driver(&snd_mpu401_pnp_driver)) >= 0) {
@@ -257,17 +270,13 @@ static int __init alsa_card_mpu401_init(void)
 	return 0;
 
  errout:
-	if (pnp_registered)
-		pnp_unregister_driver(&snd_mpu401_pnp_driver);
-	platform_driver_unregister(&snd_mpu401_driver);
+	snd_mpu401_unregister_all();
 	return err;
 }
 
 static void __exit alsa_card_mpu401_exit(void)
 {
-	if (pnp_registered)
-		pnp_unregister_driver(&snd_mpu401_pnp_driver);
-	platform_driver_unregister(&snd_mpu401_driver);
+	snd_mpu401_unregister_all();
 }
 
 module_init(alsa_card_mpu401_init)
diff --git a/sound/drivers/mtpav.c b/sound/drivers/mtpav.c
index d9c4e224fa5f..b7a0b42813e1 100644
--- a/sound/drivers/mtpav.c
+++ b/sound/drivers/mtpav.c
@@ -95,6 +95,8 @@ MODULE_PARM_DESC(irq, "Parallel IRQ # for MotuMTPAV MIDI.");
 module_param(hwports, int, 0444);
 MODULE_PARM_DESC(hwports, "Hardware ports # for MotuMTPAV MIDI.");
 
+static struct platform_device *device;
+
 /*
  *      defines
  */
@@ -763,7 +765,6 @@ static struct platform_driver snd_mtpav_driver = {
 static int __init alsa_card_mtpav_init(void)
 {
 	int err;
-	struct platform_device *device;
 
 	if ((err = platform_driver_register(&snd_mtpav_driver)) < 0)
 		return err;
@@ -778,6 +779,7 @@ static int __init alsa_card_mtpav_init(void)
 
 static void __exit alsa_card_mtpav_exit(void)
 {
+	platform_device_unregister(device);
 	platform_driver_unregister(&snd_mtpav_driver);
 }
 
diff --git a/sound/drivers/serial-u16550.c b/sound/drivers/serial-u16550.c
index 3381a43c592e..29676d800cae 100644
--- a/sound/drivers/serial-u16550.c
+++ b/sound/drivers/serial-u16550.c
@@ -168,6 +168,8 @@ typedef struct _snd_uart16550 {
 
 } snd_uart16550_t;
 
+static struct platform_device *devices[SNDRV_CARDS];
+
 static inline void snd_uart16550_add_timer(snd_uart16550_t *uart)
 {
 	if (! uart->timer_running) {
@@ -970,6 +972,15 @@ static struct platform_driver snd_serial_driver = {
 	},
 };
 
+static void __init_or_module snd_serial_unregister_all(void)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(devices); ++i)
+		platform_device_unregister(devices[i]);
+	platform_driver_unregister(&snd_serial_driver);
+}
+
 static int __init alsa_card_serial_init(void)
 {
 	int i, cards, err;
@@ -986,6 +997,7 @@ static int __init alsa_card_serial_init(void)
 			err = PTR_ERR(device);
 			goto errout;
 		}
+		devices[i] = device;
 		cards++;
 	}
 	if (! cards) {
@@ -998,13 +1010,13 @@ static int __init alsa_card_serial_init(void)
 	return 0;
 
  errout:
-	platform_driver_unregister(&snd_serial_driver);
+	snd_serial_unregister_all();
 	return err;
 }
 
 static void __exit alsa_card_serial_exit(void)
 {
-	platform_driver_unregister(&snd_serial_driver);
+	snd_serial_unregister_all();
 }
 
 module_init(alsa_card_serial_init)
diff --git a/sound/drivers/virmidi.c b/sound/drivers/virmidi.c
index 9f36a6472478..4258723de2ab 100644
--- a/sound/drivers/virmidi.c
+++ b/sound/drivers/virmidi.c
@@ -82,6 +82,8 @@ struct snd_card_virmidi {
 	struct snd_rawmidi *midi[MAX_MIDI_DEVICES];
 };
 
+static struct platform_device *devices[SNDRV_CARDS];
+
 
 static int __init snd_virmidi_probe(struct platform_device *devptr)
 {
@@ -144,6 +146,15 @@ static struct platform_driver snd_virmidi_driver = {
 	},
 };
 
+static void __init_or_module snd_virmidi_unregister_all(void)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(devices); ++i)
+		platform_device_unregister(devices[i]);
+	platform_driver_unregister(&snd_virmidi_driver);
+}
+
 static int __init alsa_card_virmidi_init(void)
 {
 	int i, cards, err;
@@ -160,6 +171,7 @@ static int __init alsa_card_virmidi_init(void)
 			err = PTR_ERR(device);
 			goto errout;
 		}
+		devices[i] = device;
 		cards++;
 	}
 	if (!cards) {
@@ -172,13 +184,13 @@ static int __init alsa_card_virmidi_init(void)
 	return 0;
 
  errout:
-	platform_driver_unregister(&snd_virmidi_driver);
+	snd_virmidi_unregister_all();
 	return err;
 }
 
 static void __exit alsa_card_virmidi_exit(void)
 {
-	platform_driver_unregister(&snd_virmidi_driver);
+	snd_virmidi_unregister_all();
 }
 
 module_init(alsa_card_virmidi_init)
diff --git a/sound/isa/ad1848/ad1848.c b/sound/isa/ad1848/ad1848.c
index 1019e9fdff53..e091bbeffd2a 100644
--- a/sound/isa/ad1848/ad1848.c
+++ b/sound/isa/ad1848/ad1848.c
@@ -62,6 +62,8 @@ MODULE_PARM_DESC(dma1, "DMA1 # for AD1848 driver.");
 module_param_array(thinkpad, bool, NULL, 0444);
 MODULE_PARM_DESC(thinkpad, "Enable only for the onboard CS4248 of IBM Thinkpad 360/750/755 series.");
 
+static struct platform_device *devices[SNDRV_CARDS];
+
 
 static int __init snd_ad1848_probe(struct platform_device *pdev)
 {
@@ -167,6 +169,15 @@ static struct platform_driver snd_ad1848_driver = {
 	},
 };
 
+static void __init_or_module snd_ad1848_unregister_all(void)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(devices); ++i)
+		platform_device_unregister(devices[i]);
+	platform_driver_unregister(&snd_ad1848_driver);
+}
+
 static int __init alsa_card_ad1848_init(void)
 {
 	int i, cards, err;
@@ -184,6 +195,7 @@ static int __init alsa_card_ad1848_init(void)
 			err = PTR_ERR(device);
 			goto errout;
 		}
+		devices[i] = device;
 		cards++;
 	}
 	if (!cards) {
@@ -196,13 +208,13 @@ static int __init alsa_card_ad1848_init(void)
 	return 0;
 
  errout:
-	platform_driver_unregister(&snd_ad1848_driver);
+	snd_ad1848_unregister_all();
 	return err;
 }
 
 static void __exit alsa_card_ad1848_exit(void)
 {
-	platform_driver_unregister(&snd_ad1848_driver);
+	snd_ad1848_unregister_all();
 }
 
 module_init(alsa_card_ad1848_init)
diff --git a/sound/isa/cmi8330.c b/sound/isa/cmi8330.c
index ba0114ebafde..bd8e23818460 100644
--- a/sound/isa/cmi8330.c
+++ b/sound/isa/cmi8330.c
@@ -108,6 +108,9 @@ MODULE_PARM_DESC(wssirq, "IRQ # for CMI8330 WSS driver.");
 module_param_array(wssdma, int, NULL, 0444);
 MODULE_PARM_DESC(wssdma, "DMA for CMI8330 WSS driver.");
 
+static struct platform_device *platform_devices[SNDRV_CARDS];
+static int pnp_registered;
+
 #define CMI8330_RMUX3D    16
 #define CMI8330_MUTEMUX   17
 #define CMI8330_OUTPUTVOL 18
@@ -665,6 +668,17 @@ static struct pnp_card_driver cmi8330_pnpc_driver = {
 };
 #endif /* CONFIG_PNP */
 
+static void __init_or_module snd_cmi8330_unregister_all(void)
+{
+	int i;
+
+	if (pnp_registered)
+		pnp_unregister_card_driver(&cmi8330_pnpc_driver);
+	for (i = 0; i < ARRAY_SIZE(platform_devices); ++i)
+		platform_device_unregister(platform_devices[i]);
+	platform_driver_unregister(&snd_cmi8330_driver);
+}
+
 static int __init alsa_card_cmi8330_init(void)
 {
 	int i, err, cards = 0;
@@ -680,31 +694,35 @@ static int __init alsa_card_cmi8330_init(void)
 							 i, NULL, 0);
 		if (IS_ERR(device)) {
 			err = PTR_ERR(device);
-			platform_driver_unregister(&snd_cmi8330_driver);
-			return err;
+			goto errout;
 		}
+		platform_devices[i] = device;
 		cards++;
 	}
 
 	err = pnp_register_card_driver(&cmi8330_pnpc_driver);
-	if (err > 0)
+	if (err >= 0) {
+		pnp_registered = 1;
 		cards += err;
+	}
 
 	if (!cards) {
-		pnp_unregister_card_driver(&cmi8330_pnpc_driver);
-		platform_driver_unregister(&snd_cmi8330_driver);
 #ifdef MODULE
 		snd_printk(KERN_ERR "CMI8330 not found or device busy\n");
 #endif
-		return -ENODEV;
+		err = -ENODEV;
+		goto errout;
 	}
 	return 0;
+
+ errout:
+	snd_cmi8330_unregister_all();
+	return err;
 }
 
 static void __exit alsa_card_cmi8330_exit(void)
 {
-	pnp_unregister_card_driver(&cmi8330_pnpc_driver);
-	platform_driver_unregister(&snd_cmi8330_driver);
+	snd_cmi8330_unregister_all();
 }
 
 module_init(alsa_card_cmi8330_init)
diff --git a/sound/isa/cs423x/cs4231.c b/sound/isa/cs423x/cs4231.c
index b5252a5d7412..ab67b5c2590d 100644
--- a/sound/isa/cs423x/cs4231.c
+++ b/sound/isa/cs423x/cs4231.c
@@ -66,6 +66,8 @@ MODULE_PARM_DESC(dma1, "DMA1 # for CS4231 driver.");
 module_param_array(dma2, int, NULL, 0444);
 MODULE_PARM_DESC(dma2, "DMA2 # for CS4231 driver.");
 
+static struct platform_device *devices[SNDRV_CARDS];
+
 
 static int __init snd_cs4231_probe(struct platform_device *pdev)
 {
@@ -183,6 +185,15 @@ static struct platform_driver snd_cs4231_driver = {
 	},
 };
 
+static void __init_or_module snd_cs4231_unregister_all(void)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(devices); ++i)
+		platform_device_unregister(devices[i]);
+	platform_driver_unregister(&snd_cs4231_driver);
+}
+
 static int __init alsa_card_cs4231_init(void)
 {
 	int i, cards, err;
@@ -200,6 +211,7 @@ static int __init alsa_card_cs4231_init(void)
 			err = PTR_ERR(device);
 			goto errout;
 		}
+		devices[i] = device;
 		cards++;
 	}
 	if (!cards) {
@@ -212,13 +224,13 @@ static int __init alsa_card_cs4231_init(void)
 	return 0;
 
  errout:
-	platform_driver_unregister(&snd_cs4231_driver);
+	snd_cs4231_unregister_all();
 	return err;
 }
 
 static void __exit alsa_card_cs4231_exit(void)
 {
-	platform_driver_unregister(&snd_cs4231_driver);
+	snd_cs4231_unregister_all();
 }
 
 module_init(alsa_card_cs4231_init)
diff --git a/sound/isa/cs423x/cs4236.c b/sound/isa/cs423x/cs4236.c
index 9e399b6e6ed9..e1683337e6cd 100644
--- a/sound/isa/cs423x/cs4236.c
+++ b/sound/isa/cs423x/cs4236.c
@@ -124,6 +124,12 @@ MODULE_PARM_DESC(dma1, "DMA1 # for " IDENT " driver.");
 module_param_array(dma2, int, NULL, 0444);
 MODULE_PARM_DESC(dma2, "DMA2 # for " IDENT " driver.");
 
+static struct platform_device *platform_devices[SNDRV_CARDS];
+static int pnpc_registered;
+#ifdef CS4232
+static int pnp_registered;
+#endif
+
 struct snd_card_cs4236 {
 	struct snd_cs4231 *chip;
 	struct resource *res_sb_port;
@@ -737,6 +743,21 @@ static struct pnp_card_driver cs423x_pnpc_driver = {
 };
 #endif /* CONFIG_PNP */
 
+static void __init_or_module snd_cs423x_unregister_all(void)
+{
+	int i;
+
+	if (pnpc_registered)
+		pnp_unregister_card_driver(&cs423x_pnpc_driver);
+#ifdef CS4232
+	if (pnp_registered)
+		pnp_unregister_driver(&cs4232_pnp_driver);
+#endif
+	for (i = 0; i < ARRAY_SIZE(platform_devices); ++i)
+		platform_device_unregister(platform_devices[i]);
+	platform_driver_unregister(&cs423x_nonpnp_driver);
+}
+
 static int __init alsa_card_cs423x_init(void)
 {
 	int i, err, cards = 0;
@@ -752,40 +773,40 @@ static int __init alsa_card_cs423x_init(void)
 							 i, NULL, 0);
 		if (IS_ERR(device)) {
 			err = PTR_ERR(device);
-			platform_driver_unregister(&cs423x_nonpnp_driver);
-			return err;
+			goto errout;
 		}
+		platform_devices[i] = device;
 		cards++;
 	}
 #ifdef CS4232
 	i = pnp_register_driver(&cs4232_pnp_driver);
-	if (i > 0)
+	if (i >= 0) {
+		pnp_registered = 1;
 		cards += i;
+	}
 #endif
 	i = pnp_register_card_driver(&cs423x_pnpc_driver);
-	if (i > 0)
+	if (i >= 0) {
+		pnpc_registered = 1;
 		cards += i;
+	}
 	if (!cards) {
-#ifdef CS4232
-		pnp_unregister_driver(&cs4232_pnp_driver);
-#endif
-		pnp_unregister_card_driver(&cs423x_pnpc_driver);
-		platform_driver_unregister(&cs423x_nonpnp_driver);
 #ifdef MODULE
 		printk(KERN_ERR IDENT " soundcard not found or device busy\n");
 #endif
-		return -ENODEV;
+		err = -ENODEV;
+		goto errout;
 	}
 	return 0;
+
+ errout:
+	snd_cs423x_unregister_all();
+	return err;
 }
 
 static void __exit alsa_card_cs423x_exit(void)
 {
-#ifdef CS4232
-	pnp_unregister_driver(&cs4232_pnp_driver);
-#endif
-	pnp_unregister_card_driver(&cs423x_pnpc_driver);
-	platform_driver_unregister(&cs423x_nonpnp_driver);
+	snd_cs423x_unregister_all();
 }
 
 module_init(alsa_card_cs423x_init)
diff --git a/sound/isa/es1688/es1688.c b/sound/isa/es1688/es1688.c
index 68bd40a76f01..50d23cf3d7cc 100644
--- a/sound/isa/es1688/es1688.c
+++ b/sound/isa/es1688/es1688.c
@@ -69,6 +69,8 @@ MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for ESx688 driver.");
 module_param_array(dma8, int, NULL, 0444);
 MODULE_PARM_DESC(dma8, "8-bit DMA # for ESx688 driver.");
 
+static struct platform_device *devices[SNDRV_CARDS];
+
 #define PFX	"es1688: "
 
 static int __init snd_es1688_probe(struct platform_device *pdev)
@@ -187,6 +189,15 @@ static struct platform_driver snd_es1688_driver = {
 	},
 };
 
+static void __init_or_module snd_es1688_unregister_all(void)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(devices); ++i)
+		platform_device_unregister(devices[i]);
+	platform_driver_unregister(&snd_es1688_driver);
+}
+
 static int __init alsa_card_es1688_init(void)
 {
 	int i, cards, err;
@@ -204,6 +215,7 @@ static int __init alsa_card_es1688_init(void)
 			err = PTR_ERR(device);
 			goto errout;
 		}
+		devices[i] = device;
 		cards++;
 	}
 	if (!cards) {
@@ -216,13 +228,13 @@ static int __init alsa_card_es1688_init(void)
 	return 0;
 
  errout:
-	platform_driver_unregister(&snd_es1688_driver);
+	snd_es1688_unregister_all();
 	return err;
 }
 
 static void __exit alsa_card_es1688_exit(void)
 {
-	platform_driver_unregister(&snd_es1688_driver);
+	snd_es1688_unregister_all();
 }
 
 module_init(alsa_card_es1688_init)
diff --git a/sound/isa/es18xx.c b/sound/isa/es18xx.c
index 34d47132f082..bf5de0782eb0 100644
--- a/sound/isa/es18xx.c
+++ b/sound/isa/es18xx.c
@@ -1877,6 +1877,9 @@ MODULE_PARM_DESC(dma1, "DMA 1 # for ES18xx driver.");
 module_param_array(dma2, int, NULL, 0444);
 MODULE_PARM_DESC(dma2, "DMA 2 # for ES18xx driver.");
 
+static struct platform_device *platform_devices[SNDRV_CARDS];
+static int pnp_registered;
+
 #ifdef CONFIG_PNP
 
 static struct pnp_card_device_id snd_audiodrive_pnpids[] = {
@@ -2202,6 +2205,17 @@ static struct pnp_card_driver es18xx_pnpc_driver = {
 };
 #endif /* CONFIG_PNP */
 
+static void __init_or_module snd_es18xx_unregister_all(void)
+{
+	int i;
+
+	if (pnp_registered)
+		pnp_unregister_card_driver(&es18xx_pnpc_driver);
+	for (i = 0; i < ARRAY_SIZE(platform_devices); ++i)
+		platform_device_unregister(platform_devices[i]);
+	platform_driver_unregister(&snd_es18xx_nonpnp_driver);
+}
+
 static int __init alsa_card_es18xx_init(void)
 {
 	int i, err, cards = 0;
@@ -2217,31 +2231,35 @@ static int __init alsa_card_es18xx_init(void)
 							 i, NULL, 0);
 		if (IS_ERR(device)) {
 			err = PTR_ERR(device);
-			platform_driver_unregister(&snd_es18xx_nonpnp_driver);
-			return err;
+			goto errout;
 		}
+		platform_devices[i] = device;
 		cards++;
 	}
 
 	i = pnp_register_card_driver(&es18xx_pnpc_driver);
-	if (i > 0)
+	if (i >= 0) {
+		pnp_registered = 1;
 		cards += i;
+	}
 
 	if(!cards) {
-		pnp_unregister_card_driver(&es18xx_pnpc_driver);
-		platform_driver_unregister(&snd_es18xx_nonpnp_driver);
 #ifdef MODULE
 		snd_printk(KERN_ERR "ESS AudioDrive ES18xx soundcard not found or device busy\n");
 #endif
-		return -ENODEV;
+		err = -ENODEV;
+		goto errout;
 	}
 	return 0;
+
+ errout:
+	snd_es18xx_unregister_all();
+	return err;
 }
 
 static void __exit alsa_card_es18xx_exit(void)
 {
-	pnp_unregister_card_driver(&es18xx_pnpc_driver);
-	platform_driver_unregister(&snd_es18xx_nonpnp_driver);
+	snd_es18xx_unregister_all();
 }
 
 module_init(alsa_card_es18xx_init)
diff --git a/sound/isa/gus/gusclassic.c b/sound/isa/gus/gusclassic.c
index 57beb74f5b9d..d1165b96fa3f 100644
--- a/sound/isa/gus/gusclassic.c
+++ b/sound/isa/gus/gusclassic.c
@@ -71,6 +71,8 @@ MODULE_PARM_DESC(channels, "GF1 channels for GUS Classic driver.");
 module_param_array(pcm_channels, int, NULL, 0444);
 MODULE_PARM_DESC(pcm_channels, "Reserved PCM channels for GUS Classic driver.");
 
+static struct platform_device *devices[SNDRV_CARDS];
+
 
 #define PFX	"gusclassic: "
 
@@ -227,6 +229,15 @@ static struct platform_driver snd_gusclassic_driver = {
 	},
 };
 
+static void __init_or_module snd_gusclassic_unregister_all(void)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(devices); ++i)
+		platform_device_unregister(devices[i]);
+	platform_driver_unregister(&snd_gusclassic_driver);
+}
+
 static int __init alsa_card_gusclassic_init(void)
 {
 	int i, cards, err;
@@ -244,6 +255,7 @@ static int __init alsa_card_gusclassic_init(void)
 			err = PTR_ERR(device);
 			goto errout;
 		}
+		devices[i] = device;
 		cards++;
 	}
 	if (!cards) {
@@ -256,13 +268,13 @@ static int __init alsa_card_gusclassic_init(void)
 	return 0;
 
  errout:
-	platform_driver_unregister(&snd_gusclassic_driver);
+	snd_gusclassic_unregister_all();
 	return err;
 }
 
 static void __exit alsa_card_gusclassic_exit(void)
 {
-	platform_driver_unregister(&snd_gusclassic_driver);
+	snd_gusclassic_unregister_all();
 }
 
 module_init(alsa_card_gusclassic_init)
diff --git a/sound/isa/gus/gusextreme.c b/sound/isa/gus/gusextreme.c
index 6fad9734a853..239f16e6b9ee 100644
--- a/sound/isa/gus/gusextreme.c
+++ b/sound/isa/gus/gusextreme.c
@@ -87,6 +87,8 @@ MODULE_PARM_DESC(channels, "GF1 channels for GUS Extreme driver.");
 module_param_array(pcm_channels, int, NULL, 0444);
 MODULE_PARM_DESC(pcm_channels, "Reserved PCM channels for GUS Extreme driver.");
 
+struct platform_device *devices[SNDRV_CARDS];
+
 
 #define PFX	"gusextreme: "
 
@@ -337,6 +339,15 @@ static struct platform_driver snd_gusextreme_driver = {
 	},
 };
 
+static void __init_or_module snd_gusextreme_unregister_all(void)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(devices); ++i)
+		platform_device_unregister(devices[i]);
+	platform_driver_unregister(&snd_gusextreme_driver);
+}
+
 static int __init alsa_card_gusextreme_init(void)
 {
 	int i, cards, err;
@@ -354,6 +365,7 @@ static int __init alsa_card_gusextreme_init(void)
 			err = PTR_ERR(device);
 			goto errout;
 		}
+		devices[i] = device;
 		cards++;
 	}
 	if (!cards) {
@@ -366,13 +378,13 @@ static int __init alsa_card_gusextreme_init(void)
 	return 0;
 
  errout:
-	platform_driver_unregister(&snd_gusextreme_driver);
+	snd_gusextreme_unregister_all();
 	return err;
 }
 
 static void __exit alsa_card_gusextreme_exit(void)
 {
-	platform_driver_unregister(&snd_gusextreme_driver);
+	snd_gusextreme_unregister_all();
 }
 
 module_init(alsa_card_gusextreme_init)
diff --git a/sound/isa/gus/gusmax.c b/sound/isa/gus/gusmax.c
index d1b70ee9b039..d4d2b2a517d5 100644
--- a/sound/isa/gus/gusmax.c
+++ b/sound/isa/gus/gusmax.c
@@ -72,6 +72,8 @@ MODULE_PARM_DESC(channels, "Used GF1 channels for GUS MAX driver.");
 module_param_array(pcm_channels, int, NULL, 0444);
 MODULE_PARM_DESC(pcm_channels, "Reserved PCM channels for GUS MAX driver.");
 
+static struct platform_device *devices[SNDRV_CARDS];
+
 struct snd_gusmax {
 	int irq;
 	struct snd_card *card;
@@ -364,6 +366,15 @@ static struct platform_driver snd_gusmax_driver = {
 	},
 };
 
+static void __init_or_module snd_gusmax_unregister_all(void)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(devices); ++i)
+		platform_device_unregister(devices[i]);
+	platform_driver_unregister(&snd_gusmax_driver);
+}
+
 static int __init alsa_card_gusmax_init(void)
 {
 	int i, cards, err;
@@ -381,6 +392,7 @@ static int __init alsa_card_gusmax_init(void)
 			err = PTR_ERR(device);
 			goto errout;
 		}
+		devices[i] = device;
 		cards++;
 	}
 	if (!cards) {
@@ -393,13 +405,13 @@ static int __init alsa_card_gusmax_init(void)
 	return 0;
 
  errout:
-	platform_driver_unregister(&snd_gusmax_driver);
+	snd_gusmax_unregister_all();
 	return err;
 }
 
 static void __exit alsa_card_gusmax_exit(void)
 {
-	platform_driver_unregister(&snd_gusmax_driver);
+	snd_gusmax_unregister_all();
 }
 
 module_init(alsa_card_gusmax_init)
diff --git a/sound/isa/gus/interwave.c b/sound/isa/gus/interwave.c
index 67a5f7402453..9838d992b101 100644
--- a/sound/isa/gus/interwave.c
+++ b/sound/isa/gus/interwave.c
@@ -115,6 +115,9 @@ MODULE_PARM_DESC(pcm_channels, "Reserved PCM channels for InterWave driver.");
 module_param_array(effect, int, NULL, 0444);
 MODULE_PARM_DESC(effect, "Effects enable for InterWave driver.");
 
+static struct platform_device *platform_devices[SNDRV_CARDS];
+static int pnp_registered;
+
 struct snd_interwave {
 	int irq;
 	struct snd_card *card;
@@ -914,6 +917,17 @@ static struct pnp_card_driver interwave_pnpc_driver = {
 
 #endif /* CONFIG_PNP */
 
+static void __init_or_module snd_interwave_unregister_all(void)
+{
+	int i;
+
+	if (pnp_registered)
+		pnp_unregister_card_driver(&interwave_pnpc_driver);
+	for (i = 0; i < ARRAY_SIZE(platform_devices); ++i)
+		platform_device_unregister(platform_devices[i]);
+	platform_driver_unregister(&snd_interwave_driver);
+}
+
 static int __init alsa_card_interwave_init(void)
 {
 	int i, err, cards = 0;
@@ -931,32 +945,36 @@ static int __init alsa_card_interwave_init(void)
 							 i, NULL, 0);
 		if (IS_ERR(device)) {
 			err = PTR_ERR(device);
-			platform_driver_unregister(&snd_interwave_driver);
-			return err;
+			goto errout;
 		}
+		platform_devices[i] = device;
 		cards++;
 	}
 
 	/* ISA PnP cards */
 	i = pnp_register_card_driver(&interwave_pnpc_driver);
-	if (i > 0)
+	if (i >= 0) {
+		pnp_registered = 1;
 		cards += i;
+	}
 
 	if (!cards) {
-		pnp_unregister_card_driver(&interwave_pnpc_driver);
-		platform_driver_unregister(&snd_interwave_driver);
 #ifdef MODULE
 		printk(KERN_ERR "InterWave soundcard not found or device busy\n");
 #endif
-		return -ENODEV;
+		err = -ENODEV;
+		goto errout;
 	}
 	return 0;
+
+ errout:
+	snd_interwave_unregister_all();
+	return err;
 }
 
 static void __exit alsa_card_interwave_exit(void)
 {
-	pnp_unregister_card_driver(&interwave_pnpc_driver);
-	platform_driver_unregister(&snd_interwave_driver);
+	snd_interwave_unregister_all();
 }
 
 module_init(alsa_card_interwave_init)
diff --git a/sound/isa/opl3sa2.c b/sound/isa/opl3sa2.c
index aafe5565b6e5..ca359e0c674b 100644
--- a/sound/isa/opl3sa2.c
+++ b/sound/isa/opl3sa2.c
@@ -90,6 +90,10 @@ MODULE_PARM_DESC(dma2, "DMA2 # for OPL3-SA driver.");
 module_param_array(opl3sa3_ymode, int, NULL, 0444);
 MODULE_PARM_DESC(opl3sa3_ymode, "Speaker size selection for 3D Enhancement mode: Desktop/Large Notebook/Small Notebook/HiFi.");
 
+static struct platform_device *platform_devices[SNDRV_CARDS];
+static int pnp_registered;
+static int pnpc_registered;
+
 /* control ports */
 #define OPL3SA2_PM_CTRL		0x01
 #define OPL3SA2_SYS_CTRL		0x02
@@ -921,6 +925,19 @@ static struct platform_driver snd_opl3sa2_nonpnp_driver = {
 	},
 };
 
+static void __init_or_module snd_opl3sa2_unregister_all(void)
+{
+	int i;
+
+	if (pnpc_registered)
+		pnp_unregister_card_driver(&opl3sa2_pnpc_driver);
+	if (pnp_registered)
+		pnp_unregister_driver(&opl3sa2_pnp_driver);
+	for (i = 0; i < ARRAY_SIZE(platform_devices); ++i)
+		platform_device_unregister(platform_devices[i]);
+	platform_driver_unregister(&snd_opl3sa2_nonpnp_driver);
+}
+
 static int __init alsa_card_opl3sa2_init(void)
 {
 	int i, err, cards = 0;
@@ -938,36 +955,40 @@ static int __init alsa_card_opl3sa2_init(void)
 							 i, NULL, 0);
 		if (IS_ERR(device)) {
 			err = PTR_ERR(device);
-			platform_driver_unregister(&snd_opl3sa2_nonpnp_driver);
-			return err;
+			goto errout;
 		}
+		platform_devices[i] = device;
 		cards++;
 	}
 
 	err = pnp_register_driver(&opl3sa2_pnp_driver);
-	if (err > 0)
+	if (err >= 0) {
+		pnp_registered = 1;
 		cards += err;
+	}
 	err = pnp_register_card_driver(&opl3sa2_pnpc_driver);
-	if (err > 0)
+	if (err >= 0) {
+		pnpc_registered = 1;
 		cards += err;
+	}
 
 	if (!cards) {
 #ifdef MODULE
 		snd_printk(KERN_ERR "Yamaha OPL3-SA soundcard not found or device busy\n");
 #endif
-		pnp_unregister_card_driver(&opl3sa2_pnpc_driver);
-		pnp_unregister_driver(&opl3sa2_pnp_driver);
-		platform_driver_unregister(&snd_opl3sa2_nonpnp_driver);
-		return -ENODEV;
+		err = -ENODEV;
+		goto errout;
 	}
 	return 0;
+
+ errout:
+	snd_opl3sa2_unregister_all();
+	return err;
 }
 
 static void __exit alsa_card_opl3sa2_exit(void)
 {
-	pnp_unregister_card_driver(&opl3sa2_pnpc_driver);
-	pnp_unregister_driver(&opl3sa2_pnp_driver);
-	platform_driver_unregister(&snd_opl3sa2_nonpnp_driver);
+	snd_opl3sa2_unregister_all();
 }
 
 module_init(alsa_card_opl3sa2_init)
diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c
index 39211e58cd68..1ea3944ef7ab 100644
--- a/sound/isa/opti9xx/opti92x-ad1848.c
+++ b/sound/isa/opti9xx/opti92x-ad1848.c
@@ -259,6 +259,7 @@ struct snd_opti9xx {
 };
 
 static int snd_opti9xx_pnp_is_probed;
+static struct platform_device *snd_opti9xx_platform_device;
 
 #ifdef CONFIG_PNP
 
@@ -2095,8 +2096,10 @@ static int __init alsa_card_opti9xx_init(void)
 		if (error < 0)
 			return error;
 		device = platform_device_register_simple(DRIVER_NAME, -1, NULL, 0);
-		if (! IS_ERR(device))
+		if (!IS_ERR(device)) {
+			snd_opti9xx_platform_device = device;
 			return 0;
+		}
 		platform_driver_unregister(&snd_opti9xx_driver);
 	}
 	pnp_unregister_card_driver(&opti9xx_pnpc_driver);
@@ -2108,8 +2111,10 @@ static int __init alsa_card_opti9xx_init(void)
 
 static void __exit alsa_card_opti9xx_exit(void)
 {
-	if (! snd_opti9xx_pnp_is_probed)
+	if (!snd_opti9xx_pnp_is_probed) {
+		platform_device_unregister(snd_opti9xx_platform_device);
 		platform_driver_unregister(&snd_opti9xx_driver);
+	}
 	pnp_unregister_card_driver(&opti9xx_pnpc_driver);
 }
 
diff --git a/sound/isa/sb/sb16.c b/sound/isa/sb/sb16.c
index 05816c5d829a..c0be7a5a3425 100644
--- a/sound/isa/sb/sb16.c
+++ b/sound/isa/sb/sb16.c
@@ -128,6 +128,11 @@ module_param_array(seq_ports, int, NULL, 0444);
 MODULE_PARM_DESC(seq_ports, "Number of sequencer ports for WaveTable synth.");
 #endif
 
+static struct platform_device *platform_devices[SNDRV_CARDS];
+#ifdef CONFIG_PNP
+static int pnp_registered;
+#endif
+
 struct snd_card_sb16 {
 	struct resource *fm_res;	/* used to block FM i/o region for legacy cards */
 	struct snd_sb *chip;
@@ -687,6 +692,19 @@ static struct pnp_card_driver sb16_pnpc_driver = {
 
 #endif /* CONFIG_PNP */
 
+static void __init_or_module snd_sb16_unregister_all(void)
+{
+	int i;
+
+#ifdef CONFIG_PNP
+	if (pnp_registered)
+		pnp_unregister_card_driver(&sb16_pnpc_driver);
+#endif
+	for (i = 0; i < ARRAY_SIZE(platform_devices); ++i)
+		platform_device_unregister(platform_devices[i]);
+	platform_driver_unregister(&snd_sb16_nonpnp_driver);
+}
+
 static int __init alsa_card_sb16_init(void)
 {
 	int i, err, cards = 0;
@@ -702,23 +720,21 @@ static int __init alsa_card_sb16_init(void)
 							 i, NULL, 0);
 		if (IS_ERR(device)) {
 			err = PTR_ERR(device);
-			platform_driver_unregister(&snd_sb16_nonpnp_driver);
-			return err;
+			goto errout;
 		}
+		platform_devices[i] = device;
 		cards++;
 	}
 #ifdef CONFIG_PNP
 	/* PnP cards at last */
 	i = pnp_register_card_driver(&sb16_pnpc_driver);
-	if (i > 0)
+	if (i >= 0) {
+		pnp_registered = 1;
 		cards += i;
+	}
 #endif
 
 	if (!cards) {
-#ifdef CONFIG_PNP
-		pnp_unregister_card_driver(&sb16_pnpc_driver);
-#endif
-		platform_driver_unregister(&snd_sb16_nonpnp_driver);
 #ifdef MODULE
 		snd_printk(KERN_ERR "Sound Blaster 16 soundcard not found or device busy\n");
 #ifdef SNDRV_SBAWE_EMU8000
@@ -727,17 +743,19 @@ static int __init alsa_card_sb16_init(void)
 		snd_printk(KERN_ERR "In case, if you have AWE card, try snd-sbawe module\n");
 #endif
 #endif
-		return -ENODEV;
+		err = -ENODEV;
+		goto errout;
 	}
 	return 0;
+
+ errout:
+	snd_sb16_unregister_all();
+	return err;
 }
 
 static void __exit alsa_card_sb16_exit(void)
 {
-#ifdef CONFIG_PNP
-	pnp_unregister_card_driver(&sb16_pnpc_driver);
-#endif
-	platform_driver_unregister(&snd_sb16_nonpnp_driver);
+	snd_sb16_unregister_all();
 }
 
 module_init(alsa_card_sb16_init)
diff --git a/sound/isa/sb/sb8.c b/sound/isa/sb/sb8.c
index 0a3d55d639a9..60ee79cd14a3 100644
--- a/sound/isa/sb/sb8.c
+++ b/sound/isa/sb/sb8.c
@@ -56,6 +56,8 @@ MODULE_PARM_DESC(irq, "IRQ # for SB8 driver.");
 module_param_array(dma8, int, NULL, 0444);
 MODULE_PARM_DESC(dma8, "8-bit DMA # for SB8 driver.");
 
+static struct platform_device *devices[SNDRV_CARDS];
+
 struct snd_sb8 {
 	struct resource *fm_res;	/* used to block FM i/o region for legacy cards */
 	struct snd_sb *chip;
@@ -238,6 +240,15 @@ static struct platform_driver snd_sb8_driver = {
 	},
 };
 
+static void __init_or_module snd_sb8_unregister_all(void)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(devices); ++i)
+		platform_device_unregister(devices[i]);
+	platform_driver_unregister(&snd_sb8_driver);
+}
+
 static int __init alsa_card_sb8_init(void)
 {
 	int i, cards, err;
@@ -255,6 +266,7 @@ static int __init alsa_card_sb8_init(void)
 			err = PTR_ERR(device);
 			goto errout;
 		}
+		devices[i] = device;
 		cards++;
 	}
 	if (!cards) {
@@ -267,13 +279,13 @@ static int __init alsa_card_sb8_init(void)
 	return 0;
 
  errout:
-	platform_driver_unregister(&snd_sb8_driver);
+	snd_sb8_unregister_all();
 	return err;
 }
 
 static void __exit alsa_card_sb8_exit(void)
 {
-	platform_driver_unregister(&snd_sb8_driver);
+	snd_sb8_unregister_all();
 }
 
 module_init(alsa_card_sb8_init)
diff --git a/sound/isa/sgalaxy.c b/sound/isa/sgalaxy.c
index 2e1d4677fe12..0dbbb35b242c 100644
--- a/sound/isa/sgalaxy.c
+++ b/sound/isa/sgalaxy.c
@@ -64,6 +64,8 @@ MODULE_PARM_DESC(irq, "IRQ # for Sound Galaxy driver.");
 module_param_array(dma1, int, NULL, 0444);
 MODULE_PARM_DESC(dma1, "DMA1 # for Sound Galaxy driver.");
 
+static struct platform_device *devices[SNDRV_CARDS];
+
 #define SGALAXY_AUXC_LEFT 18
 #define SGALAXY_AUXC_RIGHT 19
 
@@ -340,6 +342,15 @@ static struct platform_driver snd_sgalaxy_driver = {
 	},
 };
 
+static void __init_or_module snd_sgalaxy_unregister_all(void)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(devices); ++i)
+		platform_device_unregister(devices[i]);
+	platform_driver_unregister(&snd_sgalaxy_driver);
+}
+
 static int __init alsa_card_sgalaxy_init(void)
 {
 	int i, cards, err;
@@ -357,6 +368,7 @@ static int __init alsa_card_sgalaxy_init(void)
 			err = PTR_ERR(device);
 			goto errout;
 		}
+		devices[i] = device;
 		cards++;
 	}
 	if (!cards) {
@@ -369,13 +381,13 @@ static int __init alsa_card_sgalaxy_init(void)
 	return 0;
 
  errout:
-	platform_driver_unregister(&snd_sgalaxy_driver);
+	snd_sgalaxy_unregister_all();
 	return err;
 }
 
 static void __exit alsa_card_sgalaxy_exit(void)
 {
-	platform_driver_unregister(&snd_sgalaxy_driver);
+	snd_sgalaxy_unregister_all();
 }
 
 module_init(alsa_card_sgalaxy_init)
diff --git a/sound/isa/sscape.c b/sound/isa/sscape.c
index 6271efe689df..5fb981c0a281 100644
--- a/sound/isa/sscape.c
+++ b/sound/isa/sscape.c
@@ -67,6 +67,9 @@ MODULE_PARM_DESC(mpu_irq, "MPU401 IRQ # for SoundScape driver.");
 
 module_param_array(dma, int, NULL, 0444);
 MODULE_PARM_DESC(dma, "DMA # for SoundScape driver.");
+
+static struct platform_device *platform_devices[SNDRV_CARDS];
+static int pnp_registered;
   
 #ifdef CONFIG_PNP
 static struct pnp_card_device_id sscape_pnpids[] = {
@@ -1384,6 +1387,17 @@ static struct pnp_card_driver sscape_pnpc_driver = {
 
 #endif /* CONFIG_PNP */
 
+static void __init_or_module sscape_unregister_all(void)
+{
+	int i;
+
+	if (pnp_registered)
+		pnp_unregister_card_driver(&sscape_pnpc_driver);
+	for (i = 0; i < ARRAY_SIZE(platform_devices); ++i)
+		platform_device_unregister(platform_devices[i]);
+	platform_driver_unregister(&snd_sscape_driver);
+}
+
 static int __init sscape_manual_probe(void)
 {
 	struct platform_device *device;
@@ -1411,8 +1425,8 @@ static int __init sscape_manual_probe(void)
 		    dma[i] == SNDRV_AUTO_DMA) {
 			printk(KERN_INFO
 			       "sscape: insufficient parameters, need IO, IRQ, MPU-IRQ and DMA\n");
-			platform_driver_unregister(&snd_sscape_driver);
-			return -ENXIO;
+			ret = -ENXIO;
+			goto errout;
 		}
 
 		/*
@@ -1421,17 +1435,21 @@ static int __init sscape_manual_probe(void)
 		device = platform_device_register_simple(SSCAPE_DRIVER,
 							 i, NULL, 0);
 		if (IS_ERR(device)) {
-			platform_driver_unregister(&snd_sscape_driver);
-			return PTR_ERR(device);
+			ret = PTR_ERR(device);
+			goto errout;
 		}
+		platform_devices[i] = device;
 	}
 	return 0;
+
+ errout:
+	sscape_unregister_all();
+	return ret;
 }
 
 static void sscape_exit(void)
 {
-	pnp_unregister_card_driver(&sscape_pnpc_driver);
-	platform_driver_unregister(&snd_sscape_driver);
+	sscape_unregister_all();
 }
 
 
@@ -1448,7 +1466,8 @@ static int __init sscape_init(void)
 	ret = sscape_manual_probe();
 	if (ret < 0)
 		return ret;
-	pnp_register_card_driver(&sscape_pnpc_driver);
+	if (pnp_register_card_driver(&sscape_pnpc_driver) >= 0)
+		pnp_registered = 1;
 	return 0;
 }
 
diff --git a/sound/isa/wavefront/wavefront.c b/sound/isa/wavefront/wavefront.c
index 77a3012e5510..a6dcb2f970ca 100644
--- a/sound/isa/wavefront/wavefront.c
+++ b/sound/isa/wavefront/wavefront.c
@@ -83,6 +83,9 @@ MODULE_PARM_DESC(fm_port, "FM port #.");
 module_param_array(use_cs4232_midi, bool, NULL, 0444);
 MODULE_PARM_DESC(use_cs4232_midi, "Use CS4232 MPU-401 interface (inaccessibly located inside your computer)");
 
+static struct platform_device *platform_devices[SNDRV_CARDS];
+static int pnp_registered;
+
 
 #ifdef CONFIG_PNP
 
@@ -688,6 +691,17 @@ static struct pnp_card_driver wavefront_pnpc_driver = {
 
 #endif /* CONFIG_PNP */
 
+static void __init_or_module snd_wavefront_unregister_all(void)
+{
+	int i;
+
+	if (pnp_registered)
+		pnp_unregister_card_driver(&wavefront_pnpc_driver);
+	for (i = 0; i < ARRAY_SIZE(platform_devices); ++i)
+		platform_device_unregister(platform_devices[i]);
+	platform_driver_unregister(&snd_wavefront_driver);
+}
+
 static int __init alsa_card_wavefront_init(void)
 {
 	int i, err, cards = 0;
@@ -704,31 +718,36 @@ static int __init alsa_card_wavefront_init(void)
 		device = platform_device_register_simple(WAVEFRONT_DRIVER,
 							 i, NULL, 0);
 		if (IS_ERR(device)) {
-			platform_driver_unregister(&snd_wavefront_driver);
-			return PTR_ERR(device);
+			err = PTR_ERR(device);
+			goto errout;
 		}
+		platform_devices[i] = device;
 		cards++;
 	}
 
 	i = pnp_register_card_driver(&wavefront_pnpc_driver);
-	if (i > 0)
+	if (i >= 0) {
+		pnp_registered = 1;
 		cards += i;
+	}
 
 	if (!cards) {
-		pnp_unregister_card_driver(&wavefront_pnpc_driver);
-		platform_driver_unregister(&snd_wavefront_driver);
 #ifdef MODULE
 		printk (KERN_ERR "No WaveFront cards found or devices busy\n");
 #endif
-		return -ENODEV;
+		err = -ENODEV;
+		goto errout;
 	}
 	return 0;
+
+ errout:
+	snd_wavefront_unregister_all();
+	return err;
 }
 
 static void __exit alsa_card_wavefront_exit(void)
 {
-	pnp_unregister_card_driver(&wavefront_pnpc_driver);
-	platform_driver_unregister(&snd_wavefront_driver);
+	snd_wavefront_unregister_all();
 }
 
 module_init(alsa_card_wavefront_init)
diff --git a/sound/ppc/powermac.c b/sound/ppc/powermac.c
index efa06fe5f01b..f4902a219e50 100644
--- a/sound/ppc/powermac.c
+++ b/sound/ppc/powermac.c
@@ -46,6 +46,8 @@ MODULE_PARM_DESC(id, "ID string for " CHIP_NAME " soundchip.");
 module_param(enable_beep, bool, 0444);
 MODULE_PARM_DESC(enable_beep, "Enable beep using PCM.");
 
+static struct platform_device *device;
+
 
 /*
  */
@@ -182,7 +184,6 @@ static struct platform_driver snd_pmac_driver = {
 static int __init alsa_card_pmac_init(void)
 {
 	int err;
-	struct platform_device *device;
 
 	if ((err = platform_driver_register(&snd_pmac_driver)) < 0)
 		return err;
@@ -197,6 +198,7 @@ static int __init alsa_card_pmac_init(void)
 
 static void __exit alsa_card_pmac_exit(void)
 {
+	platform_device_unregister(device);
 	platform_driver_unregister(&snd_pmac_driver);
 }
 
-- 
cgit v1.2.3