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 /drivers/media/video/cx18/cx18-driver.c | |
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>
Diffstat (limited to 'drivers/media/video/cx18/cx18-driver.c')
-rw-r--r-- | drivers/media/video/cx18/cx18-driver.c | 107 |
1 files changed, 41 insertions, 66 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); |