diff options
author | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-01-06 14:06:07 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-01-07 19:18:56 -0500 |
commit | e32fadc4c2e5975a8e40541e2ba72a7032ed4cf4 (patch) | |
tree | 7718a6d3d28f6e70d8c51e8ef0eef72022935c19 | |
parent | 571d864c68d429a82fd61e97404a2de210ffc72d (diff) |
V4L/DVB (10190): cx88: Fix some Kbuild troubles
As Randy Dunlap <randy.dunlap@oracle.com> reported, cx88 has some compilation issues:
drivers/built-in.o: In function `cx88_call_i2c_clients':
(.text+0x20af17): undefined reference to `videobuf_dvb_get_frontend'
drivers/built-in.o: In function `cx8802_probe':
cx88-mpeg.c:(.devinit.text+0x268c4): undefined reference to `videobuf_dvb_alloc_frontend'
cx88-mpeg.c:(.devinit.text+0x268ea): undefined reference to `videobuf_dvb_dealloc_frontends'
With those configs:
CONFIG_VIDEO_CX88=y
CONFIG_VIDEO_CX88_BLACKBIRD=y
CONFIG_VIDEO_CX88_DVB=m
CONFIG_DVB_CORE=m
After carefully examining the code, with the current code, several cx88 drivers
(cx8800, cx8802, cx88_dvb and cx88_blackbird) should be compiled as a module,
if one of them is marked as such. Just fixing Kconfig could create a very complex
set of rules. Also, this hides a problem with the current approach where the dvb
functionality weren't confined inside dvb module.
What happens is that:
- cx88-i2c (part of cx8800) has some special rules if DVB;
- cx88-mpeg (cx8802 module) has also part of DVB init code;
- cx88-dvb has the rest of the dvb code;
- cx88-blackbird can be used with cx88-mpeg, having cx88-dvb or not.
So, instead of doing some tricks at Kconfig and wait for a next breakage,
this patch moves the dvb code inside cx88-i2c and cx88-mpeg into cx88-dvb.
Another problem is that cx8802 were being compiled, even without cx88-dvb
and cx88-blackbird modules.
While on this code, let's fix also a reported problem:
http://www.linuxtv.org/pipermail/linux-dvb/2009-January/031225.html
A solution for the issue were proposed here:
http://www.mail-archive.com/linux-media@vger.kernel.org/msg00021.html
Thanks to Randy, Andy, Gregoire and Thomas for helping us to detect
and solve the issues.
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r-- | drivers/media/video/cx88/Kconfig | 5 | ||||
-rw-r--r-- | drivers/media/video/cx88/Makefile | 3 | ||||
-rw-r--r-- | drivers/media/video/cx88/cx88-dvb.c | 46 | ||||
-rw-r--r-- | drivers/media/video/cx88/cx88-i2c.c | 24 | ||||
-rw-r--r-- | drivers/media/video/cx88/cx88-mpeg.c | 30 | ||||
-rw-r--r-- | drivers/media/video/cx88/cx88.h | 4 |
6 files changed, 65 insertions, 47 deletions
diff --git a/drivers/media/video/cx88/Kconfig b/drivers/media/video/cx88/Kconfig index b0f837588e01..2d250a2a7bc3 100644 --- a/drivers/media/video/cx88/Kconfig +++ b/drivers/media/video/cx88/Kconfig | |||
@@ -69,6 +69,11 @@ config VIDEO_CX88_DVB | |||
69 | To compile this driver as a module, choose M here: the | 69 | To compile this driver as a module, choose M here: the |
70 | module will be called cx88-dvb. | 70 | module will be called cx88-dvb. |
71 | 71 | ||
72 | config VIDEO_CX88_MPEG | ||
73 | tristate | ||
74 | depends on VIDEO_CX88_DVB || VIDEO_CX88_BLACKBIRD | ||
75 | default y | ||
76 | |||
72 | config VIDEO_CX88_VP3054 | 77 | config VIDEO_CX88_VP3054 |
73 | tristate "VP-3054 Secondary I2C Bus Support" | 78 | tristate "VP-3054 Secondary I2C Bus Support" |
74 | default m | 79 | default m |
diff --git a/drivers/media/video/cx88/Makefile b/drivers/media/video/cx88/Makefile index 6ec30f242578..b06b1275a9ec 100644 --- a/drivers/media/video/cx88/Makefile +++ b/drivers/media/video/cx88/Makefile | |||
@@ -3,7 +3,8 @@ cx88xx-objs := cx88-cards.o cx88-core.o cx88-i2c.o cx88-tvaudio.o \ | |||
3 | cx8800-objs := cx88-video.o cx88-vbi.o | 3 | cx8800-objs := cx88-video.o cx88-vbi.o |
4 | cx8802-objs := cx88-mpeg.o | 4 | cx8802-objs := cx88-mpeg.o |
5 | 5 | ||
6 | obj-$(CONFIG_VIDEO_CX88) += cx88xx.o cx8800.o cx8802.o | 6 | obj-$(CONFIG_VIDEO_CX88) += cx88xx.o cx8800.o |
7 | obj-$(CONFIG_VIDEO_CX88_MPEG) += cx8802.o | ||
7 | obj-$(CONFIG_VIDEO_CX88_ALSA) += cx88-alsa.o | 8 | obj-$(CONFIG_VIDEO_CX88_ALSA) += cx88-alsa.o |
8 | obj-$(CONFIG_VIDEO_CX88_BLACKBIRD) += cx88-blackbird.o | 9 | obj-$(CONFIG_VIDEO_CX88_BLACKBIRD) += cx88-blackbird.o |
9 | obj-$(CONFIG_VIDEO_CX88_DVB) += cx88-dvb.o | 10 | obj-$(CONFIG_VIDEO_CX88_DVB) += cx88-dvb.o |
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c index da4dd4913d9f..613dfea4ff3e 100644 --- a/drivers/media/video/cx88/cx88-dvb.c +++ b/drivers/media/video/cx88/cx88-dvb.c | |||
@@ -138,6 +138,28 @@ static int cx88_dvb_bus_ctrl(struct dvb_frontend* fe, int acquire) | |||
138 | return ret; | 138 | return ret; |
139 | } | 139 | } |
140 | 140 | ||
141 | static void cx88_dvb_gate_ctrl(struct cx88_core *core, int open) | ||
142 | { | ||
143 | struct videobuf_dvb_frontends *f; | ||
144 | struct videobuf_dvb_frontend *fe; | ||
145 | |||
146 | if (!core->dvbdev) | ||
147 | return; | ||
148 | |||
149 | f = &core->dvbdev->frontends; | ||
150 | |||
151 | if (!f) | ||
152 | return; | ||
153 | |||
154 | if (f->gate <= 1) /* undefined or fe0 */ | ||
155 | fe = videobuf_dvb_get_frontend(f, 1); | ||
156 | else | ||
157 | fe = videobuf_dvb_get_frontend(f, f->gate); | ||
158 | |||
159 | if (fe && fe->dvb.frontend && fe->dvb.frontend->ops.i2c_gate_ctrl) | ||
160 | fe->dvb.frontend->ops.i2c_gate_ctrl(fe->dvb.frontend, open); | ||
161 | } | ||
162 | |||
141 | /* ------------------------------------------------------------------ */ | 163 | /* ------------------------------------------------------------------ */ |
142 | 164 | ||
143 | static int dvico_fusionhdtv_demod_init(struct dvb_frontend* fe) | 165 | static int dvico_fusionhdtv_demod_init(struct dvb_frontend* fe) |
@@ -597,12 +619,30 @@ static int dvb_register(struct cx8802_dev *dev) | |||
597 | struct cx88_core *core = dev->core; | 619 | struct cx88_core *core = dev->core; |
598 | struct videobuf_dvb_frontend *fe0, *fe1 = NULL; | 620 | struct videobuf_dvb_frontend *fe0, *fe1 = NULL; |
599 | int mfe_shared = 0; /* bus not shared by default */ | 621 | int mfe_shared = 0; /* bus not shared by default */ |
622 | int i; | ||
600 | 623 | ||
601 | if (0 != core->i2c_rc) { | 624 | if (0 != core->i2c_rc) { |
602 | printk(KERN_ERR "%s/2: no i2c-bus available, cannot attach dvb drivers\n", core->name); | 625 | printk(KERN_ERR "%s/2: no i2c-bus available, cannot attach dvb drivers\n", core->name); |
603 | goto frontend_detach; | 626 | goto frontend_detach; |
604 | } | 627 | } |
605 | 628 | ||
629 | if (!core->board.num_frontends) | ||
630 | return -EINVAL; | ||
631 | |||
632 | mutex_init(&dev->frontends.lock); | ||
633 | INIT_LIST_HEAD(&dev->frontends.felist); | ||
634 | |||
635 | printk(KERN_INFO "%s() allocating %d frontend(s)\n", __func__, | ||
636 | core->board.num_frontends); | ||
637 | for (i = 1; i <= core->board.num_frontends; i++) { | ||
638 | fe0 = videobuf_dvb_alloc_frontend(&dev->frontends, i); | ||
639 | if (!fe0) { | ||
640 | printk(KERN_ERR "%s() failed to alloc\n", __func__); | ||
641 | videobuf_dvb_dealloc_frontends(&dev->frontends); | ||
642 | goto frontend_detach; | ||
643 | } | ||
644 | } | ||
645 | |||
606 | /* Get the first frontend */ | 646 | /* Get the first frontend */ |
607 | fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1); | 647 | fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1); |
608 | if (!fe0) | 648 | if (!fe0) |
@@ -611,6 +651,9 @@ static int dvb_register(struct cx8802_dev *dev) | |||
611 | /* multi-frontend gate control is undefined or defaults to fe0 */ | 651 | /* multi-frontend gate control is undefined or defaults to fe0 */ |
612 | dev->frontends.gate = 0; | 652 | dev->frontends.gate = 0; |
613 | 653 | ||
654 | /* Sets the gate control callback to be used by i2c command calls */ | ||
655 | core->gate_ctrl = cx88_dvb_gate_ctrl; | ||
656 | |||
614 | /* init frontend(s) */ | 657 | /* init frontend(s) */ |
615 | switch (core->boardnr) { | 658 | switch (core->boardnr) { |
616 | case CX88_BOARD_HAUPPAUGE_DVB_T1: | 659 | case CX88_BOARD_HAUPPAUGE_DVB_T1: |
@@ -1109,6 +1152,7 @@ static int dvb_register(struct cx8802_dev *dev) | |||
1109 | &dev->pci->dev, adapter_nr, mfe_shared); | 1152 | &dev->pci->dev, adapter_nr, mfe_shared); |
1110 | 1153 | ||
1111 | frontend_detach: | 1154 | frontend_detach: |
1155 | core->gate_ctrl = NULL; | ||
1112 | videobuf_dvb_dealloc_frontends(&dev->frontends); | 1156 | videobuf_dvb_dealloc_frontends(&dev->frontends); |
1113 | return -EINVAL; | 1157 | return -EINVAL; |
1114 | } | 1158 | } |
@@ -1270,6 +1314,8 @@ static int cx8802_dvb_remove(struct cx8802_driver *drv) | |||
1270 | 1314 | ||
1271 | vp3054_i2c_remove(dev); | 1315 | vp3054_i2c_remove(dev); |
1272 | 1316 | ||
1317 | core->gate_ctrl = NULL; | ||
1318 | |||
1273 | return 0; | 1319 | return 0; |
1274 | } | 1320 | } |
1275 | 1321 | ||
diff --git a/drivers/media/video/cx88/cx88-i2c.c b/drivers/media/video/cx88/cx88-i2c.c index 1ab691d20692..c0ff2305d804 100644 --- a/drivers/media/video/cx88/cx88-i2c.c +++ b/drivers/media/video/cx88/cx88-i2c.c | |||
@@ -116,30 +116,16 @@ static int detach_inform(struct i2c_client *client) | |||
116 | 116 | ||
117 | void cx88_call_i2c_clients(struct cx88_core *core, unsigned int cmd, void *arg) | 117 | void cx88_call_i2c_clients(struct cx88_core *core, unsigned int cmd, void *arg) |
118 | { | 118 | { |
119 | #if defined(CONFIG_VIDEO_CX88_DVB) || defined(CONFIG_VIDEO_CX88_DVB_MODULE) | ||
120 | struct videobuf_dvb_frontends *f = &core->dvbdev->frontends; | ||
121 | struct videobuf_dvb_frontend *fe = NULL; | ||
122 | #endif | ||
123 | if (0 != core->i2c_rc) | 119 | if (0 != core->i2c_rc) |
124 | return; | 120 | return; |
125 | 121 | ||
126 | #if defined(CONFIG_VIDEO_CX88_DVB) || defined(CONFIG_VIDEO_CX88_DVB_MODULE) | 122 | if (core->gate_ctrl) |
127 | if (core->dvbdev && f) { | 123 | core->gate_ctrl(core, 1); |
128 | if(f->gate <= 1) /* undefined or fe0 */ | ||
129 | fe = videobuf_dvb_get_frontend(f, 1); | ||
130 | else | ||
131 | fe = videobuf_dvb_get_frontend(f, f->gate); | ||
132 | 124 | ||
133 | if (fe && fe->dvb.frontend && fe->dvb.frontend->ops.i2c_gate_ctrl) | 125 | i2c_clients_command(&core->i2c_adap, cmd, arg); |
134 | fe->dvb.frontend->ops.i2c_gate_ctrl(fe->dvb.frontend, 1); | ||
135 | 126 | ||
136 | i2c_clients_command(&core->i2c_adap, cmd, arg); | 127 | if (core->gate_ctrl) |
137 | 128 | core->gate_ctrl(core, 0); | |
138 | if (fe && fe->dvb.frontend && fe->dvb.frontend->ops.i2c_gate_ctrl) | ||
139 | fe->dvb.frontend->ops.i2c_gate_ctrl(fe->dvb.frontend, 0); | ||
140 | } else | ||
141 | #endif | ||
142 | i2c_clients_command(&core->i2c_adap, cmd, arg); | ||
143 | } | 129 | } |
144 | 130 | ||
145 | static const struct i2c_algo_bit_data cx8800_i2c_algo_template = { | 131 | static const struct i2c_algo_bit_data cx8800_i2c_algo_template = { |
diff --git a/drivers/media/video/cx88/cx88-mpeg.c b/drivers/media/video/cx88/cx88-mpeg.c index 59164fc94f5f..b295b76737e3 100644 --- a/drivers/media/video/cx88/cx88-mpeg.c +++ b/drivers/media/video/cx88/cx88-mpeg.c | |||
@@ -787,6 +787,9 @@ static int __devinit cx8802_probe(struct pci_dev *pci_dev, | |||
787 | dev->pci = pci_dev; | 787 | dev->pci = pci_dev; |
788 | dev->core = core; | 788 | dev->core = core; |
789 | 789 | ||
790 | /* Maintain a reference so cx88-video can query the 8802 device. */ | ||
791 | core->dvbdev = dev; | ||
792 | |||
790 | err = cx8802_init_common(dev); | 793 | err = cx8802_init_common(dev); |
791 | if (err != 0) | 794 | if (err != 0) |
792 | goto fail_free; | 795 | goto fail_free; |
@@ -794,32 +797,6 @@ static int __devinit cx8802_probe(struct pci_dev *pci_dev, | |||
794 | INIT_LIST_HEAD(&dev->drvlist); | 797 | INIT_LIST_HEAD(&dev->drvlist); |
795 | list_add_tail(&dev->devlist,&cx8802_devlist); | 798 | list_add_tail(&dev->devlist,&cx8802_devlist); |
796 | 799 | ||
797 | #if defined(CONFIG_VIDEO_CX88_DVB) || defined(CONFIG_VIDEO_CX88_DVB_MODULE) | ||
798 | mutex_init(&dev->frontends.lock); | ||
799 | INIT_LIST_HEAD(&dev->frontends.felist); | ||
800 | |||
801 | if (core->board.num_frontends) { | ||
802 | struct videobuf_dvb_frontend *fe; | ||
803 | int i; | ||
804 | |||
805 | printk(KERN_INFO "%s() allocating %d frontend(s)\n", __func__, | ||
806 | core->board.num_frontends); | ||
807 | for (i = 1; i <= core->board.num_frontends; i++) { | ||
808 | fe = videobuf_dvb_alloc_frontend(&dev->frontends, i); | ||
809 | if(fe == NULL) { | ||
810 | printk(KERN_ERR "%s() failed to alloc\n", | ||
811 | __func__); | ||
812 | videobuf_dvb_dealloc_frontends(&dev->frontends); | ||
813 | err = -ENOMEM; | ||
814 | goto fail_free; | ||
815 | } | ||
816 | } | ||
817 | } | ||
818 | #endif | ||
819 | |||
820 | /* Maintain a reference so cx88-video can query the 8802 device. */ | ||
821 | core->dvbdev = dev; | ||
822 | |||
823 | /* now autoload cx88-dvb or cx88-blackbird */ | 800 | /* now autoload cx88-dvb or cx88-blackbird */ |
824 | request_modules(dev); | 801 | request_modules(dev); |
825 | return 0; | 802 | return 0; |
@@ -827,6 +804,7 @@ static int __devinit cx8802_probe(struct pci_dev *pci_dev, | |||
827 | fail_free: | 804 | fail_free: |
828 | kfree(dev); | 805 | kfree(dev); |
829 | fail_core: | 806 | fail_core: |
807 | core->dvbdev = NULL; | ||
830 | cx88_core_put(core,pci_dev); | 808 | cx88_core_put(core,pci_dev); |
831 | return err; | 809 | return err; |
832 | } | 810 | } |
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h index eb9ce30dc5e6..60a8b3187f14 100644 --- a/drivers/media/video/cx88/cx88.h +++ b/drivers/media/video/cx88/cx88.h | |||
@@ -302,6 +302,7 @@ struct cx88_dmaqueue { | |||
302 | struct btcx_riscmem stopper; | 302 | struct btcx_riscmem stopper; |
303 | u32 count; | 303 | u32 count; |
304 | }; | 304 | }; |
305 | struct cx88_core; | ||
305 | 306 | ||
306 | struct cx88_core { | 307 | struct cx88_core { |
307 | struct list_head devlist; | 308 | struct list_head devlist; |
@@ -334,7 +335,8 @@ struct cx88_core { | |||
334 | 335 | ||
335 | /* config info -- dvb */ | 336 | /* config info -- dvb */ |
336 | #if defined(CONFIG_VIDEO_CX88_DVB) || defined(CONFIG_VIDEO_CX88_DVB_MODULE) | 337 | #if defined(CONFIG_VIDEO_CX88_DVB) || defined(CONFIG_VIDEO_CX88_DVB_MODULE) |
337 | int (*prev_set_voltage)(struct dvb_frontend* fe, fe_sec_voltage_t voltage); | 338 | int (*prev_set_voltage)(struct dvb_frontend *fe, fe_sec_voltage_t voltage); |
339 | void (*gate_ctrl)(struct cx88_core *core, int open); | ||
338 | #endif | 340 | #endif |
339 | 341 | ||
340 | /* state info */ | 342 | /* state info */ |