Skip to content

Commit

Permalink
V4L/DVB: saa7146_vv: fix regression where v4l2_device was registered …
Browse files Browse the repository at this point in the history
…too late

v4l2_device_register needs to be called before the i2c subdevs are loaded.
However, it was called afterwards in the saa7146 driver. This caused an oops
when loading the mxb and hexium drivers. The vv_init function is now split
into two: one registers the v4l2_device, the other does the rest of the
initialization. The three drivers that depend on this have been updated to
call the new vv_devinit function.

Thanks to Michael Hunold for reporting this.

Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
  • Loading branch information
Hans Verkuil authored and Mauro Carvalho Chehab committed Feb 26, 2010
1 parent 8d55662 commit cd7d9be
Show file tree
Hide file tree
Showing 5 changed files with 22 additions and 7 deletions.
11 changes: 6 additions & 5 deletions drivers/media/common/saa7146_fops.c
Original file line number Diff line number Diff line change
Expand Up @@ -423,14 +423,15 @@ static void vv_callback(struct saa7146_dev *dev, unsigned long status)
}
}

int saa7146_vv_devinit(struct saa7146_dev *dev)
{
return v4l2_device_register(&dev->pci->dev, &dev->v4l2_dev);
}
EXPORT_SYMBOL_GPL(saa7146_vv_devinit);

int saa7146_vv_init(struct saa7146_dev* dev, struct saa7146_ext_vv *ext_vv)
{
struct saa7146_vv *vv;
int err;

err = v4l2_device_register(&dev->pci->dev, &dev->v4l2_dev);
if (err)
return err;

vv = kzalloc(sizeof(struct saa7146_vv), GFP_KERNEL);
if (vv == NULL) {
Expand Down
9 changes: 7 additions & 2 deletions drivers/media/video/hexium_gemini.c
Original file line number Diff line number Diff line change
Expand Up @@ -352,9 +352,13 @@ static struct saa7146_ext_vv vv_data;
static int hexium_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
{
struct hexium *hexium = (struct hexium *) dev->ext_priv;
int ret;

DEB_EE((".\n"));

ret = saa7146_vv_devinit(dev);
if (ret)
return ret;
hexium = kzalloc(sizeof(struct hexium), GFP_KERNEL);
if (NULL == hexium) {
printk("hexium_gemini: not enough kernel memory in hexium_attach().\n");
Expand Down Expand Up @@ -400,9 +404,10 @@ static int hexium_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_d
vv_data.ops.vidioc_enum_input = vidioc_enum_input;
vv_data.ops.vidioc_g_input = vidioc_g_input;
vv_data.ops.vidioc_s_input = vidioc_s_input;
if (0 != saa7146_register_device(&hexium->video_dev, dev, "hexium gemini", VFL_TYPE_GRABBER)) {
ret = saa7146_register_device(&hexium->video_dev, dev, "hexium gemini", VFL_TYPE_GRABBER);
if (ret < 0) {
printk("hexium_gemini: cannot register capture v4l2 device. skipping.\n");
return -1;
return ret;
}

printk("hexium_gemini: found 'hexium gemini' frame grabber-%d.\n", hexium_num);
Expand Down
4 changes: 4 additions & 0 deletions drivers/media/video/hexium_orion.c
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,10 @@ static int hexium_probe(struct saa7146_dev *dev)
return -EFAULT;
}

err = saa7146_vv_devinit(dev);
if (err)
return err;

hexium = kzalloc(sizeof(struct hexium), GFP_KERNEL);
if (NULL == hexium) {
printk("hexium_orion: hexium_probe: not enough kernel memory.\n");
Expand Down
4 changes: 4 additions & 0 deletions drivers/media/video/mxb.c
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,11 @@ static struct saa7146_extension extension;
static int mxb_probe(struct saa7146_dev *dev)
{
struct mxb *mxb = NULL;
int err;

err = saa7146_vv_devinit(dev);
if (err)
return err;
mxb = kzalloc(sizeof(struct mxb), GFP_KERNEL);
if (mxb == NULL) {
DEB_D(("not enough kernel memory.\n"));
Expand Down
1 change: 1 addition & 0 deletions include/media/saa7146_vv.h
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ void saa7146_buffer_timeout(unsigned long data);
void saa7146_dma_free(struct saa7146_dev* dev,struct videobuf_queue *q,
struct saa7146_buf *buf);

int saa7146_vv_devinit(struct saa7146_dev *dev);
int saa7146_vv_init(struct saa7146_dev* dev, struct saa7146_ext_vv *ext_vv);
int saa7146_vv_release(struct saa7146_dev* dev);

Expand Down

0 comments on commit cd7d9be

Please sign in to comment.