forked from luck/tmp_suning_uos_patched
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>
This commit is contained in:
parent
571d864c68
commit
e32fadc4c2
|
@ -69,6 +69,11 @@ config VIDEO_CX88_DVB
|
||||||
To compile this driver as a module, choose M here: the
|
To compile this driver as a module, choose M here: the
|
||||||
module will be called cx88-dvb.
|
module will be called cx88-dvb.
|
||||||
|
|
||||||
|
config VIDEO_CX88_MPEG
|
||||||
|
tristate
|
||||||
|
depends on VIDEO_CX88_DVB || VIDEO_CX88_BLACKBIRD
|
||||||
|
default y
|
||||||
|
|
||||||
config VIDEO_CX88_VP3054
|
config VIDEO_CX88_VP3054
|
||||||
tristate "VP-3054 Secondary I2C Bus Support"
|
tristate "VP-3054 Secondary I2C Bus Support"
|
||||||
default m
|
default m
|
||||||
|
|
|
@ -3,7 +3,8 @@ cx88xx-objs := cx88-cards.o cx88-core.o cx88-i2c.o cx88-tvaudio.o \
|
||||||
cx8800-objs := cx88-video.o cx88-vbi.o
|
cx8800-objs := cx88-video.o cx88-vbi.o
|
||||||
cx8802-objs := cx88-mpeg.o
|
cx8802-objs := cx88-mpeg.o
|
||||||
|
|
||||||
obj-$(CONFIG_VIDEO_CX88) += cx88xx.o cx8800.o cx8802.o
|
obj-$(CONFIG_VIDEO_CX88) += cx88xx.o cx8800.o
|
||||||
|
obj-$(CONFIG_VIDEO_CX88_MPEG) += cx8802.o
|
||||||
obj-$(CONFIG_VIDEO_CX88_ALSA) += cx88-alsa.o
|
obj-$(CONFIG_VIDEO_CX88_ALSA) += cx88-alsa.o
|
||||||
obj-$(CONFIG_VIDEO_CX88_BLACKBIRD) += cx88-blackbird.o
|
obj-$(CONFIG_VIDEO_CX88_BLACKBIRD) += cx88-blackbird.o
|
||||||
obj-$(CONFIG_VIDEO_CX88_DVB) += cx88-dvb.o
|
obj-$(CONFIG_VIDEO_CX88_DVB) += cx88-dvb.o
|
||||||
|
|
|
@ -138,6 +138,28 @@ static int cx88_dvb_bus_ctrl(struct dvb_frontend* fe, int acquire)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void cx88_dvb_gate_ctrl(struct cx88_core *core, int open)
|
||||||
|
{
|
||||||
|
struct videobuf_dvb_frontends *f;
|
||||||
|
struct videobuf_dvb_frontend *fe;
|
||||||
|
|
||||||
|
if (!core->dvbdev)
|
||||||
|
return;
|
||||||
|
|
||||||
|
f = &core->dvbdev->frontends;
|
||||||
|
|
||||||
|
if (!f)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (f->gate <= 1) /* undefined or fe0 */
|
||||||
|
fe = videobuf_dvb_get_frontend(f, 1);
|
||||||
|
else
|
||||||
|
fe = videobuf_dvb_get_frontend(f, f->gate);
|
||||||
|
|
||||||
|
if (fe && fe->dvb.frontend && fe->dvb.frontend->ops.i2c_gate_ctrl)
|
||||||
|
fe->dvb.frontend->ops.i2c_gate_ctrl(fe->dvb.frontend, open);
|
||||||
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
|
|
||||||
static int dvico_fusionhdtv_demod_init(struct dvb_frontend* fe)
|
static int dvico_fusionhdtv_demod_init(struct dvb_frontend* fe)
|
||||||
|
@ -597,12 +619,30 @@ static int dvb_register(struct cx8802_dev *dev)
|
||||||
struct cx88_core *core = dev->core;
|
struct cx88_core *core = dev->core;
|
||||||
struct videobuf_dvb_frontend *fe0, *fe1 = NULL;
|
struct videobuf_dvb_frontend *fe0, *fe1 = NULL;
|
||||||
int mfe_shared = 0; /* bus not shared by default */
|
int mfe_shared = 0; /* bus not shared by default */
|
||||||
|
int i;
|
||||||
|
|
||||||
if (0 != core->i2c_rc) {
|
if (0 != core->i2c_rc) {
|
||||||
printk(KERN_ERR "%s/2: no i2c-bus available, cannot attach dvb drivers\n", core->name);
|
printk(KERN_ERR "%s/2: no i2c-bus available, cannot attach dvb drivers\n", core->name);
|
||||||
goto frontend_detach;
|
goto frontend_detach;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!core->board.num_frontends)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
mutex_init(&dev->frontends.lock);
|
||||||
|
INIT_LIST_HEAD(&dev->frontends.felist);
|
||||||
|
|
||||||
|
printk(KERN_INFO "%s() allocating %d frontend(s)\n", __func__,
|
||||||
|
core->board.num_frontends);
|
||||||
|
for (i = 1; i <= core->board.num_frontends; i++) {
|
||||||
|
fe0 = videobuf_dvb_alloc_frontend(&dev->frontends, i);
|
||||||
|
if (!fe0) {
|
||||||
|
printk(KERN_ERR "%s() failed to alloc\n", __func__);
|
||||||
|
videobuf_dvb_dealloc_frontends(&dev->frontends);
|
||||||
|
goto frontend_detach;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Get the first frontend */
|
/* Get the first frontend */
|
||||||
fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1);
|
fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1);
|
||||||
if (!fe0)
|
if (!fe0)
|
||||||
|
@ -611,6 +651,9 @@ static int dvb_register(struct cx8802_dev *dev)
|
||||||
/* multi-frontend gate control is undefined or defaults to fe0 */
|
/* multi-frontend gate control is undefined or defaults to fe0 */
|
||||||
dev->frontends.gate = 0;
|
dev->frontends.gate = 0;
|
||||||
|
|
||||||
|
/* Sets the gate control callback to be used by i2c command calls */
|
||||||
|
core->gate_ctrl = cx88_dvb_gate_ctrl;
|
||||||
|
|
||||||
/* init frontend(s) */
|
/* init frontend(s) */
|
||||||
switch (core->boardnr) {
|
switch (core->boardnr) {
|
||||||
case CX88_BOARD_HAUPPAUGE_DVB_T1:
|
case CX88_BOARD_HAUPPAUGE_DVB_T1:
|
||||||
|
@ -1109,6 +1152,7 @@ static int dvb_register(struct cx8802_dev *dev)
|
||||||
&dev->pci->dev, adapter_nr, mfe_shared);
|
&dev->pci->dev, adapter_nr, mfe_shared);
|
||||||
|
|
||||||
frontend_detach:
|
frontend_detach:
|
||||||
|
core->gate_ctrl = NULL;
|
||||||
videobuf_dvb_dealloc_frontends(&dev->frontends);
|
videobuf_dvb_dealloc_frontends(&dev->frontends);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
@ -1270,6 +1314,8 @@ static int cx8802_dvb_remove(struct cx8802_driver *drv)
|
||||||
|
|
||||||
vp3054_i2c_remove(dev);
|
vp3054_i2c_remove(dev);
|
||||||
|
|
||||||
|
core->gate_ctrl = NULL;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -116,30 +116,16 @@ static int detach_inform(struct i2c_client *client)
|
||||||
|
|
||||||
void cx88_call_i2c_clients(struct cx88_core *core, unsigned int cmd, void *arg)
|
void cx88_call_i2c_clients(struct cx88_core *core, unsigned int cmd, void *arg)
|
||||||
{
|
{
|
||||||
#if defined(CONFIG_VIDEO_CX88_DVB) || defined(CONFIG_VIDEO_CX88_DVB_MODULE)
|
|
||||||
struct videobuf_dvb_frontends *f = &core->dvbdev->frontends;
|
|
||||||
struct videobuf_dvb_frontend *fe = NULL;
|
|
||||||
#endif
|
|
||||||
if (0 != core->i2c_rc)
|
if (0 != core->i2c_rc)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
#if defined(CONFIG_VIDEO_CX88_DVB) || defined(CONFIG_VIDEO_CX88_DVB_MODULE)
|
if (core->gate_ctrl)
|
||||||
if (core->dvbdev && f) {
|
core->gate_ctrl(core, 1);
|
||||||
if(f->gate <= 1) /* undefined or fe0 */
|
|
||||||
fe = videobuf_dvb_get_frontend(f, 1);
|
|
||||||
else
|
|
||||||
fe = videobuf_dvb_get_frontend(f, f->gate);
|
|
||||||
|
|
||||||
if (fe && fe->dvb.frontend && fe->dvb.frontend->ops.i2c_gate_ctrl)
|
i2c_clients_command(&core->i2c_adap, cmd, arg);
|
||||||
fe->dvb.frontend->ops.i2c_gate_ctrl(fe->dvb.frontend, 1);
|
|
||||||
|
|
||||||
i2c_clients_command(&core->i2c_adap, cmd, arg);
|
if (core->gate_ctrl)
|
||||||
|
core->gate_ctrl(core, 0);
|
||||||
if (fe && fe->dvb.frontend && fe->dvb.frontend->ops.i2c_gate_ctrl)
|
|
||||||
fe->dvb.frontend->ops.i2c_gate_ctrl(fe->dvb.frontend, 0);
|
|
||||||
} else
|
|
||||||
#endif
|
|
||||||
i2c_clients_command(&core->i2c_adap, cmd, arg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct i2c_algo_bit_data cx8800_i2c_algo_template = {
|
static const struct i2c_algo_bit_data cx8800_i2c_algo_template = {
|
||||||
|
|
|
@ -787,6 +787,9 @@ static int __devinit cx8802_probe(struct pci_dev *pci_dev,
|
||||||
dev->pci = pci_dev;
|
dev->pci = pci_dev;
|
||||||
dev->core = core;
|
dev->core = core;
|
||||||
|
|
||||||
|
/* Maintain a reference so cx88-video can query the 8802 device. */
|
||||||
|
core->dvbdev = dev;
|
||||||
|
|
||||||
err = cx8802_init_common(dev);
|
err = cx8802_init_common(dev);
|
||||||
if (err != 0)
|
if (err != 0)
|
||||||
goto fail_free;
|
goto fail_free;
|
||||||
|
@ -794,32 +797,6 @@ static int __devinit cx8802_probe(struct pci_dev *pci_dev,
|
||||||
INIT_LIST_HEAD(&dev->drvlist);
|
INIT_LIST_HEAD(&dev->drvlist);
|
||||||
list_add_tail(&dev->devlist,&cx8802_devlist);
|
list_add_tail(&dev->devlist,&cx8802_devlist);
|
||||||
|
|
||||||
#if defined(CONFIG_VIDEO_CX88_DVB) || defined(CONFIG_VIDEO_CX88_DVB_MODULE)
|
|
||||||
mutex_init(&dev->frontends.lock);
|
|
||||||
INIT_LIST_HEAD(&dev->frontends.felist);
|
|
||||||
|
|
||||||
if (core->board.num_frontends) {
|
|
||||||
struct videobuf_dvb_frontend *fe;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
printk(KERN_INFO "%s() allocating %d frontend(s)\n", __func__,
|
|
||||||
core->board.num_frontends);
|
|
||||||
for (i = 1; i <= core->board.num_frontends; i++) {
|
|
||||||
fe = videobuf_dvb_alloc_frontend(&dev->frontends, i);
|
|
||||||
if(fe == NULL) {
|
|
||||||
printk(KERN_ERR "%s() failed to alloc\n",
|
|
||||||
__func__);
|
|
||||||
videobuf_dvb_dealloc_frontends(&dev->frontends);
|
|
||||||
err = -ENOMEM;
|
|
||||||
goto fail_free;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Maintain a reference so cx88-video can query the 8802 device. */
|
|
||||||
core->dvbdev = dev;
|
|
||||||
|
|
||||||
/* now autoload cx88-dvb or cx88-blackbird */
|
/* now autoload cx88-dvb or cx88-blackbird */
|
||||||
request_modules(dev);
|
request_modules(dev);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -827,6 +804,7 @@ static int __devinit cx8802_probe(struct pci_dev *pci_dev,
|
||||||
fail_free:
|
fail_free:
|
||||||
kfree(dev);
|
kfree(dev);
|
||||||
fail_core:
|
fail_core:
|
||||||
|
core->dvbdev = NULL;
|
||||||
cx88_core_put(core,pci_dev);
|
cx88_core_put(core,pci_dev);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
|
@ -302,6 +302,7 @@ struct cx88_dmaqueue {
|
||||||
struct btcx_riscmem stopper;
|
struct btcx_riscmem stopper;
|
||||||
u32 count;
|
u32 count;
|
||||||
};
|
};
|
||||||
|
struct cx88_core;
|
||||||
|
|
||||||
struct cx88_core {
|
struct cx88_core {
|
||||||
struct list_head devlist;
|
struct list_head devlist;
|
||||||
|
@ -334,7 +335,8 @@ struct cx88_core {
|
||||||
|
|
||||||
/* config info -- dvb */
|
/* config info -- dvb */
|
||||||
#if defined(CONFIG_VIDEO_CX88_DVB) || defined(CONFIG_VIDEO_CX88_DVB_MODULE)
|
#if defined(CONFIG_VIDEO_CX88_DVB) || defined(CONFIG_VIDEO_CX88_DVB_MODULE)
|
||||||
int (*prev_set_voltage)(struct dvb_frontend* fe, fe_sec_voltage_t voltage);
|
int (*prev_set_voltage)(struct dvb_frontend *fe, fe_sec_voltage_t voltage);
|
||||||
|
void (*gate_ctrl)(struct cx88_core *core, int open);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* state info */
|
/* state info */
|
||||||
|
|
Loading…
Reference in New Issue
Block a user