diff options
author | Ricardo Cerqueira <v4l@cerqueira.org> | 2005-12-01 03:51:20 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-12-01 18:48:56 -0500 |
commit | f5b974cb16dd95d1ae0424f68f74550dbd793a33 (patch) | |
tree | 214fa2dc0ac32d84c56fe4a74b613eae6fbf68a0 | |
parent | 938606b02b3d7b587777e5b1e44f4196903250ca (diff) |
[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>
-rw-r--r-- | drivers/media/video/saa7134/saa7134-alsa.c | 29 | ||||
-rw-r--r-- | drivers/media/video/saa7134/saa7134-core.c | 16 | ||||
-rw-r--r-- | drivers/media/video/saa7134/saa7134-oss.c | 77 | ||||
-rw-r--r-- | drivers/media/video/saa7134/saa7134.h | 4 |
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}; | |||
58 | module_param_array(index, int, NULL, 0444); | 58 | module_param_array(index, int, NULL, 0444); |
59 | MODULE_PARM_DESC(index, "Index value for SAA7134 capture interface(s)."); | 59 | MODULE_PARM_DESC(index, "Index value for SAA7134 capture interface(s)."); |
60 | 60 | ||
61 | int position; | ||
62 | |||
63 | #define dprintk(fmt, arg...) if (debug) \ | 61 | #define dprintk(fmt, arg...) if (debug) \ |
64 | printk(KERN_DEBUG "%s/alsa: " fmt, dev->name , ## arg) | 62 | printk(KERN_DEBUG "%s/alsa: " fmt, dev->name , ## arg) |
65 | 63 | ||
@@ -945,6 +943,8 @@ int alsa_card_saa7134_create(struct saa7134_dev *dev, int devnum) | |||
945 | sprintf(card->longname, "%s at 0x%lx irq %d", | 943 | sprintf(card->longname, "%s at 0x%lx irq %d", |
946 | chip->dev->name, chip->iobase, chip->irq); | 944 | chip->dev->name, chip->iobase, chip->irq); |
947 | 945 | ||
946 | printk(KERN_INFO "%s/alsa: %s registered as card %d\n",dev->name,card->longname,index[devnum]); | ||
947 | |||
948 | if ((err = snd_card_register(card)) == 0) { | 948 | if ((err = snd_card_register(card)) == 0) { |
949 | snd_saa7134_cards[devnum] = card; | 949 | snd_saa7134_cards[devnum] = card; |
950 | return 0; | 950 | return 0; |
@@ -955,6 +955,22 @@ __nodev: | |||
955 | return err; | 955 | return err; |
956 | } | 956 | } |
957 | 957 | ||
958 | |||
959 | static int alsa_device_init(struct saa7134_dev *dev) | ||
960 | { | ||
961 | dev->dmasound.priv_data = dev; | ||
962 | alsa_card_saa7134_create(dev,dev->nr); | ||
963 | return 1; | ||
964 | } | ||
965 | |||
966 | static int alsa_device_exit(struct saa7134_dev *dev) | ||
967 | { | ||
968 | |||
969 | snd_card_free(snd_saa7134_cards[dev->nr]); | ||
970 | snd_saa7134_cards[dev->nr] = NULL; | ||
971 | return 1; | ||
972 | } | ||
973 | |||
958 | /* | 974 | /* |
959 | * Module initializer | 975 | * Module initializer |
960 | * | 976 | * |
@@ -968,22 +984,21 @@ static int saa7134_alsa_init(void) | |||
968 | struct saa7134_dev *dev = NULL; | 984 | struct saa7134_dev *dev = NULL; |
969 | struct list_head *list; | 985 | struct list_head *list; |
970 | 986 | ||
971 | position = 0; | ||
972 | |||
973 | printk(KERN_INFO "saa7134 ALSA driver for DMA sound loaded\n"); | 987 | printk(KERN_INFO "saa7134 ALSA driver for DMA sound loaded\n"); |
974 | 988 | ||
975 | list_for_each(list,&saa7134_devlist) { | 989 | list_for_each(list,&saa7134_devlist) { |
976 | dev = list_entry(list, struct saa7134_dev, devlist); | 990 | dev = list_entry(list, struct saa7134_dev, devlist); |
977 | if (dev->dmasound.priv_data == NULL) { | 991 | if (dev->dmasound.priv_data == NULL) { |
978 | dev->dmasound.priv_data = dev; | 992 | alsa_device_init(dev); |
979 | alsa_card_saa7134_create(dev,position); | ||
980 | position++; | ||
981 | } else { | 993 | } else { |
982 | printk(KERN_ERR "saa7134 ALSA: DMA sound is being handled by OSS. ignoring %s\n",dev->name); | 994 | printk(KERN_ERR "saa7134 ALSA: DMA sound is being handled by OSS. ignoring %s\n",dev->name); |
983 | return -EBUSY; | 995 | return -EBUSY; |
984 | } | 996 | } |
985 | } | 997 | } |
986 | 998 | ||
999 | dmasound_init = alsa_device_init; | ||
1000 | dmasound_exit = alsa_device_exit; | ||
1001 | |||
987 | if (dev == NULL) | 1002 | if (dev == NULL) |
988 | printk(KERN_INFO "saa7134 ALSA: no saa7134 cards found\n"); | 1003 | printk(KERN_INFO "saa7134 ALSA: no saa7134 cards found\n"); |
989 | 1004 | ||
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); | |||
88 | static LIST_HEAD(mops_list); | 88 | static LIST_HEAD(mops_list); |
89 | static unsigned int saa7134_devcount; | 89 | static unsigned int saa7134_devcount; |
90 | 90 | ||
91 | int (*dmasound_init)(struct saa7134_dev *dev); | ||
92 | int (*dmasound_exit)(struct saa7134_dev *dev); | ||
93 | |||
91 | #define dprintk(fmt, arg...) if (core_debug) \ | 94 | #define dprintk(fmt, arg...) if (core_debug) \ |
92 | printk(KERN_DEBUG "%s/core: " fmt, dev->name , ## arg) | 95 | printk(KERN_DEBUG "%s/core: " fmt, dev->name , ## arg) |
93 | 96 | ||
@@ -1017,6 +1020,10 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev, | |||
1017 | /* check for signal */ | 1020 | /* check for signal */ |
1018 | saa7134_irq_video_intl(dev); | 1021 | saa7134_irq_video_intl(dev); |
1019 | 1022 | ||
1023 | if (dmasound_init && !dev->dmasound.priv_data) { | ||
1024 | dmasound_init(dev); | ||
1025 | } | ||
1026 | |||
1020 | return 0; | 1027 | return 0; |
1021 | 1028 | ||
1022 | fail4: | 1029 | fail4: |
@@ -1040,6 +1047,11 @@ static void __devexit saa7134_finidev(struct pci_dev *pci_dev) | |||
1040 | struct list_head *item; | 1047 | struct list_head *item; |
1041 | struct saa7134_mpeg_ops *mops; | 1048 | struct saa7134_mpeg_ops *mops; |
1042 | 1049 | ||
1050 | /* Release DMA sound modules if present */ | ||
1051 | if (dmasound_exit && dev->dmasound.priv_data) { | ||
1052 | dmasound_exit(dev); | ||
1053 | } | ||
1054 | |||
1043 | /* debugging ... */ | 1055 | /* debugging ... */ |
1044 | if (irq_debug) { | 1056 | if (irq_debug) { |
1045 | u32 report = saa_readl(SAA7134_IRQ_REPORT); | 1057 | u32 report = saa_readl(SAA7134_IRQ_REPORT); |
@@ -1071,6 +1083,7 @@ static void __devexit saa7134_finidev(struct pci_dev *pci_dev) | |||
1071 | saa7134_i2c_unregister(dev); | 1083 | saa7134_i2c_unregister(dev); |
1072 | saa7134_unregister_video(dev); | 1084 | saa7134_unregister_video(dev); |
1073 | 1085 | ||
1086 | |||
1074 | /* the DMA sound modules should be unloaded before reaching | 1087 | /* the DMA sound modules should be unloaded before reaching |
1075 | this, but just in case they are still present... */ | 1088 | this, but just in case they are still present... */ |
1076 | if (dev->dmasound.priv_data != NULL) { | 1089 | if (dev->dmasound.priv_data != NULL) { |
@@ -1078,6 +1091,7 @@ static void __devexit saa7134_finidev(struct pci_dev *pci_dev) | |||
1078 | dev->dmasound.priv_data = NULL; | 1091 | dev->dmasound.priv_data = NULL; |
1079 | } | 1092 | } |
1080 | 1093 | ||
1094 | |||
1081 | /* release resources */ | 1095 | /* release resources */ |
1082 | free_irq(pci_dev->irq, dev); | 1096 | free_irq(pci_dev->irq, dev); |
1083 | iounmap(dev->lmmio); | 1097 | iounmap(dev->lmmio); |
@@ -1168,6 +1182,8 @@ EXPORT_SYMBOL(saa7134_boards); | |||
1168 | 1182 | ||
1169 | /* ----------------- for the DMA sound modules --------------- */ | 1183 | /* ----------------- for the DMA sound modules --------------- */ |
1170 | 1184 | ||
1185 | EXPORT_SYMBOL(dmasound_init); | ||
1186 | EXPORT_SYMBOL(dmasound_exit); | ||
1171 | EXPORT_SYMBOL(saa7134_pgtable_free); | 1187 | EXPORT_SYMBOL(saa7134_pgtable_free); |
1172 | EXPORT_SYMBOL(saa7134_pgtable_build); | 1188 | EXPORT_SYMBOL(saa7134_pgtable_build); |
1173 | EXPORT_SYMBOL(saa7134_pgtable_alloc); | 1189 | 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) | |||
903 | { | 903 | { |
904 | int err; | 904 | int err; |
905 | 905 | ||
906 | err = dev->dmasound.minor_dsp = | 906 | err = dev->dmasound.minor_dsp = |
907 | register_sound_dsp(&saa7134_dsp_fops, | 907 | register_sound_dsp(&saa7134_dsp_fops, |
908 | dsp_nr[dev->nr]); | 908 | dsp_nr[dev->nr]); |
909 | if (err < 0) { | 909 | if (err < 0) { |
910 | goto fail; | 910 | goto fail; |
911 | } | 911 | } |
912 | printk(KERN_INFO "%s: registered device dsp%d\n", | 912 | printk(KERN_INFO "%s: registered device dsp%d\n", |
913 | dev->name,dev->dmasound.minor_dsp >> 4); | 913 | dev->name,dev->dmasound.minor_dsp >> 4); |
914 | 914 | ||
915 | err = dev->dmasound.minor_mixer = | 915 | err = dev->dmasound.minor_mixer = |
916 | register_sound_mixer(&saa7134_mixer_fops, | 916 | register_sound_mixer(&saa7134_mixer_fops, |
917 | mixer_nr[dev->nr]); | 917 | mixer_nr[dev->nr]); |
918 | if (err < 0) | 918 | if (err < 0) |
919 | goto fail; | 919 | goto fail; |
920 | printk(KERN_INFO "%s: registered device mixer%d\n", | 920 | printk(KERN_INFO "%s: registered device mixer%d\n", |
921 | dev->name,dev->dmasound.minor_mixer >> 4); | 921 | dev->name,dev->dmasound.minor_mixer >> 4); |
922 | 922 | ||
923 | return 0; | 923 | return 0; |
924 | 924 | ||
@@ -929,6 +929,31 @@ fail: | |||
929 | 929 | ||
930 | } | 930 | } |
931 | 931 | ||
932 | static int oss_device_init(struct saa7134_dev *dev) | ||
933 | { | ||
934 | dev->dmasound.priv_data = dev; | ||
935 | saa7134_oss_init1(dev); | ||
936 | saa7134_dsp_create(dev); | ||
937 | return 1; | ||
938 | } | ||
939 | |||
940 | static int oss_device_exit(struct saa7134_dev *dev) | ||
941 | { | ||
942 | |||
943 | unregister_sound_mixer(dev->dmasound.minor_mixer); | ||
944 | unregister_sound_dsp(dev->dmasound.minor_dsp); | ||
945 | |||
946 | saa7134_oss_fini(dev); | ||
947 | |||
948 | if (dev->pci->irq > 0) { | ||
949 | synchronize_irq(dev->pci->irq); | ||
950 | free_irq(dev->pci->irq,&dev->dmasound); | ||
951 | } | ||
952 | |||
953 | dev->dmasound.priv_data = NULL; | ||
954 | return 1; | ||
955 | } | ||
956 | |||
932 | static int saa7134_oss_init(void) | 957 | static int saa7134_oss_init(void) |
933 | { | 958 | { |
934 | struct saa7134_dev *dev = NULL; | 959 | struct saa7134_dev *dev = NULL; |
@@ -939,9 +964,7 @@ static int saa7134_oss_init(void) | |||
939 | list_for_each(list,&saa7134_devlist) { | 964 | list_for_each(list,&saa7134_devlist) { |
940 | dev = list_entry(list, struct saa7134_dev, devlist); | 965 | dev = list_entry(list, struct saa7134_dev, devlist); |
941 | if (dev->dmasound.priv_data == NULL) { | 966 | if (dev->dmasound.priv_data == NULL) { |
942 | dev->dmasound.priv_data = dev; | 967 | oss_device_init(dev); |
943 | saa7134_oss_init1(dev); | ||
944 | saa7134_dsp_create(dev); | ||
945 | } else { | 968 | } else { |
946 | printk(KERN_ERR "saa7134 OSS: DMA sound is being handled by ALSA, ignoring %s\n",dev->name); | 969 | printk(KERN_ERR "saa7134 OSS: DMA sound is being handled by ALSA, ignoring %s\n",dev->name); |
947 | return -EBUSY; | 970 | return -EBUSY; |
@@ -951,6 +974,9 @@ static int saa7134_oss_init(void) | |||
951 | if (dev == NULL) | 974 | if (dev == NULL) |
952 | printk(KERN_INFO "saa7134 OSS: no saa7134 cards found\n"); | 975 | printk(KERN_INFO "saa7134 OSS: no saa7134 cards found\n"); |
953 | 976 | ||
977 | dmasound_init = oss_device_init; | ||
978 | dmasound_exit = oss_device_exit; | ||
979 | |||
954 | return 0; | 980 | return 0; |
955 | 981 | ||
956 | } | 982 | } |
@@ -967,18 +993,7 @@ void saa7134_oss_exit(void) | |||
967 | if (!dev->dmasound.minor_dsp) | 993 | if (!dev->dmasound.minor_dsp) |
968 | continue; | 994 | continue; |
969 | 995 | ||
970 | unregister_sound_mixer(dev->dmasound.minor_mixer); | 996 | oss_device_exit(dev); |
971 | unregister_sound_dsp(dev->dmasound.minor_dsp); | ||
972 | |||
973 | saa7134_oss_fini(dev); | ||
974 | |||
975 | if (dev->pci->irq > 0) { | ||
976 | synchronize_irq(dev->pci->irq); | ||
977 | free_irq(dev->pci->irq,&dev->dmasound); | ||
978 | } | ||
979 | |||
980 | dev->dmasound.priv_data = NULL; | ||
981 | |||
982 | } | 997 | } |
983 | 998 | ||
984 | printk(KERN_INFO "saa7134 OSS driver for DMA sound unloaded\n"); | 999 | 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); | |||
571 | 571 | ||
572 | int saa7134_set_dmabits(struct saa7134_dev *dev); | 572 | int saa7134_set_dmabits(struct saa7134_dev *dev); |
573 | 573 | ||
574 | extern int (*dmasound_init)(struct saa7134_dev *dev); | ||
575 | extern int (*dmasound_exit)(struct saa7134_dev *dev); | ||
576 | |||
577 | |||
574 | /* ----------------------------------------------------------- */ | 578 | /* ----------------------------------------------------------- */ |
575 | /* saa7134-cards.c */ | 579 | /* saa7134-cards.c */ |
576 | 580 | ||