diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-05-16 14:57:16 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-05-16 14:57:16 -0400 |
| commit | 01be377c62210a8d8fef35be906f9349591bb7cd (patch) | |
| tree | 98ac365ebad6412217468a9475c109cd6d364cf6 | |
| parent | 11b1177399b69528f75ad7594ce93c957d4d16b6 (diff) | |
| parent | fc8670d1f72b746ff3a5fe441f1fca4c4dba0e6f (diff) | |
Merge tag 'media/v5.2-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media
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
| -rw-r--r-- | Documentation/media/uapi/v4l/field-order.rst | 16 | ||||
| -rw-r--r-- | drivers/media/platform/atmel/atmel-isc-regs.h | 19 | ||||
| -rw-r--r-- | drivers/media/platform/atmel/atmel-isc.c | 46 | ||||
| -rw-r--r-- | drivers/media/platform/coda/coda-common.c | 10 | ||||
| -rw-r--r-- | drivers/media/platform/davinci/vpbe.c | 2 | ||||
| -rw-r--r-- | drivers/media/platform/omap/omap_vout.c | 15 | ||||
| -rw-r--r-- | drivers/media/platform/rcar-vin/rcar-csi2.c | 68 | ||||
| -rw-r--r-- | drivers/media/platform/tegra-cec/tegra_cec.c | 4 | ||||
| -rw-r--r-- | drivers/staging/media/imx/imx-ic-prpencvf.c | 2 | ||||
| -rw-r--r-- | drivers/staging/media/imx/imx-media-capture.c | 6 | ||||
| -rw-r--r-- | drivers/staging/media/imx/imx-media-csi.c | 2 | ||||
| -rw-r--r-- | drivers/staging/media/imx/imx-media.h | 3 | ||||
| -rw-r--r-- | drivers/staging/media/imx/imx7-media-csi.c | 2 | ||||
| -rw-r--r-- | drivers/staging/media/rockchip/vpu/rockchip_vpu_drv.c | 14 | ||||
| -rw-r--r-- | drivers/staging/media/rockchip/vpu/rockchip_vpu_enc.c | 3 | ||||
| -rw-r--r-- | include/media/davinci/vpbe.h | 2 |
16 files changed, 172 insertions, 42 deletions
diff --git a/Documentation/media/uapi/v4l/field-order.rst b/Documentation/media/uapi/v4l/field-order.rst index 3fb473e3b8e2..d640e922a974 100644 --- a/Documentation/media/uapi/v4l/field-order.rst +++ b/Documentation/media/uapi/v4l/field-order.rst | |||
| @@ -75,12 +75,11 @@ enum v4l2_field | |||
| 75 | 75 | ||
| 76 | * - ``V4L2_FIELD_ANY`` | 76 | * - ``V4L2_FIELD_ANY`` |
| 77 | - 0 | 77 | - 0 |
| 78 | - Applications request this field order when any one of the | 78 | - Applications request this field order when any field format |
| 79 | ``V4L2_FIELD_NONE``, ``V4L2_FIELD_TOP``, ``V4L2_FIELD_BOTTOM``, or | 79 | is acceptable. Drivers choose depending on hardware capabilities or |
| 80 | ``V4L2_FIELD_INTERLACED`` formats is acceptable. Drivers choose | 80 | e.g. the requested image size, and return the actual field order. |
| 81 | depending on hardware capabilities or e. g. the requested image | 81 | Drivers must never return ``V4L2_FIELD_ANY``. |
| 82 | size, and return the actual field order. Drivers must never return | 82 | If multiple field orders are possible the |
| 83 | ``V4L2_FIELD_ANY``. If multiple field orders are possible the | ||
| 84 | driver must choose one of the possible field orders during | 83 | driver must choose one of the possible field orders during |
| 85 | :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` or | 84 | :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` or |
| 86 | :ref:`VIDIOC_TRY_FMT <VIDIOC_G_FMT>`. struct | 85 | :ref:`VIDIOC_TRY_FMT <VIDIOC_G_FMT>`. struct |
| @@ -88,9 +87,8 @@ enum v4l2_field | |||
| 88 | ``V4L2_FIELD_ANY``. | 87 | ``V4L2_FIELD_ANY``. |
| 89 | * - ``V4L2_FIELD_NONE`` | 88 | * - ``V4L2_FIELD_NONE`` |
| 90 | - 1 | 89 | - 1 |
| 91 | - Images are in progressive format, not interlaced. The driver may | 90 | - Images are in progressive (frame-based) format, not interlaced |
| 92 | also indicate this order when it cannot distinguish between | 91 | (field-based). |
| 93 | ``V4L2_FIELD_TOP`` and ``V4L2_FIELD_BOTTOM``. | ||
| 94 | * - ``V4L2_FIELD_TOP`` | 92 | * - ``V4L2_FIELD_TOP`` |
| 95 | - 2 | 93 | - 2 |
| 96 | - Images consist of the top (aka odd) field only. | 94 | - Images consist of the top (aka odd) field only. |
diff --git a/drivers/media/platform/atmel/atmel-isc-regs.h b/drivers/media/platform/atmel/atmel-isc-regs.h index d730693f299c..8f7f8efc71a7 100644 --- a/drivers/media/platform/atmel/atmel-isc-regs.h +++ b/drivers/media/platform/atmel/atmel-isc-regs.h | |||
| @@ -37,6 +37,25 @@ | |||
| 37 | #define ISC_PFG_CFG0_BPS_TWELVE (0x0 << 28) | 37 | #define ISC_PFG_CFG0_BPS_TWELVE (0x0 << 28) |
| 38 | #define ISC_PFE_CFG0_BPS_MASK GENMASK(30, 28) | 38 | #define ISC_PFE_CFG0_BPS_MASK GENMASK(30, 28) |
| 39 | 39 | ||
| 40 | #define ISC_PFE_CFG0_COLEN BIT(12) | ||
| 41 | #define ISC_PFE_CFG0_ROWEN BIT(13) | ||
| 42 | |||
| 43 | /* ISC Parallel Front End Configuration 1 Register */ | ||
| 44 | #define ISC_PFE_CFG1 0x00000010 | ||
| 45 | |||
| 46 | #define ISC_PFE_CFG1_COLMIN(v) ((v)) | ||
| 47 | #define ISC_PFE_CFG1_COLMIN_MASK GENMASK(15, 0) | ||
| 48 | #define ISC_PFE_CFG1_COLMAX(v) ((v) << 16) | ||
| 49 | #define ISC_PFE_CFG1_COLMAX_MASK GENMASK(31, 16) | ||
| 50 | |||
| 51 | /* ISC Parallel Front End Configuration 2 Register */ | ||
| 52 | #define ISC_PFE_CFG2 0x00000014 | ||
| 53 | |||
| 54 | #define ISC_PFE_CFG2_ROWMIN(v) ((v)) | ||
| 55 | #define ISC_PFE_CFG2_ROWMIN_MASK GENMASK(15, 0) | ||
| 56 | #define ISC_PFE_CFG2_ROWMAX(v) ((v) << 16) | ||
| 57 | #define ISC_PFE_CFG2_ROWMAX_MASK GENMASK(31, 16) | ||
| 58 | |||
| 40 | /* ISC Clock Enable Register */ | 59 | /* ISC Clock Enable Register */ |
| 41 | #define ISC_CLKEN 0x00000018 | 60 | #define ISC_CLKEN 0x00000018 |
| 42 | 61 | ||
diff --git a/drivers/media/platform/atmel/atmel-isc.c b/drivers/media/platform/atmel/atmel-isc.c index 4bba9da206e4..94cb309fdb52 100644 --- a/drivers/media/platform/atmel/atmel-isc.c +++ b/drivers/media/platform/atmel/atmel-isc.c | |||
| @@ -721,6 +721,40 @@ static void isc_start_dma(struct isc_device *isc) | |||
| 721 | u32 sizeimage = isc->fmt.fmt.pix.sizeimage; | 721 | u32 sizeimage = isc->fmt.fmt.pix.sizeimage; |
| 722 | u32 dctrl_dview; | 722 | u32 dctrl_dview; |
| 723 | dma_addr_t addr0; | 723 | dma_addr_t addr0; |
| 724 | u32 h, w; | ||
| 725 | |||
| 726 | h = isc->fmt.fmt.pix.height; | ||
| 727 | w = isc->fmt.fmt.pix.width; | ||
| 728 | |||
| 729 | /* | ||
| 730 | * In case the sensor is not RAW, it will output a pixel (12-16 bits) | ||
| 731 | * with two samples on the ISC Data bus (which is 8-12) | ||
| 732 | * ISC will count each sample, so, we need to multiply these values | ||
| 733 | * by two, to get the real number of samples for the required pixels. | ||
| 734 | */ | ||
| 735 | if (!ISC_IS_FORMAT_RAW(isc->config.sd_format->mbus_code)) { | ||
| 736 | h <<= 1; | ||
| 737 | w <<= 1; | ||
| 738 | } | ||
| 739 | |||
| 740 | /* | ||
| 741 | * We limit the column/row count that the ISC will output according | ||
| 742 | * to the configured resolution that we want. | ||
| 743 | * This will avoid the situation where the sensor is misconfigured, | ||
| 744 | * sending more data, and the ISC will just take it and DMA to memory, | ||
| 745 | * causing corruption. | ||
| 746 | */ | ||
| 747 | regmap_write(regmap, ISC_PFE_CFG1, | ||
| 748 | (ISC_PFE_CFG1_COLMIN(0) & ISC_PFE_CFG1_COLMIN_MASK) | | ||
| 749 | (ISC_PFE_CFG1_COLMAX(w - 1) & ISC_PFE_CFG1_COLMAX_MASK)); | ||
| 750 | |||
| 751 | regmap_write(regmap, ISC_PFE_CFG2, | ||
| 752 | (ISC_PFE_CFG2_ROWMIN(0) & ISC_PFE_CFG2_ROWMIN_MASK) | | ||
| 753 | (ISC_PFE_CFG2_ROWMAX(h - 1) & ISC_PFE_CFG2_ROWMAX_MASK)); | ||
| 754 | |||
| 755 | regmap_update_bits(regmap, ISC_PFE_CFG0, | ||
| 756 | ISC_PFE_CFG0_COLEN | ISC_PFE_CFG0_ROWEN, | ||
| 757 | ISC_PFE_CFG0_COLEN | ISC_PFE_CFG0_ROWEN); | ||
| 724 | 758 | ||
| 725 | addr0 = vb2_dma_contig_plane_dma_addr(&isc->cur_frm->vb.vb2_buf, 0); | 759 | addr0 = vb2_dma_contig_plane_dma_addr(&isc->cur_frm->vb.vb2_buf, 0); |
| 726 | regmap_write(regmap, ISC_DAD0, addr0); | 760 | regmap_write(regmap, ISC_DAD0, addr0); |
| @@ -1965,6 +1999,8 @@ static int isc_async_complete(struct v4l2_async_notifier *notifier) | |||
| 1965 | struct vb2_queue *q = &isc->vb2_vidq; | 1999 | struct vb2_queue *q = &isc->vb2_vidq; |
| 1966 | int ret; | 2000 | int ret; |
| 1967 | 2001 | ||
| 2002 | INIT_WORK(&isc->awb_work, isc_awb_work); | ||
| 2003 | |||
| 1968 | ret = v4l2_device_register_subdev_nodes(&isc->v4l2_dev); | 2004 | ret = v4l2_device_register_subdev_nodes(&isc->v4l2_dev); |
| 1969 | if (ret < 0) { | 2005 | if (ret < 0) { |
| 1970 | v4l2_err(&isc->v4l2_dev, "Failed to register subdev nodes\n"); | 2006 | 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) | |||
| 2018 | return ret; | 2054 | return ret; |
| 2019 | } | 2055 | } |
| 2020 | 2056 | ||
| 2021 | INIT_WORK(&isc->awb_work, isc_awb_work); | ||
| 2022 | |||
| 2023 | /* Register video device */ | 2057 | /* Register video device */ |
| 2024 | strscpy(vdev->name, ATMEL_ISC_NAME, sizeof(vdev->name)); | 2058 | strscpy(vdev->name, ATMEL_ISC_NAME, sizeof(vdev->name)); |
| 2025 | vdev->release = video_device_release_empty; | 2059 | vdev->release = video_device_release_empty; |
| @@ -2135,8 +2169,11 @@ static int isc_parse_dt(struct device *dev, struct isc_device *isc) | |||
| 2135 | break; | 2169 | break; |
| 2136 | } | 2170 | } |
| 2137 | 2171 | ||
| 2138 | subdev_entity->asd = devm_kzalloc(dev, | 2172 | /* asd will be freed by the subsystem once it's added to the |
| 2139 | sizeof(*subdev_entity->asd), GFP_KERNEL); | 2173 | * notifier list |
| 2174 | */ | ||
| 2175 | subdev_entity->asd = kzalloc(sizeof(*subdev_entity->asd), | ||
| 2176 | GFP_KERNEL); | ||
| 2140 | if (!subdev_entity->asd) { | 2177 | if (!subdev_entity->asd) { |
| 2141 | of_node_put(rem); | 2178 | of_node_put(rem); |
| 2142 | ret = -ENOMEM; | 2179 | ret = -ENOMEM; |
| @@ -2284,6 +2321,7 @@ static int atmel_isc_probe(struct platform_device *pdev) | |||
| 2284 | subdev_entity->asd); | 2321 | subdev_entity->asd); |
| 2285 | if (ret) { | 2322 | if (ret) { |
| 2286 | fwnode_handle_put(subdev_entity->asd->match.fwnode); | 2323 | fwnode_handle_put(subdev_entity->asd->match.fwnode); |
| 2324 | kfree(subdev_entity->asd); | ||
| 2287 | goto cleanup_subdev; | 2325 | goto cleanup_subdev; |
| 2288 | } | 2326 | } |
| 2289 | 2327 | ||
diff --git a/drivers/media/platform/coda/coda-common.c b/drivers/media/platform/coda/coda-common.c index 3ce58dee4422..1d96cca61547 100644 --- a/drivers/media/platform/coda/coda-common.c +++ b/drivers/media/platform/coda/coda-common.c | |||
| @@ -1515,10 +1515,20 @@ static int coda_queue_setup(struct vb2_queue *vq, | |||
| 1515 | 1515 | ||
| 1516 | static int coda_buf_prepare(struct vb2_buffer *vb) | 1516 | static int coda_buf_prepare(struct vb2_buffer *vb) |
| 1517 | { | 1517 | { |
| 1518 | struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); | ||
| 1518 | struct coda_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); | 1519 | struct coda_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); |
| 1519 | struct coda_q_data *q_data; | 1520 | struct coda_q_data *q_data; |
| 1520 | 1521 | ||
| 1521 | q_data = get_q_data(ctx, vb->vb2_queue->type); | 1522 | q_data = get_q_data(ctx, vb->vb2_queue->type); |
| 1523 | if (V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) { | ||
| 1524 | if (vbuf->field == V4L2_FIELD_ANY) | ||
| 1525 | vbuf->field = V4L2_FIELD_NONE; | ||
| 1526 | if (vbuf->field != V4L2_FIELD_NONE) { | ||
| 1527 | v4l2_warn(&ctx->dev->v4l2_dev, | ||
| 1528 | "%s field isn't supported\n", __func__); | ||
| 1529 | return -EINVAL; | ||
| 1530 | } | ||
| 1531 | } | ||
| 1522 | 1532 | ||
| 1523 | if (vb2_plane_size(vb, 0) < q_data->sizeimage) { | 1533 | if (vb2_plane_size(vb, 0) < q_data->sizeimage) { |
| 1524 | v4l2_warn(&ctx->dev->v4l2_dev, | 1534 | v4l2_warn(&ctx->dev->v4l2_dev, |
diff --git a/drivers/media/platform/davinci/vpbe.c b/drivers/media/platform/davinci/vpbe.c index 8339163a5231..4e24f5d781f4 100644 --- a/drivers/media/platform/davinci/vpbe.c +++ b/drivers/media/platform/davinci/vpbe.c | |||
| @@ -104,7 +104,7 @@ static int vpbe_enum_outputs(struct vpbe_device *vpbe_dev, | |||
| 104 | struct v4l2_output *output) | 104 | struct v4l2_output *output) |
| 105 | { | 105 | { |
| 106 | struct vpbe_config *cfg = vpbe_dev->cfg; | 106 | struct vpbe_config *cfg = vpbe_dev->cfg; |
| 107 | int temp_index = output->index; | 107 | unsigned int temp_index = output->index; |
| 108 | 108 | ||
| 109 | if (temp_index >= cfg->num_outputs) | 109 | if (temp_index >= cfg->num_outputs) |
| 110 | return -EINVAL; | 110 | return -EINVAL; |
diff --git a/drivers/media/platform/omap/omap_vout.c b/drivers/media/platform/omap/omap_vout.c index 37f0d7146dfa..cb6a9e3946b6 100644 --- a/drivers/media/platform/omap/omap_vout.c +++ b/drivers/media/platform/omap/omap_vout.c | |||
| @@ -1527,23 +1527,20 @@ static int vidioc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b) | |||
| 1527 | unsigned long size; | 1527 | unsigned long size; |
| 1528 | struct videobuf_buffer *vb; | 1528 | struct videobuf_buffer *vb; |
| 1529 | 1529 | ||
| 1530 | vb = q->bufs[b->index]; | ||
| 1531 | |||
| 1532 | if (!vout->streaming) | 1530 | if (!vout->streaming) |
| 1533 | return -EINVAL; | 1531 | return -EINVAL; |
| 1534 | 1532 | ||
| 1535 | if (file->f_flags & O_NONBLOCK) | 1533 | ret = videobuf_dqbuf(q, b, !!(file->f_flags & O_NONBLOCK)); |
| 1536 | /* Call videobuf_dqbuf for non blocking mode */ | 1534 | if (ret) |
| 1537 | ret = videobuf_dqbuf(q, (struct v4l2_buffer *)b, 1); | 1535 | return ret; |
| 1538 | else | 1536 | |
| 1539 | /* Call videobuf_dqbuf for blocking mode */ | 1537 | vb = q->bufs[b->index]; |
| 1540 | ret = videobuf_dqbuf(q, (struct v4l2_buffer *)b, 0); | ||
| 1541 | 1538 | ||
| 1542 | addr = (unsigned long) vout->buf_phy_addr[vb->i]; | 1539 | addr = (unsigned long) vout->buf_phy_addr[vb->i]; |
| 1543 | size = (unsigned long) vb->size; | 1540 | size = (unsigned long) vb->size; |
| 1544 | dma_unmap_single(vout->vid_dev->v4l2_dev.dev, addr, | 1541 | dma_unmap_single(vout->vid_dev->v4l2_dev.dev, addr, |
| 1545 | size, DMA_TO_DEVICE); | 1542 | size, DMA_TO_DEVICE); |
| 1546 | return ret; | 1543 | return 0; |
| 1547 | } | 1544 | } |
| 1548 | 1545 | ||
| 1549 | static int vidioc_streamon(struct file *file, void *fh, enum v4l2_buf_type i) | 1546 | static int vidioc_streamon(struct file *file, void *fh, enum v4l2_buf_type i) |
diff --git a/drivers/media/platform/rcar-vin/rcar-csi2.c b/drivers/media/platform/rcar-vin/rcar-csi2.c index 799e526fd3df..8f097e514900 100644 --- a/drivers/media/platform/rcar-vin/rcar-csi2.c +++ b/drivers/media/platform/rcar-vin/rcar-csi2.c | |||
| @@ -68,6 +68,7 @@ struct rcar_csi2; | |||
| 68 | /* Field Detection Control */ | 68 | /* Field Detection Control */ |
| 69 | #define FLD_REG 0x1c | 69 | #define FLD_REG 0x1c |
| 70 | #define FLD_FLD_NUM(n) (((n) & 0xff) << 16) | 70 | #define FLD_FLD_NUM(n) (((n) & 0xff) << 16) |
| 71 | #define FLD_DET_SEL(n) (((n) & 0x3) << 4) | ||
| 71 | #define FLD_FLD_EN4 BIT(3) | 72 | #define FLD_FLD_EN4 BIT(3) |
| 72 | #define FLD_FLD_EN3 BIT(2) | 73 | #define FLD_FLD_EN3 BIT(2) |
| 73 | #define FLD_FLD_EN2 BIT(1) | 74 | #define FLD_FLD_EN2 BIT(1) |
| @@ -84,6 +85,9 @@ struct rcar_csi2; | |||
| 84 | 85 | ||
| 85 | /* Interrupt Enable */ | 86 | /* Interrupt Enable */ |
| 86 | #define INTEN_REG 0x30 | 87 | #define INTEN_REG 0x30 |
| 88 | #define INTEN_INT_AFIFO_OF BIT(27) | ||
| 89 | #define INTEN_INT_ERRSOTHS BIT(4) | ||
| 90 | #define INTEN_INT_ERRSOTSYNCHS BIT(3) | ||
| 87 | 91 | ||
| 88 | /* Interrupt Source Mask */ | 92 | /* Interrupt Source Mask */ |
| 89 | #define INTCLOSE_REG 0x34 | 93 | #define INTCLOSE_REG 0x34 |
| @@ -475,7 +479,7 @@ static int rcsi2_calc_mbps(struct rcar_csi2 *priv, unsigned int bpp) | |||
| 475 | static int rcsi2_start_receiver(struct rcar_csi2 *priv) | 479 | static int rcsi2_start_receiver(struct rcar_csi2 *priv) |
| 476 | { | 480 | { |
| 477 | const struct rcar_csi2_format *format; | 481 | const struct rcar_csi2_format *format; |
| 478 | u32 phycnt, vcdt = 0, vcdt2 = 0; | 482 | u32 phycnt, vcdt = 0, vcdt2 = 0, fld = 0; |
| 479 | unsigned int i; | 483 | unsigned int i; |
| 480 | int mbps, ret; | 484 | int mbps, ret; |
| 481 | 485 | ||
| @@ -507,6 +511,16 @@ static int rcsi2_start_receiver(struct rcar_csi2 *priv) | |||
| 507 | vcdt2 |= vcdt_part << ((i % 2) * 16); | 511 | vcdt2 |= vcdt_part << ((i % 2) * 16); |
| 508 | } | 512 | } |
| 509 | 513 | ||
| 514 | if (priv->mf.field == V4L2_FIELD_ALTERNATE) { | ||
| 515 | fld = FLD_DET_SEL(1) | FLD_FLD_EN4 | FLD_FLD_EN3 | FLD_FLD_EN2 | ||
| 516 | | FLD_FLD_EN; | ||
| 517 | |||
| 518 | if (priv->mf.height == 240) | ||
| 519 | fld |= FLD_FLD_NUM(0); | ||
| 520 | else | ||
| 521 | fld |= FLD_FLD_NUM(1); | ||
| 522 | } | ||
| 523 | |||
| 510 | phycnt = PHYCNT_ENABLECLK; | 524 | phycnt = PHYCNT_ENABLECLK; |
| 511 | phycnt |= (1 << priv->lanes) - 1; | 525 | phycnt |= (1 << priv->lanes) - 1; |
| 512 | 526 | ||
| @@ -514,6 +528,10 @@ static int rcsi2_start_receiver(struct rcar_csi2 *priv) | |||
| 514 | if (mbps < 0) | 528 | if (mbps < 0) |
| 515 | return mbps; | 529 | return mbps; |
| 516 | 530 | ||
| 531 | /* Enable interrupts. */ | ||
| 532 | rcsi2_write(priv, INTEN_REG, INTEN_INT_AFIFO_OF | INTEN_INT_ERRSOTHS | ||
| 533 | | INTEN_INT_ERRSOTSYNCHS); | ||
| 534 | |||
| 517 | /* Init */ | 535 | /* Init */ |
| 518 | rcsi2_write(priv, TREF_REG, TREF_TREF); | 536 | rcsi2_write(priv, TREF_REG, TREF_TREF); |
| 519 | rcsi2_write(priv, PHTC_REG, 0); | 537 | rcsi2_write(priv, PHTC_REG, 0); |
| @@ -549,8 +567,7 @@ static int rcsi2_start_receiver(struct rcar_csi2 *priv) | |||
| 549 | rcsi2_write(priv, PHYCNT_REG, phycnt); | 567 | rcsi2_write(priv, PHYCNT_REG, phycnt); |
| 550 | rcsi2_write(priv, LINKCNT_REG, LINKCNT_MONITOR_EN | | 568 | rcsi2_write(priv, LINKCNT_REG, LINKCNT_MONITOR_EN | |
| 551 | LINKCNT_REG_MONI_PACT_EN | LINKCNT_ICLK_NONSTOP); | 569 | LINKCNT_REG_MONI_PACT_EN | LINKCNT_ICLK_NONSTOP); |
| 552 | rcsi2_write(priv, FLD_REG, FLD_FLD_NUM(2) | FLD_FLD_EN4 | | 570 | rcsi2_write(priv, FLD_REG, fld); |
| 553 | FLD_FLD_EN3 | FLD_FLD_EN2 | FLD_FLD_EN); | ||
| 554 | rcsi2_write(priv, PHYCNT_REG, phycnt | PHYCNT_SHUTDOWNZ); | 571 | rcsi2_write(priv, PHYCNT_REG, phycnt | PHYCNT_SHUTDOWNZ); |
| 555 | rcsi2_write(priv, PHYCNT_REG, phycnt | PHYCNT_SHUTDOWNZ | PHYCNT_RSTZ); | 572 | rcsi2_write(priv, PHYCNT_REG, phycnt | PHYCNT_SHUTDOWNZ | PHYCNT_RSTZ); |
| 556 | 573 | ||
| @@ -675,6 +692,43 @@ static const struct v4l2_subdev_ops rcar_csi2_subdev_ops = { | |||
| 675 | .pad = &rcar_csi2_pad_ops, | 692 | .pad = &rcar_csi2_pad_ops, |
| 676 | }; | 693 | }; |
| 677 | 694 | ||
| 695 | static irqreturn_t rcsi2_irq(int irq, void *data) | ||
| 696 | { | ||
| 697 | struct rcar_csi2 *priv = data; | ||
| 698 | u32 status, err_status; | ||
| 699 | |||
| 700 | status = rcsi2_read(priv, INTSTATE_REG); | ||
| 701 | err_status = rcsi2_read(priv, INTERRSTATE_REG); | ||
| 702 | |||
| 703 | if (!status) | ||
| 704 | return IRQ_HANDLED; | ||
| 705 | |||
| 706 | rcsi2_write(priv, INTSTATE_REG, status); | ||
| 707 | |||
| 708 | if (!err_status) | ||
| 709 | return IRQ_HANDLED; | ||
| 710 | |||
| 711 | rcsi2_write(priv, INTERRSTATE_REG, err_status); | ||
| 712 | |||
| 713 | dev_info(priv->dev, "Transfer error, restarting CSI-2 receiver\n"); | ||
| 714 | |||
| 715 | return IRQ_WAKE_THREAD; | ||
| 716 | } | ||
| 717 | |||
| 718 | static irqreturn_t rcsi2_irq_thread(int irq, void *data) | ||
| 719 | { | ||
| 720 | struct rcar_csi2 *priv = data; | ||
| 721 | |||
| 722 | mutex_lock(&priv->lock); | ||
| 723 | rcsi2_stop(priv); | ||
| 724 | usleep_range(1000, 2000); | ||
| 725 | if (rcsi2_start(priv)) | ||
| 726 | dev_warn(priv->dev, "Failed to restart CSI-2 receiver\n"); | ||
| 727 | mutex_unlock(&priv->lock); | ||
| 728 | |||
| 729 | return IRQ_HANDLED; | ||
| 730 | } | ||
| 731 | |||
| 678 | /* ----------------------------------------------------------------------------- | 732 | /* ----------------------------------------------------------------------------- |
| 679 | * Async handling and registration of subdevices and links. | 733 | * Async handling and registration of subdevices and links. |
| 680 | */ | 734 | */ |
| @@ -947,7 +1001,7 @@ static int rcsi2_probe_resources(struct rcar_csi2 *priv, | |||
| 947 | struct platform_device *pdev) | 1001 | struct platform_device *pdev) |
| 948 | { | 1002 | { |
| 949 | struct resource *res; | 1003 | struct resource *res; |
| 950 | int irq; | 1004 | int irq, ret; |
| 951 | 1005 | ||
| 952 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1006 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 953 | priv->base = devm_ioremap_resource(&pdev->dev, res); | 1007 | priv->base = devm_ioremap_resource(&pdev->dev, res); |
| @@ -958,6 +1012,12 @@ static int rcsi2_probe_resources(struct rcar_csi2 *priv, | |||
| 958 | if (irq < 0) | 1012 | if (irq < 0) |
| 959 | return irq; | 1013 | return irq; |
| 960 | 1014 | ||
| 1015 | ret = devm_request_threaded_irq(&pdev->dev, irq, rcsi2_irq, | ||
| 1016 | rcsi2_irq_thread, IRQF_SHARED, | ||
| 1017 | KBUILD_MODNAME, priv); | ||
| 1018 | if (ret) | ||
| 1019 | return ret; | ||
| 1020 | |||
| 961 | priv->rstc = devm_reset_control_get(&pdev->dev, NULL); | 1021 | priv->rstc = devm_reset_control_get(&pdev->dev, NULL); |
| 962 | if (IS_ERR(priv->rstc)) | 1022 | if (IS_ERR(priv->rstc)) |
| 963 | return PTR_ERR(priv->rstc); | 1023 | return PTR_ERR(priv->rstc); |
diff --git a/drivers/media/platform/tegra-cec/tegra_cec.c b/drivers/media/platform/tegra-cec/tegra_cec.c index 7fb3a4fa07c1..447bdfbe5afe 100644 --- a/drivers/media/platform/tegra-cec/tegra_cec.c +++ b/drivers/media/platform/tegra-cec/tegra_cec.c | |||
| @@ -334,8 +334,8 @@ static int tegra_cec_probe(struct platform_device *pdev) | |||
| 334 | 334 | ||
| 335 | hdmi_dev = cec_notifier_parse_hdmi_phandle(&pdev->dev); | 335 | hdmi_dev = cec_notifier_parse_hdmi_phandle(&pdev->dev); |
| 336 | 336 | ||
| 337 | if (!hdmi_dev) | 337 | if (IS_ERR(hdmi_dev)) |
| 338 | return -ENODEV; | 338 | return PTR_ERR(hdmi_dev); |
| 339 | 339 | ||
| 340 | cec = devm_kzalloc(&pdev->dev, sizeof(struct tegra_cec), GFP_KERNEL); | 340 | cec = devm_kzalloc(&pdev->dev, sizeof(struct tegra_cec), GFP_KERNEL); |
| 341 | 341 | ||
diff --git a/drivers/staging/media/imx/imx-ic-prpencvf.c b/drivers/staging/media/imx/imx-ic-prpencvf.c index 1ba4a5154fb5..64037b0a8387 100644 --- a/drivers/staging/media/imx/imx-ic-prpencvf.c +++ b/drivers/staging/media/imx/imx-ic-prpencvf.c | |||
| @@ -1266,7 +1266,7 @@ static int prp_registered(struct v4l2_subdev *sd) | |||
| 1266 | if (ret) | 1266 | if (ret) |
| 1267 | return ret; | 1267 | return ret; |
| 1268 | 1268 | ||
| 1269 | ret = imx_media_capture_device_register(priv->vdev); | 1269 | ret = imx_media_capture_device_register(priv->md, priv->vdev); |
| 1270 | if (ret) | 1270 | if (ret) |
| 1271 | return ret; | 1271 | return ret; |
| 1272 | 1272 | ||
diff --git a/drivers/staging/media/imx/imx-media-capture.c b/drivers/staging/media/imx/imx-media-capture.c index b7ce9d439279..9430c835c434 100644 --- a/drivers/staging/media/imx/imx-media-capture.c +++ b/drivers/staging/media/imx/imx-media-capture.c | |||
| @@ -701,7 +701,8 @@ void imx_media_capture_device_error(struct imx_media_video_dev *vdev) | |||
| 701 | } | 701 | } |
| 702 | EXPORT_SYMBOL_GPL(imx_media_capture_device_error); | 702 | EXPORT_SYMBOL_GPL(imx_media_capture_device_error); |
| 703 | 703 | ||
| 704 | int imx_media_capture_device_register(struct imx_media_video_dev *vdev) | 704 | int imx_media_capture_device_register(struct imx_media_dev *md, |
| 705 | struct imx_media_video_dev *vdev) | ||
| 705 | { | 706 | { |
| 706 | struct capture_priv *priv = to_capture_priv(vdev); | 707 | struct capture_priv *priv = to_capture_priv(vdev); |
| 707 | struct v4l2_subdev *sd = priv->src_sd; | 708 | struct v4l2_subdev *sd = priv->src_sd; |
| @@ -710,8 +711,7 @@ int imx_media_capture_device_register(struct imx_media_video_dev *vdev) | |||
| 710 | struct v4l2_subdev_format fmt_src; | 711 | struct v4l2_subdev_format fmt_src; |
| 711 | int ret; | 712 | int ret; |
| 712 | 713 | ||
| 713 | /* get media device */ | 714 | priv->md = md; |
| 714 | priv->md = dev_get_drvdata(sd->v4l2_dev->dev); | ||
| 715 | 715 | ||
| 716 | vfd->v4l2_dev = sd->v4l2_dev; | 716 | vfd->v4l2_dev = sd->v4l2_dev; |
| 717 | 717 | ||
diff --git a/drivers/staging/media/imx/imx-media-csi.c b/drivers/staging/media/imx/imx-media-csi.c index 28fe66052cc7..1d248aca40a9 100644 --- a/drivers/staging/media/imx/imx-media-csi.c +++ b/drivers/staging/media/imx/imx-media-csi.c | |||
| @@ -1812,7 +1812,7 @@ static int csi_registered(struct v4l2_subdev *sd) | |||
| 1812 | if (ret) | 1812 | if (ret) |
| 1813 | goto free_fim; | 1813 | goto free_fim; |
| 1814 | 1814 | ||
| 1815 | ret = imx_media_capture_device_register(priv->vdev); | 1815 | ret = imx_media_capture_device_register(priv->md, priv->vdev); |
| 1816 | if (ret) | 1816 | if (ret) |
| 1817 | goto free_fim; | 1817 | goto free_fim; |
| 1818 | 1818 | ||
diff --git a/drivers/staging/media/imx/imx-media.h b/drivers/staging/media/imx/imx-media.h index eb59ba0c3b62..6587aa49e005 100644 --- a/drivers/staging/media/imx/imx-media.h +++ b/drivers/staging/media/imx/imx-media.h | |||
| @@ -268,7 +268,8 @@ int imx_media_of_add_csi(struct imx_media_dev *imxmd, | |||
| 268 | struct imx_media_video_dev * | 268 | struct imx_media_video_dev * |
| 269 | imx_media_capture_device_init(struct v4l2_subdev *src_sd, int pad); | 269 | imx_media_capture_device_init(struct v4l2_subdev *src_sd, int pad); |
| 270 | void imx_media_capture_device_remove(struct imx_media_video_dev *vdev); | 270 | void imx_media_capture_device_remove(struct imx_media_video_dev *vdev); |
| 271 | int imx_media_capture_device_register(struct imx_media_video_dev *vdev); | 271 | int imx_media_capture_device_register(struct imx_media_dev *md, |
| 272 | struct imx_media_video_dev *vdev); | ||
| 272 | void imx_media_capture_device_unregister(struct imx_media_video_dev *vdev); | 273 | void imx_media_capture_device_unregister(struct imx_media_video_dev *vdev); |
| 273 | struct imx_media_buffer * | 274 | struct imx_media_buffer * |
| 274 | imx_media_capture_device_next_buf(struct imx_media_video_dev *vdev); | 275 | imx_media_capture_device_next_buf(struct imx_media_video_dev *vdev); |
diff --git a/drivers/staging/media/imx/imx7-media-csi.c b/drivers/staging/media/imx/imx7-media-csi.c index 18eb5d3ecf10..a708a0340eb1 100644 --- a/drivers/staging/media/imx/imx7-media-csi.c +++ b/drivers/staging/media/imx/imx7-media-csi.c | |||
| @@ -1126,7 +1126,7 @@ static int imx7_csi_registered(struct v4l2_subdev *sd) | |||
| 1126 | if (ret < 0) | 1126 | if (ret < 0) |
| 1127 | return ret; | 1127 | return ret; |
| 1128 | 1128 | ||
| 1129 | ret = imx_media_capture_device_register(csi->vdev); | 1129 | ret = imx_media_capture_device_register(csi->imxmd, csi->vdev); |
| 1130 | if (ret < 0) | 1130 | if (ret < 0) |
| 1131 | return ret; | 1131 | return ret; |
| 1132 | 1132 | ||
diff --git a/drivers/staging/media/rockchip/vpu/rockchip_vpu_drv.c b/drivers/staging/media/rockchip/vpu/rockchip_vpu_drv.c index 58721c46fba4..8bbc905b26c8 100644 --- a/drivers/staging/media/rockchip/vpu/rockchip_vpu_drv.c +++ b/drivers/staging/media/rockchip/vpu/rockchip_vpu_drv.c | |||
| @@ -352,7 +352,7 @@ static int rockchip_vpu_video_device_register(struct rockchip_vpu_dev *vpu) | |||
| 352 | vpu->vfd_enc = vfd; | 352 | vpu->vfd_enc = vfd; |
| 353 | video_set_drvdata(vfd, vpu); | 353 | video_set_drvdata(vfd, vpu); |
| 354 | 354 | ||
| 355 | ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0); | 355 | ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1); |
| 356 | if (ret) { | 356 | if (ret) { |
| 357 | v4l2_err(&vpu->v4l2_dev, "Failed to register video device\n"); | 357 | v4l2_err(&vpu->v4l2_dev, "Failed to register video device\n"); |
| 358 | goto err_free_dev; | 358 | goto err_free_dev; |
| @@ -463,6 +463,8 @@ static int rockchip_vpu_probe(struct platform_device *pdev) | |||
| 463 | 463 | ||
| 464 | vpu->mdev.dev = vpu->dev; | 464 | vpu->mdev.dev = vpu->dev; |
| 465 | strscpy(vpu->mdev.model, DRIVER_NAME, sizeof(vpu->mdev.model)); | 465 | strscpy(vpu->mdev.model, DRIVER_NAME, sizeof(vpu->mdev.model)); |
| 466 | strscpy(vpu->mdev.bus_info, "platform: " DRIVER_NAME, | ||
| 467 | sizeof(vpu->mdev.model)); | ||
| 466 | media_device_init(&vpu->mdev); | 468 | media_device_init(&vpu->mdev); |
| 467 | vpu->v4l2_dev.mdev = &vpu->mdev; | 469 | vpu->v4l2_dev.mdev = &vpu->mdev; |
| 468 | 470 | ||
| @@ -480,15 +482,18 @@ static int rockchip_vpu_probe(struct platform_device *pdev) | |||
| 480 | return 0; | 482 | return 0; |
| 481 | err_video_dev_unreg: | 483 | err_video_dev_unreg: |
| 482 | if (vpu->vfd_enc) { | 484 | if (vpu->vfd_enc) { |
| 485 | v4l2_m2m_unregister_media_controller(vpu->m2m_dev); | ||
| 483 | video_unregister_device(vpu->vfd_enc); | 486 | video_unregister_device(vpu->vfd_enc); |
| 484 | video_device_release(vpu->vfd_enc); | 487 | video_device_release(vpu->vfd_enc); |
| 485 | } | 488 | } |
| 486 | err_m2m_rel: | 489 | err_m2m_rel: |
| 490 | media_device_cleanup(&vpu->mdev); | ||
| 487 | v4l2_m2m_release(vpu->m2m_dev); | 491 | v4l2_m2m_release(vpu->m2m_dev); |
| 488 | err_v4l2_unreg: | 492 | err_v4l2_unreg: |
| 489 | v4l2_device_unregister(&vpu->v4l2_dev); | 493 | v4l2_device_unregister(&vpu->v4l2_dev); |
| 490 | err_clk_unprepare: | 494 | err_clk_unprepare: |
| 491 | clk_bulk_unprepare(vpu->variant->num_clocks, vpu->clocks); | 495 | clk_bulk_unprepare(vpu->variant->num_clocks, vpu->clocks); |
| 496 | pm_runtime_dont_use_autosuspend(vpu->dev); | ||
| 492 | pm_runtime_disable(vpu->dev); | 497 | pm_runtime_disable(vpu->dev); |
| 493 | return ret; | 498 | return ret; |
| 494 | } | 499 | } |
| @@ -500,15 +505,16 @@ static int rockchip_vpu_remove(struct platform_device *pdev) | |||
| 500 | v4l2_info(&vpu->v4l2_dev, "Removing %s\n", pdev->name); | 505 | v4l2_info(&vpu->v4l2_dev, "Removing %s\n", pdev->name); |
| 501 | 506 | ||
| 502 | media_device_unregister(&vpu->mdev); | 507 | media_device_unregister(&vpu->mdev); |
| 503 | v4l2_m2m_unregister_media_controller(vpu->m2m_dev); | ||
| 504 | v4l2_m2m_release(vpu->m2m_dev); | ||
| 505 | media_device_cleanup(&vpu->mdev); | ||
| 506 | if (vpu->vfd_enc) { | 508 | if (vpu->vfd_enc) { |
| 509 | v4l2_m2m_unregister_media_controller(vpu->m2m_dev); | ||
| 507 | video_unregister_device(vpu->vfd_enc); | 510 | video_unregister_device(vpu->vfd_enc); |
| 508 | video_device_release(vpu->vfd_enc); | 511 | video_device_release(vpu->vfd_enc); |
| 509 | } | 512 | } |
| 513 | media_device_cleanup(&vpu->mdev); | ||
| 514 | v4l2_m2m_release(vpu->m2m_dev); | ||
| 510 | v4l2_device_unregister(&vpu->v4l2_dev); | 515 | v4l2_device_unregister(&vpu->v4l2_dev); |
| 511 | clk_bulk_unprepare(vpu->variant->num_clocks, vpu->clocks); | 516 | clk_bulk_unprepare(vpu->variant->num_clocks, vpu->clocks); |
| 517 | pm_runtime_dont_use_autosuspend(vpu->dev); | ||
| 512 | pm_runtime_disable(vpu->dev); | 518 | pm_runtime_disable(vpu->dev); |
| 513 | return 0; | 519 | return 0; |
| 514 | } | 520 | } |
diff --git a/drivers/staging/media/rockchip/vpu/rockchip_vpu_enc.c b/drivers/staging/media/rockchip/vpu/rockchip_vpu_enc.c index fb5e36aedd8c..dcbfc3cbc9f3 100644 --- a/drivers/staging/media/rockchip/vpu/rockchip_vpu_enc.c +++ b/drivers/staging/media/rockchip/vpu/rockchip_vpu_enc.c | |||
| @@ -152,9 +152,10 @@ static int vidioc_querycap(struct file *file, void *priv, | |||
| 152 | struct v4l2_capability *cap) | 152 | struct v4l2_capability *cap) |
| 153 | { | 153 | { |
| 154 | struct rockchip_vpu_dev *vpu = video_drvdata(file); | 154 | struct rockchip_vpu_dev *vpu = video_drvdata(file); |
| 155 | struct video_device *vdev = video_devdata(file); | ||
| 155 | 156 | ||
| 156 | strscpy(cap->driver, vpu->dev->driver->name, sizeof(cap->driver)); | 157 | strscpy(cap->driver, vpu->dev->driver->name, sizeof(cap->driver)); |
| 157 | strscpy(cap->card, vpu->vfd_enc->name, sizeof(cap->card)); | 158 | strscpy(cap->card, vdev->name, sizeof(cap->card)); |
| 158 | snprintf(cap->bus_info, sizeof(cap->bus_info), "platform: %s", | 159 | snprintf(cap->bus_info, sizeof(cap->bus_info), "platform: %s", |
| 159 | vpu->dev->driver->name); | 160 | vpu->dev->driver->name); |
| 160 | return 0; | 161 | return 0; |
diff --git a/include/media/davinci/vpbe.h b/include/media/davinci/vpbe.h index 5c31a7682492..f76d2f25a824 100644 --- a/include/media/davinci/vpbe.h +++ b/include/media/davinci/vpbe.h | |||
| @@ -92,7 +92,7 @@ struct vpbe_config { | |||
| 92 | struct encoder_config_info *ext_encoders; | 92 | struct encoder_config_info *ext_encoders; |
| 93 | /* amplifier information goes here */ | 93 | /* amplifier information goes here */ |
| 94 | struct amp_config_info *amp; | 94 | struct amp_config_info *amp; |
| 95 | int num_outputs; | 95 | unsigned int num_outputs; |
| 96 | /* Order is venc outputs followed by LCD and then external encoders */ | 96 | /* Order is venc outputs followed by LCD and then external encoders */ |
| 97 | struct vpbe_output *outputs; | 97 | struct vpbe_output *outputs; |
| 98 | }; | 98 | }; |
