Commit f7a9275d949cb0bf1f259a1546e52a0bf518151c
Committed by
Jaroslav Kysela
1 parent
416c1079d3
Exists in
master
and in
7 other branches
[ALSA] unregister platform devices
Call platform_device_unregister() for all platform devices that we've registered. Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
Showing 24 changed files with 415 additions and 111 deletions Side-by-side Diff
- sound/arm/sa11xx-uda1341.c
- sound/drivers/dummy.c
- sound/drivers/mpu401/mpu401.c
- sound/drivers/mtpav.c
- sound/drivers/serial-u16550.c
- sound/drivers/virmidi.c
- sound/isa/ad1848/ad1848.c
- sound/isa/cmi8330.c
- sound/isa/cs423x/cs4231.c
- sound/isa/cs423x/cs4236.c
- sound/isa/es1688/es1688.c
- sound/isa/es18xx.c
- sound/isa/gus/gusclassic.c
- sound/isa/gus/gusextreme.c
- sound/isa/gus/gusmax.c
- sound/isa/gus/interwave.c
- sound/isa/opl3sa2.c
- sound/isa/opti9xx/opti92x-ad1848.c
- sound/isa/sb/sb16.c
- sound/isa/sb/sb8.c
- sound/isa/sgalaxy.c
- sound/isa/sscape.c
- sound/isa/wavefront/wavefront.c
- sound/ppc/powermac.c
sound/arm/sa11xx-uda1341.c
... | ... | @@ -21,7 +21,7 @@ |
21 | 21 | * merged HAL layer (patches from Brian) |
22 | 22 | */ |
23 | 23 | |
24 | -/* $Id: sa11xx-uda1341.c,v 1.26 2005/11/17 17:19:50 tiwai Exp $ */ | |
24 | +/* $Id: sa11xx-uda1341.c,v 1.27 2005/12/07 09:13:42 cladisch Exp $ */ | |
25 | 25 | |
26 | 26 | /*************************************************************************************************** |
27 | 27 | * |
... | ... | @@ -155,6 +155,8 @@ |
155 | 155 | .mask = 0, |
156 | 156 | }; |
157 | 157 | |
158 | +static struct platform_device *device; | |
159 | + | |
158 | 160 | /* }}} */ |
159 | 161 | |
160 | 162 | /* {{{ Clock and sample rate stuff */ |
... | ... | @@ -976,7 +978,6 @@ |
976 | 978 | static int __init sa11xx_uda1341_init(void) |
977 | 979 | { |
978 | 980 | int err; |
979 | - struct platform_device *device; | |
980 | 981 | |
981 | 982 | if (!machine_is_h3xxx()) |
982 | 983 | return -ENODEV; |
... | ... | @@ -992,6 +993,7 @@ |
992 | 993 | |
993 | 994 | static void __exit sa11xx_uda1341_exit(void) |
994 | 995 | { |
996 | + platform_device_unregister(device); | |
995 | 997 | platform_driver_unregister(&sa11xx_uda1341_driver); |
996 | 998 | } |
997 | 999 |
sound/drivers/dummy.c
... | ... | @@ -144,6 +144,8 @@ |
144 | 144 | //module_param_array(midi_devs, int, NULL, 0444); |
145 | 145 | //MODULE_PARM_DESC(midi_devs, "MIDI devices # (0-2) for dummy driver."); |
146 | 146 | |
147 | +static struct platform_device *devices[SNDRV_CARDS]; | |
148 | + | |
147 | 149 | #define MIXER_ADDR_MASTER 0 |
148 | 150 | #define MIXER_ADDR_LINE 1 |
149 | 151 | #define MIXER_ADDR_MIC 2 |
... | ... | @@ -634,6 +636,15 @@ |
634 | 636 | }, |
635 | 637 | }; |
636 | 638 | |
639 | +static void __init_or_module snd_dummy_unregister_all(void) | |
640 | +{ | |
641 | + int i; | |
642 | + | |
643 | + for (i = 0; i < ARRAY_SIZE(devices); ++i) | |
644 | + platform_device_unregister(devices[i]); | |
645 | + platform_driver_unregister(&snd_dummy_driver); | |
646 | +} | |
647 | + | |
637 | 648 | static int __init alsa_card_dummy_init(void) |
638 | 649 | { |
639 | 650 | int i, cards, err; |
... | ... | @@ -650,6 +661,7 @@ |
650 | 661 | err = PTR_ERR(device); |
651 | 662 | goto errout; |
652 | 663 | } |
664 | + devices[i] = device; | |
653 | 665 | cards++; |
654 | 666 | } |
655 | 667 | if (!cards) { |
656 | 668 | |
... | ... | @@ -662,13 +674,13 @@ |
662 | 674 | return 0; |
663 | 675 | |
664 | 676 | errout: |
665 | - platform_driver_unregister(&snd_dummy_driver); | |
677 | + snd_dummy_unregister_all(); | |
666 | 678 | return err; |
667 | 679 | } |
668 | 680 | |
669 | 681 | static void __exit alsa_card_dummy_exit(void) |
670 | 682 | { |
671 | - platform_driver_unregister(&snd_dummy_driver); | |
683 | + snd_dummy_unregister_all(); | |
672 | 684 | } |
673 | 685 | |
674 | 686 | module_init(alsa_card_dummy_init) |
sound/drivers/mpu401/mpu401.c
... | ... | @@ -58,6 +58,7 @@ |
58 | 58 | module_param_array(irq, int, NULL, 0444); |
59 | 59 | MODULE_PARM_DESC(irq, "IRQ # for MPU-401 device."); |
60 | 60 | |
61 | +static struct platform_device *platform_devices[SNDRV_CARDS]; | |
61 | 62 | static int pnp_registered = 0; |
62 | 63 | |
63 | 64 | static int snd_mpu401_create(int dev, struct snd_card **rcard) |
... | ... | @@ -220,6 +221,17 @@ |
220 | 221 | static struct pnp_driver snd_mpu401_pnp_driver; |
221 | 222 | #endif |
222 | 223 | |
224 | +static void __init_or_module snd_mpu401_unregister_all(void) | |
225 | +{ | |
226 | + int i; | |
227 | + | |
228 | + if (pnp_registered) | |
229 | + pnp_unregister_driver(&snd_mpu401_pnp_driver); | |
230 | + for (i = 0; i < ARRAY_SIZE(platform_devices); ++i) | |
231 | + platform_device_unregister(platform_devices[i]); | |
232 | + platform_driver_unregister(&snd_mpu401_driver); | |
233 | +} | |
234 | + | |
223 | 235 | static int __init alsa_card_mpu401_init(void) |
224 | 236 | { |
225 | 237 | int i, err, devices; |
... | ... | @@ -240,6 +252,7 @@ |
240 | 252 | err = PTR_ERR(device); |
241 | 253 | goto errout; |
242 | 254 | } |
255 | + platform_devices[i] = device; | |
243 | 256 | devices++; |
244 | 257 | } |
245 | 258 | if ((err = pnp_register_driver(&snd_mpu401_pnp_driver)) >= 0) { |
246 | 259 | |
... | ... | @@ -257,17 +270,13 @@ |
257 | 270 | return 0; |
258 | 271 | |
259 | 272 | errout: |
260 | - if (pnp_registered) | |
261 | - pnp_unregister_driver(&snd_mpu401_pnp_driver); | |
262 | - platform_driver_unregister(&snd_mpu401_driver); | |
273 | + snd_mpu401_unregister_all(); | |
263 | 274 | return err; |
264 | 275 | } |
265 | 276 | |
266 | 277 | static void __exit alsa_card_mpu401_exit(void) |
267 | 278 | { |
268 | - if (pnp_registered) | |
269 | - pnp_unregister_driver(&snd_mpu401_pnp_driver); | |
270 | - platform_driver_unregister(&snd_mpu401_driver); | |
279 | + snd_mpu401_unregister_all(); | |
271 | 280 | } |
272 | 281 | |
273 | 282 | module_init(alsa_card_mpu401_init) |
sound/drivers/mtpav.c
... | ... | @@ -95,6 +95,8 @@ |
95 | 95 | module_param(hwports, int, 0444); |
96 | 96 | MODULE_PARM_DESC(hwports, "Hardware ports # for MotuMTPAV MIDI."); |
97 | 97 | |
98 | +static struct platform_device *device; | |
99 | + | |
98 | 100 | /* |
99 | 101 | * defines |
100 | 102 | */ |
... | ... | @@ -763,7 +765,6 @@ |
763 | 765 | static int __init alsa_card_mtpav_init(void) |
764 | 766 | { |
765 | 767 | int err; |
766 | - struct platform_device *device; | |
767 | 768 | |
768 | 769 | if ((err = platform_driver_register(&snd_mtpav_driver)) < 0) |
769 | 770 | return err; |
... | ... | @@ -778,6 +779,7 @@ |
778 | 779 | |
779 | 780 | static void __exit alsa_card_mtpav_exit(void) |
780 | 781 | { |
782 | + platform_device_unregister(device); | |
781 | 783 | platform_driver_unregister(&snd_mtpav_driver); |
782 | 784 | } |
783 | 785 |
sound/drivers/serial-u16550.c
... | ... | @@ -168,6 +168,8 @@ |
168 | 168 | |
169 | 169 | } snd_uart16550_t; |
170 | 170 | |
171 | +static struct platform_device *devices[SNDRV_CARDS]; | |
172 | + | |
171 | 173 | static inline void snd_uart16550_add_timer(snd_uart16550_t *uart) |
172 | 174 | { |
173 | 175 | if (! uart->timer_running) { |
... | ... | @@ -970,6 +972,15 @@ |
970 | 972 | }, |
971 | 973 | }; |
972 | 974 | |
975 | +static void __init_or_module snd_serial_unregister_all(void) | |
976 | +{ | |
977 | + int i; | |
978 | + | |
979 | + for (i = 0; i < ARRAY_SIZE(devices); ++i) | |
980 | + platform_device_unregister(devices[i]); | |
981 | + platform_driver_unregister(&snd_serial_driver); | |
982 | +} | |
983 | + | |
973 | 984 | static int __init alsa_card_serial_init(void) |
974 | 985 | { |
975 | 986 | int i, cards, err; |
... | ... | @@ -986,6 +997,7 @@ |
986 | 997 | err = PTR_ERR(device); |
987 | 998 | goto errout; |
988 | 999 | } |
1000 | + devices[i] = device; | |
989 | 1001 | cards++; |
990 | 1002 | } |
991 | 1003 | if (! cards) { |
992 | 1004 | |
... | ... | @@ -998,13 +1010,13 @@ |
998 | 1010 | return 0; |
999 | 1011 | |
1000 | 1012 | errout: |
1001 | - platform_driver_unregister(&snd_serial_driver); | |
1013 | + snd_serial_unregister_all(); | |
1002 | 1014 | return err; |
1003 | 1015 | } |
1004 | 1016 | |
1005 | 1017 | static void __exit alsa_card_serial_exit(void) |
1006 | 1018 | { |
1007 | - platform_driver_unregister(&snd_serial_driver); | |
1019 | + snd_serial_unregister_all(); | |
1008 | 1020 | } |
1009 | 1021 | |
1010 | 1022 | module_init(alsa_card_serial_init) |
sound/drivers/virmidi.c
... | ... | @@ -82,7 +82,9 @@ |
82 | 82 | struct snd_rawmidi *midi[MAX_MIDI_DEVICES]; |
83 | 83 | }; |
84 | 84 | |
85 | +static struct platform_device *devices[SNDRV_CARDS]; | |
85 | 86 | |
87 | + | |
86 | 88 | static int __init snd_virmidi_probe(struct platform_device *devptr) |
87 | 89 | { |
88 | 90 | struct snd_card *card; |
... | ... | @@ -144,6 +146,15 @@ |
144 | 146 | }, |
145 | 147 | }; |
146 | 148 | |
149 | +static void __init_or_module snd_virmidi_unregister_all(void) | |
150 | +{ | |
151 | + int i; | |
152 | + | |
153 | + for (i = 0; i < ARRAY_SIZE(devices); ++i) | |
154 | + platform_device_unregister(devices[i]); | |
155 | + platform_driver_unregister(&snd_virmidi_driver); | |
156 | +} | |
157 | + | |
147 | 158 | static int __init alsa_card_virmidi_init(void) |
148 | 159 | { |
149 | 160 | int i, cards, err; |
... | ... | @@ -160,6 +171,7 @@ |
160 | 171 | err = PTR_ERR(device); |
161 | 172 | goto errout; |
162 | 173 | } |
174 | + devices[i] = device; | |
163 | 175 | cards++; |
164 | 176 | } |
165 | 177 | if (!cards) { |
166 | 178 | |
... | ... | @@ -172,13 +184,13 @@ |
172 | 184 | return 0; |
173 | 185 | |
174 | 186 | errout: |
175 | - platform_driver_unregister(&snd_virmidi_driver); | |
187 | + snd_virmidi_unregister_all(); | |
176 | 188 | return err; |
177 | 189 | } |
178 | 190 | |
179 | 191 | static void __exit alsa_card_virmidi_exit(void) |
180 | 192 | { |
181 | - platform_driver_unregister(&snd_virmidi_driver); | |
193 | + snd_virmidi_unregister_all(); | |
182 | 194 | } |
183 | 195 | |
184 | 196 | module_init(alsa_card_virmidi_init) |
sound/isa/ad1848/ad1848.c
... | ... | @@ -62,7 +62,9 @@ |
62 | 62 | module_param_array(thinkpad, bool, NULL, 0444); |
63 | 63 | MODULE_PARM_DESC(thinkpad, "Enable only for the onboard CS4248 of IBM Thinkpad 360/750/755 series."); |
64 | 64 | |
65 | +static struct platform_device *devices[SNDRV_CARDS]; | |
65 | 66 | |
67 | + | |
66 | 68 | static int __init snd_ad1848_probe(struct platform_device *pdev) |
67 | 69 | { |
68 | 70 | int dev = pdev->id; |
... | ... | @@ -167,6 +169,15 @@ |
167 | 169 | }, |
168 | 170 | }; |
169 | 171 | |
172 | +static void __init_or_module snd_ad1848_unregister_all(void) | |
173 | +{ | |
174 | + int i; | |
175 | + | |
176 | + for (i = 0; i < ARRAY_SIZE(devices); ++i) | |
177 | + platform_device_unregister(devices[i]); | |
178 | + platform_driver_unregister(&snd_ad1848_driver); | |
179 | +} | |
180 | + | |
170 | 181 | static int __init alsa_card_ad1848_init(void) |
171 | 182 | { |
172 | 183 | int i, cards, err; |
... | ... | @@ -184,6 +195,7 @@ |
184 | 195 | err = PTR_ERR(device); |
185 | 196 | goto errout; |
186 | 197 | } |
198 | + devices[i] = device; | |
187 | 199 | cards++; |
188 | 200 | } |
189 | 201 | if (!cards) { |
190 | 202 | |
... | ... | @@ -196,13 +208,13 @@ |
196 | 208 | return 0; |
197 | 209 | |
198 | 210 | errout: |
199 | - platform_driver_unregister(&snd_ad1848_driver); | |
211 | + snd_ad1848_unregister_all(); | |
200 | 212 | return err; |
201 | 213 | } |
202 | 214 | |
203 | 215 | static void __exit alsa_card_ad1848_exit(void) |
204 | 216 | { |
205 | - platform_driver_unregister(&snd_ad1848_driver); | |
217 | + snd_ad1848_unregister_all(); | |
206 | 218 | } |
207 | 219 | |
208 | 220 | module_init(alsa_card_ad1848_init) |
sound/isa/cmi8330.c
... | ... | @@ -108,6 +108,9 @@ |
108 | 108 | module_param_array(wssdma, int, NULL, 0444); |
109 | 109 | MODULE_PARM_DESC(wssdma, "DMA for CMI8330 WSS driver."); |
110 | 110 | |
111 | +static struct platform_device *platform_devices[SNDRV_CARDS]; | |
112 | +static int pnp_registered; | |
113 | + | |
111 | 114 | #define CMI8330_RMUX3D 16 |
112 | 115 | #define CMI8330_MUTEMUX 17 |
113 | 116 | #define CMI8330_OUTPUTVOL 18 |
... | ... | @@ -665,6 +668,17 @@ |
665 | 668 | }; |
666 | 669 | #endif /* CONFIG_PNP */ |
667 | 670 | |
671 | +static void __init_or_module snd_cmi8330_unregister_all(void) | |
672 | +{ | |
673 | + int i; | |
674 | + | |
675 | + if (pnp_registered) | |
676 | + pnp_unregister_card_driver(&cmi8330_pnpc_driver); | |
677 | + for (i = 0; i < ARRAY_SIZE(platform_devices); ++i) | |
678 | + platform_device_unregister(platform_devices[i]); | |
679 | + platform_driver_unregister(&snd_cmi8330_driver); | |
680 | +} | |
681 | + | |
668 | 682 | static int __init alsa_card_cmi8330_init(void) |
669 | 683 | { |
670 | 684 | int i, err, cards = 0; |
671 | 685 | |
672 | 686 | |
673 | 687 | |
674 | 688 | |
675 | 689 | |
676 | 690 | |
677 | 691 | |
... | ... | @@ -680,31 +694,35 @@ |
680 | 694 | i, NULL, 0); |
681 | 695 | if (IS_ERR(device)) { |
682 | 696 | err = PTR_ERR(device); |
683 | - platform_driver_unregister(&snd_cmi8330_driver); | |
684 | - return err; | |
697 | + goto errout; | |
685 | 698 | } |
699 | + platform_devices[i] = device; | |
686 | 700 | cards++; |
687 | 701 | } |
688 | 702 | |
689 | 703 | err = pnp_register_card_driver(&cmi8330_pnpc_driver); |
690 | - if (err > 0) | |
704 | + if (err >= 0) { | |
705 | + pnp_registered = 1; | |
691 | 706 | cards += err; |
707 | + } | |
692 | 708 | |
693 | 709 | if (!cards) { |
694 | - pnp_unregister_card_driver(&cmi8330_pnpc_driver); | |
695 | - platform_driver_unregister(&snd_cmi8330_driver); | |
696 | 710 | #ifdef MODULE |
697 | 711 | snd_printk(KERN_ERR "CMI8330 not found or device busy\n"); |
698 | 712 | #endif |
699 | - return -ENODEV; | |
713 | + err = -ENODEV; | |
714 | + goto errout; | |
700 | 715 | } |
701 | 716 | return 0; |
717 | + | |
718 | + errout: | |
719 | + snd_cmi8330_unregister_all(); | |
720 | + return err; | |
702 | 721 | } |
703 | 722 | |
704 | 723 | static void __exit alsa_card_cmi8330_exit(void) |
705 | 724 | { |
706 | - pnp_unregister_card_driver(&cmi8330_pnpc_driver); | |
707 | - platform_driver_unregister(&snd_cmi8330_driver); | |
725 | + snd_cmi8330_unregister_all(); | |
708 | 726 | } |
709 | 727 | |
710 | 728 | module_init(alsa_card_cmi8330_init) |
sound/isa/cs423x/cs4231.c
... | ... | @@ -66,7 +66,9 @@ |
66 | 66 | module_param_array(dma2, int, NULL, 0444); |
67 | 67 | MODULE_PARM_DESC(dma2, "DMA2 # for CS4231 driver."); |
68 | 68 | |
69 | +static struct platform_device *devices[SNDRV_CARDS]; | |
69 | 70 | |
71 | + | |
70 | 72 | static int __init snd_cs4231_probe(struct platform_device *pdev) |
71 | 73 | { |
72 | 74 | int dev = pdev->id; |
... | ... | @@ -183,6 +185,15 @@ |
183 | 185 | }, |
184 | 186 | }; |
185 | 187 | |
188 | +static void __init_or_module snd_cs4231_unregister_all(void) | |
189 | +{ | |
190 | + int i; | |
191 | + | |
192 | + for (i = 0; i < ARRAY_SIZE(devices); ++i) | |
193 | + platform_device_unregister(devices[i]); | |
194 | + platform_driver_unregister(&snd_cs4231_driver); | |
195 | +} | |
196 | + | |
186 | 197 | static int __init alsa_card_cs4231_init(void) |
187 | 198 | { |
188 | 199 | int i, cards, err; |
... | ... | @@ -200,6 +211,7 @@ |
200 | 211 | err = PTR_ERR(device); |
201 | 212 | goto errout; |
202 | 213 | } |
214 | + devices[i] = device; | |
203 | 215 | cards++; |
204 | 216 | } |
205 | 217 | if (!cards) { |
206 | 218 | |
... | ... | @@ -212,13 +224,13 @@ |
212 | 224 | return 0; |
213 | 225 | |
214 | 226 | errout: |
215 | - platform_driver_unregister(&snd_cs4231_driver); | |
227 | + snd_cs4231_unregister_all(); | |
216 | 228 | return err; |
217 | 229 | } |
218 | 230 | |
219 | 231 | static void __exit alsa_card_cs4231_exit(void) |
220 | 232 | { |
221 | - platform_driver_unregister(&snd_cs4231_driver); | |
233 | + snd_cs4231_unregister_all(); | |
222 | 234 | } |
223 | 235 | |
224 | 236 | module_init(alsa_card_cs4231_init) |
sound/isa/cs423x/cs4236.c
... | ... | @@ -124,6 +124,12 @@ |
124 | 124 | module_param_array(dma2, int, NULL, 0444); |
125 | 125 | MODULE_PARM_DESC(dma2, "DMA2 # for " IDENT " driver."); |
126 | 126 | |
127 | +static struct platform_device *platform_devices[SNDRV_CARDS]; | |
128 | +static int pnpc_registered; | |
129 | +#ifdef CS4232 | |
130 | +static int pnp_registered; | |
131 | +#endif | |
132 | + | |
127 | 133 | struct snd_card_cs4236 { |
128 | 134 | struct snd_cs4231 *chip; |
129 | 135 | struct resource *res_sb_port; |
... | ... | @@ -737,6 +743,21 @@ |
737 | 743 | }; |
738 | 744 | #endif /* CONFIG_PNP */ |
739 | 745 | |
746 | +static void __init_or_module snd_cs423x_unregister_all(void) | |
747 | +{ | |
748 | + int i; | |
749 | + | |
750 | + if (pnpc_registered) | |
751 | + pnp_unregister_card_driver(&cs423x_pnpc_driver); | |
752 | +#ifdef CS4232 | |
753 | + if (pnp_registered) | |
754 | + pnp_unregister_driver(&cs4232_pnp_driver); | |
755 | +#endif | |
756 | + for (i = 0; i < ARRAY_SIZE(platform_devices); ++i) | |
757 | + platform_device_unregister(platform_devices[i]); | |
758 | + platform_driver_unregister(&cs423x_nonpnp_driver); | |
759 | +} | |
760 | + | |
740 | 761 | static int __init alsa_card_cs423x_init(void) |
741 | 762 | { |
742 | 763 | int i, err, cards = 0; |
743 | 764 | |
744 | 765 | |
745 | 766 | |
746 | 767 | |
747 | 768 | |
748 | 769 | |
749 | 770 | |
750 | 771 | |
751 | 772 | |
... | ... | @@ -752,40 +773,40 @@ |
752 | 773 | i, NULL, 0); |
753 | 774 | if (IS_ERR(device)) { |
754 | 775 | err = PTR_ERR(device); |
755 | - platform_driver_unregister(&cs423x_nonpnp_driver); | |
756 | - return err; | |
776 | + goto errout; | |
757 | 777 | } |
778 | + platform_devices[i] = device; | |
758 | 779 | cards++; |
759 | 780 | } |
760 | 781 | #ifdef CS4232 |
761 | 782 | i = pnp_register_driver(&cs4232_pnp_driver); |
762 | - if (i > 0) | |
783 | + if (i >= 0) { | |
784 | + pnp_registered = 1; | |
763 | 785 | cards += i; |
786 | + } | |
764 | 787 | #endif |
765 | 788 | i = pnp_register_card_driver(&cs423x_pnpc_driver); |
766 | - if (i > 0) | |
789 | + if (i >= 0) { | |
790 | + pnpc_registered = 1; | |
767 | 791 | cards += i; |
792 | + } | |
768 | 793 | if (!cards) { |
769 | -#ifdef CS4232 | |
770 | - pnp_unregister_driver(&cs4232_pnp_driver); | |
771 | -#endif | |
772 | - pnp_unregister_card_driver(&cs423x_pnpc_driver); | |
773 | - platform_driver_unregister(&cs423x_nonpnp_driver); | |
774 | 794 | #ifdef MODULE |
775 | 795 | printk(KERN_ERR IDENT " soundcard not found or device busy\n"); |
776 | 796 | #endif |
777 | - return -ENODEV; | |
797 | + err = -ENODEV; | |
798 | + goto errout; | |
778 | 799 | } |
779 | 800 | return 0; |
801 | + | |
802 | + errout: | |
803 | + snd_cs423x_unregister_all(); | |
804 | + return err; | |
780 | 805 | } |
781 | 806 | |
782 | 807 | static void __exit alsa_card_cs423x_exit(void) |
783 | 808 | { |
784 | -#ifdef CS4232 | |
785 | - pnp_unregister_driver(&cs4232_pnp_driver); | |
786 | -#endif | |
787 | - pnp_unregister_card_driver(&cs423x_pnpc_driver); | |
788 | - platform_driver_unregister(&cs423x_nonpnp_driver); | |
809 | + snd_cs423x_unregister_all(); | |
789 | 810 | } |
790 | 811 | |
791 | 812 | module_init(alsa_card_cs423x_init) |
sound/isa/es1688/es1688.c
... | ... | @@ -69,6 +69,8 @@ |
69 | 69 | module_param_array(dma8, int, NULL, 0444); |
70 | 70 | MODULE_PARM_DESC(dma8, "8-bit DMA # for ESx688 driver."); |
71 | 71 | |
72 | +static struct platform_device *devices[SNDRV_CARDS]; | |
73 | + | |
72 | 74 | #define PFX "es1688: " |
73 | 75 | |
74 | 76 | static int __init snd_es1688_probe(struct platform_device *pdev) |
... | ... | @@ -187,6 +189,15 @@ |
187 | 189 | }, |
188 | 190 | }; |
189 | 191 | |
192 | +static void __init_or_module snd_es1688_unregister_all(void) | |
193 | +{ | |
194 | + int i; | |
195 | + | |
196 | + for (i = 0; i < ARRAY_SIZE(devices); ++i) | |
197 | + platform_device_unregister(devices[i]); | |
198 | + platform_driver_unregister(&snd_es1688_driver); | |
199 | +} | |
200 | + | |
190 | 201 | static int __init alsa_card_es1688_init(void) |
191 | 202 | { |
192 | 203 | int i, cards, err; |
... | ... | @@ -204,6 +215,7 @@ |
204 | 215 | err = PTR_ERR(device); |
205 | 216 | goto errout; |
206 | 217 | } |
218 | + devices[i] = device; | |
207 | 219 | cards++; |
208 | 220 | } |
209 | 221 | if (!cards) { |
210 | 222 | |
... | ... | @@ -216,13 +228,13 @@ |
216 | 228 | return 0; |
217 | 229 | |
218 | 230 | errout: |
219 | - platform_driver_unregister(&snd_es1688_driver); | |
231 | + snd_es1688_unregister_all(); | |
220 | 232 | return err; |
221 | 233 | } |
222 | 234 | |
223 | 235 | static void __exit alsa_card_es1688_exit(void) |
224 | 236 | { |
225 | - platform_driver_unregister(&snd_es1688_driver); | |
237 | + snd_es1688_unregister_all(); | |
226 | 238 | } |
227 | 239 | |
228 | 240 | module_init(alsa_card_es1688_init) |
sound/isa/es18xx.c
... | ... | @@ -1877,6 +1877,9 @@ |
1877 | 1877 | module_param_array(dma2, int, NULL, 0444); |
1878 | 1878 | MODULE_PARM_DESC(dma2, "DMA 2 # for ES18xx driver."); |
1879 | 1879 | |
1880 | +static struct platform_device *platform_devices[SNDRV_CARDS]; | |
1881 | +static int pnp_registered; | |
1882 | + | |
1880 | 1883 | #ifdef CONFIG_PNP |
1881 | 1884 | |
1882 | 1885 | static struct pnp_card_device_id snd_audiodrive_pnpids[] = { |
... | ... | @@ -2202,6 +2205,17 @@ |
2202 | 2205 | }; |
2203 | 2206 | #endif /* CONFIG_PNP */ |
2204 | 2207 | |
2208 | +static void __init_or_module snd_es18xx_unregister_all(void) | |
2209 | +{ | |
2210 | + int i; | |
2211 | + | |
2212 | + if (pnp_registered) | |
2213 | + pnp_unregister_card_driver(&es18xx_pnpc_driver); | |
2214 | + for (i = 0; i < ARRAY_SIZE(platform_devices); ++i) | |
2215 | + platform_device_unregister(platform_devices[i]); | |
2216 | + platform_driver_unregister(&snd_es18xx_nonpnp_driver); | |
2217 | +} | |
2218 | + | |
2205 | 2219 | static int __init alsa_card_es18xx_init(void) |
2206 | 2220 | { |
2207 | 2221 | int i, err, cards = 0; |
2208 | 2222 | |
2209 | 2223 | |
2210 | 2224 | |
2211 | 2225 | |
2212 | 2226 | |
2213 | 2227 | |
2214 | 2228 | |
... | ... | @@ -2217,31 +2231,35 @@ |
2217 | 2231 | i, NULL, 0); |
2218 | 2232 | if (IS_ERR(device)) { |
2219 | 2233 | err = PTR_ERR(device); |
2220 | - platform_driver_unregister(&snd_es18xx_nonpnp_driver); | |
2221 | - return err; | |
2234 | + goto errout; | |
2222 | 2235 | } |
2236 | + platform_devices[i] = device; | |
2223 | 2237 | cards++; |
2224 | 2238 | } |
2225 | 2239 | |
2226 | 2240 | i = pnp_register_card_driver(&es18xx_pnpc_driver); |
2227 | - if (i > 0) | |
2241 | + if (i >= 0) { | |
2242 | + pnp_registered = 1; | |
2228 | 2243 | cards += i; |
2244 | + } | |
2229 | 2245 | |
2230 | 2246 | if(!cards) { |
2231 | - pnp_unregister_card_driver(&es18xx_pnpc_driver); | |
2232 | - platform_driver_unregister(&snd_es18xx_nonpnp_driver); | |
2233 | 2247 | #ifdef MODULE |
2234 | 2248 | snd_printk(KERN_ERR "ESS AudioDrive ES18xx soundcard not found or device busy\n"); |
2235 | 2249 | #endif |
2236 | - return -ENODEV; | |
2250 | + err = -ENODEV; | |
2251 | + goto errout; | |
2237 | 2252 | } |
2238 | 2253 | return 0; |
2254 | + | |
2255 | + errout: | |
2256 | + snd_es18xx_unregister_all(); | |
2257 | + return err; | |
2239 | 2258 | } |
2240 | 2259 | |
2241 | 2260 | static void __exit alsa_card_es18xx_exit(void) |
2242 | 2261 | { |
2243 | - pnp_unregister_card_driver(&es18xx_pnpc_driver); | |
2244 | - platform_driver_unregister(&snd_es18xx_nonpnp_driver); | |
2262 | + snd_es18xx_unregister_all(); | |
2245 | 2263 | } |
2246 | 2264 | |
2247 | 2265 | module_init(alsa_card_es18xx_init) |
sound/isa/gus/gusclassic.c
... | ... | @@ -71,7 +71,9 @@ |
71 | 71 | module_param_array(pcm_channels, int, NULL, 0444); |
72 | 72 | MODULE_PARM_DESC(pcm_channels, "Reserved PCM channels for GUS Classic driver."); |
73 | 73 | |
74 | +static struct platform_device *devices[SNDRV_CARDS]; | |
74 | 75 | |
76 | + | |
75 | 77 | #define PFX "gusclassic: " |
76 | 78 | |
77 | 79 | static int __init snd_gusclassic_detect(struct snd_gus_card * gus) |
... | ... | @@ -227,6 +229,15 @@ |
227 | 229 | }, |
228 | 230 | }; |
229 | 231 | |
232 | +static void __init_or_module snd_gusclassic_unregister_all(void) | |
233 | +{ | |
234 | + int i; | |
235 | + | |
236 | + for (i = 0; i < ARRAY_SIZE(devices); ++i) | |
237 | + platform_device_unregister(devices[i]); | |
238 | + platform_driver_unregister(&snd_gusclassic_driver); | |
239 | +} | |
240 | + | |
230 | 241 | static int __init alsa_card_gusclassic_init(void) |
231 | 242 | { |
232 | 243 | int i, cards, err; |
... | ... | @@ -244,6 +255,7 @@ |
244 | 255 | err = PTR_ERR(device); |
245 | 256 | goto errout; |
246 | 257 | } |
258 | + devices[i] = device; | |
247 | 259 | cards++; |
248 | 260 | } |
249 | 261 | if (!cards) { |
250 | 262 | |
... | ... | @@ -256,13 +268,13 @@ |
256 | 268 | return 0; |
257 | 269 | |
258 | 270 | errout: |
259 | - platform_driver_unregister(&snd_gusclassic_driver); | |
271 | + snd_gusclassic_unregister_all(); | |
260 | 272 | return err; |
261 | 273 | } |
262 | 274 | |
263 | 275 | static void __exit alsa_card_gusclassic_exit(void) |
264 | 276 | { |
265 | - platform_driver_unregister(&snd_gusclassic_driver); | |
277 | + snd_gusclassic_unregister_all(); | |
266 | 278 | } |
267 | 279 | |
268 | 280 | module_init(alsa_card_gusclassic_init) |
sound/isa/gus/gusextreme.c
... | ... | @@ -87,7 +87,9 @@ |
87 | 87 | module_param_array(pcm_channels, int, NULL, 0444); |
88 | 88 | MODULE_PARM_DESC(pcm_channels, "Reserved PCM channels for GUS Extreme driver."); |
89 | 89 | |
90 | +struct platform_device *devices[SNDRV_CARDS]; | |
90 | 91 | |
92 | + | |
91 | 93 | #define PFX "gusextreme: " |
92 | 94 | |
93 | 95 | static int __init snd_gusextreme_detect(int dev, |
... | ... | @@ -337,6 +339,15 @@ |
337 | 339 | }, |
338 | 340 | }; |
339 | 341 | |
342 | +static void __init_or_module snd_gusextreme_unregister_all(void) | |
343 | +{ | |
344 | + int i; | |
345 | + | |
346 | + for (i = 0; i < ARRAY_SIZE(devices); ++i) | |
347 | + platform_device_unregister(devices[i]); | |
348 | + platform_driver_unregister(&snd_gusextreme_driver); | |
349 | +} | |
350 | + | |
340 | 351 | static int __init alsa_card_gusextreme_init(void) |
341 | 352 | { |
342 | 353 | int i, cards, err; |
... | ... | @@ -354,6 +365,7 @@ |
354 | 365 | err = PTR_ERR(device); |
355 | 366 | goto errout; |
356 | 367 | } |
368 | + devices[i] = device; | |
357 | 369 | cards++; |
358 | 370 | } |
359 | 371 | if (!cards) { |
360 | 372 | |
... | ... | @@ -366,13 +378,13 @@ |
366 | 378 | return 0; |
367 | 379 | |
368 | 380 | errout: |
369 | - platform_driver_unregister(&snd_gusextreme_driver); | |
381 | + snd_gusextreme_unregister_all(); | |
370 | 382 | return err; |
371 | 383 | } |
372 | 384 | |
373 | 385 | static void __exit alsa_card_gusextreme_exit(void) |
374 | 386 | { |
375 | - platform_driver_unregister(&snd_gusextreme_driver); | |
387 | + snd_gusextreme_unregister_all(); | |
376 | 388 | } |
377 | 389 | |
378 | 390 | module_init(alsa_card_gusextreme_init) |
sound/isa/gus/gusmax.c
... | ... | @@ -72,6 +72,8 @@ |
72 | 72 | module_param_array(pcm_channels, int, NULL, 0444); |
73 | 73 | MODULE_PARM_DESC(pcm_channels, "Reserved PCM channels for GUS MAX driver."); |
74 | 74 | |
75 | +static struct platform_device *devices[SNDRV_CARDS]; | |
76 | + | |
75 | 77 | struct snd_gusmax { |
76 | 78 | int irq; |
77 | 79 | struct snd_card *card; |
... | ... | @@ -364,6 +366,15 @@ |
364 | 366 | }, |
365 | 367 | }; |
366 | 368 | |
369 | +static void __init_or_module snd_gusmax_unregister_all(void) | |
370 | +{ | |
371 | + int i; | |
372 | + | |
373 | + for (i = 0; i < ARRAY_SIZE(devices); ++i) | |
374 | + platform_device_unregister(devices[i]); | |
375 | + platform_driver_unregister(&snd_gusmax_driver); | |
376 | +} | |
377 | + | |
367 | 378 | static int __init alsa_card_gusmax_init(void) |
368 | 379 | { |
369 | 380 | int i, cards, err; |
... | ... | @@ -381,6 +392,7 @@ |
381 | 392 | err = PTR_ERR(device); |
382 | 393 | goto errout; |
383 | 394 | } |
395 | + devices[i] = device; | |
384 | 396 | cards++; |
385 | 397 | } |
386 | 398 | if (!cards) { |
387 | 399 | |
... | ... | @@ -393,13 +405,13 @@ |
393 | 405 | return 0; |
394 | 406 | |
395 | 407 | errout: |
396 | - platform_driver_unregister(&snd_gusmax_driver); | |
408 | + snd_gusmax_unregister_all(); | |
397 | 409 | return err; |
398 | 410 | } |
399 | 411 | |
400 | 412 | static void __exit alsa_card_gusmax_exit(void) |
401 | 413 | { |
402 | - platform_driver_unregister(&snd_gusmax_driver); | |
414 | + snd_gusmax_unregister_all(); | |
403 | 415 | } |
404 | 416 | |
405 | 417 | module_init(alsa_card_gusmax_init) |
sound/isa/gus/interwave.c
... | ... | @@ -115,6 +115,9 @@ |
115 | 115 | module_param_array(effect, int, NULL, 0444); |
116 | 116 | MODULE_PARM_DESC(effect, "Effects enable for InterWave driver."); |
117 | 117 | |
118 | +static struct platform_device *platform_devices[SNDRV_CARDS]; | |
119 | +static int pnp_registered; | |
120 | + | |
118 | 121 | struct snd_interwave { |
119 | 122 | int irq; |
120 | 123 | struct snd_card *card; |
... | ... | @@ -914,6 +917,17 @@ |
914 | 917 | |
915 | 918 | #endif /* CONFIG_PNP */ |
916 | 919 | |
920 | +static void __init_or_module snd_interwave_unregister_all(void) | |
921 | +{ | |
922 | + int i; | |
923 | + | |
924 | + if (pnp_registered) | |
925 | + pnp_unregister_card_driver(&interwave_pnpc_driver); | |
926 | + for (i = 0; i < ARRAY_SIZE(platform_devices); ++i) | |
927 | + platform_device_unregister(platform_devices[i]); | |
928 | + platform_driver_unregister(&snd_interwave_driver); | |
929 | +} | |
930 | + | |
917 | 931 | static int __init alsa_card_interwave_init(void) |
918 | 932 | { |
919 | 933 | int i, err, cards = 0; |
920 | 934 | |
921 | 935 | |
922 | 936 | |
923 | 937 | |
924 | 938 | |
925 | 939 | |
926 | 940 | |
... | ... | @@ -931,32 +945,36 @@ |
931 | 945 | i, NULL, 0); |
932 | 946 | if (IS_ERR(device)) { |
933 | 947 | err = PTR_ERR(device); |
934 | - platform_driver_unregister(&snd_interwave_driver); | |
935 | - return err; | |
948 | + goto errout; | |
936 | 949 | } |
950 | + platform_devices[i] = device; | |
937 | 951 | cards++; |
938 | 952 | } |
939 | 953 | |
940 | 954 | /* ISA PnP cards */ |
941 | 955 | i = pnp_register_card_driver(&interwave_pnpc_driver); |
942 | - if (i > 0) | |
956 | + if (i >= 0) { | |
957 | + pnp_registered = 1; | |
943 | 958 | cards += i; |
959 | + } | |
944 | 960 | |
945 | 961 | if (!cards) { |
946 | - pnp_unregister_card_driver(&interwave_pnpc_driver); | |
947 | - platform_driver_unregister(&snd_interwave_driver); | |
948 | 962 | #ifdef MODULE |
949 | 963 | printk(KERN_ERR "InterWave soundcard not found or device busy\n"); |
950 | 964 | #endif |
951 | - return -ENODEV; | |
965 | + err = -ENODEV; | |
966 | + goto errout; | |
952 | 967 | } |
953 | 968 | return 0; |
969 | + | |
970 | + errout: | |
971 | + snd_interwave_unregister_all(); | |
972 | + return err; | |
954 | 973 | } |
955 | 974 | |
956 | 975 | static void __exit alsa_card_interwave_exit(void) |
957 | 976 | { |
958 | - pnp_unregister_card_driver(&interwave_pnpc_driver); | |
959 | - platform_driver_unregister(&snd_interwave_driver); | |
977 | + snd_interwave_unregister_all(); | |
960 | 978 | } |
961 | 979 | |
962 | 980 | module_init(alsa_card_interwave_init) |
sound/isa/opl3sa2.c
... | ... | @@ -90,6 +90,10 @@ |
90 | 90 | module_param_array(opl3sa3_ymode, int, NULL, 0444); |
91 | 91 | MODULE_PARM_DESC(opl3sa3_ymode, "Speaker size selection for 3D Enhancement mode: Desktop/Large Notebook/Small Notebook/HiFi."); |
92 | 92 | |
93 | +static struct platform_device *platform_devices[SNDRV_CARDS]; | |
94 | +static int pnp_registered; | |
95 | +static int pnpc_registered; | |
96 | + | |
93 | 97 | /* control ports */ |
94 | 98 | #define OPL3SA2_PM_CTRL 0x01 |
95 | 99 | #define OPL3SA2_SYS_CTRL 0x02 |
... | ... | @@ -921,6 +925,19 @@ |
921 | 925 | }, |
922 | 926 | }; |
923 | 927 | |
928 | +static void __init_or_module snd_opl3sa2_unregister_all(void) | |
929 | +{ | |
930 | + int i; | |
931 | + | |
932 | + if (pnpc_registered) | |
933 | + pnp_unregister_card_driver(&opl3sa2_pnpc_driver); | |
934 | + if (pnp_registered) | |
935 | + pnp_unregister_driver(&opl3sa2_pnp_driver); | |
936 | + for (i = 0; i < ARRAY_SIZE(platform_devices); ++i) | |
937 | + platform_device_unregister(platform_devices[i]); | |
938 | + platform_driver_unregister(&snd_opl3sa2_nonpnp_driver); | |
939 | +} | |
940 | + | |
924 | 941 | static int __init alsa_card_opl3sa2_init(void) |
925 | 942 | { |
926 | 943 | int i, err, cards = 0; |
927 | 944 | |
928 | 945 | |
929 | 946 | |
930 | 947 | |
931 | 948 | |
932 | 949 | |
933 | 950 | |
934 | 951 | |
... | ... | @@ -938,36 +955,40 @@ |
938 | 955 | i, NULL, 0); |
939 | 956 | if (IS_ERR(device)) { |
940 | 957 | err = PTR_ERR(device); |
941 | - platform_driver_unregister(&snd_opl3sa2_nonpnp_driver); | |
942 | - return err; | |
958 | + goto errout; | |
943 | 959 | } |
960 | + platform_devices[i] = device; | |
944 | 961 | cards++; |
945 | 962 | } |
946 | 963 | |
947 | 964 | err = pnp_register_driver(&opl3sa2_pnp_driver); |
948 | - if (err > 0) | |
965 | + if (err >= 0) { | |
966 | + pnp_registered = 1; | |
949 | 967 | cards += err; |
968 | + } | |
950 | 969 | err = pnp_register_card_driver(&opl3sa2_pnpc_driver); |
951 | - if (err > 0) | |
970 | + if (err >= 0) { | |
971 | + pnpc_registered = 1; | |
952 | 972 | cards += err; |
973 | + } | |
953 | 974 | |
954 | 975 | if (!cards) { |
955 | 976 | #ifdef MODULE |
956 | 977 | snd_printk(KERN_ERR "Yamaha OPL3-SA soundcard not found or device busy\n"); |
957 | 978 | #endif |
958 | - pnp_unregister_card_driver(&opl3sa2_pnpc_driver); | |
959 | - pnp_unregister_driver(&opl3sa2_pnp_driver); | |
960 | - platform_driver_unregister(&snd_opl3sa2_nonpnp_driver); | |
961 | - return -ENODEV; | |
979 | + err = -ENODEV; | |
980 | + goto errout; | |
962 | 981 | } |
963 | 982 | return 0; |
983 | + | |
984 | + errout: | |
985 | + snd_opl3sa2_unregister_all(); | |
986 | + return err; | |
964 | 987 | } |
965 | 988 | |
966 | 989 | static void __exit alsa_card_opl3sa2_exit(void) |
967 | 990 | { |
968 | - pnp_unregister_card_driver(&opl3sa2_pnpc_driver); | |
969 | - pnp_unregister_driver(&opl3sa2_pnp_driver); | |
970 | - platform_driver_unregister(&snd_opl3sa2_nonpnp_driver); | |
991 | + snd_opl3sa2_unregister_all(); | |
971 | 992 | } |
972 | 993 | |
973 | 994 | module_init(alsa_card_opl3sa2_init) |
sound/isa/opti9xx/opti92x-ad1848.c
... | ... | @@ -259,6 +259,7 @@ |
259 | 259 | }; |
260 | 260 | |
261 | 261 | static int snd_opti9xx_pnp_is_probed; |
262 | +static struct platform_device *snd_opti9xx_platform_device; | |
262 | 263 | |
263 | 264 | #ifdef CONFIG_PNP |
264 | 265 | |
265 | 266 | |
... | ... | @@ -2095,8 +2096,10 @@ |
2095 | 2096 | if (error < 0) |
2096 | 2097 | return error; |
2097 | 2098 | device = platform_device_register_simple(DRIVER_NAME, -1, NULL, 0); |
2098 | - if (! IS_ERR(device)) | |
2099 | + if (!IS_ERR(device)) { | |
2100 | + snd_opti9xx_platform_device = device; | |
2099 | 2101 | return 0; |
2102 | + } | |
2100 | 2103 | platform_driver_unregister(&snd_opti9xx_driver); |
2101 | 2104 | } |
2102 | 2105 | pnp_unregister_card_driver(&opti9xx_pnpc_driver); |
2103 | 2106 | |
... | ... | @@ -2108,8 +2111,10 @@ |
2108 | 2111 | |
2109 | 2112 | static void __exit alsa_card_opti9xx_exit(void) |
2110 | 2113 | { |
2111 | - if (! snd_opti9xx_pnp_is_probed) | |
2114 | + if (!snd_opti9xx_pnp_is_probed) { | |
2115 | + platform_device_unregister(snd_opti9xx_platform_device); | |
2112 | 2116 | platform_driver_unregister(&snd_opti9xx_driver); |
2117 | + } | |
2113 | 2118 | pnp_unregister_card_driver(&opti9xx_pnpc_driver); |
2114 | 2119 | } |
2115 | 2120 |
sound/isa/sb/sb16.c
... | ... | @@ -128,6 +128,11 @@ |
128 | 128 | MODULE_PARM_DESC(seq_ports, "Number of sequencer ports for WaveTable synth."); |
129 | 129 | #endif |
130 | 130 | |
131 | +static struct platform_device *platform_devices[SNDRV_CARDS]; | |
132 | +#ifdef CONFIG_PNP | |
133 | +static int pnp_registered; | |
134 | +#endif | |
135 | + | |
131 | 136 | struct snd_card_sb16 { |
132 | 137 | struct resource *fm_res; /* used to block FM i/o region for legacy cards */ |
133 | 138 | struct snd_sb *chip; |
... | ... | @@ -687,6 +692,19 @@ |
687 | 692 | |
688 | 693 | #endif /* CONFIG_PNP */ |
689 | 694 | |
695 | +static void __init_or_module snd_sb16_unregister_all(void) | |
696 | +{ | |
697 | + int i; | |
698 | + | |
699 | +#ifdef CONFIG_PNP | |
700 | + if (pnp_registered) | |
701 | + pnp_unregister_card_driver(&sb16_pnpc_driver); | |
702 | +#endif | |
703 | + for (i = 0; i < ARRAY_SIZE(platform_devices); ++i) | |
704 | + platform_device_unregister(platform_devices[i]); | |
705 | + platform_driver_unregister(&snd_sb16_nonpnp_driver); | |
706 | +} | |
707 | + | |
690 | 708 | static int __init alsa_card_sb16_init(void) |
691 | 709 | { |
692 | 710 | int i, err, cards = 0; |
693 | 711 | |
694 | 712 | |
695 | 713 | |
696 | 714 | |
... | ... | @@ -702,23 +720,21 @@ |
702 | 720 | i, NULL, 0); |
703 | 721 | if (IS_ERR(device)) { |
704 | 722 | err = PTR_ERR(device); |
705 | - platform_driver_unregister(&snd_sb16_nonpnp_driver); | |
706 | - return err; | |
723 | + goto errout; | |
707 | 724 | } |
725 | + platform_devices[i] = device; | |
708 | 726 | cards++; |
709 | 727 | } |
710 | 728 | #ifdef CONFIG_PNP |
711 | 729 | /* PnP cards at last */ |
712 | 730 | i = pnp_register_card_driver(&sb16_pnpc_driver); |
713 | - if (i > 0) | |
731 | + if (i >= 0) { | |
732 | + pnp_registered = 1; | |
714 | 733 | cards += i; |
734 | + } | |
715 | 735 | #endif |
716 | 736 | |
717 | 737 | if (!cards) { |
718 | -#ifdef CONFIG_PNP | |
719 | - pnp_unregister_card_driver(&sb16_pnpc_driver); | |
720 | -#endif | |
721 | - platform_driver_unregister(&snd_sb16_nonpnp_driver); | |
722 | 738 | #ifdef MODULE |
723 | 739 | snd_printk(KERN_ERR "Sound Blaster 16 soundcard not found or device busy\n"); |
724 | 740 | #ifdef SNDRV_SBAWE_EMU8000 |
725 | 741 | |
726 | 742 | |
... | ... | @@ -727,17 +743,19 @@ |
727 | 743 | snd_printk(KERN_ERR "In case, if you have AWE card, try snd-sbawe module\n"); |
728 | 744 | #endif |
729 | 745 | #endif |
730 | - return -ENODEV; | |
746 | + err = -ENODEV; | |
747 | + goto errout; | |
731 | 748 | } |
732 | 749 | return 0; |
750 | + | |
751 | + errout: | |
752 | + snd_sb16_unregister_all(); | |
753 | + return err; | |
733 | 754 | } |
734 | 755 | |
735 | 756 | static void __exit alsa_card_sb16_exit(void) |
736 | 757 | { |
737 | -#ifdef CONFIG_PNP | |
738 | - pnp_unregister_card_driver(&sb16_pnpc_driver); | |
739 | -#endif | |
740 | - platform_driver_unregister(&snd_sb16_nonpnp_driver); | |
758 | + snd_sb16_unregister_all(); | |
741 | 759 | } |
742 | 760 | |
743 | 761 | module_init(alsa_card_sb16_init) |
sound/isa/sb/sb8.c
... | ... | @@ -56,6 +56,8 @@ |
56 | 56 | module_param_array(dma8, int, NULL, 0444); |
57 | 57 | MODULE_PARM_DESC(dma8, "8-bit DMA # for SB8 driver."); |
58 | 58 | |
59 | +static struct platform_device *devices[SNDRV_CARDS]; | |
60 | + | |
59 | 61 | struct snd_sb8 { |
60 | 62 | struct resource *fm_res; /* used to block FM i/o region for legacy cards */ |
61 | 63 | struct snd_sb *chip; |
... | ... | @@ -238,6 +240,15 @@ |
238 | 240 | }, |
239 | 241 | }; |
240 | 242 | |
243 | +static void __init_or_module snd_sb8_unregister_all(void) | |
244 | +{ | |
245 | + int i; | |
246 | + | |
247 | + for (i = 0; i < ARRAY_SIZE(devices); ++i) | |
248 | + platform_device_unregister(devices[i]); | |
249 | + platform_driver_unregister(&snd_sb8_driver); | |
250 | +} | |
251 | + | |
241 | 252 | static int __init alsa_card_sb8_init(void) |
242 | 253 | { |
243 | 254 | int i, cards, err; |
... | ... | @@ -255,6 +266,7 @@ |
255 | 266 | err = PTR_ERR(device); |
256 | 267 | goto errout; |
257 | 268 | } |
269 | + devices[i] = device; | |
258 | 270 | cards++; |
259 | 271 | } |
260 | 272 | if (!cards) { |
261 | 273 | |
... | ... | @@ -267,13 +279,13 @@ |
267 | 279 | return 0; |
268 | 280 | |
269 | 281 | errout: |
270 | - platform_driver_unregister(&snd_sb8_driver); | |
282 | + snd_sb8_unregister_all(); | |
271 | 283 | return err; |
272 | 284 | } |
273 | 285 | |
274 | 286 | static void __exit alsa_card_sb8_exit(void) |
275 | 287 | { |
276 | - platform_driver_unregister(&snd_sb8_driver); | |
288 | + snd_sb8_unregister_all(); | |
277 | 289 | } |
278 | 290 | |
279 | 291 | module_init(alsa_card_sb8_init) |
sound/isa/sgalaxy.c
... | ... | @@ -64,6 +64,8 @@ |
64 | 64 | module_param_array(dma1, int, NULL, 0444); |
65 | 65 | MODULE_PARM_DESC(dma1, "DMA1 # for Sound Galaxy driver."); |
66 | 66 | |
67 | +static struct platform_device *devices[SNDRV_CARDS]; | |
68 | + | |
67 | 69 | #define SGALAXY_AUXC_LEFT 18 |
68 | 70 | #define SGALAXY_AUXC_RIGHT 19 |
69 | 71 | |
... | ... | @@ -340,6 +342,15 @@ |
340 | 342 | }, |
341 | 343 | }; |
342 | 344 | |
345 | +static void __init_or_module snd_sgalaxy_unregister_all(void) | |
346 | +{ | |
347 | + int i; | |
348 | + | |
349 | + for (i = 0; i < ARRAY_SIZE(devices); ++i) | |
350 | + platform_device_unregister(devices[i]); | |
351 | + platform_driver_unregister(&snd_sgalaxy_driver); | |
352 | +} | |
353 | + | |
343 | 354 | static int __init alsa_card_sgalaxy_init(void) |
344 | 355 | { |
345 | 356 | int i, cards, err; |
... | ... | @@ -357,6 +368,7 @@ |
357 | 368 | err = PTR_ERR(device); |
358 | 369 | goto errout; |
359 | 370 | } |
371 | + devices[i] = device; | |
360 | 372 | cards++; |
361 | 373 | } |
362 | 374 | if (!cards) { |
363 | 375 | |
... | ... | @@ -369,13 +381,13 @@ |
369 | 381 | return 0; |
370 | 382 | |
371 | 383 | errout: |
372 | - platform_driver_unregister(&snd_sgalaxy_driver); | |
384 | + snd_sgalaxy_unregister_all(); | |
373 | 385 | return err; |
374 | 386 | } |
375 | 387 | |
376 | 388 | static void __exit alsa_card_sgalaxy_exit(void) |
377 | 389 | { |
378 | - platform_driver_unregister(&snd_sgalaxy_driver); | |
390 | + snd_sgalaxy_unregister_all(); | |
379 | 391 | } |
380 | 392 | |
381 | 393 | module_init(alsa_card_sgalaxy_init) |
sound/isa/sscape.c
... | ... | @@ -67,6 +67,9 @@ |
67 | 67 | |
68 | 68 | module_param_array(dma, int, NULL, 0444); |
69 | 69 | MODULE_PARM_DESC(dma, "DMA # for SoundScape driver."); |
70 | + | |
71 | +static struct platform_device *platform_devices[SNDRV_CARDS]; | |
72 | +static int pnp_registered; | |
70 | 73 | |
71 | 74 | #ifdef CONFIG_PNP |
72 | 75 | static struct pnp_card_device_id sscape_pnpids[] = { |
... | ... | @@ -1384,6 +1387,17 @@ |
1384 | 1387 | |
1385 | 1388 | #endif /* CONFIG_PNP */ |
1386 | 1389 | |
1390 | +static void __init_or_module sscape_unregister_all(void) | |
1391 | +{ | |
1392 | + int i; | |
1393 | + | |
1394 | + if (pnp_registered) | |
1395 | + pnp_unregister_card_driver(&sscape_pnpc_driver); | |
1396 | + for (i = 0; i < ARRAY_SIZE(platform_devices); ++i) | |
1397 | + platform_device_unregister(platform_devices[i]); | |
1398 | + platform_driver_unregister(&snd_sscape_driver); | |
1399 | +} | |
1400 | + | |
1387 | 1401 | static int __init sscape_manual_probe(void) |
1388 | 1402 | { |
1389 | 1403 | struct platform_device *device; |
... | ... | @@ -1411,8 +1425,8 @@ |
1411 | 1425 | dma[i] == SNDRV_AUTO_DMA) { |
1412 | 1426 | printk(KERN_INFO |
1413 | 1427 | "sscape: insufficient parameters, need IO, IRQ, MPU-IRQ and DMA\n"); |
1414 | - platform_driver_unregister(&snd_sscape_driver); | |
1415 | - return -ENXIO; | |
1428 | + ret = -ENXIO; | |
1429 | + goto errout; | |
1416 | 1430 | } |
1417 | 1431 | |
1418 | 1432 | /* |
1419 | 1433 | |
1420 | 1434 | |
1421 | 1435 | |
... | ... | @@ -1421,17 +1435,21 @@ |
1421 | 1435 | device = platform_device_register_simple(SSCAPE_DRIVER, |
1422 | 1436 | i, NULL, 0); |
1423 | 1437 | if (IS_ERR(device)) { |
1424 | - platform_driver_unregister(&snd_sscape_driver); | |
1425 | - return PTR_ERR(device); | |
1438 | + ret = PTR_ERR(device); | |
1439 | + goto errout; | |
1426 | 1440 | } |
1441 | + platform_devices[i] = device; | |
1427 | 1442 | } |
1428 | 1443 | return 0; |
1444 | + | |
1445 | + errout: | |
1446 | + sscape_unregister_all(); | |
1447 | + return ret; | |
1429 | 1448 | } |
1430 | 1449 | |
1431 | 1450 | static void sscape_exit(void) |
1432 | 1451 | { |
1433 | - pnp_unregister_card_driver(&sscape_pnpc_driver); | |
1434 | - platform_driver_unregister(&snd_sscape_driver); | |
1452 | + sscape_unregister_all(); | |
1435 | 1453 | } |
1436 | 1454 | |
1437 | 1455 | |
... | ... | @@ -1448,7 +1466,8 @@ |
1448 | 1466 | ret = sscape_manual_probe(); |
1449 | 1467 | if (ret < 0) |
1450 | 1468 | return ret; |
1451 | - pnp_register_card_driver(&sscape_pnpc_driver); | |
1469 | + if (pnp_register_card_driver(&sscape_pnpc_driver) >= 0) | |
1470 | + pnp_registered = 1; | |
1452 | 1471 | return 0; |
1453 | 1472 | } |
1454 | 1473 |
sound/isa/wavefront/wavefront.c
... | ... | @@ -83,7 +83,10 @@ |
83 | 83 | module_param_array(use_cs4232_midi, bool, NULL, 0444); |
84 | 84 | MODULE_PARM_DESC(use_cs4232_midi, "Use CS4232 MPU-401 interface (inaccessibly located inside your computer)"); |
85 | 85 | |
86 | +static struct platform_device *platform_devices[SNDRV_CARDS]; | |
87 | +static int pnp_registered; | |
86 | 88 | |
89 | + | |
87 | 90 | #ifdef CONFIG_PNP |
88 | 91 | |
89 | 92 | static struct pnp_card_device_id snd_wavefront_pnpids[] = { |
... | ... | @@ -688,6 +691,17 @@ |
688 | 691 | |
689 | 692 | #endif /* CONFIG_PNP */ |
690 | 693 | |
694 | +static void __init_or_module snd_wavefront_unregister_all(void) | |
695 | +{ | |
696 | + int i; | |
697 | + | |
698 | + if (pnp_registered) | |
699 | + pnp_unregister_card_driver(&wavefront_pnpc_driver); | |
700 | + for (i = 0; i < ARRAY_SIZE(platform_devices); ++i) | |
701 | + platform_device_unregister(platform_devices[i]); | |
702 | + platform_driver_unregister(&snd_wavefront_driver); | |
703 | +} | |
704 | + | |
691 | 705 | static int __init alsa_card_wavefront_init(void) |
692 | 706 | { |
693 | 707 | int i, err, cards = 0; |
694 | 708 | |
695 | 709 | |
696 | 710 | |
697 | 711 | |
698 | 712 | |
699 | 713 | |
700 | 714 | |
... | ... | @@ -704,31 +718,36 @@ |
704 | 718 | device = platform_device_register_simple(WAVEFRONT_DRIVER, |
705 | 719 | i, NULL, 0); |
706 | 720 | if (IS_ERR(device)) { |
707 | - platform_driver_unregister(&snd_wavefront_driver); | |
708 | - return PTR_ERR(device); | |
721 | + err = PTR_ERR(device); | |
722 | + goto errout; | |
709 | 723 | } |
724 | + platform_devices[i] = device; | |
710 | 725 | cards++; |
711 | 726 | } |
712 | 727 | |
713 | 728 | i = pnp_register_card_driver(&wavefront_pnpc_driver); |
714 | - if (i > 0) | |
729 | + if (i >= 0) { | |
730 | + pnp_registered = 1; | |
715 | 731 | cards += i; |
732 | + } | |
716 | 733 | |
717 | 734 | if (!cards) { |
718 | - pnp_unregister_card_driver(&wavefront_pnpc_driver); | |
719 | - platform_driver_unregister(&snd_wavefront_driver); | |
720 | 735 | #ifdef MODULE |
721 | 736 | printk (KERN_ERR "No WaveFront cards found or devices busy\n"); |
722 | 737 | #endif |
723 | - return -ENODEV; | |
738 | + err = -ENODEV; | |
739 | + goto errout; | |
724 | 740 | } |
725 | 741 | return 0; |
742 | + | |
743 | + errout: | |
744 | + snd_wavefront_unregister_all(); | |
745 | + return err; | |
726 | 746 | } |
727 | 747 | |
728 | 748 | static void __exit alsa_card_wavefront_exit(void) |
729 | 749 | { |
730 | - pnp_unregister_card_driver(&wavefront_pnpc_driver); | |
731 | - platform_driver_unregister(&snd_wavefront_driver); | |
750 | + snd_wavefront_unregister_all(); | |
732 | 751 | } |
733 | 752 | |
734 | 753 | module_init(alsa_card_wavefront_init) |
sound/ppc/powermac.c
... | ... | @@ -46,7 +46,9 @@ |
46 | 46 | module_param(enable_beep, bool, 0444); |
47 | 47 | MODULE_PARM_DESC(enable_beep, "Enable beep using PCM."); |
48 | 48 | |
49 | +static struct platform_device *device; | |
49 | 50 | |
51 | + | |
50 | 52 | /* |
51 | 53 | */ |
52 | 54 | |
... | ... | @@ -182,7 +184,6 @@ |
182 | 184 | static int __init alsa_card_pmac_init(void) |
183 | 185 | { |
184 | 186 | int err; |
185 | - struct platform_device *device; | |
186 | 187 | |
187 | 188 | if ((err = platform_driver_register(&snd_pmac_driver)) < 0) |
188 | 189 | return err; |
... | ... | @@ -197,6 +198,7 @@ |
197 | 198 | |
198 | 199 | static void __exit alsa_card_pmac_exit(void) |
199 | 200 | { |
201 | + platform_device_unregister(device); | |
200 | 202 | platform_driver_unregister(&snd_pmac_driver); |
201 | 203 | } |
202 | 204 |