From f7a9275d949cb0bf1f259a1546e52a0bf518151c Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Wed, 7 Dec 2005 09:13:42 +0100 Subject: [PATCH] [ALSA] unregister platform devices Call platform_device_unregister() for all platform devices that we've registered. Signed-off-by: Clemens Ladisch --- 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(-) 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); } -- 2.20.1