summaryrefslogtreecommitdiff
path: root/sound/isa
diff options
context:
space:
mode:
authorClemens Ladisch <clemens@ladisch.de>2005-12-07 09:13:42 +0100
committerJaroslav Kysela <perex@suse.cz>2006-01-03 12:30:39 +0100
commitf7a9275d949cb0bf1f259a1546e52a0bf518151c (patch)
tree4d96d9b6196d43684903857ba676dc51bbde4026 /sound/isa
parent416c1079d30f1a52399b96f6772e993274b774ae (diff)
downloadlinux-3.10-f7a9275d949cb0bf1f259a1546e52a0bf518151c.tar.gz
linux-3.10-f7a9275d949cb0bf1f259a1546e52a0bf518151c.tar.bz2
linux-3.10-f7a9275d949cb0bf1f259a1546e52a0bf518151c.zip
[ALSA] unregister platform devices
Call platform_device_unregister() for all platform devices that we've registered. Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
Diffstat (limited to 'sound/isa')
-rw-r--r--sound/isa/ad1848/ad1848.c16
-rw-r--r--sound/isa/cmi8330.c34
-rw-r--r--sound/isa/cs423x/cs4231.c16
-rw-r--r--sound/isa/cs423x/cs4236.c51
-rw-r--r--sound/isa/es1688/es1688.c16
-rw-r--r--sound/isa/es18xx.c34
-rw-r--r--sound/isa/gus/gusclassic.c16
-rw-r--r--sound/isa/gus/gusextreme.c16
-rw-r--r--sound/isa/gus/gusmax.c16
-rw-r--r--sound/isa/gus/interwave.c34
-rw-r--r--sound/isa/opl3sa2.c43
-rw-r--r--sound/isa/opti9xx/opti92x-ad1848.c9
-rw-r--r--sound/isa/sb/sb16.c42
-rw-r--r--sound/isa/sb/sb8.c16
-rw-r--r--sound/isa/sgalaxy.c16
-rw-r--r--sound/isa/sscape.c33
-rw-r--r--sound/isa/wavefront/wavefront.c35
17 files changed, 348 insertions, 95 deletions
diff --git a/sound/isa/ad1848/ad1848.c b/sound/isa/ad1848/ad1848.c
index 1019e9fdff5..e091bbeffd2 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 ba0114ebafd..bd8e2381846 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 b5252a5d741..ab67b5c2590 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 9e399b6e6ed..e1683337e6c 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 68bd40a76f0..50d23cf3d7c 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 34d47132f08..bf5de0782eb 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 57beb74f5b9..d1165b96fa3 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 6fad9734a85..239f16e6b9e 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 d1b70ee9b03..d4d2b2a517d 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 67a5f740245..9838d992b10 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 aafe5565b6e..ca359e0c674 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 39211e58cd6..1ea3944ef7a 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 05816c5d829..c0be7a5a342 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 0a3d55d639a..60ee79cd14a 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 2e1d4677fe1..0dbbb35b242 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 6271efe689d..5fb981c0a28 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 77a3012e551..a6dcb2f970c 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)