Merge tag 'media/v5.2-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab...
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 16 May 2019 18:57:16 +0000 (11:57 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 16 May 2019 18:57:16 +0000 (11:57 -0700)
Pull media fixes from Mauro Carvalho Chehab:
 "Some fixes for some platform drivers (rockchip, atmel, omap, daVinci,
  tegra-cec, coda and rcar).

  Also includes a fix on one of the V4L2 uAPI doc, explaining a border
  case"

* tag 'media/v5.2-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media:
  media: rockchip/vpu: Fix/re-order probe-error/remove path
  media: rockchip/vpu: Initialize mdev->bus_info
  media: rockchip/vpu: Get vdev from the file arg in vidioc_querycap()
  media: rockchip/vpu: Add missing dont_use_autosuspend() calls
  media: rockchip/vpu: Do not request id 0 for our video device
  media: tegra-cec: fix cec_notifier_parse_hdmi_phandle return check
  media: davinci/vpbe: array underflow in vpbe_enum_outputs()
  media: field-order.rst: clarify FIELD_ANY and FIELD_NONE
  media: staging/imx: add media device to capture register
  media: rcar-csi2: Propagate the FLD signal for NTSC and PAL
  media: rcar-csi2: restart CSI-2 link if error is detected
  media: omap_vout: potential buffer overflow in vidioc_dqbuf()
  media: coda: fix unset field and fail on invalid field in buf_prepare
  media: atmel: atmel-isc: fix asd memory allocation
  media: atmel: atmel-isc: fix INIT_WORK misplacement
  media: atmel: atmel-isc: limit incoming pixels per frame

16 files changed:
Documentation/media/uapi/v4l/field-order.rst
drivers/media/platform/atmel/atmel-isc-regs.h
drivers/media/platform/atmel/atmel-isc.c
drivers/media/platform/coda/coda-common.c
drivers/media/platform/davinci/vpbe.c
drivers/media/platform/omap/omap_vout.c
drivers/media/platform/rcar-vin/rcar-csi2.c
drivers/media/platform/tegra-cec/tegra_cec.c
drivers/staging/media/imx/imx-ic-prpencvf.c
drivers/staging/media/imx/imx-media-capture.c
drivers/staging/media/imx/imx-media-csi.c
drivers/staging/media/imx/imx-media.h
drivers/staging/media/imx/imx7-media-csi.c
drivers/staging/media/rockchip/vpu/rockchip_vpu_drv.c
drivers/staging/media/rockchip/vpu/rockchip_vpu_enc.c
include/media/davinci/vpbe.h

index 3fb473e3b8e2e205d4e0d6692a891d560eec3781..d640e922a9748c795ec670f4375098372052f6dd 100644 (file)
@@ -75,12 +75,11 @@ enum v4l2_field
 
     * - ``V4L2_FIELD_ANY``
       - 0
-      - Applications request this field order when any one of the
-       ``V4L2_FIELD_NONE``, ``V4L2_FIELD_TOP``, ``V4L2_FIELD_BOTTOM``, or
-       ``V4L2_FIELD_INTERLACED`` formats is acceptable. Drivers choose
-       depending on hardware capabilities or e. g. the requested image
-       size, and return the actual field order. Drivers must never return
-       ``V4L2_FIELD_ANY``. If multiple field orders are possible the
+      - Applications request this field order when any field format
+       is acceptable. Drivers choose depending on hardware capabilities or
+       e.g. the requested image size, and return the actual field order.
+       Drivers must never return ``V4L2_FIELD_ANY``.
+       If multiple field orders are possible the
        driver must choose one of the possible field orders during
        :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` or
        :ref:`VIDIOC_TRY_FMT <VIDIOC_G_FMT>`. struct
@@ -88,9 +87,8 @@ enum v4l2_field
        ``V4L2_FIELD_ANY``.
     * - ``V4L2_FIELD_NONE``
       - 1
-      - Images are in progressive format, not interlaced. The driver may
-       also indicate this order when it cannot distinguish between
-       ``V4L2_FIELD_TOP`` and ``V4L2_FIELD_BOTTOM``.
+      - Images are in progressive (frame-based) format, not interlaced
+        (field-based).
     * - ``V4L2_FIELD_TOP``
       - 2
       - Images consist of the top (aka odd) field only.
index d730693f299cfccf098f6466f66076a1765109b8..8f7f8efc71a7d945e3e5b014f12f2492e64948ff 100644 (file)
 #define ISC_PFG_CFG0_BPS_TWELVE (0x0 << 28)
 #define ISC_PFE_CFG0_BPS_MASK   GENMASK(30, 28)
 
+#define ISC_PFE_CFG0_COLEN     BIT(12)
+#define ISC_PFE_CFG0_ROWEN     BIT(13)
+
+/* ISC Parallel Front End Configuration 1 Register */
+#define ISC_PFE_CFG1    0x00000010
+
+#define ISC_PFE_CFG1_COLMIN(v)         ((v))
+#define ISC_PFE_CFG1_COLMIN_MASK       GENMASK(15, 0)
+#define ISC_PFE_CFG1_COLMAX(v)         ((v) << 16)
+#define ISC_PFE_CFG1_COLMAX_MASK       GENMASK(31, 16)
+
+/* ISC Parallel Front End Configuration 2 Register */
+#define ISC_PFE_CFG2    0x00000014
+
+#define ISC_PFE_CFG2_ROWMIN(v)         ((v))
+#define ISC_PFE_CFG2_ROWMIN_MASK       GENMASK(15, 0)
+#define ISC_PFE_CFG2_ROWMAX(v)         ((v) << 16)
+#define ISC_PFE_CFG2_ROWMAX_MASK       GENMASK(31, 16)
+
 /* ISC Clock Enable Register */
 #define ISC_CLKEN               0x00000018
 
index 4bba9da206e416a65dde7834b6c25cee14eeed3f..94cb309fdb527dffdf501b0c8fa3fb946e76bdc9 100644 (file)
@@ -721,6 +721,40 @@ static void isc_start_dma(struct isc_device *isc)
        u32 sizeimage = isc->fmt.fmt.pix.sizeimage;
        u32 dctrl_dview;
        dma_addr_t addr0;
+       u32 h, w;
+
+       h = isc->fmt.fmt.pix.height;
+       w = isc->fmt.fmt.pix.width;
+
+       /*
+        * In case the sensor is not RAW, it will output a pixel (12-16 bits)
+        * with two samples on the ISC Data bus (which is 8-12)
+        * ISC will count each sample, so, we need to multiply these values
+        * by two, to get the real number of samples for the required pixels.
+        */
+       if (!ISC_IS_FORMAT_RAW(isc->config.sd_format->mbus_code)) {
+               h <<= 1;
+               w <<= 1;
+       }
+
+       /*
+        * We limit the column/row count that the ISC will output according
+        * to the configured resolution that we want.
+        * This will avoid the situation where the sensor is misconfigured,
+        * sending more data, and the ISC will just take it and DMA to memory,
+        * causing corruption.
+        */
+       regmap_write(regmap, ISC_PFE_CFG1,
+                    (ISC_PFE_CFG1_COLMIN(0) & ISC_PFE_CFG1_COLMIN_MASK) |
+                    (ISC_PFE_CFG1_COLMAX(w - 1) & ISC_PFE_CFG1_COLMAX_MASK));
+
+       regmap_write(regmap, ISC_PFE_CFG2,
+                    (ISC_PFE_CFG2_ROWMIN(0) & ISC_PFE_CFG2_ROWMIN_MASK) |
+                    (ISC_PFE_CFG2_ROWMAX(h - 1) & ISC_PFE_CFG2_ROWMAX_MASK));
+
+       regmap_update_bits(regmap, ISC_PFE_CFG0,
+                          ISC_PFE_CFG0_COLEN | ISC_PFE_CFG0_ROWEN,
+                          ISC_PFE_CFG0_COLEN | ISC_PFE_CFG0_ROWEN);
 
        addr0 = vb2_dma_contig_plane_dma_addr(&isc->cur_frm->vb.vb2_buf, 0);
        regmap_write(regmap, ISC_DAD0, addr0);
@@ -1965,6 +1999,8 @@ static int isc_async_complete(struct v4l2_async_notifier *notifier)
        struct vb2_queue *q = &isc->vb2_vidq;
        int ret;
 
+       INIT_WORK(&isc->awb_work, isc_awb_work);
+
        ret = v4l2_device_register_subdev_nodes(&isc->v4l2_dev);
        if (ret < 0) {
                v4l2_err(&isc->v4l2_dev, "Failed to register subdev nodes\n");
@@ -2018,8 +2054,6 @@ static int isc_async_complete(struct v4l2_async_notifier *notifier)
                return ret;
        }
 
-       INIT_WORK(&isc->awb_work, isc_awb_work);
-
        /* Register video device */
        strscpy(vdev->name, ATMEL_ISC_NAME, sizeof(vdev->name));
        vdev->release           = video_device_release_empty;
@@ -2135,8 +2169,11 @@ static int isc_parse_dt(struct device *dev, struct isc_device *isc)
                        break;
                }
 
-               subdev_entity->asd = devm_kzalloc(dev,
-                                    sizeof(*subdev_entity->asd), GFP_KERNEL);
+               /* asd will be freed by the subsystem once it's added to the
+                * notifier list
+                */
+               subdev_entity->asd = kzalloc(sizeof(*subdev_entity->asd),
+                                            GFP_KERNEL);
                if (!subdev_entity->asd) {
                        of_node_put(rem);
                        ret = -ENOMEM;
@@ -2284,6 +2321,7 @@ static int atmel_isc_probe(struct platform_device *pdev)
                                                     subdev_entity->asd);
                if (ret) {
                        fwnode_handle_put(subdev_entity->asd->match.fwnode);
+                       kfree(subdev_entity->asd);
                        goto cleanup_subdev;
                }
 
index 3ce58dee4422bd16d61802c641e16e392a9597a3..1d96cca615477d513974e78cec2c7553eb603128 100644 (file)
@@ -1515,10 +1515,20 @@ static int coda_queue_setup(struct vb2_queue *vq,
 
 static int coda_buf_prepare(struct vb2_buffer *vb)
 {
+       struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
        struct coda_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
        struct coda_q_data *q_data;
 
        q_data = get_q_data(ctx, vb->vb2_queue->type);
+       if (V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) {
+               if (vbuf->field == V4L2_FIELD_ANY)
+                       vbuf->field = V4L2_FIELD_NONE;
+               if (vbuf->field != V4L2_FIELD_NONE) {
+                       v4l2_warn(&ctx->dev->v4l2_dev,
+                                 "%s field isn't supported\n", __func__);
+                       return -EINVAL;
+               }
+       }
 
        if (vb2_plane_size(vb, 0) < q_data->sizeimage) {
                v4l2_warn(&ctx->dev->v4l2_dev,
index 8339163a5231e37c5c0dcb926a175bfa64fd3507..4e24f5d781f4fe96da0e43648e13190eac578b49 100644 (file)
@@ -104,7 +104,7 @@ static int vpbe_enum_outputs(struct vpbe_device *vpbe_dev,
                             struct v4l2_output *output)
 {
        struct vpbe_config *cfg = vpbe_dev->cfg;
-       int temp_index = output->index;
+       unsigned int temp_index = output->index;
 
        if (temp_index >= cfg->num_outputs)
                return -EINVAL;
index 37f0d7146dfa480fa3e7b9551177c29495ee7208..cb6a9e3946b6d8fcea499e8d8f5800700e26feae 100644 (file)
@@ -1527,23 +1527,20 @@ static int vidioc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b)
        unsigned long size;
        struct videobuf_buffer *vb;
 
-       vb = q->bufs[b->index];
-
        if (!vout->streaming)
                return -EINVAL;
 
-       if (file->f_flags & O_NONBLOCK)
-               /* Call videobuf_dqbuf for non blocking mode */
-               ret = videobuf_dqbuf(q, (struct v4l2_buffer *)b, 1);
-       else
-               /* Call videobuf_dqbuf for  blocking mode */
-               ret = videobuf_dqbuf(q, (struct v4l2_buffer *)b, 0);
+       ret = videobuf_dqbuf(q, b, !!(file->f_flags & O_NONBLOCK));
+       if (ret)
+               return ret;
+
+       vb = q->bufs[b->index];
 
        addr = (unsigned long) vout->buf_phy_addr[vb->i];
        size = (unsigned long) vb->size;
        dma_unmap_single(vout->vid_dev->v4l2_dev.dev,  addr,
                                size, DMA_TO_DEVICE);
-       return ret;
+       return 0;
 }
 
 static int vidioc_streamon(struct file *file, void *fh, enum v4l2_buf_type i)
index 799e526fd3df555441a0821a8948e35166f575b4..8f097e514900307ff2de242b08f4cdd07b9c3188 100644 (file)
@@ -68,6 +68,7 @@ struct rcar_csi2;
 /* Field Detection Control */
 #define FLD_REG                                0x1c
 #define FLD_FLD_NUM(n)                 (((n) & 0xff) << 16)
+#define FLD_DET_SEL(n)                 (((n) & 0x3) << 4)
 #define FLD_FLD_EN4                    BIT(3)
 #define FLD_FLD_EN3                    BIT(2)
 #define FLD_FLD_EN2                    BIT(1)
@@ -84,6 +85,9 @@ struct rcar_csi2;
 
 /* Interrupt Enable */
 #define INTEN_REG                      0x30
+#define INTEN_INT_AFIFO_OF             BIT(27)
+#define INTEN_INT_ERRSOTHS             BIT(4)
+#define INTEN_INT_ERRSOTSYNCHS         BIT(3)
 
 /* Interrupt Source Mask */
 #define INTCLOSE_REG                   0x34
@@ -475,7 +479,7 @@ static int rcsi2_calc_mbps(struct rcar_csi2 *priv, unsigned int bpp)
 static int rcsi2_start_receiver(struct rcar_csi2 *priv)
 {
        const struct rcar_csi2_format *format;
-       u32 phycnt, vcdt = 0, vcdt2 = 0;
+       u32 phycnt, vcdt = 0, vcdt2 = 0, fld = 0;
        unsigned int i;
        int mbps, ret;
 
@@ -507,6 +511,16 @@ static int rcsi2_start_receiver(struct rcar_csi2 *priv)
                        vcdt2 |= vcdt_part << ((i % 2) * 16);
        }
 
+       if (priv->mf.field == V4L2_FIELD_ALTERNATE) {
+               fld = FLD_DET_SEL(1) | FLD_FLD_EN4 | FLD_FLD_EN3 | FLD_FLD_EN2
+                       | FLD_FLD_EN;
+
+               if (priv->mf.height == 240)
+                       fld |= FLD_FLD_NUM(0);
+               else
+                       fld |= FLD_FLD_NUM(1);
+       }
+
        phycnt = PHYCNT_ENABLECLK;
        phycnt |= (1 << priv->lanes) - 1;
 
@@ -514,6 +528,10 @@ static int rcsi2_start_receiver(struct rcar_csi2 *priv)
        if (mbps < 0)
                return mbps;
 
+       /* Enable interrupts. */
+       rcsi2_write(priv, INTEN_REG, INTEN_INT_AFIFO_OF | INTEN_INT_ERRSOTHS
+                   | INTEN_INT_ERRSOTSYNCHS);
+
        /* Init */
        rcsi2_write(priv, TREF_REG, TREF_TREF);
        rcsi2_write(priv, PHTC_REG, 0);
@@ -549,8 +567,7 @@ static int rcsi2_start_receiver(struct rcar_csi2 *priv)
        rcsi2_write(priv, PHYCNT_REG, phycnt);
        rcsi2_write(priv, LINKCNT_REG, LINKCNT_MONITOR_EN |
                    LINKCNT_REG_MONI_PACT_EN | LINKCNT_ICLK_NONSTOP);
-       rcsi2_write(priv, FLD_REG, FLD_FLD_NUM(2) | FLD_FLD_EN4 |
-                   FLD_FLD_EN3 | FLD_FLD_EN2 | FLD_FLD_EN);
+       rcsi2_write(priv, FLD_REG, fld);
        rcsi2_write(priv, PHYCNT_REG, phycnt | PHYCNT_SHUTDOWNZ);
        rcsi2_write(priv, PHYCNT_REG, phycnt | PHYCNT_SHUTDOWNZ | PHYCNT_RSTZ);
 
@@ -675,6 +692,43 @@ static const struct v4l2_subdev_ops rcar_csi2_subdev_ops = {
        .pad    = &rcar_csi2_pad_ops,
 };
 
+static irqreturn_t rcsi2_irq(int irq, void *data)
+{
+       struct rcar_csi2 *priv = data;
+       u32 status, err_status;
+
+       status = rcsi2_read(priv, INTSTATE_REG);
+       err_status = rcsi2_read(priv, INTERRSTATE_REG);
+
+       if (!status)
+               return IRQ_HANDLED;
+
+       rcsi2_write(priv, INTSTATE_REG, status);
+
+       if (!err_status)
+               return IRQ_HANDLED;
+
+       rcsi2_write(priv, INTERRSTATE_REG, err_status);
+
+       dev_info(priv->dev, "Transfer error, restarting CSI-2 receiver\n");
+
+       return IRQ_WAKE_THREAD;
+}
+
+static irqreturn_t rcsi2_irq_thread(int irq, void *data)
+{
+       struct rcar_csi2 *priv = data;
+
+       mutex_lock(&priv->lock);
+       rcsi2_stop(priv);
+       usleep_range(1000, 2000);
+       if (rcsi2_start(priv))
+               dev_warn(priv->dev, "Failed to restart CSI-2 receiver\n");
+       mutex_unlock(&priv->lock);
+
+       return IRQ_HANDLED;
+}
+
 /* -----------------------------------------------------------------------------
  * Async handling and registration of subdevices and links.
  */
@@ -947,7 +1001,7 @@ static int rcsi2_probe_resources(struct rcar_csi2 *priv,
                                 struct platform_device *pdev)
 {
        struct resource *res;
-       int irq;
+       int irq, ret;
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        priv->base = devm_ioremap_resource(&pdev->dev, res);
@@ -958,6 +1012,12 @@ static int rcsi2_probe_resources(struct rcar_csi2 *priv,
        if (irq < 0)
                return irq;
 
+       ret = devm_request_threaded_irq(&pdev->dev, irq, rcsi2_irq,
+                                       rcsi2_irq_thread, IRQF_SHARED,
+                                       KBUILD_MODNAME, priv);
+       if (ret)
+               return ret;
+
        priv->rstc = devm_reset_control_get(&pdev->dev, NULL);
        if (IS_ERR(priv->rstc))
                return PTR_ERR(priv->rstc);
index 7fb3a4fa07c1e7d674a4a39e414b51f40f5656e7..447bdfbe5afe190ca2e5ca67ce990a9291729e7a 100644 (file)
@@ -334,8 +334,8 @@ static int tegra_cec_probe(struct platform_device *pdev)
 
        hdmi_dev = cec_notifier_parse_hdmi_phandle(&pdev->dev);
 
-       if (!hdmi_dev)
-               return -ENODEV;
+       if (IS_ERR(hdmi_dev))
+               return PTR_ERR(hdmi_dev);
 
        cec = devm_kzalloc(&pdev->dev, sizeof(struct tegra_cec), GFP_KERNEL);
 
index 1ba4a5154fb5518e145f41ae579f42696067ae2e..64037b0a83877e15d2e6846e5abc662199335396 100644 (file)
@@ -1266,7 +1266,7 @@ static int prp_registered(struct v4l2_subdev *sd)
        if (ret)
                return ret;
 
-       ret = imx_media_capture_device_register(priv->vdev);
+       ret = imx_media_capture_device_register(priv->md, priv->vdev);
        if (ret)
                return ret;
 
index b7ce9d4392791ab3bea39a020644b6122bd11f41..9430c835c4349ddfe68ec5937ea250d6e2d6f121 100644 (file)
@@ -701,7 +701,8 @@ void imx_media_capture_device_error(struct imx_media_video_dev *vdev)
 }
 EXPORT_SYMBOL_GPL(imx_media_capture_device_error);
 
-int imx_media_capture_device_register(struct imx_media_video_dev *vdev)
+int imx_media_capture_device_register(struct imx_media_dev *md,
+                                     struct imx_media_video_dev *vdev)
 {
        struct capture_priv *priv = to_capture_priv(vdev);
        struct v4l2_subdev *sd = priv->src_sd;
@@ -710,8 +711,7 @@ int imx_media_capture_device_register(struct imx_media_video_dev *vdev)
        struct v4l2_subdev_format fmt_src;
        int ret;
 
-       /* get media device */
-       priv->md = dev_get_drvdata(sd->v4l2_dev->dev);
+       priv->md = md;
 
        vfd->v4l2_dev = sd->v4l2_dev;
 
index 28fe66052cc7486622d79ac91e5f859aa3fb0932..1d248aca40a9ec3795fcf27c70fb1fa81ce9a164 100644 (file)
@@ -1812,7 +1812,7 @@ static int csi_registered(struct v4l2_subdev *sd)
        if (ret)
                goto free_fim;
 
-       ret = imx_media_capture_device_register(priv->vdev);
+       ret = imx_media_capture_device_register(priv->md, priv->vdev);
        if (ret)
                goto free_fim;
 
index eb59ba0c3b62bfbc270142513ceb27cccd275adf..6587aa49e0051859b79076c515f9701a1876870d 100644 (file)
@@ -268,7 +268,8 @@ int imx_media_of_add_csi(struct imx_media_dev *imxmd,
 struct imx_media_video_dev *
 imx_media_capture_device_init(struct v4l2_subdev *src_sd, int pad);
 void imx_media_capture_device_remove(struct imx_media_video_dev *vdev);
-int imx_media_capture_device_register(struct imx_media_video_dev *vdev);
+int imx_media_capture_device_register(struct imx_media_dev *md,
+                                     struct imx_media_video_dev *vdev);
 void imx_media_capture_device_unregister(struct imx_media_video_dev *vdev);
 struct imx_media_buffer *
 imx_media_capture_device_next_buf(struct imx_media_video_dev *vdev);
index 18eb5d3ecf102ad5bca3f84379f1c290d2929a92..a708a0340eb18a0a0d5931870b946e13ba78181a 100644 (file)
@@ -1126,7 +1126,7 @@ static int imx7_csi_registered(struct v4l2_subdev *sd)
        if (ret < 0)
                return ret;
 
-       ret = imx_media_capture_device_register(csi->vdev);
+       ret = imx_media_capture_device_register(csi->imxmd, csi->vdev);
        if (ret < 0)
                return ret;
 
index 58721c46fba4184ea03ce95da4c574704b984f68..8bbc905b26c83d7b41c8159ad898f46bfeaa6b76 100644 (file)
@@ -352,7 +352,7 @@ static int rockchip_vpu_video_device_register(struct rockchip_vpu_dev *vpu)
        vpu->vfd_enc = vfd;
        video_set_drvdata(vfd, vpu);
 
-       ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0);
+       ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1);
        if (ret) {
                v4l2_err(&vpu->v4l2_dev, "Failed to register video device\n");
                goto err_free_dev;
@@ -463,6 +463,8 @@ static int rockchip_vpu_probe(struct platform_device *pdev)
 
        vpu->mdev.dev = vpu->dev;
        strscpy(vpu->mdev.model, DRIVER_NAME, sizeof(vpu->mdev.model));
+       strscpy(vpu->mdev.bus_info, "platform: " DRIVER_NAME,
+               sizeof(vpu->mdev.model));
        media_device_init(&vpu->mdev);
        vpu->v4l2_dev.mdev = &vpu->mdev;
 
@@ -480,15 +482,18 @@ static int rockchip_vpu_probe(struct platform_device *pdev)
        return 0;
 err_video_dev_unreg:
        if (vpu->vfd_enc) {
+               v4l2_m2m_unregister_media_controller(vpu->m2m_dev);
                video_unregister_device(vpu->vfd_enc);
                video_device_release(vpu->vfd_enc);
        }
 err_m2m_rel:
+       media_device_cleanup(&vpu->mdev);
        v4l2_m2m_release(vpu->m2m_dev);
 err_v4l2_unreg:
        v4l2_device_unregister(&vpu->v4l2_dev);
 err_clk_unprepare:
        clk_bulk_unprepare(vpu->variant->num_clocks, vpu->clocks);
+       pm_runtime_dont_use_autosuspend(vpu->dev);
        pm_runtime_disable(vpu->dev);
        return ret;
 }
@@ -500,15 +505,16 @@ static int rockchip_vpu_remove(struct platform_device *pdev)
        v4l2_info(&vpu->v4l2_dev, "Removing %s\n", pdev->name);
 
        media_device_unregister(&vpu->mdev);
-       v4l2_m2m_unregister_media_controller(vpu->m2m_dev);
-       v4l2_m2m_release(vpu->m2m_dev);
-       media_device_cleanup(&vpu->mdev);
        if (vpu->vfd_enc) {
+               v4l2_m2m_unregister_media_controller(vpu->m2m_dev);
                video_unregister_device(vpu->vfd_enc);
                video_device_release(vpu->vfd_enc);
        }
+       media_device_cleanup(&vpu->mdev);
+       v4l2_m2m_release(vpu->m2m_dev);
        v4l2_device_unregister(&vpu->v4l2_dev);
        clk_bulk_unprepare(vpu->variant->num_clocks, vpu->clocks);
+       pm_runtime_dont_use_autosuspend(vpu->dev);
        pm_runtime_disable(vpu->dev);
        return 0;
 }
index fb5e36aedd8c5e58feda0b675eba83e038e309b3..dcbfc3cbc9f31539b26f0f10ad577fca3224c0be 100644 (file)
@@ -152,9 +152,10 @@ static int vidioc_querycap(struct file *file, void *priv,
                           struct v4l2_capability *cap)
 {
        struct rockchip_vpu_dev *vpu = video_drvdata(file);
+       struct video_device *vdev = video_devdata(file);
 
        strscpy(cap->driver, vpu->dev->driver->name, sizeof(cap->driver));
-       strscpy(cap->card, vpu->vfd_enc->name, sizeof(cap->card));
+       strscpy(cap->card, vdev->name, sizeof(cap->card));
        snprintf(cap->bus_info, sizeof(cap->bus_info), "platform: %s",
                 vpu->dev->driver->name);
        return 0;
index 5c31a768249201d48459e6f603d9a00df5e8cf14..f76d2f25a82474f1ab80eb7dd7004b94f288900d 100644 (file)
@@ -92,7 +92,7 @@ struct vpbe_config {
        struct encoder_config_info *ext_encoders;
        /* amplifier information goes here */
        struct amp_config_info *amp;
-       int num_outputs;
+       unsigned int num_outputs;
        /* Order is venc outputs followed by LCD and then external encoders */
        struct vpbe_output *outputs;
 };