Merge branch 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab...
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 18 Nov 2013 23:08:02 +0000 (15:08 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 18 Nov 2013 23:08:02 +0000 (15:08 -0800)
Pull media updates from Mauro Carvalho Chehab:
 "This series include:
   - a new Remote Controller driver for ST SoC with the corresponding DT
     bindings
   - a new frontend (cx24117)
   - a new I2C camera flash driver (lm3560)
   - a new mem2mem driver for TI SoC (ti-vpe)
   - support for Raphael r828d added to r820t driver
   - some improvements on buffer allocation at VB2 core
   - usual driver fixes and improvements

  PS this time, we have a smaller number of patches.  While it is hard
  to pinpoint to the reasons, I believe that it is mainly due to:

   1) there are several patch series ready, but depending on DT review.
      I decided to grant some extra time for DT maintainers to look on
      it, as they're expecting to have more time with the changes agreed
      during ARM mini-summit and KS.  If they can't review in time for
      3.14, I'll review myself and apply for the next merge window.

   2) I suspect that having both LinuxCon EU and LinuxCon NA happening
      during the same merge window affected the development
      productivity, as several core media developers participated on
      both events"

* 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (151 commits)
  [media] media: st-rc: Add ST remote control driver
  [media] gpio-ir-recv: Include linux/of.h header
  [media] tvp7002: Include linux/of.h header
  [media] tvp514x: Include linux/of.h header
  [media] ths8200: Include linux/of.h header
  [media] adv7343: Include linux/of.h header
  [media] v4l: Fix typo in v4l2_subdev_get_try_crop()
  [media] media: i2c: add driver for dual LED Flash, lm3560
  [media] rtl28xxu: add 15f4:0131 Astrometa DVB-T2
  [media] rtl28xxu: add RTL2832P + R828D support
  [media] rtl2832: add new tuner R828D
  [media] r820t: add support for R828D
  [media] media/i2c: ths8200: fix build failure with gcc 4.5.4
  [media] Add support for KWorld UB435-Q V2
  [media] staging/media: fix msi3101 build errors
  [media] ddbridge: Remove casting the return value which is a void pointer
  [media] ngene: Remove casting the return value which is a void pointer
  [media] dm1105: remove unneeded not-null test
  [media] sh_mobile_ceu_camera: remove deprecated IRQF_DISABLED
  [media] media: rcar_vin: Add preliminary r8a7790 support
  ...

1  2 
drivers/media/i2c/Kconfig
drivers/media/i2c/ths8200.c
drivers/media/platform/Kconfig
drivers/media/platform/coda.c
drivers/media/radio/si470x/radio-si470x-common.c
drivers/media/v4l2-core/videobuf2-core.c
drivers/staging/media/lirc/lirc_bt829.c

@@@ -621,6 -621,15 +621,15 @@@ config VIDEO_AS3645
          This is a driver for the AS3645A and LM3555 flash controllers. It has
          build in control for flash, torch and indicator LEDs.
  
+ config VIDEO_LM3560
+       tristate "LM3560 dual flash driver support"
+       depends on I2C && VIDEO_V4L2 && MEDIA_CONTROLLER
+       depends on MEDIA_CAMERA_SUPPORT
+       select REGMAP_I2C
+       ---help---
+         This is a driver for the lm3560 dual flash controllers. It controls
+         flash, torch LEDs.
  comment "Video improvement chips"
  
  config VIDEO_UPD64031A
@@@ -646,7 -655,7 +655,7 @@@ config VIDEO_UPD6408
          To compile this driver as a module, choose M here: the
          module will be called upd64083.
  
 -comment "Miscelaneous helper chips"
 +comment "Miscellaneous helper chips"
  
  config VIDEO_THS7303
        tristate "THS7303/53 Video Amplifier"
@@@ -19,6 -19,7 +19,7 @@@
  
  #include <linux/i2c.h>
  #include <linux/module.h>
+ #include <linux/of.h>
  #include <linux/v4l2-dv-timings.h>
  
  #include <media/v4l2-dv-timings.h>
@@@ -46,10 -47,18 +47,10 @@@ struct ths8200_state 
  
  static const struct v4l2_dv_timings_cap ths8200_timings_cap = {
        .type = V4L2_DV_BT_656_1120,
 -      /* Allow gcc 4.5.4 to build this */
 -      .reserved = { },
 -      {
 -              .bt = {
 -                      .max_width = 1920,
 -                      .max_height = 1080,
 -                      .min_pixelclock = 25000000,
 -                      .max_pixelclock = 148500000,
 -                      .standards = V4L2_DV_BT_STD_CEA861,
 -                      .capabilities = V4L2_DV_BT_CAP_PROGRESSIVE,
 -              },
 -      },
 +      /* keep this initialization for compatibility with GCC < 4.4.6 */
 +      .reserved = { 0 },
 +      V4L2_INIT_BT_TIMINGS(0, 1920, 0, 1080, 25000000, 148500000,
 +              V4L2_DV_BT_STD_CEA861, V4L2_DV_BT_CAP_PROGRESSIVE)
  };
  
  static inline struct ths8200_state *to_state(struct v4l2_subdev *sd)
@@@ -112,7 -112,7 +112,7 @@@ config VIDEO_OMAP3_DEBU
  config VIDEO_S3C_CAMIF
        tristate "Samsung S3C24XX/S3C64XX SoC Camera Interface driver"
        depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API
 -      depends on (PLAT_S3C64XX || PLAT_S3C24XX) && PM_RUNTIME
 +      depends on (ARCH_S3C64XX || PLAT_S3C24XX) && PM_RUNTIME
        select VIDEOBUF2_DMA_CONTIG
        ---help---
          This is a v4l2 driver for s3c24xx and s3c64xx SoC series camera
@@@ -143,6 -143,7 +143,7 @@@ if V4L_MEM2MEM_DRIVER
  config VIDEO_CODA
        tristate "Chips&Media Coda multi-standard codec IP"
        depends on VIDEO_DEV && VIDEO_V4L2 && ARCH_MXC
+       select SRAM
        select VIDEOBUF2_DMA_CONTIG
        select V4L2_MEM2MEM_DEV
        ---help---
@@@ -212,7 -213,7 +213,7 @@@ config VIDEO_SH_VE
  
  config VIDEO_RENESAS_VSP1
        tristate "Renesas VSP1 Video Processing Engine"
-       depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+       depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && HAS_DMA
        select VIDEOBUF2_DMA_CONTIG
        ---help---
          This is a V4L2 driver for the Renesas VSP1 video processing engine.
          To compile this driver as a module, choose M here: the module
          will be called vsp1.
  
+ config VIDEO_TI_VPE
+       tristate "TI VPE (Video Processing Engine) driver"
+       depends on VIDEO_DEV && VIDEO_V4L2 && SOC_DRA7XX
+       select VIDEOBUF2_DMA_CONTIG
+       select V4L2_MEM2MEM_DEV
+       default n
+       ---help---
+         Support for the TI VPE(Video Processing Engine) block
+         found on DRA7XX SoC.
+ config VIDEO_TI_VPE_DEBUG
+       bool "VPE debug messages"
+       depends on VIDEO_TI_VPE
+       ---help---
+         Enable debug messages on VPE driver.
  endif # V4L_MEM2MEM_DRIVERS
  
  menuconfig V4L_TEST_DRIVERS
@@@ -39,7 -39,7 +39,7 @@@
  
  #define CODA_NAME             "coda"
  
- #define CODA_MAX_INSTANCES    4
+ #define CODADX6_MAX_INSTANCES 4
  
  #define CODA_FMO_BUF_SIZE     32
  #define CODADX6_WORK_BUF_SIZE (288 * 1024 + CODA_FMO_BUF_SIZE * 8 * 1024)
@@@ -54,8 -54,6 +54,6 @@@
  
  #define CODA_MAX_FRAMEBUFFERS 8
  
- #define MAX_W         8192
- #define MAX_H         8192
  #define CODA_MAX_FRAME_SIZE   0x100000
  #define FMO_SLICE_SAVE_BUF_SIZE         (32)
  #define CODA_DEFAULT_GAMMA            4096
@@@ -394,14 -392,57 +392,57 @@@ static struct coda_codec *coda_find_cod
        return &codecs[k];
  }
  
+ static void coda_get_max_dimensions(struct coda_dev *dev,
+                                   struct coda_codec *codec,
+                                   int *max_w, int *max_h)
+ {
+       struct coda_codec *codecs = dev->devtype->codecs;
+       int num_codecs = dev->devtype->num_codecs;
+       unsigned int w, h;
+       int k;
+       if (codec) {
+               w = codec->max_w;
+               h = codec->max_h;
+       } else {
+               for (k = 0, w = 0, h = 0; k < num_codecs; k++) {
+                       w = max(w, codecs[k].max_w);
+                       h = max(h, codecs[k].max_h);
+               }
+       }
+       if (max_w)
+               *max_w = w;
+       if (max_h)
+               *max_h = h;
+ }
+ static char *coda_product_name(int product)
+ {
+       static char buf[9];
+       switch (product) {
+       case CODA_DX6:
+               return "CodaDx6";
+       case CODA_7541:
+               return "CODA7541";
+       default:
+               snprintf(buf, sizeof(buf), "(0x%04x)", product);
+               return buf;
+       }
+ }
  /*
   * V4L2 ioctl() operations.
   */
- static int vidioc_querycap(struct file *file, void *priv,
-                          struct v4l2_capability *cap)
+ static int coda_querycap(struct file *file, void *priv,
+                        struct v4l2_capability *cap)
  {
+       struct coda_ctx *ctx = fh_to_ctx(priv);
        strlcpy(cap->driver, CODA_NAME, sizeof(cap->driver));
-       strlcpy(cap->card, CODA_NAME, sizeof(cap->card));
+       strlcpy(cap->card, coda_product_name(ctx->dev->devtype->product),
+               sizeof(cap->card));
        strlcpy(cap->bus_info, "platform:" CODA_NAME, sizeof(cap->bus_info));
        /*
         * This is only a mem-to-mem video device. The capture and output
@@@ -457,6 -498,8 +498,8 @@@ static int enum_fmt(void *priv, struct 
                fmt = &formats[i];
                strlcpy(f->description, fmt->name, sizeof(f->description));
                f->pixelformat = fmt->fourcc;
+               if (!coda_format_is_yuv(fmt->fourcc))
+                       f->flags |= V4L2_FMT_FLAG_COMPRESSED;
                return 0;
        }
  
        return -EINVAL;
  }
  
- static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
-                                  struct v4l2_fmtdesc *f)
+ static int coda_enum_fmt_vid_cap(struct file *file, void *priv,
+                                struct v4l2_fmtdesc *f)
  {
        struct coda_ctx *ctx = fh_to_ctx(priv);
        struct vb2_queue *src_vq;
        return enum_fmt(priv, f, V4L2_BUF_TYPE_VIDEO_CAPTURE, 0);
  }
  
- static int vidioc_enum_fmt_vid_out(struct file *file, void *priv,
-                                  struct v4l2_fmtdesc *f)
+ static int coda_enum_fmt_vid_out(struct file *file, void *priv,
+                                struct v4l2_fmtdesc *f)
  {
        return enum_fmt(priv, f, V4L2_BUF_TYPE_VIDEO_OUTPUT, 0);
  }
  
- static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
+ static int coda_g_fmt(struct file *file, void *priv,
+                     struct v4l2_format *f)
  {
        struct vb2_queue *vq;
        struct coda_q_data *q_data;
        return 0;
  }
  
- static int vidioc_try_fmt(struct coda_codec *codec, struct v4l2_format *f)
+ static int coda_try_fmt(struct coda_ctx *ctx, struct coda_codec *codec,
+                       struct v4l2_format *f)
  {
+       struct coda_dev *dev = ctx->dev;
+       struct coda_q_data *q_data;
        unsigned int max_w, max_h;
        enum v4l2_field field;
  
         * if any of the dimensions is unsupported */
        f->fmt.pix.field = field;
  
-       if (codec) {
-               max_w = codec->max_w;
-               max_h = codec->max_h;
-       } else {
-               max_w = MAX_W;
-               max_h = MAX_H;
+       coda_get_max_dimensions(dev, codec, &max_w, &max_h);
+       v4l_bound_align_image(&f->fmt.pix.width, MIN_W, max_w, W_ALIGN,
+                             &f->fmt.pix.height, MIN_H, max_h, H_ALIGN,
+                             S_ALIGN);
+       switch (f->fmt.pix.pixelformat) {
+       case V4L2_PIX_FMT_YUV420:
+       case V4L2_PIX_FMT_YVU420:
+       case V4L2_PIX_FMT_H264:
+       case V4L2_PIX_FMT_MPEG4:
+       case V4L2_PIX_FMT_JPEG:
+               break;
+       default:
+               q_data = get_q_data(ctx, f->type);
+               f->fmt.pix.pixelformat = q_data->fourcc;
        }
-       v4l_bound_align_image(&f->fmt.pix.width, MIN_W, max_w,
-                             W_ALIGN, &f->fmt.pix.height,
-                             MIN_H, max_h, H_ALIGN, S_ALIGN);
  
-       if (coda_format_is_yuv(f->fmt.pix.pixelformat)) {
+       switch (f->fmt.pix.pixelformat) {
+       case V4L2_PIX_FMT_YUV420:
+       case V4L2_PIX_FMT_YVU420:
                /* Frame stride must be multiple of 8 */
                f->fmt.pix.bytesperline = round_up(f->fmt.pix.width, 8);
                f->fmt.pix.sizeimage = f->fmt.pix.bytesperline *
                                        f->fmt.pix.height * 3 / 2;
-       } else { /*encoded formats h.264/mpeg4 */
+               break;
+       case V4L2_PIX_FMT_H264:
+       case V4L2_PIX_FMT_MPEG4:
+       case V4L2_PIX_FMT_JPEG:
                f->fmt.pix.bytesperline = 0;
                f->fmt.pix.sizeimage = CODA_MAX_FRAME_SIZE;
+               break;
+       default:
+               BUG();
        }
  
+       f->fmt.pix.priv = 0;
        return 0;
  }
  
- static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
-                                 struct v4l2_format *f)
+ static int coda_try_fmt_vid_cap(struct file *file, void *priv,
+                               struct v4l2_format *f)
  {
        struct coda_ctx *ctx = fh_to_ctx(priv);
        struct coda_codec *codec;
  
        f->fmt.pix.colorspace = ctx->colorspace;
  
-       ret = vidioc_try_fmt(codec, f);
+       ret = coda_try_fmt(ctx, codec, f);
        if (ret < 0)
                return ret;
  
        return 0;
  }
  
- static int vidioc_try_fmt_vid_out(struct file *file, void *priv,
-                                 struct v4l2_format *f)
+ static int coda_try_fmt_vid_out(struct file *file, void *priv,
+                               struct v4l2_format *f)
  {
        struct coda_ctx *ctx = fh_to_ctx(priv);
        struct coda_codec *codec;
        if (!f->fmt.pix.colorspace)
                f->fmt.pix.colorspace = V4L2_COLORSPACE_REC709;
  
-       return vidioc_try_fmt(codec, f);
+       return coda_try_fmt(ctx, codec, f);
  }
  
- static int vidioc_s_fmt(struct coda_ctx *ctx, struct v4l2_format *f)
+ static int coda_s_fmt(struct coda_ctx *ctx, struct v4l2_format *f)
  {
        struct coda_q_data *q_data;
        struct vb2_queue *vq;
        return 0;
  }
  
- static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
-                               struct v4l2_format *f)
+ static int coda_s_fmt_vid_cap(struct file *file, void *priv,
+                             struct v4l2_format *f)
  {
        struct coda_ctx *ctx = fh_to_ctx(priv);
        int ret;
  
-       ret = vidioc_try_fmt_vid_cap(file, priv, f);
+       ret = coda_try_fmt_vid_cap(file, priv, f);
        if (ret)
                return ret;
  
-       return vidioc_s_fmt(ctx, f);
+       return coda_s_fmt(ctx, f);
  }
  
- static int vidioc_s_fmt_vid_out(struct file *file, void *priv,
-                               struct v4l2_format *f)
+ static int coda_s_fmt_vid_out(struct file *file, void *priv,
+                             struct v4l2_format *f)
  {
        struct coda_ctx *ctx = fh_to_ctx(priv);
        int ret;
  
-       ret = vidioc_try_fmt_vid_out(file, priv, f);
+       ret = coda_try_fmt_vid_out(file, priv, f);
        if (ret)
                return ret;
  
-       ret = vidioc_s_fmt(ctx, f);
+       ret = coda_s_fmt(ctx, f);
        if (ret)
                ctx->colorspace = f->fmt.pix.colorspace;
  
        return ret;
  }
  
- static int vidioc_reqbufs(struct file *file, void *priv,
-                         struct v4l2_requestbuffers *reqbufs)
+ static int coda_reqbufs(struct file *file, void *priv,
+                       struct v4l2_requestbuffers *reqbufs)
  {
        struct coda_ctx *ctx = fh_to_ctx(priv);
  
        return v4l2_m2m_reqbufs(file, ctx->m2m_ctx, reqbufs);
  }
  
- static int vidioc_querybuf(struct file *file, void *priv,
-                          struct v4l2_buffer *buf)
+ static int coda_querybuf(struct file *file, void *priv,
+                        struct v4l2_buffer *buf)
  {
        struct coda_ctx *ctx = fh_to_ctx(priv);
  
        return v4l2_m2m_querybuf(file, ctx->m2m_ctx, buf);
  }
  
- static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
+ static int coda_qbuf(struct file *file, void *priv,
+                    struct v4l2_buffer *buf)
  {
        struct coda_ctx *ctx = fh_to_ctx(priv);
  
        return v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf);
  }
  
- static int vidioc_expbuf(struct file *file, void *priv,
-                        struct v4l2_exportbuffer *eb)
+ static int coda_expbuf(struct file *file, void *priv,
+                      struct v4l2_exportbuffer *eb)
  {
        struct coda_ctx *ctx = fh_to_ctx(priv);
  
@@@ -718,7 -782,8 +782,8 @@@ static bool coda_buf_is_end_of_stream(s
                (buf->sequence == (ctx->qsequence - 1)));
  }
  
- static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
+ static int coda_dqbuf(struct file *file, void *priv,
+                     struct v4l2_buffer *buf)
  {
        struct coda_ctx *ctx = fh_to_ctx(priv);
        int ret;
        return ret;
  }
  
- static int vidioc_create_bufs(struct file *file, void *priv,
-                             struct v4l2_create_buffers *create)
+ static int coda_create_bufs(struct file *file, void *priv,
+                           struct v4l2_create_buffers *create)
  {
        struct coda_ctx *ctx = fh_to_ctx(priv);
  
        return v4l2_m2m_create_bufs(file, ctx->m2m_ctx, create);
  }
  
- static int vidioc_streamon(struct file *file, void *priv,
-                          enum v4l2_buf_type type)
+ static int coda_streamon(struct file *file, void *priv,
+                        enum v4l2_buf_type type)
  {
        struct coda_ctx *ctx = fh_to_ctx(priv);
  
        return v4l2_m2m_streamon(file, ctx->m2m_ctx, type);
  }
  
- static int vidioc_streamoff(struct file *file, void *priv,
-                           enum v4l2_buf_type type)
+ static int coda_streamoff(struct file *file, void *priv,
+                         enum v4l2_buf_type type)
  {
        struct coda_ctx *ctx = fh_to_ctx(priv);
        int ret;
        return ret;
  }
  
- static int vidioc_decoder_cmd(struct file *file, void *fh,
-                             struct v4l2_decoder_cmd *dc)
+ static int coda_try_decoder_cmd(struct file *file, void *fh,
+                               struct v4l2_decoder_cmd *dc)
  {
-       struct coda_ctx *ctx = fh_to_ctx(fh);
        if (dc->cmd != V4L2_DEC_CMD_STOP)
                return -EINVAL;
  
-       if ((dc->flags & V4L2_DEC_CMD_STOP_TO_BLACK) ||
-           (dc->flags & V4L2_DEC_CMD_STOP_IMMEDIATELY))
+       if (dc->flags & V4L2_DEC_CMD_STOP_TO_BLACK)
                return -EINVAL;
  
-       if (dc->stop.pts != 0)
+       if (!(dc->flags & V4L2_DEC_CMD_STOP_IMMEDIATELY) && (dc->stop.pts != 0))
                return -EINVAL;
  
+       return 0;
+ }
+ static int coda_decoder_cmd(struct file *file, void *fh,
+                           struct v4l2_decoder_cmd *dc)
+ {
+       struct coda_ctx *ctx = fh_to_ctx(fh);
+       int ret;
+       ret = coda_try_decoder_cmd(file, fh, dc);
+       if (ret < 0)
+               return ret;
+       /* Ignore decoder stop command silently in encoder context */
        if (ctx->inst_type != CODA_INST_DECODER)
-               return -EINVAL;
+               return 0;
  
        /* Set the strem-end flag on this context */
        ctx->bit_stream_param |= CODA_BIT_STREAM_END_FLAG;
        return 0;
  }
  
- static int vidioc_subscribe_event(struct v4l2_fh *fh,
-                                 const struct v4l2_event_subscription *sub)
+ static int coda_subscribe_event(struct v4l2_fh *fh,
+                               const struct v4l2_event_subscription *sub)
  {
        switch (sub->type) {
        case V4L2_EVENT_EOS:
  }
  
  static const struct v4l2_ioctl_ops coda_ioctl_ops = {
-       .vidioc_querycap        = vidioc_querycap,
+       .vidioc_querycap        = coda_querycap,
  
-       .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
-       .vidioc_g_fmt_vid_cap   = vidioc_g_fmt,
-       .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
-       .vidioc_s_fmt_vid_cap   = vidioc_s_fmt_vid_cap,
+       .vidioc_enum_fmt_vid_cap = coda_enum_fmt_vid_cap,
+       .vidioc_g_fmt_vid_cap   = coda_g_fmt,
+       .vidioc_try_fmt_vid_cap = coda_try_fmt_vid_cap,
+       .vidioc_s_fmt_vid_cap   = coda_s_fmt_vid_cap,
  
-       .vidioc_enum_fmt_vid_out = vidioc_enum_fmt_vid_out,
-       .vidioc_g_fmt_vid_out   = vidioc_g_fmt,
-       .vidioc_try_fmt_vid_out = vidioc_try_fmt_vid_out,
-       .vidioc_s_fmt_vid_out   = vidioc_s_fmt_vid_out,
+       .vidioc_enum_fmt_vid_out = coda_enum_fmt_vid_out,
+       .vidioc_g_fmt_vid_out   = coda_g_fmt,
+       .vidioc_try_fmt_vid_out = coda_try_fmt_vid_out,
+       .vidioc_s_fmt_vid_out   = coda_s_fmt_vid_out,
  
-       .vidioc_reqbufs         = vidioc_reqbufs,
-       .vidioc_querybuf        = vidioc_querybuf,
+       .vidioc_reqbufs         = coda_reqbufs,
+       .vidioc_querybuf        = coda_querybuf,
  
-       .vidioc_qbuf            = vidioc_qbuf,
-       .vidioc_expbuf          = vidioc_expbuf,
-       .vidioc_dqbuf           = vidioc_dqbuf,
-       .vidioc_create_bufs     = vidioc_create_bufs,
+       .vidioc_qbuf            = coda_qbuf,
+       .vidioc_expbuf          = coda_expbuf,
+       .vidioc_dqbuf           = coda_dqbuf,
+       .vidioc_create_bufs     = coda_create_bufs,
  
-       .vidioc_streamon        = vidioc_streamon,
-       .vidioc_streamoff       = vidioc_streamoff,
+       .vidioc_streamon        = coda_streamon,
+       .vidioc_streamoff       = coda_streamoff,
  
-       .vidioc_decoder_cmd     = vidioc_decoder_cmd,
+       .vidioc_try_decoder_cmd = coda_try_decoder_cmd,
+       .vidioc_decoder_cmd     = coda_decoder_cmd,
  
-       .vidioc_subscribe_event = vidioc_subscribe_event,
+       .vidioc_subscribe_event = coda_subscribe_event,
        .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
  };
  
@@@ -1928,8 -2005,9 +2005,9 @@@ static int coda_start_streaming(struct 
        if (!(ctx->streamon_out & ctx->streamon_cap))
                return 0;
  
-       /* Allow device_run with no buffers queued and after streamoff */
-       v4l2_m2m_set_src_buffered(ctx->m2m_ctx, true);
+       /* Allow decoder device_run with no new buffers queued */
+       if (ctx->inst_type == CODA_INST_DECODER)
+               v4l2_m2m_set_src_buffered(ctx->m2m_ctx, true);
  
        ctx->gopcounter = ctx->params.gop_size - 1;
        buf = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
        coda_setup_iram(ctx);
  
        if (dst_fourcc == V4L2_PIX_FMT_H264) {
-               value  = (FMO_SLICE_SAVE_BUF_SIZE << 7);
-               value |= (0 & CODA_FMOPARAM_TYPE_MASK) << CODA_FMOPARAM_TYPE_OFFSET;
-               value |=  0 & CODA_FMOPARAM_SLICENUM_MASK;
                if (dev->devtype->product == CODA_DX6) {
+                       value = FMO_SLICE_SAVE_BUF_SIZE << 7;
                        coda_write(dev, value, CODADX6_CMD_ENC_SEQ_FMO);
                } else {
                        coda_write(dev, ctx->iram_info.search_ram_paddr,
@@@ -2371,7 -2447,13 +2447,13 @@@ static int coda_queue_init(void *priv, 
  
  static int coda_next_free_instance(struct coda_dev *dev)
  {
-       return ffz(dev->instance_mask);
+       int idx = ffz(dev->instance_mask);
+       if ((idx < 0) ||
+           (dev->devtype->product == CODA_DX6 && idx > CODADX6_MAX_INSTANCES))
+               return -EBUSY;
+       return idx;
  }
  
  static int coda_open(struct file *file)
                return -ENOMEM;
  
        idx = coda_next_free_instance(dev);
-       if (idx >= CODA_MAX_INSTANCES) {
-               ret = -EBUSY;
+       if (idx < 0) {
+               ret = idx;
                goto err_coda_max;
        }
        set_bit(idx, &dev->instance_mask);
@@@ -2719,7 -2801,6 +2801,6 @@@ static void coda_finish_encode(struct c
        dst_buf = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx);
  
        /* Get results from the coda */
-       coda_read(dev, CODA_RET_ENC_PIC_TYPE);
        start_ptr = coda_read(dev, CODA_CMD_ENC_PIC_BB_START);
        wr_ptr = coda_read(dev, CODA_REG_BIT_WR_PTR(ctx->reg_idx));
  
        coda_read(dev, CODA_RET_ENC_PIC_SLICE_NUM);
        coda_read(dev, CODA_RET_ENC_PIC_FLAG);
  
-       if (src_buf->v4l2_buf.flags & V4L2_BUF_FLAG_KEYFRAME) {
+       if (coda_read(dev, CODA_RET_ENC_PIC_TYPE) == 0) {
                dst_buf->v4l2_buf.flags |= V4L2_BUF_FLAG_KEYFRAME;
                dst_buf->v4l2_buf.flags &= ~V4L2_BUF_FLAG_PFRAME;
        } else {
@@@ -2861,21 -2942,6 +2942,6 @@@ static bool coda_firmware_supported(u3
        return false;
  }
  
- static char *coda_product_name(int product)
- {
-       static char buf[9];
-       switch (product) {
-       case CODA_DX6:
-               return "CodaDx6";
-       case CODA_7541:
-               return "CODA7541";
-       default:
-               snprintf(buf, sizeof(buf), "(0x%04x)", product);
-               return buf;
-       }
- }
  static int coda_hw_init(struct coda_dev *dev)
  {
        u16 product, major, minor, release;
@@@ -3232,12 -3298,13 +3298,12 @@@ static int coda_probe(struct platform_d
                dev->iram_size = CODA7_IRAM_SIZE;
                break;
        }
 -      dev->iram_vaddr = gen_pool_alloc(dev->iram_pool, dev->iram_size);
 +      dev->iram_vaddr = (unsigned long)gen_pool_dma_alloc(dev->iram_pool,
 +                      dev->iram_size, (dma_addr_t *)&dev->iram_paddr);
        if (!dev->iram_vaddr) {
                dev_err(&pdev->dev, "unable to alloc iram\n");
                return -ENOMEM;
        }
 -      dev->iram_paddr = gen_pool_virt_to_phys(dev->iram_pool,
 -                                              dev->iram_vaddr);
  
        platform_set_drvdata(pdev, dev);
  
@@@ -218,7 -218,7 +218,7 @@@ static int si470x_set_chan(struct si470
                goto done;
  
        /* wait till tune operation has completed */
 -      INIT_COMPLETION(radio->completion);
 +      reinit_completion(&radio->completion);
        retval = wait_for_completion_timeout(&radio->completion,
                        msecs_to_jiffies(tune_timeout));
        if (!retval)
@@@ -254,7 -254,7 +254,7 @@@ static unsigned int si470x_get_step(str
        /* 2:  50 kHz */
        default:
                return 50 * 16;
-       };
+       }
  }
  
  
@@@ -341,7 -341,7 +341,7 @@@ static int si470x_set_seek(struct si470
                return retval;
  
        /* wait till tune operation has completed */
 -      INIT_COMPLETION(radio->completion);
 +      reinit_completion(&radio->completion);
        retval = wait_for_completion_timeout(&radio->completion,
                        msecs_to_jiffies(seek_timeout));
        if (!retval)
@@@ -241,7 -241,8 +241,8 @@@ static int __vb2_queue_alloc(struct vb2
                q->bufs[q->num_buffers + buffer] = vb;
        }
  
-       __setup_offsets(q, buffer);
+       if (memory == V4L2_MEMORY_MMAP)
+               __setup_offsets(q, buffer);
  
        dprintk(1, "Allocated %d buffers, %d plane(s) each\n",
                        buffer, num_planes);
@@@ -353,9 -354,7 +354,9 @@@ static int __verify_length(struct vb2_b
  
                        if (b->m.planes[plane].bytesused > length)
                                return -EINVAL;
 -                      if (b->m.planes[plane].data_offset >=
 +
 +                      if (b->m.planes[plane].data_offset > 0 &&
 +                          b->m.planes[plane].data_offset >=
                            b->m.planes[plane].bytesused)
                                return -EINVAL;
                }
@@@ -1015,6 -1014,10 +1016,10 @@@ static int __qbuf_userptr(struct vb2_bu
  
                /* Check if the provided plane buffer is large enough */
                if (planes[plane].length < q->plane_sizes[plane]) {
+                       dprintk(1, "qbuf: provided buffer size %u is less than "
+                                               "setup size %u for plane %d\n",
+                                               planes[plane].length,
+                                               q->plane_sizes[plane], plane);
                        ret = -EINVAL;
                        goto err;
                }
@@@ -1205,8 -1208,11 +1210,11 @@@ static int __buf_prepare(struct vb2_buf
        int ret;
  
        ret = __verify_length(vb, b);
-       if (ret < 0)
+       if (ret < 0) {
+               dprintk(1, "%s(): plane parameters verification failed: %d\n",
+                       __func__, ret);
                return ret;
+       }
  
        switch (q->memory) {
        case V4L2_MEMORY_MMAP:
@@@ -2469,10 -2475,11 +2477,11 @@@ size_t vb2_read(struct vb2_queue *q, ch
  }
  EXPORT_SYMBOL_GPL(vb2_read);
  
- size_t vb2_write(struct vb2_queue *q, char __user *data, size_t count,
+ size_t vb2_write(struct vb2_queue *q, const char __user *data, size_t count,
                loff_t *ppos, int nonblocking)
  {
-       return __vb2_perform_fileio(q, data, count, ppos, nonblocking, 0);
+       return __vb2_perform_fileio(q, (char __user *) data, count,
+                                                       ppos, nonblocking, 0);
  }
  EXPORT_SYMBOL_GPL(vb2_write);
  
@@@ -2633,7 -2640,7 +2642,7 @@@ int vb2_fop_release(struct file *file
  }
  EXPORT_SYMBOL_GPL(vb2_fop_release);
  
- ssize_t vb2_fop_write(struct file *file, char __user *buf,
+ ssize_t vb2_fop_write(struct file *file, const char __user *buf,
                size_t count, loff_t *ppos)
  {
        struct video_device *vdev = video_devdata(file);
@@@ -63,7 -63,7 +63,7 @@@ static bool debug
        } while (0)
  
  static int atir_minor;
- static unsigned long pci_addr_phys;
+ static phys_addr_t pci_addr_phys;
  static unsigned char *pci_addr_lin;
  
  static struct lirc_driver atir_driver;
@@@ -78,11 -78,11 +78,11 @@@ static struct pci_dev *do_pci_probe(voi
                pci_addr_phys = 0;
                if (my_dev->resource[0].flags & IORESOURCE_MEM) {
                        pci_addr_phys = my_dev->resource[0].start;
-                       pr_info("memory at 0x%08X\n",
-                              (unsigned int)pci_addr_phys);
+                       pr_info("memory at %pa\n", &pci_addr_phys);
                }
                if (pci_addr_phys == 0) {
                        pr_err("no memory resource ?\n");
+                       pci_dev_put(my_dev);
                        return NULL;
                }
        } else {
@@@ -120,19 -120,26 +120,26 @@@ static void atir_set_use_dec(void *data
  int init_module(void)
  {
        struct pci_dev *pdev;
+       int rc;
  
        pdev = do_pci_probe();
        if (pdev == NULL)
                return -ENODEV;
  
-       if (!atir_init_start())
-               return -ENODEV;
+       rc = pci_enable_device(pdev);
+       if (rc)
+               goto err_put_dev;
+       if (!atir_init_start()) {
+               rc = -ENODEV;
+               goto err_disable;
+       }
  
        strcpy(atir_driver.name, "ATIR");
        atir_driver.minor       = -1;
        atir_driver.code_length = 8;
        atir_driver.sample_rate = 10;
 -      atir_driver.data        = 0;
 +      atir_driver.data        = NULL;
        atir_driver.add_to_buf  = atir_add_to_buf;
        atir_driver.set_use_inc = atir_set_use_inc;
        atir_driver.set_use_dec = atir_set_use_dec;
        atir_minor = lirc_register_driver(&atir_driver);
        if (atir_minor < 0) {
                pr_err("failed to register driver!\n");
-               return atir_minor;
+               rc = atir_minor;
+               goto err_unmap;
        }
        dprintk("driver is registered on minor %d\n", atir_minor);
  
        return 0;
+ err_unmap:
+       iounmap(pci_addr_lin);
+ err_disable:
+       pci_disable_device(pdev);
+ err_put_dev:
+       pci_dev_put(pdev);
+       return rc;
  }
  
  
  void cleanup_module(void)
  {
+       struct pci_dev *pdev = to_pci_dev(atir_driver.dev);
        lirc_unregister_driver(atir_minor);
+       iounmap(pci_addr_lin);
+       pci_disable_device(pdev);
+       pci_dev_put(pdev);
  }
  
  
  static int atir_init_start(void)
  {
        pci_addr_lin = ioremap(pci_addr_phys + DATA_PCI_OFF, 0x400);
 -      if (pci_addr_lin == 0) {
 +      if (!pci_addr_lin) {
                pr_info("pci mem must be mapped\n");
                return 0;
        }