Эх сурвалжийг харах

Merge tag 'media/v4.20-3' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media

Pull media fixes from Mauro Carvalho Chehab:

 - add a missing include at v4l2-controls uAPI header

 - minor kAPI update for the request API

 - some fixes at CEC core

 - use a lower minimum height for the virtual codec driver

 - cleanup a gcc warning due to the lack of a fall though markup

 - tc358743: Remove unnecessary self assignment

 - fix the V4L event subscription logic

 - docs: Document metadata format in struct v4l2_format

 - omap3isp and ipu3-cio2: fix unbinding logic

* tag 'media/v4.20-3' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media:
  media: ipu3-cio2: Use cio2_queues_exit
  media: ipu3-cio2: Unregister device nodes first, then release resources
  media: omap3isp: Unregister media device as first
  media: docs: Document metadata format in struct v4l2_format
  media: v4l: event: Add subscription to list before calling "add" operation
  media: dm365_ipipeif: better annotate a fall though
  media: Rename vb2_m2m_request_queue -> v4l2_m2m_request_queue
  media: cec: increase debug level for 'queue full'
  media: cec: check for non-OK/NACK conditions while claiming a LA
  media: vicodec: lower minimum height to 360
  media: tc358743: Remove unnecessary self assignment
  media: v4l: fix uapi mpeg slice params definition
  v4l2-controls: add a missing include
Linus Torvalds 6 жил өмнө
parent
commit
06e68fed32

+ 1 - 1
Documentation/media/uapi/v4l/dev-meta.rst

@@ -40,7 +40,7 @@ To use the :ref:`format` ioctls applications set the ``type`` field of the
 the desired operation. Both drivers and applications must set the remainder of
 the desired operation. Both drivers and applications must set the remainder of
 the :c:type:`v4l2_format` structure to 0.
 the :c:type:`v4l2_format` structure to 0.
 
 
-.. _v4l2-meta-format:
+.. c:type:: v4l2_meta_format
 
 
 .. tabularcolumns:: |p{1.4cm}|p{2.2cm}|p{13.9cm}|
 .. tabularcolumns:: |p{1.4cm}|p{2.2cm}|p{13.9cm}|
 
 

+ 5 - 0
Documentation/media/uapi/v4l/vidioc-g-fmt.rst

@@ -132,6 +132,11 @@ The format as returned by :ref:`VIDIOC_TRY_FMT <VIDIOC_G_FMT>` must be identical
       - ``sdr``
       - ``sdr``
       - Definition of a data format, see :ref:`pixfmt`, used by SDR
       - Definition of a data format, see :ref:`pixfmt`, used by SDR
 	capture and output devices.
 	capture and output devices.
+    * -
+      - struct :c:type:`v4l2_meta_format`
+      - ``meta``
+      - Definition of a metadata format, see :ref:`meta-formats`, used by
+	metadata capture devices.
     * -
     * -
       - __u8
       - __u8
       - ``raw_data``\ [200]
       - ``raw_data``\ [200]

+ 38 - 11
drivers/media/cec/cec-adap.c

@@ -807,7 +807,7 @@ int cec_transmit_msg_fh(struct cec_adapter *adap, struct cec_msg *msg,
 	}
 	}
 
 
 	if (adap->transmit_queue_sz >= CEC_MAX_MSG_TX_QUEUE_SZ) {
 	if (adap->transmit_queue_sz >= CEC_MAX_MSG_TX_QUEUE_SZ) {
-		dprintk(1, "%s: transmit queue full\n", __func__);
+		dprintk(2, "%s: transmit queue full\n", __func__);
 		return -EBUSY;
 		return -EBUSY;
 	}
 	}
 
 
@@ -1180,6 +1180,8 @@ static int cec_config_log_addr(struct cec_adapter *adap,
 {
 {
 	struct cec_log_addrs *las = &adap->log_addrs;
 	struct cec_log_addrs *las = &adap->log_addrs;
 	struct cec_msg msg = { };
 	struct cec_msg msg = { };
+	const unsigned int max_retries = 2;
+	unsigned int i;
 	int err;
 	int err;
 
 
 	if (cec_has_log_addr(adap, log_addr))
 	if (cec_has_log_addr(adap, log_addr))
@@ -1188,19 +1190,44 @@ static int cec_config_log_addr(struct cec_adapter *adap,
 	/* Send poll message */
 	/* Send poll message */
 	msg.len = 1;
 	msg.len = 1;
 	msg.msg[0] = (log_addr << 4) | log_addr;
 	msg.msg[0] = (log_addr << 4) | log_addr;
-	err = cec_transmit_msg_fh(adap, &msg, NULL, true);
 
 
-	/*
-	 * While trying to poll the physical address was reset
-	 * and the adapter was unconfigured, so bail out.
-	 */
-	if (!adap->is_configuring)
-		return -EINTR;
+	for (i = 0; i < max_retries; i++) {
+		err = cec_transmit_msg_fh(adap, &msg, NULL, true);
 
 
-	if (err)
-		return err;
+		/*
+		 * While trying to poll the physical address was reset
+		 * and the adapter was unconfigured, so bail out.
+		 */
+		if (!adap->is_configuring)
+			return -EINTR;
+
+		if (err)
+			return err;
 
 
-	if (msg.tx_status & CEC_TX_STATUS_OK)
+		/*
+		 * The message was aborted due to a disconnect or
+		 * unconfigure, just bail out.
+		 */
+		if (msg.tx_status & CEC_TX_STATUS_ABORTED)
+			return -EINTR;
+		if (msg.tx_status & CEC_TX_STATUS_OK)
+			return 0;
+		if (msg.tx_status & CEC_TX_STATUS_NACK)
+			break;
+		/*
+		 * Retry up to max_retries times if the message was neither
+		 * OKed or NACKed. This can happen due to e.g. a Lost
+		 * Arbitration condition.
+		 */
+	}
+
+	/*
+	 * If we are unable to get an OK or a NACK after max_retries attempts
+	 * (and note that each attempt already consists of four polls), then
+	 * then we assume that something is really weird and that it is not a
+	 * good idea to try and claim this logical address.
+	 */
+	if (i == max_retries)
 		return 0;
 		return 0;
 
 
 	/*
 	/*

+ 0 - 1
drivers/media/i2c/tc358743.c

@@ -1918,7 +1918,6 @@ static int tc358743_probe_of(struct tc358743_state *state)
 	ret = v4l2_fwnode_endpoint_alloc_parse(of_fwnode_handle(ep), &endpoint);
 	ret = v4l2_fwnode_endpoint_alloc_parse(of_fwnode_handle(ep), &endpoint);
 	if (ret) {
 	if (ret) {
 		dev_err(dev, "failed to parse endpoint\n");
 		dev_err(dev, "failed to parse endpoint\n");
-		ret = ret;
 		goto put_node;
 		goto put_node;
 	}
 	}
 
 

+ 2 - 4
drivers/media/pci/intel/ipu3/ipu3-cio2.c

@@ -1844,14 +1844,12 @@ fail_mutex_destroy:
 static void cio2_pci_remove(struct pci_dev *pci_dev)
 static void cio2_pci_remove(struct pci_dev *pci_dev)
 {
 {
 	struct cio2_device *cio2 = pci_get_drvdata(pci_dev);
 	struct cio2_device *cio2 = pci_get_drvdata(pci_dev);
-	unsigned int i;
 
 
+	media_device_unregister(&cio2->media_dev);
 	cio2_notifier_exit(cio2);
 	cio2_notifier_exit(cio2);
+	cio2_queues_exit(cio2);
 	cio2_fbpt_exit_dummy(cio2);
 	cio2_fbpt_exit_dummy(cio2);
-	for (i = 0; i < CIO2_QUEUES; i++)
-		cio2_queue_exit(cio2, &cio2->queue[i]);
 	v4l2_device_unregister(&cio2->v4l2_dev);
 	v4l2_device_unregister(&cio2->v4l2_dev);
-	media_device_unregister(&cio2->media_dev);
 	media_device_cleanup(&cio2->media_dev);
 	media_device_cleanup(&cio2->media_dev);
 	mutex_destroy(&cio2->lock);
 	mutex_destroy(&cio2->lock);
 }
 }

+ 2 - 1
drivers/media/platform/omap3isp/isp.c

@@ -1587,6 +1587,8 @@ static void isp_pm_complete(struct device *dev)
 
 
 static void isp_unregister_entities(struct isp_device *isp)
 static void isp_unregister_entities(struct isp_device *isp)
 {
 {
+	media_device_unregister(&isp->media_dev);
+
 	omap3isp_csi2_unregister_entities(&isp->isp_csi2a);
 	omap3isp_csi2_unregister_entities(&isp->isp_csi2a);
 	omap3isp_ccp2_unregister_entities(&isp->isp_ccp2);
 	omap3isp_ccp2_unregister_entities(&isp->isp_ccp2);
 	omap3isp_ccdc_unregister_entities(&isp->isp_ccdc);
 	omap3isp_ccdc_unregister_entities(&isp->isp_ccdc);
@@ -1597,7 +1599,6 @@ static void isp_unregister_entities(struct isp_device *isp)
 	omap3isp_stat_unregister_entities(&isp->isp_hist);
 	omap3isp_stat_unregister_entities(&isp->isp_hist);
 
 
 	v4l2_device_unregister(&isp->v4l2_dev);
 	v4l2_device_unregister(&isp->v4l2_dev);
-	media_device_unregister(&isp->media_dev);
 	media_device_cleanup(&isp->media_dev);
 	media_device_cleanup(&isp->media_dev);
 }
 }
 
 

+ 1 - 1
drivers/media/platform/vicodec/vicodec-core.c

@@ -42,7 +42,7 @@ MODULE_PARM_DESC(debug, " activates debug info");
 #define MAX_WIDTH		4096U
 #define MAX_WIDTH		4096U
 #define MIN_WIDTH		640U
 #define MIN_WIDTH		640U
 #define MAX_HEIGHT		2160U
 #define MAX_HEIGHT		2160U
-#define MIN_HEIGHT		480U
+#define MIN_HEIGHT		360U
 
 
 #define dprintk(dev, fmt, arg...) \
 #define dprintk(dev, fmt, arg...) \
 	v4l2_dbg(1, debug, &dev->v4l2_dev, "%s: " fmt, __func__, ## arg)
 	v4l2_dbg(1, debug, &dev->v4l2_dev, "%s: " fmt, __func__, ## arg)

+ 1 - 1
drivers/media/platform/vim2m.c

@@ -1009,7 +1009,7 @@ static const struct v4l2_m2m_ops m2m_ops = {
 
 
 static const struct media_device_ops m2m_media_ops = {
 static const struct media_device_ops m2m_media_ops = {
 	.req_validate = vb2_request_validate,
 	.req_validate = vb2_request_validate,
-	.req_queue = vb2_m2m_request_queue,
+	.req_queue = v4l2_m2m_request_queue,
 };
 };
 
 
 static int vim2m_probe(struct platform_device *pdev)
 static int vim2m_probe(struct platform_device *pdev)

+ 5 - 0
drivers/media/v4l2-core/v4l2-ctrls.c

@@ -1664,6 +1664,11 @@ static int std_validate(const struct v4l2_ctrl *ctrl, u32 idx,
 		    p_mpeg2_slice_params->forward_ref_index >= VIDEO_MAX_FRAME)
 		    p_mpeg2_slice_params->forward_ref_index >= VIDEO_MAX_FRAME)
 			return -EINVAL;
 			return -EINVAL;
 
 
+		if (p_mpeg2_slice_params->pad ||
+		    p_mpeg2_slice_params->picture.pad ||
+		    p_mpeg2_slice_params->sequence.pad)
+			return -EINVAL;
+
 		return 0;
 		return 0;
 
 
 	case V4L2_CTRL_TYPE_MPEG2_QUANTIZATION:
 	case V4L2_CTRL_TYPE_MPEG2_QUANTIZATION:

+ 24 - 19
drivers/media/v4l2-core/v4l2-event.c

@@ -193,6 +193,22 @@ int v4l2_event_pending(struct v4l2_fh *fh)
 }
 }
 EXPORT_SYMBOL_GPL(v4l2_event_pending);
 EXPORT_SYMBOL_GPL(v4l2_event_pending);
 
 
+static void __v4l2_event_unsubscribe(struct v4l2_subscribed_event *sev)
+{
+	struct v4l2_fh *fh = sev->fh;
+	unsigned int i;
+
+	lockdep_assert_held(&fh->subscribe_lock);
+	assert_spin_locked(&fh->vdev->fh_lock);
+
+	/* Remove any pending events for this subscription */
+	for (i = 0; i < sev->in_use; i++) {
+		list_del(&sev->events[sev_pos(sev, i)].list);
+		fh->navailable--;
+	}
+	list_del(&sev->list);
+}
+
 int v4l2_event_subscribe(struct v4l2_fh *fh,
 int v4l2_event_subscribe(struct v4l2_fh *fh,
 			 const struct v4l2_event_subscription *sub, unsigned elems,
 			 const struct v4l2_event_subscription *sub, unsigned elems,
 			 const struct v4l2_subscribed_event_ops *ops)
 			 const struct v4l2_subscribed_event_ops *ops)
@@ -224,27 +240,23 @@ int v4l2_event_subscribe(struct v4l2_fh *fh,
 
 
 	spin_lock_irqsave(&fh->vdev->fh_lock, flags);
 	spin_lock_irqsave(&fh->vdev->fh_lock, flags);
 	found_ev = v4l2_event_subscribed(fh, sub->type, sub->id);
 	found_ev = v4l2_event_subscribed(fh, sub->type, sub->id);
+	if (!found_ev)
+		list_add(&sev->list, &fh->subscribed);
 	spin_unlock_irqrestore(&fh->vdev->fh_lock, flags);
 	spin_unlock_irqrestore(&fh->vdev->fh_lock, flags);
 
 
 	if (found_ev) {
 	if (found_ev) {
 		/* Already listening */
 		/* Already listening */
 		kvfree(sev);
 		kvfree(sev);
-		goto out_unlock;
-	}
-
-	if (sev->ops && sev->ops->add) {
+	} else if (sev->ops && sev->ops->add) {
 		ret = sev->ops->add(sev, elems);
 		ret = sev->ops->add(sev, elems);
 		if (ret) {
 		if (ret) {
+			spin_lock_irqsave(&fh->vdev->fh_lock, flags);
+			__v4l2_event_unsubscribe(sev);
+			spin_unlock_irqrestore(&fh->vdev->fh_lock, flags);
 			kvfree(sev);
 			kvfree(sev);
-			goto out_unlock;
 		}
 		}
 	}
 	}
 
 
-	spin_lock_irqsave(&fh->vdev->fh_lock, flags);
-	list_add(&sev->list, &fh->subscribed);
-	spin_unlock_irqrestore(&fh->vdev->fh_lock, flags);
-
-out_unlock:
 	mutex_unlock(&fh->subscribe_lock);
 	mutex_unlock(&fh->subscribe_lock);
 
 
 	return ret;
 	return ret;
@@ -279,7 +291,6 @@ int v4l2_event_unsubscribe(struct v4l2_fh *fh,
 {
 {
 	struct v4l2_subscribed_event *sev;
 	struct v4l2_subscribed_event *sev;
 	unsigned long flags;
 	unsigned long flags;
-	int i;
 
 
 	if (sub->type == V4L2_EVENT_ALL) {
 	if (sub->type == V4L2_EVENT_ALL) {
 		v4l2_event_unsubscribe_all(fh);
 		v4l2_event_unsubscribe_all(fh);
@@ -291,14 +302,8 @@ int v4l2_event_unsubscribe(struct v4l2_fh *fh,
 	spin_lock_irqsave(&fh->vdev->fh_lock, flags);
 	spin_lock_irqsave(&fh->vdev->fh_lock, flags);
 
 
 	sev = v4l2_event_subscribed(fh, sub->type, sub->id);
 	sev = v4l2_event_subscribed(fh, sub->type, sub->id);
-	if (sev != NULL) {
-		/* Remove any pending events for this subscription */
-		for (i = 0; i < sev->in_use; i++) {
-			list_del(&sev->events[sev_pos(sev, i)].list);
-			fh->navailable--;
-		}
-		list_del(&sev->list);
-	}
+	if (sev != NULL)
+		__v4l2_event_unsubscribe(sev);
 
 
 	spin_unlock_irqrestore(&fh->vdev->fh_lock, flags);
 	spin_unlock_irqrestore(&fh->vdev->fh_lock, flags);
 
 

+ 2 - 2
drivers/media/v4l2-core/v4l2-mem2mem.c

@@ -953,7 +953,7 @@ void v4l2_m2m_buf_queue(struct v4l2_m2m_ctx *m2m_ctx,
 }
 }
 EXPORT_SYMBOL_GPL(v4l2_m2m_buf_queue);
 EXPORT_SYMBOL_GPL(v4l2_m2m_buf_queue);
 
 
-void vb2_m2m_request_queue(struct media_request *req)
+void v4l2_m2m_request_queue(struct media_request *req)
 {
 {
 	struct media_request_object *obj, *obj_safe;
 	struct media_request_object *obj, *obj_safe;
 	struct v4l2_m2m_ctx *m2m_ctx = NULL;
 	struct v4l2_m2m_ctx *m2m_ctx = NULL;
@@ -997,7 +997,7 @@ void vb2_m2m_request_queue(struct media_request *req)
 	if (m2m_ctx)
 	if (m2m_ctx)
 		v4l2_m2m_try_schedule(m2m_ctx);
 		v4l2_m2m_try_schedule(m2m_ctx);
 }
 }
-EXPORT_SYMBOL_GPL(vb2_m2m_request_queue);
+EXPORT_SYMBOL_GPL(v4l2_m2m_request_queue);
 
 
 /* Videobuf2 ioctl helpers */
 /* Videobuf2 ioctl helpers */
 
 

+ 1 - 0
drivers/staging/media/davinci_vpfe/dm365_ipipeif.c

@@ -310,6 +310,7 @@ static int ipipeif_hw_setup(struct v4l2_subdev *sd)
 			ipipeif_write(val, ipipeif_base_addr, IPIPEIF_CFG2);
 			ipipeif_write(val, ipipeif_base_addr, IPIPEIF_CFG2);
 			break;
 			break;
 		}
 		}
+		/* fall through */
 
 
 	case IPIPEIF_SDRAM_YUV:
 	case IPIPEIF_SDRAM_YUV:
 		/* Set clock divider */
 		/* Set clock divider */

+ 1 - 1
drivers/staging/media/sunxi/cedrus/cedrus.c

@@ -253,7 +253,7 @@ static const struct v4l2_m2m_ops cedrus_m2m_ops = {
 
 
 static const struct media_device_ops cedrus_m2m_media_ops = {
 static const struct media_device_ops cedrus_m2m_media_ops = {
 	.req_validate	= cedrus_request_validate,
 	.req_validate	= cedrus_request_validate,
-	.req_queue	= vb2_m2m_request_queue,
+	.req_queue	= v4l2_m2m_request_queue,
 };
 };
 
 
 static int cedrus_probe(struct platform_device *pdev)
 static int cedrus_probe(struct platform_device *pdev)

+ 1 - 1
include/media/v4l2-mem2mem.h

@@ -624,7 +624,7 @@ v4l2_m2m_dst_buf_remove_by_idx(struct v4l2_m2m_ctx *m2m_ctx, unsigned int idx)
 
 
 /* v4l2 request helper */
 /* v4l2 request helper */
 
 
-void vb2_m2m_request_queue(struct media_request *req);
+void v4l2_m2m_request_queue(struct media_request *req);
 
 
 /* v4l2 ioctl helpers */
 /* v4l2 ioctl helpers */
 
 

+ 5 - 0
include/uapi/linux/v4l2-controls.h

@@ -50,6 +50,8 @@
 #ifndef __LINUX_V4L2_CONTROLS_H
 #ifndef __LINUX_V4L2_CONTROLS_H
 #define __LINUX_V4L2_CONTROLS_H
 #define __LINUX_V4L2_CONTROLS_H
 
 
+#include <linux/types.h>
+
 /* Control classes */
 /* Control classes */
 #define V4L2_CTRL_CLASS_USER		0x00980000	/* Old-style 'user' controls */
 #define V4L2_CTRL_CLASS_USER		0x00980000	/* Old-style 'user' controls */
 #define V4L2_CTRL_CLASS_MPEG		0x00990000	/* MPEG-compression controls */
 #define V4L2_CTRL_CLASS_MPEG		0x00990000	/* MPEG-compression controls */
@@ -1110,6 +1112,7 @@ struct v4l2_mpeg2_sequence {
 	__u8	profile_and_level_indication;
 	__u8	profile_and_level_indication;
 	__u8	progressive_sequence;
 	__u8	progressive_sequence;
 	__u8	chroma_format;
 	__u8	chroma_format;
+	__u8	pad;
 };
 };
 
 
 struct v4l2_mpeg2_picture {
 struct v4l2_mpeg2_picture {
@@ -1128,6 +1131,7 @@ struct v4l2_mpeg2_picture {
 	__u8	alternate_scan;
 	__u8	alternate_scan;
 	__u8	repeat_first_field;
 	__u8	repeat_first_field;
 	__u8	progressive_frame;
 	__u8	progressive_frame;
+	__u8	pad;
 };
 };
 
 
 struct v4l2_ctrl_mpeg2_slice_params {
 struct v4l2_ctrl_mpeg2_slice_params {
@@ -1142,6 +1146,7 @@ struct v4l2_ctrl_mpeg2_slice_params {
 
 
 	__u8	backward_ref_index;
 	__u8	backward_ref_index;
 	__u8	forward_ref_index;
 	__u8	forward_ref_index;
+	__u8	pad;
 };
 };
 
 
 struct v4l2_ctrl_mpeg2_quantization {
 struct v4l2_ctrl_mpeg2_quantization {