diff options
author | Andy Walls <awalls@radix.net> | 2009-02-14 15:08:37 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-03-30 11:43:01 -0400 |
commit | 5811cf99df2e3c102055be3ea77508e56c9f77c6 (patch) | |
tree | 75be74b5072280edadeee2c1f6c42f5e961c208c | |
parent | 1a2670465ec94029e5df62e3decca9e2f7aea075 (diff) |
V4L/DVB (10756): cx18: Slim down instance handling, build names from v4l2_device.name
Convert card instance handling to a lighter weight mechanism like ivtv.
Also convert name strings and debug messages to use v4l2_device.name.
Signed-off-by: Andy Walls <awalls@radix.net>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r-- | drivers/media/video/cx18/cx18-driver.c | 107 | ||||
-rw-r--r-- | drivers/media/video/cx18/cx18-driver.h | 27 | ||||
-rw-r--r-- | drivers/media/video/cx18/cx18-fileops.c | 35 | ||||
-rw-r--r-- | drivers/media/video/cx18/cx18-i2c.c | 2 | ||||
-rw-r--r-- | drivers/media/video/cx18/cx18-ioctl.c | 10 | ||||
-rw-r--r-- | drivers/media/video/cx18/cx18-streams.c | 9 |
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 */ | ||
44 | int 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. */ |
51 | int cx18_first_minor; | 47 | int cx18_first_minor; |
52 | 48 | ||
53 | /* Master variable for all cx18 info */ | ||
54 | struct cx18 *cx18_cards[CX18_MAX_CARDS]; | ||
55 | |||
56 | /* Protects cx18_cards_active */ | ||
57 | DEFINE_SPINLOCK(cx18_cards_lock); | ||
58 | |||
59 | /* add your revision and whatnot here */ | 49 | /* add your revision and whatnot here */ |
60 | static struct pci_device_id cx18_pci_tbl[] __devinitdata = { | 50 | static 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 | ||
66 | MODULE_DEVICE_TABLE(pci, cx18_pci_tbl); | 56 | MODULE_DEVICE_TABLE(pci, cx18_pci_tbl); |
67 | 57 | ||
58 | static atomic_t cx18_instance = ATOMIC_INIT(0); | ||
59 | |||
68 | /* Parameter declarations */ | 60 | /* Parameter declarations */ |
69 | static int cardtype[CX18_MAX_CARDS]; | 61 | static int cardtype[CX18_MAX_CARDS]; |
70 | static int tuner[CX18_MAX_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1, | 62 | static 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 | ||
940 | free_streams: | 929 | free_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); |
950 | free_workqueue: | 939 | free_workqueue: |
951 | destroy_workqueue(cx->work_queue); | 940 | destroy_workqueue(cx->work_queue); |
952 | unregister_v4l2: | ||
953 | v4l2_device_unregister(&cx->v4l2_dev); | ||
954 | err: | 941 | err: |
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) | |||
1069 | static void cx18_remove(struct pci_dev *pci_dev) | 1053 | static 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 | ||
1142 | static void module_cleanup(void) | 1126 | static 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 | ||
1156 | module_init(module_start); | 1131 | module_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 */ |
447 | struct cx18 { | 447 | struct 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 | ||
549 | static 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 */ |
551 | extern struct cx18 *cx18_cards[]; | ||
552 | extern int cx18_cards_active; | ||
553 | extern int cx18_first_minor; | 555 | extern int cx18_first_minor; |
554 | extern 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 | ||
683 | int cx18_v4l2_open(struct file *filp) | 683 | int 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, | |||
387 | static int cx18_cxc(struct cx18 *cx, unsigned int cmd, void *arg) | 387 | static 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); |