Merge branch 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6

* 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6:
  [media] V4L: soc-camera: regression fix: calculate .sizeimage in soc_camera.c
  [media] v4l2-subdev: fix broken subdev control enumeration
  [media] Fix cx88 remote control input
  [media] v4l: Release module if subdev registration fails
This commit is contained in:
Linus Torvalds 2011-05-18 03:16:38 -07:00
commit 2e9521fd65
4 changed files with 54 additions and 15 deletions

View File

@ -524,7 +524,7 @@ void cx88_ir_irq(struct cx88_core *core)
for (todo = 32; todo > 0; todo -= bits) { for (todo = 32; todo > 0; todo -= bits) {
ev.pulse = samples & 0x80000000 ? false : true; ev.pulse = samples & 0x80000000 ? false : true;
bits = min(todo, 32U - fls(ev.pulse ? samples : ~samples)); bits = min(todo, 32U - fls(ev.pulse ? samples : ~samples));
ev.duration = (bits * NSEC_PER_SEC) / (1000 * ir_samplerate); ev.duration = (bits * (NSEC_PER_SEC / 1000)) / ir_samplerate;
ir_raw_event_store_with_filter(ir->dev, &ev); ir_raw_event_store_with_filter(ir->dev, &ev);
samples <<= bits; samples <<= bits;
} }

View File

@ -136,11 +136,50 @@ unsigned long soc_camera_apply_sensor_flags(struct soc_camera_link *icl,
} }
EXPORT_SYMBOL(soc_camera_apply_sensor_flags); EXPORT_SYMBOL(soc_camera_apply_sensor_flags);
#define pixfmtstr(x) (x) & 0xff, ((x) >> 8) & 0xff, ((x) >> 16) & 0xff, \
((x) >> 24) & 0xff
static int soc_camera_try_fmt(struct soc_camera_device *icd,
struct v4l2_format *f)
{
struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
struct v4l2_pix_format *pix = &f->fmt.pix;
int ret;
dev_dbg(&icd->dev, "TRY_FMT(%c%c%c%c, %ux%u)\n",
pixfmtstr(pix->pixelformat), pix->width, pix->height);
pix->bytesperline = 0;
pix->sizeimage = 0;
ret = ici->ops->try_fmt(icd, f);
if (ret < 0)
return ret;
if (!pix->sizeimage) {
if (!pix->bytesperline) {
const struct soc_camera_format_xlate *xlate;
xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
if (!xlate)
return -EINVAL;
ret = soc_mbus_bytes_per_line(pix->width,
xlate->host_fmt);
if (ret > 0)
pix->bytesperline = ret;
}
if (pix->bytesperline)
pix->sizeimage = pix->bytesperline * pix->height;
}
return 0;
}
static int soc_camera_try_fmt_vid_cap(struct file *file, void *priv, static int soc_camera_try_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f) struct v4l2_format *f)
{ {
struct soc_camera_device *icd = file->private_data; struct soc_camera_device *icd = file->private_data;
struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
WARN_ON(priv != file->private_data); WARN_ON(priv != file->private_data);
@ -149,7 +188,7 @@ static int soc_camera_try_fmt_vid_cap(struct file *file, void *priv,
return -EINVAL; return -EINVAL;
/* limit format to hardware capabilities */ /* limit format to hardware capabilities */
return ici->ops->try_fmt(icd, f); return soc_camera_try_fmt(icd, f);
} }
static int soc_camera_enum_input(struct file *file, void *priv, static int soc_camera_enum_input(struct file *file, void *priv,
@ -362,9 +401,6 @@ static void soc_camera_free_user_formats(struct soc_camera_device *icd)
icd->user_formats = NULL; icd->user_formats = NULL;
} }
#define pixfmtstr(x) (x) & 0xff, ((x) >> 8) & 0xff, ((x) >> 16) & 0xff, \
((x) >> 24) & 0xff
/* Called with .vb_lock held, or from the first open(2), see comment there */ /* Called with .vb_lock held, or from the first open(2), see comment there */
static int soc_camera_set_fmt(struct soc_camera_device *icd, static int soc_camera_set_fmt(struct soc_camera_device *icd,
struct v4l2_format *f) struct v4l2_format *f)
@ -377,7 +413,7 @@ static int soc_camera_set_fmt(struct soc_camera_device *icd,
pixfmtstr(pix->pixelformat), pix->width, pix->height); pixfmtstr(pix->pixelformat), pix->width, pix->height);
/* We always call try_fmt() before set_fmt() or set_crop() */ /* We always call try_fmt() before set_fmt() or set_crop() */
ret = ici->ops->try_fmt(icd, f); ret = soc_camera_try_fmt(icd, f);
if (ret < 0) if (ret < 0)
return ret; return ret;

View File

@ -155,15 +155,18 @@ int v4l2_device_register_subdev(struct v4l2_device *v4l2_dev,
sd->v4l2_dev = v4l2_dev; sd->v4l2_dev = v4l2_dev;
if (sd->internal_ops && sd->internal_ops->registered) { if (sd->internal_ops && sd->internal_ops->registered) {
err = sd->internal_ops->registered(sd); err = sd->internal_ops->registered(sd);
if (err) if (err) {
module_put(sd->owner);
return err; return err;
} }
}
/* This just returns 0 if either of the two args is NULL */ /* This just returns 0 if either of the two args is NULL */
err = v4l2_ctrl_add_handler(v4l2_dev->ctrl_handler, sd->ctrl_handler); err = v4l2_ctrl_add_handler(v4l2_dev->ctrl_handler, sd->ctrl_handler);
if (err) { if (err) {
if (sd->internal_ops && sd->internal_ops->unregistered) if (sd->internal_ops && sd->internal_ops->unregistered)
sd->internal_ops->unregistered(sd); sd->internal_ops->unregistered(sd);
module_put(sd->owner);
return err; return err;
} }

View File

@ -155,25 +155,25 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg)
switch (cmd) { switch (cmd) {
case VIDIOC_QUERYCTRL: case VIDIOC_QUERYCTRL:
return v4l2_subdev_queryctrl(sd, arg); return v4l2_queryctrl(sd->ctrl_handler, arg);
case VIDIOC_QUERYMENU: case VIDIOC_QUERYMENU:
return v4l2_subdev_querymenu(sd, arg); return v4l2_querymenu(sd->ctrl_handler, arg);
case VIDIOC_G_CTRL: case VIDIOC_G_CTRL:
return v4l2_subdev_g_ctrl(sd, arg); return v4l2_g_ctrl(sd->ctrl_handler, arg);
case VIDIOC_S_CTRL: case VIDIOC_S_CTRL:
return v4l2_subdev_s_ctrl(sd, arg); return v4l2_s_ctrl(sd->ctrl_handler, arg);
case VIDIOC_G_EXT_CTRLS: case VIDIOC_G_EXT_CTRLS:
return v4l2_subdev_g_ext_ctrls(sd, arg); return v4l2_g_ext_ctrls(sd->ctrl_handler, arg);
case VIDIOC_S_EXT_CTRLS: case VIDIOC_S_EXT_CTRLS:
return v4l2_subdev_s_ext_ctrls(sd, arg); return v4l2_s_ext_ctrls(sd->ctrl_handler, arg);
case VIDIOC_TRY_EXT_CTRLS: case VIDIOC_TRY_EXT_CTRLS:
return v4l2_subdev_try_ext_ctrls(sd, arg); return v4l2_try_ext_ctrls(sd->ctrl_handler, arg);
case VIDIOC_DQEVENT: case VIDIOC_DQEVENT:
if (!(sd->flags & V4L2_SUBDEV_FL_HAS_EVENTS)) if (!(sd->flags & V4L2_SUBDEV_FL_HAS_EVENTS))