summary refs log tree commit diff
path: root/drivers
diff options
context:
space:
mode:
authorRicardo Cerqueira <v4l@cerqueira.org>2005-12-01 00:51:20 -0800
committerLinus Torvalds <torvalds@g5.osdl.org>2005-12-01 15:48:56 -0800
commitf5b974cb16dd95d1ae0424f68f74550dbd793a33 (patch)
tree214fa2dc0ac32d84c56fe4a74b613eae6fbf68a0 /drivers
parent938606b02b3d7b587777e5b1e44f4196903250ca (diff)
downloadlinux-f5b974cb16dd95d1ae0424f68f74550dbd793a33.tar.gz
[PATCH] V4L: Fix hotplugging issues with saa7134
- Fixed issue with hotplugging and DMA sound (sound was lost when replugging
  a card)

- Added notifiers to main saa7134 module to let the sound sub-modules know
  when a card has been inserted or removed

Signed-off-by: Ricardo Cerqueira <v4l@cerqueira.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@brturbo.com.br>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/video/saa7134/saa7134-alsa.c29
-rw-r--r--drivers/media/video/saa7134/saa7134-core.c16
-rw-r--r--drivers/media/video/saa7134/saa7134-oss.c77
-rw-r--r--drivers/media/video/saa7134/saa7134.h4
4 files changed, 88 insertions, 38 deletions
diff --git a/drivers/media/video/saa7134/saa7134-alsa.c b/drivers/media/video/saa7134/saa7134-alsa.c
index 5707c666660b..32a1f3ec4410 100644
--- a/drivers/media/video/saa7134/saa7134-alsa.c
+++ b/drivers/media/video/saa7134/saa7134-alsa.c
@@ -58,8 +58,6 @@ static int enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 0};
 module_param_array(index, int, NULL, 0444);
 MODULE_PARM_DESC(index, "Index value for SAA7134 capture interface(s).");
 
-int position;
-
 #define dprintk(fmt, arg...)    if (debug) \
         printk(KERN_DEBUG "%s/alsa: " fmt, dev->name , ## arg)
 
@@ -945,6 +943,8 @@ int alsa_card_saa7134_create(struct saa7134_dev *dev, int devnum)
 	sprintf(card->longname, "%s at 0x%lx irq %d",
 		chip->dev->name, chip->iobase, chip->irq);
 
+	printk(KERN_INFO "%s/alsa: %s registered as card %d\n",dev->name,card->longname,index[devnum]);
+
 	if ((err = snd_card_register(card)) == 0) {
 		snd_saa7134_cards[devnum] = card;
 		return 0;
@@ -955,6 +955,22 @@ __nodev:
 	return err;
 }
 
+
+static int alsa_device_init(struct saa7134_dev *dev)
+{
+	dev->dmasound.priv_data = dev;
+	alsa_card_saa7134_create(dev,dev->nr);
+	return 1;
+}
+
+static int alsa_device_exit(struct saa7134_dev *dev)
+{
+
+	snd_card_free(snd_saa7134_cards[dev->nr]);
+	snd_saa7134_cards[dev->nr] = NULL;
+	return 1;
+}
+
 /*
  * Module initializer
  *
@@ -968,22 +984,21 @@ static int saa7134_alsa_init(void)
 	struct saa7134_dev *dev = NULL;
 	struct list_head *list;
 
-	position = 0;
-
         printk(KERN_INFO "saa7134 ALSA driver for DMA sound loaded\n");
 
 	list_for_each(list,&saa7134_devlist) {
 		dev = list_entry(list, struct saa7134_dev, devlist);
 		if (dev->dmasound.priv_data == NULL) {
-			dev->dmasound.priv_data = dev;
-			alsa_card_saa7134_create(dev,position);
-			position++;
+			alsa_device_init(dev);
 		} else {
 			printk(KERN_ERR "saa7134 ALSA: DMA sound is being handled by OSS. ignoring %s\n",dev->name);
 			return -EBUSY;
 		}
 	}
 
+	dmasound_init = alsa_device_init;
+	dmasound_exit = alsa_device_exit;
+
 	if (dev == NULL)
 		printk(KERN_INFO "saa7134 ALSA: no saa7134 cards found\n");
 
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c
index 4275d2ddb864..0aca7229f3ce 100644
--- a/drivers/media/video/saa7134/saa7134-core.c
+++ b/drivers/media/video/saa7134/saa7134-core.c
@@ -88,6 +88,9 @@ LIST_HEAD(saa7134_devlist);
 static LIST_HEAD(mops_list);
 static unsigned int saa7134_devcount;
 
+int (*dmasound_init)(struct saa7134_dev *dev);
+int (*dmasound_exit)(struct saa7134_dev *dev);
+
 #define dprintk(fmt, arg...)	if (core_debug) \
 	printk(KERN_DEBUG "%s/core: " fmt, dev->name , ## arg)
 
@@ -1017,6 +1020,10 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
 	/* check for signal */
 	saa7134_irq_video_intl(dev);
 
+	if (dmasound_init && !dev->dmasound.priv_data) {
+		dmasound_init(dev);
+	}
+
 	return 0;
 
  fail4:
@@ -1040,6 +1047,11 @@ static void __devexit saa7134_finidev(struct pci_dev *pci_dev)
 	struct list_head *item;
 	struct saa7134_mpeg_ops *mops;
 
+	/* Release DMA sound modules if present */
+	if (dmasound_exit && dev->dmasound.priv_data) {
+		dmasound_exit(dev);
+	}
+
 	/* debugging ... */
 	if (irq_debug) {
 		u32 report = saa_readl(SAA7134_IRQ_REPORT);
@@ -1071,6 +1083,7 @@ static void __devexit saa7134_finidev(struct pci_dev *pci_dev)
 	saa7134_i2c_unregister(dev);
 	saa7134_unregister_video(dev);
 
+
 	/* the DMA sound modules should be unloaded before reaching
 	   this, but just in case they are still present... */
 	if (dev->dmasound.priv_data != NULL) {
@@ -1078,6 +1091,7 @@ static void __devexit saa7134_finidev(struct pci_dev *pci_dev)
 		dev->dmasound.priv_data = NULL;
 	}
 
+
 	/* release resources */
 	free_irq(pci_dev->irq, dev);
 	iounmap(dev->lmmio);
@@ -1168,6 +1182,8 @@ EXPORT_SYMBOL(saa7134_boards);
 
 /* ----------------- for the DMA sound modules --------------- */
 
+EXPORT_SYMBOL(dmasound_init);
+EXPORT_SYMBOL(dmasound_exit);
 EXPORT_SYMBOL(saa7134_pgtable_free);
 EXPORT_SYMBOL(saa7134_pgtable_build);
 EXPORT_SYMBOL(saa7134_pgtable_alloc);
diff --git a/drivers/media/video/saa7134/saa7134-oss.c b/drivers/media/video/saa7134/saa7134-oss.c
index fd9ed11ab1e2..299046974382 100644
--- a/drivers/media/video/saa7134/saa7134-oss.c
+++ b/drivers/media/video/saa7134/saa7134-oss.c
@@ -903,22 +903,22 @@ int saa7134_dsp_create(struct saa7134_dev *dev)
 {
 	int err;
 
-                        err = dev->dmasound.minor_dsp =
-                                register_sound_dsp(&saa7134_dsp_fops,
-                                                   dsp_nr[dev->nr]);
-                        if (err < 0) {
-                                goto fail;
-                        }
-                        printk(KERN_INFO "%s: registered device dsp%d\n",
-                               dev->name,dev->dmasound.minor_dsp >> 4);
-
-                        err = dev->dmasound.minor_mixer =
-                                register_sound_mixer(&saa7134_mixer_fops,
-                                                     mixer_nr[dev->nr]);
-                        if (err < 0)
-                                goto fail;
-                        printk(KERN_INFO "%s: registered device mixer%d\n",
-                               dev->name,dev->dmasound.minor_mixer >> 4);
+	err = dev->dmasound.minor_dsp =
+		register_sound_dsp(&saa7134_dsp_fops,
+                			dsp_nr[dev->nr]);
+	if (err < 0) {
+		goto fail;
+	}
+	printk(KERN_INFO "%s: registered device dsp%d\n",
+		dev->name,dev->dmasound.minor_dsp >> 4);
+
+	err = dev->dmasound.minor_mixer =
+		register_sound_mixer(&saa7134_mixer_fops,
+					mixer_nr[dev->nr]);
+	if (err < 0)
+		goto fail;
+	printk(KERN_INFO "%s: registered device mixer%d\n",
+		dev->name,dev->dmasound.minor_mixer >> 4);
 
 	return 0;
 
@@ -929,6 +929,31 @@ fail:
 
 }
 
+static int oss_device_init(struct saa7134_dev *dev)
+{
+	dev->dmasound.priv_data = dev;
+	saa7134_oss_init1(dev);
+	saa7134_dsp_create(dev);
+	return 1;
+}
+
+static int oss_device_exit(struct saa7134_dev *dev)
+{
+
+	unregister_sound_mixer(dev->dmasound.minor_mixer);
+	unregister_sound_dsp(dev->dmasound.minor_dsp);
+
+	saa7134_oss_fini(dev);
+
+	if (dev->pci->irq > 0) {
+		synchronize_irq(dev->pci->irq);
+		free_irq(dev->pci->irq,&dev->dmasound);
+	}
+
+	dev->dmasound.priv_data = NULL;
+	return 1;
+}
+
 static int saa7134_oss_init(void)
 {
         struct saa7134_dev *dev = NULL;
@@ -939,9 +964,7 @@ static int saa7134_oss_init(void)
         list_for_each(list,&saa7134_devlist) {
                 dev = list_entry(list, struct saa7134_dev, devlist);
 		if (dev->dmasound.priv_data == NULL) {
-			dev->dmasound.priv_data = dev;
-			saa7134_oss_init1(dev);
-			saa7134_dsp_create(dev);
+			oss_device_init(dev);
 		} else {
                 	printk(KERN_ERR "saa7134 OSS: DMA sound is being handled by ALSA, ignoring %s\n",dev->name);
 			return -EBUSY;
@@ -951,6 +974,9 @@ static int saa7134_oss_init(void)
         if (dev == NULL)
                 printk(KERN_INFO "saa7134 OSS: no saa7134 cards found\n");
 
+	dmasound_init = oss_device_init;
+	dmasound_exit = oss_device_exit;
+
         return 0;
 
 }
@@ -967,18 +993,7 @@ void saa7134_oss_exit(void)
 		if (!dev->dmasound.minor_dsp)
 			continue;
 
-                unregister_sound_mixer(dev->dmasound.minor_mixer);
-                unregister_sound_dsp(dev->dmasound.minor_dsp);
-
-		saa7134_oss_fini(dev);
-
-		if (dev->pci->irq > 0) {
-			synchronize_irq(dev->pci->irq);
-			free_irq(dev->pci->irq,&dev->dmasound);
-		}
-
-        	dev->dmasound.priv_data = NULL;
-
+		oss_device_exit(dev);
         }
 
         printk(KERN_INFO "saa7134 OSS driver for DMA sound unloaded\n");
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
index 244e1973081c..add49db1ad41 100644
--- a/drivers/media/video/saa7134/saa7134.h
+++ b/drivers/media/video/saa7134/saa7134.h
@@ -571,6 +571,10 @@ void saa7134_dma_free(struct saa7134_dev *dev,struct saa7134_buf *buf);
 
 int saa7134_set_dmabits(struct saa7134_dev *dev);
 
+extern int (*dmasound_init)(struct saa7134_dev *dev);
+extern int (*dmasound_exit)(struct saa7134_dev *dev);
+
+
 /* ----------------------------------------------------------- */
 /* saa7134-cards.c                                             */