* 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 $ */
/***************************************************************************************************
*
.mask = 0,
};
+static struct platform_device *device;
+
/* }}} */
/* {{{ Clock and sample rate stuff */
static int __init sa11xx_uda1341_init(void)
{
int err;
- struct platform_device *device;
if (!machine_is_h3xxx())
return -ENODEV;
static void __exit sa11xx_uda1341_exit(void)
{
+ platform_device_unregister(device);
platform_driver_unregister(&sa11xx_uda1341_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
},
};
+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;
err = PTR_ERR(device);
goto errout;
}
+ devices[i] = device;
cards++;
}
if (!cards) {
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)
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)
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;
err = PTR_ERR(device);
goto errout;
}
+ platform_devices[i] = device;
devices++;
}
if ((err = pnp_register_driver(&snd_mpu401_pnp_driver)) >= 0) {
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)
module_param(hwports, int, 0444);
MODULE_PARM_DESC(hwports, "Hardware ports # for MotuMTPAV MIDI.");
+static struct platform_device *device;
+
/*
* defines
*/
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;
static void __exit alsa_card_mtpav_exit(void)
{
+ platform_device_unregister(device);
platform_driver_unregister(&snd_mtpav_driver);
}
} 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) {
},
};
+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;
err = PTR_ERR(device);
goto errout;
}
+ devices[i] = device;
cards++;
}
if (! cards) {
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)
struct snd_rawmidi *midi[MAX_MIDI_DEVICES];
};
+static struct platform_device *devices[SNDRV_CARDS];
+
static int __init snd_virmidi_probe(struct platform_device *devptr)
{
},
};
+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;
err = PTR_ERR(device);
goto errout;
}
+ devices[i] = device;
cards++;
}
if (!cards) {
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)
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)
{
},
};
+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;
err = PTR_ERR(device);
goto errout;
}
+ devices[i] = device;
cards++;
}
if (!cards) {
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)
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
};
#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;
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)
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)
{
},
};
+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;
err = PTR_ERR(device);
goto errout;
}
+ devices[i] = device;
cards++;
}
if (!cards) {
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)
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;
};
#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;
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)
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)
},
};
+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;
err = PTR_ERR(device);
goto errout;
}
+ devices[i] = device;
cards++;
}
if (!cards) {
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)
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[] = {
};
#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;
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)
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: "
},
};
+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;
err = PTR_ERR(device);
goto errout;
}
+ devices[i] = device;
cards++;
}
if (!cards) {
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)
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: "
},
};
+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;
err = PTR_ERR(device);
goto errout;
}
+ devices[i] = device;
cards++;
}
if (!cards) {
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)
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;
},
};
+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;
err = PTR_ERR(device);
goto errout;
}
+ devices[i] = device;
cards++;
}
if (!cards) {
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)
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;
#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;
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)
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
},
};
+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;
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)
};
static int snd_opti9xx_pnp_is_probed;
+static struct platform_device *snd_opti9xx_platform_device;
#ifdef CONFIG_PNP
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);
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);
}
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;
#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;
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
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)
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;
},
};
+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;
err = PTR_ERR(device);
goto errout;
}
+ devices[i] = device;
cards++;
}
if (!cards) {
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)
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
},
};
+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;
err = PTR_ERR(device);
goto errout;
}
+ devices[i] = device;
cards++;
}
if (!cards) {
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)
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[] = {
#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;
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;
}
/*
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();
}
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;
}
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
#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;
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)
module_param(enable_beep, bool, 0444);
MODULE_PARM_DESC(enable_beep, "Enable beep using PCM.");
+static struct platform_device *device;
+
/*
*/
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;
static void __exit alsa_card_pmac_exit(void)
{
+ platform_device_unregister(device);
platform_driver_unregister(&snd_pmac_driver);
}