aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/video/cx18/cx18-driver.c107
-rw-r--r--drivers/media/video/cx18/cx18-driver.h27
-rw-r--r--drivers/media/video/cx18/cx18-fileops.c35
-rw-r--r--drivers/media/video/cx18/cx18-i2c.c2
-rw-r--r--drivers/media/video/cx18/cx18-ioctl.c10
-rw-r--r--drivers/media/video/cx18/cx18-streams.c9
6 files changed, 71 insertions, 119 deletions
diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c
index 2a45bbc757e8..f69e688ab6f4 100644
--- a/drivers/media/video/cx18/cx18-driver.c
+++ b/drivers/media/video/cx18/cx18-driver.c
@@ -39,10 +39,6 @@
39 39
40#include <media/tveeprom.h> 40#include <media/tveeprom.h>
41 41
42
43/* var to keep track of the number of array elements in use */
44int cx18_cards_active;
45
46/* If you have already X v4l cards, then set this to X. This way 42/* If you have already X v4l cards, then set this to X. This way
47 the device numbers stay matched. Example: you have a WinTV card 43 the device numbers stay matched. Example: you have a WinTV card
48 without radio and a Compro H900 with. Normally this would give a 44 without radio and a Compro H900 with. Normally this would give a
@@ -50,12 +46,6 @@ int cx18_cards_active;
50 setting this to 1 you ensure that radio0 is now also radio1. */ 46 setting this to 1 you ensure that radio0 is now also radio1. */
51int cx18_first_minor; 47int cx18_first_minor;
52 48
53/* Master variable for all cx18 info */
54struct cx18 *cx18_cards[CX18_MAX_CARDS];
55
56/* Protects cx18_cards_active */
57DEFINE_SPINLOCK(cx18_cards_lock);
58
59/* add your revision and whatnot here */ 49/* add your revision and whatnot here */
60static struct pci_device_id cx18_pci_tbl[] __devinitdata = { 50static struct pci_device_id cx18_pci_tbl[] __devinitdata = {
61 {PCI_VENDOR_ID_CX, PCI_DEVICE_ID_CX23418, 51 {PCI_VENDOR_ID_CX, PCI_DEVICE_ID_CX23418,
@@ -65,6 +55,8 @@ static struct pci_device_id cx18_pci_tbl[] __devinitdata = {
65 55
66MODULE_DEVICE_TABLE(pci, cx18_pci_tbl); 56MODULE_DEVICE_TABLE(pci, cx18_pci_tbl);
67 57
58static atomic_t cx18_instance = ATOMIC_INIT(0);
59
68/* Parameter declarations */ 60/* Parameter declarations */
69static int cardtype[CX18_MAX_CARDS]; 61static int cardtype[CX18_MAX_CARDS];
70static int tuner[CX18_MAX_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1, 62static int tuner[CX18_MAX_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1,
@@ -491,9 +483,9 @@ static void cx18_process_options(struct cx18 *cx)
491 cx->stream_buf_size[i] *= 1024; /* convert from kB to bytes */ 483 cx->stream_buf_size[i] *= 1024; /* convert from kB to bytes */
492 } 484 }
493 485
494 cx->options.cardtype = cardtype[cx->num]; 486 cx->options.cardtype = cardtype[cx->instance];
495 cx->options.tuner = tuner[cx->num]; 487 cx->options.tuner = tuner[cx->instance];
496 cx->options.radio = radio[cx->num]; 488 cx->options.radio = radio[cx->instance];
497 489
498 cx->std = cx18_parse_std(cx); 490 cx->std = cx18_parse_std(cx);
499 if (cx->options.cardtype == -1) { 491 if (cx->options.cardtype == -1) {
@@ -550,7 +542,7 @@ done:
550} 542}
551 543
552/* Precondition: the cx18 structure has been memset to 0. Only 544/* Precondition: the cx18 structure has been memset to 0. Only
553 the dev and num fields have been filled in. 545 the dev and instance fields have been filled in.
554 No assumptions on the card type may be made here (see cx18_init_struct2 546 No assumptions on the card type may be made here (see cx18_init_struct2
555 for that). 547 for that).
556 */ 548 */
@@ -567,7 +559,7 @@ static int __devinit cx18_init_struct1(struct cx18 *cx)
567 mutex_init(&cx->epu2apu_mb_lock); 559 mutex_init(&cx->epu2apu_mb_lock);
568 mutex_init(&cx->epu2cpu_mb_lock); 560 mutex_init(&cx->epu2cpu_mb_lock);
569 561
570 cx->work_queue = create_singlethread_workqueue(cx->name); 562 cx->work_queue = create_singlethread_workqueue(cx->v4l2_dev.name);
571 if (cx->work_queue == NULL) { 563 if (cx->work_queue == NULL) {
572 CX18_ERR("Unable to create work hander thread\n"); 564 CX18_ERR("Unable to create work hander thread\n");
573 return -ENOMEM; 565 return -ENOMEM;
@@ -647,15 +639,16 @@ static int cx18_setup_pci(struct cx18 *cx, struct pci_dev *pci_dev,
647 CX18_DEBUG_INFO("Enabling pci device\n"); 639 CX18_DEBUG_INFO("Enabling pci device\n");
648 640
649 if (pci_enable_device(pci_dev)) { 641 if (pci_enable_device(pci_dev)) {
650 CX18_ERR("Can't enable device %d!\n", cx->num); 642 CX18_ERR("Can't enable device %d!\n", cx->instance);
651 return -EIO; 643 return -EIO;
652 } 644 }
653 if (pci_set_dma_mask(pci_dev, 0xffffffff)) { 645 if (pci_set_dma_mask(pci_dev, 0xffffffff)) {
654 CX18_ERR("No suitable DMA available on card %d.\n", cx->num); 646 CX18_ERR("No suitable DMA available, card %d\n", cx->instance);
655 return -EIO; 647 return -EIO;
656 } 648 }
657 if (!request_mem_region(cx->base_addr, CX18_MEM_SIZE, "cx18 encoder")) { 649 if (!request_mem_region(cx->base_addr, CX18_MEM_SIZE, "cx18 encoder")) {
658 CX18_ERR("Cannot request encoder memory region on card %d.\n", cx->num); 650 CX18_ERR("Cannot request encoder memory region, card %d\n",
651 cx->instance);
659 return -EIO; 652 return -EIO;
660 } 653 }
661 654
@@ -741,44 +734,42 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev,
741 u32 devtype; 734 u32 devtype;
742 struct cx18 *cx; 735 struct cx18 *cx;
743 736
744 spin_lock(&cx18_cards_lock); 737 /* FIXME - module parameter arrays constrain max instances */
745 738 i = atomic_inc_return(&cx18_instance) - 1;
746 /* Make sure we've got a place for this card */ 739 if (i >= CX18_MAX_CARDS) {
747 if (cx18_cards_active == CX18_MAX_CARDS) { 740 printk(KERN_ERR "cx18: cannot manage card %d, driver has a "
748 printk(KERN_ERR "cx18: Maximum number of cards detected (%d).\n", 741 "limit of 0 - %d\n", i, CX18_MAX_CARDS - 1);
749 cx18_cards_active);
750 spin_unlock(&cx18_cards_lock);
751 return -ENOMEM; 742 return -ENOMEM;
752 } 743 }
753 744
754 cx = kzalloc(sizeof(struct cx18), GFP_ATOMIC); 745 cx = kzalloc(sizeof(struct cx18), GFP_ATOMIC);
755 if (!cx) { 746 if (cx == NULL) {
756 spin_unlock(&cx18_cards_lock); 747 printk(KERN_ERR "cx18: cannot manage card %d, out of memory\n",
748 i);
757 return -ENOMEM; 749 return -ENOMEM;
758 } 750 }
759 cx18_cards[cx18_cards_active] = cx;
760 cx->num = cx18_cards_active++;
761 snprintf(cx->name, sizeof(cx->name), "cx18-%d", cx->num);
762 CX18_INFO("Initializing card #%d\n", cx->num);
763
764 spin_unlock(&cx18_cards_lock);
765
766 cx->pci_dev = pci_dev; 751 cx->pci_dev = pci_dev;
752 cx->instance = i;
753
767 retval = v4l2_device_register(&pci_dev->dev, &cx->v4l2_dev); 754 retval = v4l2_device_register(&pci_dev->dev, &cx->v4l2_dev);
768 if (retval) { 755 if (retval) {
769 CX18_ERR("Call to v4l2_device_register() failed\n"); 756 printk(KERN_ERR "cx18: v4l2_device_register of card %d failed"
770 goto err; 757 "\n", cx->instance);
758 kfree(cx);
759 return retval;
771 } 760 }
772 CX18_DEBUG_INFO("registered v4l2_device name: %s\n", cx->v4l2_dev.name); 761 snprintf(cx->v4l2_dev.name, sizeof(cx->v4l2_dev.name), "cx18-%d",
762 cx->instance);
763 CX18_INFO("Initializing card %d\n", cx->instance);
773 764
774 cx18_process_options(cx); 765 cx18_process_options(cx);
775 if (cx->options.cardtype == -1) { 766 if (cx->options.cardtype == -1) {
776 retval = -ENODEV; 767 retval = -ENODEV;
777 goto unregister_v4l2; 768 goto err;
778 } 769 }
779 if (cx18_init_struct1(cx)) { 770 if (cx18_init_struct1(cx)) {
780 retval = -ENOMEM; 771 retval = -ENOMEM;
781 goto unregister_v4l2; 772 goto err;
782 } 773 }
783 774
784 CX18_DEBUG_INFO("base addr: 0x%08x\n", cx->base_addr); 775 CX18_DEBUG_INFO("base addr: 0x%08x\n", cx->base_addr);
@@ -829,8 +820,6 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev,
829 goto free_map; 820 goto free_map;
830 } 821 }
831 822
832 CX18_DEBUG_INFO("Active card count: %d.\n", cx18_cards_active);
833
834 if (cx->card->hw_all & CX18_HW_TVEEPROM) { 823 if (cx->card->hw_all & CX18_HW_TVEEPROM) {
835 /* Based on the model number the cardtype may be changed. 824 /* Based on the model number the cardtype may be changed.
836 The PCI IDs are not always reliable. */ 825 The PCI IDs are not always reliable. */
@@ -847,7 +836,8 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev,
847 836
848 /* Register IRQ */ 837 /* Register IRQ */
849 retval = request_irq(cx->pci_dev->irq, cx18_irq_handler, 838 retval = request_irq(cx->pci_dev->irq, cx18_irq_handler,
850 IRQF_SHARED | IRQF_DISABLED, cx->name, (void *)cx); 839 IRQF_SHARED | IRQF_DISABLED,
840 cx->v4l2_dev.name, (void *)cx);
851 if (retval) { 841 if (retval) {
852 CX18_ERR("Failed to register irq %d\n", retval); 842 CX18_ERR("Failed to register irq %d\n", retval);
853 goto free_i2c; 843 goto free_i2c;
@@ -933,8 +923,7 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev,
933 goto free_streams; 923 goto free_streams;
934 } 924 }
935 925
936 CX18_INFO("Initialized card #%d: %s\n", cx->num, cx->card_name); 926 CX18_INFO("Initialized card: %s\n", cx->card_name);
937
938 return 0; 927 return 0;
939 928
940free_streams: 929free_streams:
@@ -949,18 +938,13 @@ free_mem:
949 release_mem_region(cx->base_addr, CX18_MEM_SIZE); 938 release_mem_region(cx->base_addr, CX18_MEM_SIZE);
950free_workqueue: 939free_workqueue:
951 destroy_workqueue(cx->work_queue); 940 destroy_workqueue(cx->work_queue);
952unregister_v4l2:
953 v4l2_device_unregister(&cx->v4l2_dev);
954err: 941err:
955 if (retval == 0) 942 if (retval == 0)
956 retval = -ENODEV; 943 retval = -ENODEV;
957 CX18_ERR("Error %d on initialization\n", retval); 944 CX18_ERR("Error %d on initialization\n", retval);
958 945
959 i = cx->num; 946 v4l2_device_unregister(&cx->v4l2_dev);
960 spin_lock(&cx18_cards_lock); 947 kfree(cx);
961 kfree(cx18_cards[i]);
962 cx18_cards[i] = NULL;
963 spin_unlock(&cx18_cards_lock);
964 return retval; 948 return retval;
965} 949}
966 950
@@ -1069,9 +1053,9 @@ static void cx18_cancel_epu_work_orders(struct cx18 *cx)
1069static void cx18_remove(struct pci_dev *pci_dev) 1053static void cx18_remove(struct pci_dev *pci_dev)
1070{ 1054{
1071 struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev); 1055 struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev);
1072 struct cx18 *cx = container_of(v4l2_dev, struct cx18, v4l2_dev); 1056 struct cx18 *cx = to_cx18(v4l2_dev);
1073 1057
1074 CX18_DEBUG_INFO("Removing Card #%d\n", cx->num); 1058 CX18_DEBUG_INFO("Removing Card\n");
1075 1059
1076 /* Stop all captures */ 1060 /* Stop all captures */
1077 CX18_DEBUG_INFO("Stopping all streams\n"); 1061 CX18_DEBUG_INFO("Stopping all streams\n");
@@ -1099,10 +1083,12 @@ static void cx18_remove(struct pci_dev *pci_dev)
1099 release_mem_region(cx->base_addr, CX18_MEM_SIZE); 1083 release_mem_region(cx->base_addr, CX18_MEM_SIZE);
1100 1084
1101 pci_disable_device(cx->pci_dev); 1085 pci_disable_device(cx->pci_dev);
1086 /* FIXME - we leak cx->vbi.sliced_mpeg_data[i] allocations */
1102 1087
1103 v4l2_device_unregister(v4l2_dev); 1088 CX18_INFO("Removed %s\n", cx->card_name);
1104 1089
1105 CX18_INFO("Removed %s, card #%d\n", cx->card_name, cx->num); 1090 v4l2_device_unregister(v4l2_dev);
1091 kfree(cx);
1106} 1092}
1107 1093
1108/* define a pci_driver for card detection */ 1094/* define a pci_driver for card detection */
@@ -1117,8 +1103,6 @@ static int module_start(void)
1117{ 1103{
1118 printk(KERN_INFO "cx18: Start initialization, version %s\n", CX18_VERSION); 1104 printk(KERN_INFO "cx18: Start initialization, version %s\n", CX18_VERSION);
1119 1105
1120 memset(cx18_cards, 0, sizeof(cx18_cards));
1121
1122 /* Validate parameters */ 1106 /* Validate parameters */
1123 if (cx18_first_minor < 0 || cx18_first_minor >= CX18_MAX_CARDS) { 1107 if (cx18_first_minor < 0 || cx18_first_minor >= CX18_MAX_CARDS) {
1124 printk(KERN_ERR "cx18: Exiting, cx18_first_minor must be between 0 and %d\n", 1108 printk(KERN_ERR "cx18: Exiting, cx18_first_minor must be between 0 and %d\n",
@@ -1141,16 +1125,7 @@ static int module_start(void)
1141 1125
1142static void module_cleanup(void) 1126static void module_cleanup(void)
1143{ 1127{
1144 int i;
1145
1146 pci_unregister_driver(&cx18_pci_driver); 1128 pci_unregister_driver(&cx18_pci_driver);
1147
1148 for (i = 0; i < cx18_cards_active; i++) {
1149 if (cx18_cards[i] == NULL)
1150 continue;
1151 kfree(cx18_cards[i]);
1152 }
1153
1154} 1129}
1155 1130
1156module_init(module_start); 1131module_init(module_start);
diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h
index 7fc914c521f7..def82bd1078a 100644
--- a/drivers/media/video/cx18/cx18-driver.h
+++ b/drivers/media/video/cx18/cx18-driver.h
@@ -144,12 +144,12 @@
144/* Flag to turn on high volume debugging */ 144/* Flag to turn on high volume debugging */
145#define CX18_DBGFLG_HIGHVOL (1 << 8) 145#define CX18_DBGFLG_HIGHVOL (1 << 8)
146 146
147/* NOTE: extra space before comma in 'cx->num , ## args' is required for 147/* NOTE: extra space before comma in 'fmt , ## args' is required for
148 gcc-2.95, otherwise it won't compile. */ 148 gcc-2.95, otherwise it won't compile. */
149#define CX18_DEBUG(x, type, fmt, args...) \ 149#define CX18_DEBUG(x, type, fmt, args...) \
150 do { \ 150 do { \
151 if ((x) & cx18_debug) \ 151 if ((x) & cx18_debug) \
152 printk(KERN_INFO "cx18-%d " type ": " fmt, cx->num , ## args); \ 152 v4l2_info(&cx->v4l2_dev, " " type ": " fmt , ## args); \
153 } while (0) 153 } while (0)
154#define CX18_DEBUG_WARN(fmt, args...) CX18_DEBUG(CX18_DBGFLG_WARN, "warning", fmt , ## args) 154#define CX18_DEBUG_WARN(fmt, args...) CX18_DEBUG(CX18_DBGFLG_WARN, "warning", fmt , ## args)
155#define CX18_DEBUG_INFO(fmt, args...) CX18_DEBUG(CX18_DBGFLG_INFO, "info", fmt , ## args) 155#define CX18_DEBUG_INFO(fmt, args...) CX18_DEBUG(CX18_DBGFLG_INFO, "info", fmt , ## args)
@@ -163,7 +163,7 @@
163#define CX18_DEBUG_HIGH_VOL(x, type, fmt, args...) \ 163#define CX18_DEBUG_HIGH_VOL(x, type, fmt, args...) \
164 do { \ 164 do { \
165 if (((x) & cx18_debug) && (cx18_debug & CX18_DBGFLG_HIGHVOL)) \ 165 if (((x) & cx18_debug) && (cx18_debug & CX18_DBGFLG_HIGHVOL)) \
166 printk(KERN_INFO "cx18%d " type ": " fmt, cx->num , ## args); \ 166 v4l2_info(&cx->v4l2_dev, " " type ": " fmt , ## args); \
167 } while (0) 167 } while (0)
168#define CX18_DEBUG_HI_WARN(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_WARN, "warning", fmt , ## args) 168#define CX18_DEBUG_HI_WARN(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_WARN, "warning", fmt , ## args)
169#define CX18_DEBUG_HI_INFO(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_INFO, "info", fmt , ## args) 169#define CX18_DEBUG_HI_INFO(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_INFO, "info", fmt , ## args)
@@ -175,9 +175,9 @@
175#define CX18_DEBUG_HI_IRQ(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_IRQ, "irq", fmt , ## args) 175#define CX18_DEBUG_HI_IRQ(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_IRQ, "irq", fmt , ## args)
176 176
177/* Standard kernel messages */ 177/* Standard kernel messages */
178#define CX18_ERR(fmt, args...) printk(KERN_ERR "cx18-%d: " fmt, cx->num , ## args) 178#define CX18_ERR(fmt, args...) v4l2_err(&cx->v4l2_dev, fmt , ## args)
179#define CX18_WARN(fmt, args...) printk(KERN_WARNING "cx18-%d: " fmt, cx->num , ## args) 179#define CX18_WARN(fmt, args...) v4l2_warn(&cx->v4l2_dev, fmt , ## args)
180#define CX18_INFO(fmt, args...) printk(KERN_INFO "cx18-%d: " fmt, cx->num , ## args) 180#define CX18_INFO(fmt, args...) v4l2_info(&cx->v4l2_dev, fmt , ## args)
181 181
182/* Values for CX18_API_DEC_PLAYBACK_SPEED mpeg_frame_type_mask parameter: */ 182/* Values for CX18_API_DEC_PLAYBACK_SPEED mpeg_frame_type_mask parameter: */
183#define MPEG_FRAME_TYPE_IFRAME 1 183#define MPEG_FRAME_TYPE_IFRAME 1
@@ -445,8 +445,7 @@ struct cx18_i2c_algo_callback_data {
445 445
446/* Struct to hold info about cx18 cards */ 446/* Struct to hold info about cx18 cards */
447struct cx18 { 447struct cx18 {
448 int num; /* board number, -1 during init! */ 448 int instance;
449 char name[8]; /* board name for printk and interrupts (e.g. 'cx180') */
450 struct pci_dev *pci_dev; 449 struct pci_dev *pci_dev;
451 struct v4l2_device v4l2_dev; 450 struct v4l2_device v4l2_dev;
452 451
@@ -455,8 +454,8 @@ struct cx18 {
455 const struct cx18_card_tuner_i2c *card_i2c; /* i2c addresses to probe for tuner */ 454 const struct cx18_card_tuner_i2c *card_i2c; /* i2c addresses to probe for tuner */
456 u8 is_50hz; 455 u8 is_50hz;
457 u8 is_60hz; 456 u8 is_60hz;
458 u8 is_out_50hz; 457 u8 is_out_50hz; /* FIXME - remove, we don't have an output decoder */
459 u8 is_out_60hz; 458 u8 is_out_60hz; /* FIXME - remove, we don't have an output decoder */
460 u8 nof_inputs; /* number of video inputs */ 459 u8 nof_inputs; /* number of video inputs */
461 u8 nof_audio_inputs; /* number of audio inputs */ 460 u8 nof_audio_inputs; /* number of audio inputs */
462 u16 buffer_id; /* buffer ID counter */ 461 u16 buffer_id; /* buffer ID counter */
@@ -547,11 +546,13 @@ struct cx18 {
547 v4l2_std_id tuner_std; /* The norm of the tuner (fixed) */ 546 v4l2_std_id tuner_std; /* The norm of the tuner (fixed) */
548}; 547};
549 548
549static inline struct cx18 *to_cx18(struct v4l2_device *v4l2_dev)
550{
551 return container_of(v4l2_dev, struct cx18, v4l2_dev);
552}
553
550/* Globals */ 554/* Globals */
551extern struct cx18 *cx18_cards[];
552extern int cx18_cards_active;
553extern int cx18_first_minor; 555extern int cx18_first_minor;
554extern spinlock_t cx18_cards_lock;
555 556
556/*==============Prototypes==================*/ 557/*==============Prototypes==================*/
557 558
diff --git a/drivers/media/video/cx18/cx18-fileops.c b/drivers/media/video/cx18/cx18-fileops.c
index 68dd50ac4bfe..757982ea3766 100644
--- a/drivers/media/video/cx18/cx18-fileops.c
+++ b/drivers/media/video/cx18/cx18-fileops.c
@@ -682,38 +682,15 @@ static int cx18_serialized_open(struct cx18_stream *s, struct file *filp)
682 682
683int cx18_v4l2_open(struct file *filp) 683int cx18_v4l2_open(struct file *filp)
684{ 684{
685 int res, x, y = 0; 685 int res;
686 struct cx18 *cx = NULL; 686 struct video_device *video_dev = video_devdata(filp);
687 struct cx18_stream *s = NULL; 687 struct cx18_stream *s = video_get_drvdata(video_dev);
688 int minor = video_devdata(filp)->minor; 688 struct cx18 *cx = s->cx;;
689
690 /* Find which card this open was on */
691 spin_lock(&cx18_cards_lock);
692 for (x = 0; cx == NULL && x < cx18_cards_active; x++) {
693 /* find out which stream this open was on */
694 for (y = 0; y < CX18_MAX_STREAMS; y++) {
695 if (cx18_cards[x] == NULL)
696 continue;
697 s = &cx18_cards[x]->streams[y];
698 if (s->video_dev && s->video_dev->minor == minor) {
699 cx = cx18_cards[x];
700 break;
701 }
702 }
703 }
704 spin_unlock(&cx18_cards_lock);
705
706 if (cx == NULL) {
707 /* Couldn't find a device registered
708 on that minor, shouldn't happen! */
709 printk(KERN_WARNING "No cx18 device found on minor %d\n",
710 minor);
711 return -ENXIO;
712 }
713 689
714 mutex_lock(&cx->serialize_lock); 690 mutex_lock(&cx->serialize_lock);
715 if (cx18_init_on_first_open(cx)) { 691 if (cx18_init_on_first_open(cx)) {
716 CX18_ERR("Failed to initialize on minor %d\n", minor); 692 CX18_ERR("Failed to initialize on minor %d\n",
693 video_dev->minor);
717 mutex_unlock(&cx->serialize_lock); 694 mutex_unlock(&cx->serialize_lock);
718 return -ENXIO; 695 return -ENXIO;
719 } 696 }
diff --git a/drivers/media/video/cx18/cx18-i2c.c b/drivers/media/video/cx18/cx18-i2c.c
index 200d9257a926..db2c3e6997d0 100644
--- a/drivers/media/video/cx18/cx18-i2c.c
+++ b/drivers/media/video/cx18/cx18-i2c.c
@@ -358,7 +358,7 @@ int init_cx18_i2c(struct cx18 *cx)
358 cx->i2c_adap[i].algo_data = &cx->i2c_algo[i]; 358 cx->i2c_adap[i].algo_data = &cx->i2c_algo[i];
359 359
360 sprintf(cx->i2c_adap[i].name + strlen(cx->i2c_adap[i].name), 360 sprintf(cx->i2c_adap[i].name + strlen(cx->i2c_adap[i].name),
361 " #%d-%d", cx->num, i); 361 " #%d-%d", cx->instance, i);
362 i2c_set_adapdata(&cx->i2c_adap[i], cx); 362 i2c_set_adapdata(&cx->i2c_adap[i], cx);
363 363
364 memcpy(&cx->i2c_client[i], &cx18_i2c_client_template, 364 memcpy(&cx->i2c_client[i], &cx18_i2c_client_template,
diff --git a/drivers/media/video/cx18/cx18-ioctl.c b/drivers/media/video/cx18/cx18-ioctl.c
index 5c8e9cb244f9..3277b3d3ceae 100644
--- a/drivers/media/video/cx18/cx18-ioctl.c
+++ b/drivers/media/video/cx18/cx18-ioctl.c
@@ -387,20 +387,17 @@ static int cx18_g_chip_ident(struct file *file, void *fh,
387static int cx18_cxc(struct cx18 *cx, unsigned int cmd, void *arg) 387static int cx18_cxc(struct cx18 *cx, unsigned int cmd, void *arg)
388{ 388{
389 struct v4l2_dbg_register *regs = arg; 389 struct v4l2_dbg_register *regs = arg;
390 unsigned long flags;
391 390
392 if (!capable(CAP_SYS_ADMIN)) 391 if (!capable(CAP_SYS_ADMIN))
393 return -EPERM; 392 return -EPERM;
394 if (regs->reg >= CX18_MEM_OFFSET + CX18_MEM_SIZE) 393 if (regs->reg >= CX18_MEM_OFFSET + CX18_MEM_SIZE)
395 return -EINVAL; 394 return -EINVAL;
396 395
397 spin_lock_irqsave(&cx18_cards_lock, flags);
398 regs->size = 4; 396 regs->size = 4;
399 if (cmd == VIDIOC_DBG_G_REGISTER) 397 if (cmd == VIDIOC_DBG_G_REGISTER)
400 regs->val = cx18_read_enc(cx, regs->reg); 398 regs->val = cx18_read_enc(cx, regs->reg);
401 else 399 else
402 cx18_write_enc(cx, regs->val, regs->reg); 400 cx18_write_enc(cx, regs->val, regs->reg);
403 spin_unlock_irqrestore(&cx18_cards_lock, flags);
404 return 0; 401 return 0;
405} 402}
406 403
@@ -847,7 +844,7 @@ static int cx18_log_status(struct file *file, void *fh)
847 int i; 844 int i;
848 845
849 CX18_INFO("================= START STATUS CARD #%d " 846 CX18_INFO("================= START STATUS CARD #%d "
850 "=================\n", cx->num); 847 "=================\n", cx->instance);
851 CX18_INFO("Version: %s Card: %s\n", CX18_VERSION, cx->card_name); 848 CX18_INFO("Version: %s Card: %s\n", CX18_VERSION, cx->card_name);
852 if (cx->hw_flags & CX18_HW_TVEEPROM) { 849 if (cx->hw_flags & CX18_HW_TVEEPROM) {
853 struct tveeprom tv; 850 struct tveeprom tv;
@@ -865,7 +862,7 @@ static int cx18_log_status(struct file *file, void *fh)
865 mutex_unlock(&cx->gpio_lock); 862 mutex_unlock(&cx->gpio_lock);
866 CX18_INFO("Tuner: %s\n", 863 CX18_INFO("Tuner: %s\n",
867 test_bit(CX18_F_I_RADIO_USER, &cx->i_flags) ? "Radio" : "TV"); 864 test_bit(CX18_F_I_RADIO_USER, &cx->i_flags) ? "Radio" : "TV");
868 cx2341x_log_status(&cx->params, cx->name); 865 cx2341x_log_status(&cx->params, cx->v4l2_dev.name);
869 CX18_INFO("Status flags: 0x%08lx\n", cx->i_flags); 866 CX18_INFO("Status flags: 0x%08lx\n", cx->i_flags);
870 for (i = 0; i < CX18_MAX_STREAMS; i++) { 867 for (i = 0; i < CX18_MAX_STREAMS; i++) {
871 struct cx18_stream *s = &cx->streams[i]; 868 struct cx18_stream *s = &cx->streams[i];
@@ -880,7 +877,8 @@ static int cx18_log_status(struct file *file, void *fh)
880 CX18_INFO("Read MPEG/VBI: %lld/%lld bytes\n", 877 CX18_INFO("Read MPEG/VBI: %lld/%lld bytes\n",
881 (long long)cx->mpg_data_received, 878 (long long)cx->mpg_data_received,
882 (long long)cx->vbi_data_inserted); 879 (long long)cx->vbi_data_inserted);
883 CX18_INFO("================== END STATUS CARD #%d ==================\n", cx->num); 880 CX18_INFO("================== END STATUS CARD #%d "
881 "==================\n", cx->instance);
884 return 0; 882 return 0;
885} 883}
886 884
diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c
index 778aa0c0f9b5..eff4a14d0152 100644
--- a/drivers/media/video/cx18/cx18-streams.c
+++ b/drivers/media/video/cx18/cx18-streams.c
@@ -130,7 +130,7 @@ static int cx18_prep_dev(struct cx18 *cx, int type)
130 struct cx18_stream *s = &cx->streams[type]; 130 struct cx18_stream *s = &cx->streams[type];
131 u32 cap = cx->v4l2_cap; 131 u32 cap = cx->v4l2_cap;
132 int num_offset = cx18_stream_info[type].num_offset; 132 int num_offset = cx18_stream_info[type].num_offset;
133 int num = cx->num + cx18_first_minor + num_offset; 133 int num = cx->instance + cx18_first_minor + num_offset;
134 134
135 /* These four fields are always initialized. If video_dev == NULL, then 135 /* These four fields are always initialized. If video_dev == NULL, then
136 this stream is not in use. In that case no other fields but these 136 this stream is not in use. In that case no other fields but these
@@ -170,11 +170,11 @@ static int cx18_prep_dev(struct cx18 *cx, int type)
170 return -ENOMEM; 170 return -ENOMEM;
171 } 171 }
172 172
173 snprintf(s->video_dev->name, sizeof(s->video_dev->name), "cx18-%d", 173 snprintf(s->video_dev->name, sizeof(s->video_dev->name), "%s %s",
174 cx->num); 174 cx->v4l2_dev.name, s->name);
175 175
176 s->video_dev->num = num; 176 s->video_dev->num = num;
177 s->video_dev->parent = &cx->pci_dev->dev; 177 s->video_dev->v4l2_dev = &cx->v4l2_dev;
178 s->video_dev->fops = &cx18_v4l2_enc_fops; 178 s->video_dev->fops = &cx18_v4l2_enc_fops;
179 s->video_dev->release = video_device_release; 179 s->video_dev->release = video_device_release;
180 s->video_dev->tvnorms = V4L2_STD_ALL; 180 s->video_dev->tvnorms = V4L2_STD_ALL;
@@ -239,6 +239,7 @@ static int cx18_reg_dev(struct cx18 *cx, int type)
239 num = s_mpg->video_dev->num 239 num = s_mpg->video_dev->num
240 + cx18_stream_info[type].num_offset; 240 + cx18_stream_info[type].num_offset;
241 } 241 }
242 video_set_drvdata(s->video_dev, s);
242 243
243 /* Register device. First try the desired minor, then any free one. */ 244 /* Register device. First try the desired minor, then any free one. */
244 ret = video_register_device(s->video_dev, vfl_type, num); 245 ret = video_register_device(s->video_dev, vfl_type, num);