forked from luck/tmp_suning_uos_patched
[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>
This commit is contained in:
parent
938606b02b
commit
f5b974cb16
@ -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 @@ int alsa_card_saa7134_create(struct saa7134_dev *dev, int devnum)
|
||||
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");
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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_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_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 @@ int saa7134_dsp_create(struct saa7134_dev *dev)
|
||||
|
||||
}
|
||||
|
||||
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");
|
||||
|
@ -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 */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user