Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f5b974cb authored by Ricardo Cerqueira's avatar Ricardo Cerqueira Committed by Linus Torvalds
Browse files

[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: default avatarRicardo Cerqueira <v4l@cerqueira.org>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@brturbo.com.br>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 938606b0
Loading
Loading
Loading
Loading
+22 −7
Original line number Diff line number Diff line
@@ -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");

+16 −0
Original line number Diff line number Diff line
@@ -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);
+46 −31
Original line number Diff line number Diff line
@@ -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");
+4 −0
Original line number Diff line number Diff line
@@ -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                                             */