Commit 01be377c authored by Linus Torvalds's avatar Linus Torvalds

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
parents 11b11773 fc8670d1
...@@ -75,12 +75,11 @@ enum v4l2_field ...@@ -75,12 +75,11 @@ enum v4l2_field
* - ``V4L2_FIELD_ANY`` * - ``V4L2_FIELD_ANY``
- 0 - 0
- Applications request this field order when any one of the - Applications request this field order when any field format
``V4L2_FIELD_NONE``, ``V4L2_FIELD_TOP``, ``V4L2_FIELD_BOTTOM``, or is acceptable. Drivers choose depending on hardware capabilities or
``V4L2_FIELD_INTERLACED`` formats is acceptable. Drivers choose e.g. the requested image size, and return the actual field order.
depending on hardware capabilities or e. g. the requested image Drivers must never return ``V4L2_FIELD_ANY``.
size, and return the actual field order. Drivers must never return If multiple field orders are possible the
``V4L2_FIELD_ANY``. If multiple field orders are possible the
driver must choose one of the possible field orders during driver must choose one of the possible field orders during
:ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` or :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` or
:ref:`VIDIOC_TRY_FMT <VIDIOC_G_FMT>`. struct :ref:`VIDIOC_TRY_FMT <VIDIOC_G_FMT>`. struct
...@@ -88,9 +87,8 @@ enum v4l2_field ...@@ -88,9 +87,8 @@ enum v4l2_field
``V4L2_FIELD_ANY``. ``V4L2_FIELD_ANY``.
* - ``V4L2_FIELD_NONE`` * - ``V4L2_FIELD_NONE``
- 1 - 1
- Images are in progressive format, not interlaced. The driver may - Images are in progressive (frame-based) format, not interlaced
also indicate this order when it cannot distinguish between (field-based).
``V4L2_FIELD_TOP`` and ``V4L2_FIELD_BOTTOM``.
* - ``V4L2_FIELD_TOP`` * - ``V4L2_FIELD_TOP``
- 2 - 2
- Images consist of the top (aka odd) field only. - Images consist of the top (aka odd) field only.
......
...@@ -37,6 +37,25 @@ ...@@ -37,6 +37,25 @@
#define ISC_PFG_CFG0_BPS_TWELVE (0x0 << 28) #define ISC_PFG_CFG0_BPS_TWELVE (0x0 << 28)
#define ISC_PFE_CFG0_BPS_MASK GENMASK(30, 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 */ /* ISC Clock Enable Register */
#define ISC_CLKEN 0x00000018 #define ISC_CLKEN 0x00000018
......
...@@ -721,6 +721,40 @@ static void isc_start_dma(struct isc_device *isc) ...@@ -721,6 +721,40 @@ static void isc_start_dma(struct isc_device *isc)
u32 sizeimage = isc->fmt.fmt.pix.sizeimage; u32 sizeimage = isc->fmt.fmt.pix.sizeimage;
u32 dctrl_dview; u32 dctrl_dview;
dma_addr_t addr0; 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); addr0 = vb2_dma_contig_plane_dma_addr(&isc->cur_frm->vb.vb2_buf, 0);
regmap_write(regmap, ISC_DAD0, addr0); regmap_write(regmap, ISC_DAD0, addr0);
...@@ -1965,6 +1999,8 @@ static int isc_async_complete(struct v4l2_async_notifier *notifier) ...@@ -1965,6 +1999,8 @@ static int isc_async_complete(struct v4l2_async_notifier *notifier)
struct vb2_queue *q = &isc->vb2_vidq; struct vb2_queue *q = &isc->vb2_vidq;
int ret; int ret;
INIT_WORK(&isc->awb_work, isc_awb_work);
ret = v4l2_device_register_subdev_nodes(&isc->v4l2_dev); ret = v4l2_device_register_subdev_nodes(&isc->v4l2_dev);
if (ret < 0) { if (ret < 0) {
v4l2_err(&isc->v4l2_dev, "Failed to register subdev nodes\n"); 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,8 +2054,6 @@ static int isc_async_complete(struct v4l2_async_notifier *notifier)
return ret; return ret;
} }
INIT_WORK(&isc->awb_work, isc_awb_work);
/* Register video device */ /* Register video device */
strscpy(vdev->name, ATMEL_ISC_NAME, sizeof(vdev->name)); strscpy(vdev->name, ATMEL_ISC_NAME, sizeof(vdev->name));
vdev->release = video_device_release_empty; vdev->release = video_device_release_empty;
...@@ -2135,8 +2169,11 @@ static int isc_parse_dt(struct device *dev, struct isc_device *isc) ...@@ -2135,8 +2169,11 @@ static int isc_parse_dt(struct device *dev, struct isc_device *isc)
break; break;
} }
subdev_entity->asd = devm_kzalloc(dev, /* asd will be freed by the subsystem once it's added to the
sizeof(*subdev_entity->asd), GFP_KERNEL); * notifier list
*/
subdev_entity->asd = kzalloc(sizeof(*subdev_entity->asd),
GFP_KERNEL);
if (!subdev_entity->asd) { if (!subdev_entity->asd) {
of_node_put(rem); of_node_put(rem);
ret = -ENOMEM; ret = -ENOMEM;
...@@ -2284,6 +2321,7 @@ static int atmel_isc_probe(struct platform_device *pdev) ...@@ -2284,6 +2321,7 @@ static int atmel_isc_probe(struct platform_device *pdev)
subdev_entity->asd); subdev_entity->asd);
if (ret) { if (ret) {
fwnode_handle_put(subdev_entity->asd->match.fwnode); fwnode_handle_put(subdev_entity->asd->match.fwnode);
kfree(subdev_entity->asd);
goto cleanup_subdev; goto cleanup_subdev;
} }
......
...@@ -1515,10 +1515,20 @@ static int coda_queue_setup(struct vb2_queue *vq, ...@@ -1515,10 +1515,20 @@ static int coda_queue_setup(struct vb2_queue *vq,
static int coda_buf_prepare(struct vb2_buffer *vb) 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_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
struct coda_q_data *q_data; struct coda_q_data *q_data;
q_data = get_q_data(ctx, vb->vb2_queue->type); 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) { if (vb2_plane_size(vb, 0) < q_data->sizeimage) {
v4l2_warn(&ctx->dev->v4l2_dev, v4l2_warn(&ctx->dev->v4l2_dev,
......
...@@ -104,7 +104,7 @@ static int vpbe_enum_outputs(struct vpbe_device *vpbe_dev, ...@@ -104,7 +104,7 @@ static int vpbe_enum_outputs(struct vpbe_device *vpbe_dev,
struct v4l2_output *output) struct v4l2_output *output)
{ {
struct vpbe_config *cfg = vpbe_dev->cfg; struct vpbe_config *cfg = vpbe_dev->cfg;
int temp_index = output->index; unsigned int temp_index = output->index;
if (temp_index >= cfg->num_outputs) if (temp_index >= cfg->num_outputs)
return -EINVAL; return -EINVAL;
......
...@@ -1527,23 +1527,20 @@ static int vidioc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b) ...@@ -1527,23 +1527,20 @@ static int vidioc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b)
unsigned long size; unsigned long size;
struct videobuf_buffer *vb; struct videobuf_buffer *vb;
vb = q->bufs[b->index];
if (!vout->streaming) if (!vout->streaming)
return -EINVAL; return -EINVAL;
if (file->f_flags & O_NONBLOCK) ret = videobuf_dqbuf(q, b, !!(file->f_flags & O_NONBLOCK));
/* Call videobuf_dqbuf for non blocking mode */ if (ret)
ret = videobuf_dqbuf(q, (struct v4l2_buffer *)b, 1); return ret;
else
/* Call videobuf_dqbuf for blocking mode */ vb = q->bufs[b->index];
ret = videobuf_dqbuf(q, (struct v4l2_buffer *)b, 0);
addr = (unsigned long) vout->buf_phy_addr[vb->i]; addr = (unsigned long) vout->buf_phy_addr[vb->i];
size = (unsigned long) vb->size; size = (unsigned long) vb->size;
dma_unmap_single(vout->vid_dev->v4l2_dev.dev, addr, dma_unmap_single(vout->vid_dev->v4l2_dev.dev, addr,
size, DMA_TO_DEVICE); size, DMA_TO_DEVICE);
return ret; return 0;
} }
static int vidioc_streamon(struct file *file, void *fh, enum v4l2_buf_type i) static int vidioc_streamon(struct file *file, void *fh, enum v4l2_buf_type i)
......
...@@ -68,6 +68,7 @@ struct rcar_csi2; ...@@ -68,6 +68,7 @@ struct rcar_csi2;
/* Field Detection Control */ /* Field Detection Control */
#define FLD_REG 0x1c #define FLD_REG 0x1c
#define FLD_FLD_NUM(n) (((n) & 0xff) << 16) #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_EN4 BIT(3)
#define FLD_FLD_EN3 BIT(2) #define FLD_FLD_EN3 BIT(2)
#define FLD_FLD_EN2 BIT(1) #define FLD_FLD_EN2 BIT(1)
...@@ -84,6 +85,9 @@ struct rcar_csi2; ...@@ -84,6 +85,9 @@ struct rcar_csi2;
/* Interrupt Enable */ /* Interrupt Enable */
#define INTEN_REG 0x30 #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 */ /* Interrupt Source Mask */
#define INTCLOSE_REG 0x34 #define INTCLOSE_REG 0x34
...@@ -475,7 +479,7 @@ static int rcsi2_calc_mbps(struct rcar_csi2 *priv, unsigned int bpp) ...@@ -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) static int rcsi2_start_receiver(struct rcar_csi2 *priv)
{ {
const struct rcar_csi2_format *format; const struct rcar_csi2_format *format;
u32 phycnt, vcdt = 0, vcdt2 = 0; u32 phycnt, vcdt = 0, vcdt2 = 0, fld = 0;
unsigned int i; unsigned int i;
int mbps, ret; int mbps, ret;
...@@ -507,6 +511,16 @@ static int rcsi2_start_receiver(struct rcar_csi2 *priv) ...@@ -507,6 +511,16 @@ static int rcsi2_start_receiver(struct rcar_csi2 *priv)
vcdt2 |= vcdt_part << ((i % 2) * 16); 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 = PHYCNT_ENABLECLK;
phycnt |= (1 << priv->lanes) - 1; phycnt |= (1 << priv->lanes) - 1;
...@@ -514,6 +528,10 @@ static int rcsi2_start_receiver(struct rcar_csi2 *priv) ...@@ -514,6 +528,10 @@ static int rcsi2_start_receiver(struct rcar_csi2 *priv)
if (mbps < 0) if (mbps < 0)
return mbps; return mbps;
/* Enable interrupts. */
rcsi2_write(priv, INTEN_REG, INTEN_INT_AFIFO_OF | INTEN_INT_ERRSOTHS
| INTEN_INT_ERRSOTSYNCHS);
/* Init */ /* Init */
rcsi2_write(priv, TREF_REG, TREF_TREF); rcsi2_write(priv, TREF_REG, TREF_TREF);
rcsi2_write(priv, PHTC_REG, 0); rcsi2_write(priv, PHTC_REG, 0);
...@@ -549,8 +567,7 @@ static int rcsi2_start_receiver(struct rcar_csi2 *priv) ...@@ -549,8 +567,7 @@ static int rcsi2_start_receiver(struct rcar_csi2 *priv)
rcsi2_write(priv, PHYCNT_REG, phycnt); rcsi2_write(priv, PHYCNT_REG, phycnt);
rcsi2_write(priv, LINKCNT_REG, LINKCNT_MONITOR_EN | rcsi2_write(priv, LINKCNT_REG, LINKCNT_MONITOR_EN |
LINKCNT_REG_MONI_PACT_EN | LINKCNT_ICLK_NONSTOP); LINKCNT_REG_MONI_PACT_EN | LINKCNT_ICLK_NONSTOP);
rcsi2_write(priv, FLD_REG, FLD_FLD_NUM(2) | FLD_FLD_EN4 | rcsi2_write(priv, FLD_REG, fld);
FLD_FLD_EN3 | FLD_FLD_EN2 | FLD_FLD_EN);
rcsi2_write(priv, PHYCNT_REG, phycnt | PHYCNT_SHUTDOWNZ); rcsi2_write(priv, PHYCNT_REG, phycnt | PHYCNT_SHUTDOWNZ);
rcsi2_write(priv, PHYCNT_REG, phycnt | PHYCNT_SHUTDOWNZ | PHYCNT_RSTZ); rcsi2_write(priv, PHYCNT_REG, phycnt | PHYCNT_SHUTDOWNZ | PHYCNT_RSTZ);
...@@ -675,6 +692,43 @@ static const struct v4l2_subdev_ops rcar_csi2_subdev_ops = { ...@@ -675,6 +692,43 @@ static const struct v4l2_subdev_ops rcar_csi2_subdev_ops = {
.pad = &rcar_csi2_pad_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. * Async handling and registration of subdevices and links.
*/ */
...@@ -947,7 +1001,7 @@ static int rcsi2_probe_resources(struct rcar_csi2 *priv, ...@@ -947,7 +1001,7 @@ static int rcsi2_probe_resources(struct rcar_csi2 *priv,
struct platform_device *pdev) struct platform_device *pdev)
{ {
struct resource *res; struct resource *res;
int irq; int irq, ret;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
priv->base = devm_ioremap_resource(&pdev->dev, res); priv->base = devm_ioremap_resource(&pdev->dev, res);
...@@ -958,6 +1012,12 @@ static int rcsi2_probe_resources(struct rcar_csi2 *priv, ...@@ -958,6 +1012,12 @@ static int rcsi2_probe_resources(struct rcar_csi2 *priv,
if (irq < 0) if (irq < 0)
return irq; 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); priv->rstc = devm_reset_control_get(&pdev->dev, NULL);
if (IS_ERR(priv->rstc)) if (IS_ERR(priv->rstc))
return PTR_ERR(priv->rstc); return PTR_ERR(priv->rstc);
......
...@@ -334,8 +334,8 @@ static int tegra_cec_probe(struct platform_device *pdev) ...@@ -334,8 +334,8 @@ static int tegra_cec_probe(struct platform_device *pdev)
hdmi_dev = cec_notifier_parse_hdmi_phandle(&pdev->dev); hdmi_dev = cec_notifier_parse_hdmi_phandle(&pdev->dev);
if (!hdmi_dev) if (IS_ERR(hdmi_dev))
return -ENODEV; return PTR_ERR(hdmi_dev);
cec = devm_kzalloc(&pdev->dev, sizeof(struct tegra_cec), GFP_KERNEL); cec = devm_kzalloc(&pdev->dev, sizeof(struct tegra_cec), GFP_KERNEL);
......
...@@ -1266,7 +1266,7 @@ static int prp_registered(struct v4l2_subdev *sd) ...@@ -1266,7 +1266,7 @@ static int prp_registered(struct v4l2_subdev *sd)
if (ret) if (ret)
return ret; return ret;
ret = imx_media_capture_device_register(priv->vdev); ret = imx_media_capture_device_register(priv->md, priv->vdev);
if (ret) if (ret)
return ret; return ret;
......
...@@ -701,7 +701,8 @@ void imx_media_capture_device_error(struct imx_media_video_dev *vdev) ...@@ -701,7 +701,8 @@ void imx_media_capture_device_error(struct imx_media_video_dev *vdev)
} }
EXPORT_SYMBOL_GPL(imx_media_capture_device_error); 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 capture_priv *priv = to_capture_priv(vdev);
struct v4l2_subdev *sd = priv->src_sd; struct v4l2_subdev *sd = priv->src_sd;
...@@ -710,8 +711,7 @@ int imx_media_capture_device_register(struct imx_media_video_dev *vdev) ...@@ -710,8 +711,7 @@ int imx_media_capture_device_register(struct imx_media_video_dev *vdev)
struct v4l2_subdev_format fmt_src; struct v4l2_subdev_format fmt_src;
int ret; int ret;
/* get media device */ priv->md = md;
priv->md = dev_get_drvdata(sd->v4l2_dev->dev);
vfd->v4l2_dev = sd->v4l2_dev; vfd->v4l2_dev = sd->v4l2_dev;
......
...@@ -1812,7 +1812,7 @@ static int csi_registered(struct v4l2_subdev *sd) ...@@ -1812,7 +1812,7 @@ static int csi_registered(struct v4l2_subdev *sd)
if (ret) if (ret)
goto free_fim; goto free_fim;
ret = imx_media_capture_device_register(priv->vdev); ret = imx_media_capture_device_register(priv->md, priv->vdev);
if (ret) if (ret)
goto free_fim; goto free_fim;
......
...@@ -268,7 +268,8 @@ int imx_media_of_add_csi(struct imx_media_dev *imxmd, ...@@ -268,7 +268,8 @@ int imx_media_of_add_csi(struct imx_media_dev *imxmd,
struct imx_media_video_dev * struct imx_media_video_dev *
imx_media_capture_device_init(struct v4l2_subdev *src_sd, int pad); imx_media_capture_device_init(struct v4l2_subdev *src_sd, int pad);
void imx_media_capture_device_remove(struct imx_media_video_dev *vdev); 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); void imx_media_capture_device_unregister(struct imx_media_video_dev *vdev);
struct imx_media_buffer * struct imx_media_buffer *
imx_media_capture_device_next_buf(struct imx_media_video_dev *vdev); imx_media_capture_device_next_buf(struct imx_media_video_dev *vdev);
......
...@@ -1126,7 +1126,7 @@ static int imx7_csi_registered(struct v4l2_subdev *sd) ...@@ -1126,7 +1126,7 @@ static int imx7_csi_registered(struct v4l2_subdev *sd)
if (ret < 0) if (ret < 0)
return ret; return ret;
ret = imx_media_capture_device_register(csi->vdev); ret = imx_media_capture_device_register(csi->imxmd, csi->vdev);
if (ret < 0) if (ret < 0)
return ret; return ret;
......
...@@ -352,7 +352,7 @@ static int rockchip_vpu_video_device_register(struct rockchip_vpu_dev *vpu) ...@@ -352,7 +352,7 @@ static int rockchip_vpu_video_device_register(struct rockchip_vpu_dev *vpu)
vpu->vfd_enc = vfd; vpu->vfd_enc = vfd;
video_set_drvdata(vfd, vpu); 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) { if (ret) {
v4l2_err(&vpu->v4l2_dev, "Failed to register video device\n"); v4l2_err(&vpu->v4l2_dev, "Failed to register video device\n");
goto err_free_dev; goto err_free_dev;
...@@ -463,6 +463,8 @@ static int rockchip_vpu_probe(struct platform_device *pdev) ...@@ -463,6 +463,8 @@ static int rockchip_vpu_probe(struct platform_device *pdev)
vpu->mdev.dev = vpu->dev; vpu->mdev.dev = vpu->dev;
strscpy(vpu->mdev.model, DRIVER_NAME, sizeof(vpu->mdev.model)); 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); media_device_init(&vpu->mdev);
vpu->v4l2_dev.mdev = &vpu->mdev; vpu->v4l2_dev.mdev = &vpu->mdev;
...@@ -480,15 +482,18 @@ static int rockchip_vpu_probe(struct platform_device *pdev) ...@@ -480,15 +482,18 @@ static int rockchip_vpu_probe(struct platform_device *pdev)
return 0; return 0;
err_video_dev_unreg: err_video_dev_unreg:
if (vpu->vfd_enc) { if (vpu->vfd_enc) {
v4l2_m2m_unregister_media_controller(vpu->m2m_dev);
video_unregister_device(vpu->vfd_enc); video_unregister_device(vpu->vfd_enc);
video_device_release(vpu->vfd_enc); video_device_release(vpu->vfd_enc);
} }
err_m2m_rel: err_m2m_rel:
media_device_cleanup(&vpu->mdev);
v4l2_m2m_release(vpu->m2m_dev); v4l2_m2m_release(vpu->m2m_dev);
err_v4l2_unreg: err_v4l2_unreg:
v4l2_device_unregister(&vpu->v4l2_dev); v4l2_device_unregister(&vpu->v4l2_dev);
err_clk_unprepare: err_clk_unprepare:
clk_bulk_unprepare(vpu->variant->num_clocks, vpu->clocks); clk_bulk_unprepare(vpu->variant->num_clocks, vpu->clocks);
pm_runtime_dont_use_autosuspend(vpu->dev);
pm_runtime_disable(vpu->dev); pm_runtime_disable(vpu->dev);
return ret; return ret;
} }
...@@ -500,15 +505,16 @@ static int rockchip_vpu_remove(struct platform_device *pdev) ...@@ -500,15 +505,16 @@ static int rockchip_vpu_remove(struct platform_device *pdev)
v4l2_info(&vpu->v4l2_dev, "Removing %s\n", pdev->name); v4l2_info(&vpu->v4l2_dev, "Removing %s\n", pdev->name);
media_device_unregister(&vpu->mdev); 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) { if (vpu->vfd_enc) {
v4l2_m2m_unregister_media_controller(vpu->m2m_dev);
video_unregister_device(vpu->vfd_enc); video_unregister_device(vpu->vfd_enc);
video_device_release(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); v4l2_device_unregister(&vpu->v4l2_dev);
clk_bulk_unprepare(vpu->variant->num_clocks, vpu->clocks); clk_bulk_unprepare(vpu->variant->num_clocks, vpu->clocks);
pm_runtime_dont_use_autosuspend(vpu->dev);
pm_runtime_disable(vpu->dev); pm_runtime_disable(vpu->dev);
return 0; return 0;
} }
......
...@@ -152,9 +152,10 @@ static int vidioc_querycap(struct file *file, void *priv, ...@@ -152,9 +152,10 @@ static int vidioc_querycap(struct file *file, void *priv,
struct v4l2_capability *cap) struct v4l2_capability *cap)
{ {
struct rockchip_vpu_dev *vpu = video_drvdata(file); 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->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", snprintf(cap->bus_info, sizeof(cap->bus_info), "platform: %s",
vpu->dev->driver->name); vpu->dev->driver->name);
return 0; return 0;
......
...@@ -92,7 +92,7 @@ struct vpbe_config { ...@@ -92,7 +92,7 @@ struct vpbe_config {
struct encoder_config_info *ext_encoders; struct encoder_config_info *ext_encoders;
/* amplifier information goes here */ /* amplifier information goes here */
struct amp_config_info *amp; struct amp_config_info *amp;
int num_outputs; unsigned int num_outputs;
/* Order is venc outputs followed by LCD and then external encoders */ /* Order is venc outputs followed by LCD and then external encoders */
struct vpbe_output *outputs; struct vpbe_output *outputs;
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment