[RFC PATCH 2/9] media: request: add generic queue

2017-12-14 Thread Alexandre Courbot
Add a generic request queue that supports most use-case and should be
usable as-is by drivers without special hardware features.

The generic queue stores the requests into a FIFO list and executes them
sequentially.

Signed-off-by: Alexandre Courbot 
---
 drivers/media/Makefile  |   2 +-
 drivers/media/media-request-queue-generic.c | 150 
 include/media/media-request.h   |   8 ++
 3 files changed, 159 insertions(+), 1 deletion(-)
 create mode 100644 drivers/media/media-request-queue-generic.c

diff --git a/drivers/media/Makefile b/drivers/media/Makefile
index 985d35ec6b29..90117fff1339 100644
--- a/drivers/media/Makefile
+++ b/drivers/media/Makefile
@@ -4,7 +4,7 @@
 #
 
 media-objs := media-device.o media-devnode.o media-entity.o \
-  media-request.o
+  media-request.o media-request-queue-generic.o
 
 #
 # I2C drivers should come before other drivers, otherwise they'll fail
diff --git a/drivers/media/media-request-queue-generic.c 
b/drivers/media/media-request-queue-generic.c
new file mode 100644
index ..780414b6d46a
--- /dev/null
+++ b/drivers/media/media-request-queue-generic.c
@@ -0,0 +1,150 @@
+/*
+ * Generic request queue implementation.
+ *
+ * Copyright (C) 2017, The Chromium OS Authors.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include 
+
+#include 
+#include 
+
+/**
+ * struct media_request_generic - request enabled for the generic queue
+ *
+ * @base:  base request member
+ * @queue: entry in media_request_queue_generic::queued_requests
+ */
+struct media_request_generic {
+   struct media_request base;
+   struct list_head queue;
+};
+#define to_generic_request(r) \
+   container_of(r, struct media_request_generic, base)
+
+/**
+ * struct media_request_queue_generic - generic request queue implementation
+ *
+ * Implements a simple request queue, where the next queued request is executed
+ * as soon as the previous one completes.
+ *
+ * @base:  base request queue member
+ * @mutex: protects the queue
+ * @queued_requests:   list of requests to be sequentially executed
+ */
+struct media_request_queue_generic {
+   struct media_request_queue base;
+
+   struct list_head queued_requests;
+};
+#define to_generic_queue(q) \
+   container_of(q, struct media_request_queue_generic, base)
+
+static struct media_request *
+media_request_generic_alloc(struct media_request_queue *queue)
+{
+   struct media_request_generic *req;
+
+   req = kzalloc(sizeof(*req), GFP_KERNEL);
+   if (!req)
+   return ERR_PTR(-ENOMEM);
+
+   return >base;
+}
+
+static void media_request_generic_free(struct media_request_queue *queue,
+  struct media_request *_req)
+{
+   struct media_request_generic *req = to_generic_request(_req);
+
+   kfree(req);
+}
+
+static void schedule_next_req(struct media_request_queue_generic *queue)
+{
+   struct media_request_generic *req;
+   struct media_request_entity_data *data;
+
+   req = list_first_entry_or_null(>queued_requests, typeof(*req),
+  queue);
+   if (!req)
+   return;
+
+   list_del(>queue);
+   queue->base.active_request = >base;
+
+   list_for_each_entry(data, >base.data, list) {
+   int ret;
+
+   ret = data->entity->req_ops->apply_data(data);
+   }
+
+   list_for_each_entry(data, >base.data, list) {
+   data->entity->ops->process_request(>base, data);
+   }
+}
+
+static void media_request_generic_complete(struct media_request_queue *_queue)
+{
+   struct media_request_queue_generic *queue = to_generic_queue(_queue);
+
+   queue->base.active_request = NULL;
+   schedule_next_req(queue);
+}
+
+static int media_request_generic_queue(struct media_request_queue *_queue,
+  struct media_request *_req)
+{
+   struct media_request_queue_generic *queue = to_generic_queue(_queue);
+   struct media_request_generic *req = to_generic_request(_req);
+
+   list_add_tail(>queue, >queued_requests);
+
+   if (!queue->base.active_request)
+   schedule_next_req(queue);
+
+   return 0;
+}
+
+static void
+media_request_generic_queue_release(struct media_request_queue *_queue)
+{
+   struct media_request_queue_generic *queue = to_generic_queue(_queue);
+
+   media_request_queue_release(>base);
+   kfree(queue);

[RFC PATCH 4/9] videodev2.h: Add request field to v4l2_buffer

2017-12-14 Thread Alexandre Courbot
From: Hans Verkuil 

When queuing buffers allow for passing the request ID that
should be associated with this buffer.

Signed-off-by: Hans Verkuil 
[acour...@chromium.org: make request ID 32-bit]
Signed-off-by: Alexandre Courbot 
---
 drivers/media/usb/cpia2/cpia2_v4l.c   | 2 +-
 drivers/media/v4l2-core/v4l2-compat-ioctl32.c | 7 ---
 drivers/media/v4l2-core/v4l2-ioctl.c  | 4 ++--
 drivers/media/v4l2-core/videobuf2-v4l2.c  | 3 ++-
 include/media/videobuf2-v4l2.h| 2 ++
 include/uapi/linux/videodev2.h| 3 ++-
 6 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/drivers/media/usb/cpia2/cpia2_v4l.c 
b/drivers/media/usb/cpia2/cpia2_v4l.c
index 3dedd83f0b19..7217dde95a8a 100644
--- a/drivers/media/usb/cpia2/cpia2_v4l.c
+++ b/drivers/media/usb/cpia2/cpia2_v4l.c
@@ -948,7 +948,7 @@ static int cpia2_dqbuf(struct file *file, void *fh, struct 
v4l2_buffer *buf)
buf->sequence = cam->buffers[buf->index].seq;
buf->m.offset = cam->buffers[buf->index].data - cam->frame_buffer;
buf->length = cam->frame_size;
-   buf->reserved2 = 0;
+   buf->request = 0;
buf->reserved = 0;
memset(>timecode, 0, sizeof(buf->timecode));
 
diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c 
b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
index 821f2aa299ae..94f07c3b0b53 100644
--- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
+++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
@@ -370,7 +370,7 @@ struct v4l2_buffer32 {
__s32   fd;
} m;
__u32   length;
-   __u32   reserved2;
+   __u32   request;
__u32   reserved;
 };
 
@@ -438,7 +438,8 @@ static int get_v4l2_buffer32(struct v4l2_buffer *kp, struct 
v4l2_buffer32 __user
get_user(kp->type, >type) ||
get_user(kp->flags, >flags) ||
get_user(kp->memory, >memory) ||
-   get_user(kp->length, >length))
+   get_user(kp->length, >length) ||
+   get_user(kp->request, >request))
return -EFAULT;
 
if (V4L2_TYPE_IS_OUTPUT(kp->type))
@@ -533,7 +534,7 @@ static int put_v4l2_buffer32(struct v4l2_buffer *kp, struct 
v4l2_buffer32 __user
put_user(kp->timestamp.tv_usec, >timestamp.tv_usec) ||
copy_to_user(>timecode, >timecode, sizeof(struct 
v4l2_timecode)) ||
put_user(kp->sequence, >sequence) ||
-   put_user(kp->reserved2, >reserved2) ||
+   put_user(kp->request, >request) ||
put_user(kp->reserved, >reserved) ||
put_user(kp->length, >length))
return -EFAULT;
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c 
b/drivers/media/v4l2-core/v4l2-ioctl.c
index ec4ecd5aa8bf..8d041247e97f 100644
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
@@ -437,13 +437,13 @@ static void v4l_print_buffer(const void *arg, bool 
write_only)
const struct v4l2_plane *plane;
int i;
 
-   pr_cont("%02ld:%02d:%02d.%08ld index=%d, type=%s, flags=0x%08x, 
field=%s, sequence=%d, memory=%s",
+   pr_cont("%02ld:%02d:%02d.%08ld index=%d, type=%s, request=%u, 
flags=0x%08x, field=%s, sequence=%d, memory=%s",
p->timestamp.tv_sec / 3600,
(int)(p->timestamp.tv_sec / 60) % 60,
(int)(p->timestamp.tv_sec % 60),
(long)p->timestamp.tv_usec,
p->index,
-   prt_names(p->type, v4l2_type_names),
+   prt_names(p->type, v4l2_type_names), p->request,
p->flags, prt_names(p->field, v4l2_field_names),
p->sequence, prt_names(p->memory, v4l2_memory_names));
 
diff --git a/drivers/media/v4l2-core/videobuf2-v4l2.c 
b/drivers/media/v4l2-core/videobuf2-v4l2.c
index 0c0669976bdc..bde7b8a3a303 100644
--- a/drivers/media/v4l2-core/videobuf2-v4l2.c
+++ b/drivers/media/v4l2-core/videobuf2-v4l2.c
@@ -203,7 +203,7 @@ static void __fill_v4l2_buffer(struct vb2_buffer *vb, void 
*pb)
b->timestamp = ns_to_timeval(vb->timestamp);
b->timecode = vbuf->timecode;
b->sequence = vbuf->sequence;
-   b->reserved2 = 0;
+   b->request = vbuf->request;
b->reserved = 0;
 
if (q->is_multiplanar) {
@@ -320,6 +320,7 @@ static int __fill_vb2_buffer(struct vb2_buffer *vb,
}
vb->timestamp = 0;
vbuf->sequence = 0;
+   vbuf->request = b->request;
 
if (V4L2_TYPE_IS_MULTIPLANAR(b->type)) {
if (b->memory == VB2_MEMORY_USERPTR) {
diff --git a/include/media/videobuf2-v4l2.h b/include/media/videobuf2-v4l2.h
index 036127c54bbf..ef2be0ccff14 100644
--- a/include/media/videobuf2-v4l2.h
+++ 

[RFC PATCH 1/9] media: add request API core and UAPI

2017-12-14 Thread Alexandre Courbot
The request API provides a way to group buffers and device parameters
into units of work to be queued and executed. This patch introduces the
UAPI and core framework.

This patch is based on the previous work by Laurent Pinchart. The core
has changed considerably, but the UAPI is mostly untouched.

Signed-off-by: Alexandre Courbot 
---
 drivers/media/Makefile   |   3 +-
 drivers/media/media-device.c |   6 +
 drivers/media/media-request.c| 390 +++
 drivers/media/v4l2-core/v4l2-ioctl.c |   2 +-
 include/media/media-device.h |   3 +
 include/media/media-entity.h |   6 +
 include/media/media-request.h| 269 
 include/uapi/linux/media.h   |  11 +
 8 files changed, 688 insertions(+), 2 deletions(-)
 create mode 100644 drivers/media/media-request.c
 create mode 100644 include/media/media-request.h

diff --git a/drivers/media/Makefile b/drivers/media/Makefile
index 594b462ddf0e..985d35ec6b29 100644
--- a/drivers/media/Makefile
+++ b/drivers/media/Makefile
@@ -3,7 +3,8 @@
 # Makefile for the kernel multimedia device drivers.
 #
 
-media-objs := media-device.o media-devnode.o media-entity.o
+media-objs := media-device.o media-devnode.o media-entity.o \
+  media-request.o
 
 #
 # I2C drivers should come before other drivers, otherwise they'll fail
diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c
index e79f72b8b858..045cec7d2de9 100644
--- a/drivers/media/media-device.c
+++ b/drivers/media/media-device.c
@@ -32,6 +32,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #ifdef CONFIG_MEDIA_CONTROLLER
 
@@ -407,6 +408,7 @@ static const struct media_ioctl_info ioctl_info[] = {
MEDIA_IOC(ENUM_LINKS, media_device_enum_links, 
MEDIA_IOC_FL_GRAPH_MUTEX),
MEDIA_IOC(SETUP_LINK, media_device_setup_link, 
MEDIA_IOC_FL_GRAPH_MUTEX),
MEDIA_IOC(G_TOPOLOGY, media_device_get_topology, 
MEDIA_IOC_FL_GRAPH_MUTEX),
+   MEDIA_IOC(REQUEST_CMD, media_device_request_cmd, 0),
 };
 
 static long media_device_ioctl(struct file *filp, unsigned int cmd,
@@ -688,6 +690,10 @@ EXPORT_SYMBOL_GPL(media_device_init);
 
 void media_device_cleanup(struct media_device *mdev)
 {
+   if (mdev->req_queue) {
+   mdev->req_queue->ops->release(mdev->req_queue);
+   mdev->req_queue = NULL;
+   }
ida_destroy(>entity_internal_idx);
mdev->entity_internal_idx_max = 0;
media_graph_walk_cleanup(>pm_count_walk);
diff --git a/drivers/media/media-request.c b/drivers/media/media-request.c
new file mode 100644
index ..15dc65ddfe41
--- /dev/null
+++ b/drivers/media/media-request.c
@@ -0,0 +1,390 @@
+/*
+ * Request and request queue base management
+ *
+ * Copyright (C) 2017, The Chromium OS Authors.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+
+const struct file_operations request_fops;
+
+void media_request_get(struct media_request *req)
+{
+   kref_get(>kref);
+}
+EXPORT_SYMBOL_GPL(media_request_get);
+
+struct media_request *
+media_request_get_from_fd(int fd)
+{
+   struct file *f;
+   struct media_request *req;
+
+   f = fget(fd);
+   if (!f)
+   return NULL;
+
+   /* Not a request FD? */
+   if (f->f_op != _fops) {
+   fput(f);
+   return NULL;
+   }
+
+   req = f->private_data;
+   media_request_get(req);
+   fput(f);
+
+   return req;
+}
+EXPORT_SYMBOL_GPL(media_request_get_from_fd);
+
+static void media_request_release(struct kref *kref)
+{
+   struct media_request_entity_data *data, *next;
+   struct media_request *req =
+   container_of(kref, typeof(*req), kref);
+   struct media_device *mdev = req->queue->mdev;
+
+   dev_dbg(mdev->dev, "%s: releasing request %u\n", __func__, req->id);
+
+   list_del(>list);
+   list_for_each_entry_safe(data, next, >data, list) {
+   list_del(>list);
+   data->entity->req_ops->release_data(data);
+   }
+
+   req->queue->ops->req_free(req->queue, req);
+}
+
+void media_request_put(struct media_request *req)
+{
+   kref_put(>kref, media_request_release);
+}
+EXPORT_SYMBOL_GPL(media_request_put);
+
+struct media_request_entity_data *
+media_request_get_entity_data(struct media_request *req,
+ struct media_entity *entity, void *fh)
+{
+   struct 

[RFC PATCH 8/9] media: vim2m: add media device

2017-12-14 Thread Alexandre Courbot
Request API requires a media node. Add one to the vim2m driver so we can
use requests with it.

Signed-off-by: Alexandre Courbot 
---
 drivers/media/platform/vim2m.c | 24 
 1 file changed, 24 insertions(+)

diff --git a/drivers/media/platform/vim2m.c b/drivers/media/platform/vim2m.c
index b01fba020d5f..a32e8a7950eb 100644
--- a/drivers/media/platform/vim2m.c
+++ b/drivers/media/platform/vim2m.c
@@ -140,6 +140,9 @@ static struct vim2m_fmt *find_format(struct v4l2_format *f)
 struct vim2m_dev {
struct v4l2_device  v4l2_dev;
struct video_device vfd;
+#ifdef CONFIG_MEDIA_CONTROLLER
+   struct media_device mdev;
+#endif
 
atomic_tnum_inst;
struct mutexdev_mutex;
@@ -1001,6 +1004,13 @@ static int vim2m_probe(struct platform_device *pdev)
 
spin_lock_init(>irqlock);
 
+#ifdef CONFIG_MEDIA_CONTROLLER
+   dev->mdev.dev = >dev;
+   strlcpy(dev->mdev.model, "vim2m", sizeof(dev->mdev.model));
+   media_device_init(>mdev);
+   dev->v4l2_dev.mdev = >mdev;
+#endif
+
ret = v4l2_device_register(>dev, >v4l2_dev);
if (ret)
return ret;
@@ -1034,6 +1044,13 @@ static int vim2m_probe(struct platform_device *pdev)
goto err_m2m;
}
 
+#ifdef CONFIG_MEDIA_CONTROLLER
+   /* Register the media device node */
+   ret = media_device_register(>mdev);
+   if (ret)
+   goto err_m2m;
+#endif
+
return 0;
 
 err_m2m:
@@ -1050,6 +1067,13 @@ static int vim2m_remove(struct platform_device *pdev)
struct vim2m_dev *dev = platform_get_drvdata(pdev);
 
v4l2_info(>v4l2_dev, "Removing " MEM2MEM_NAME);
+
+#ifdef CONFIG_MEDIA_CONTROLLER
+   if (media_devnode_is_registered(dev->mdev.devnode))
+   media_device_unregister(>mdev);
+   media_device_cleanup(>mdev);
+#endif
+
v4l2_m2m_release(dev->m2m_dev);
del_timer_sync(>timer);
video_unregister_device(>vfd);
-- 
2.15.1.504.g5279b80103-goog



[RFC PATCH 6/9] media: vb2: add support for requests in QBUF ioctl

2017-12-14 Thread Alexandre Courbot
Support the request argument of the QBUF ioctl.

Signed-off-by: Alexandre Courbot 
---
 drivers/media/v4l2-core/v4l2-ioctl.c | 93 +++-
 1 file changed, 92 insertions(+), 1 deletion(-)

diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c 
b/drivers/media/v4l2-core/v4l2-ioctl.c
index 8d041247e97f..28f9c368563e 100644
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
@@ -29,6 +29,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 
@@ -965,6 +966,81 @@ static int check_fmt(struct file *file, enum v4l2_buf_type 
type)
return -EINVAL;
 }
 
+/*
+ * Validate that a given request can be used during an ioctl.
+ *
+ * When using the request API, request file descriptors must be matched against
+ * the actual request object. User-space can pass any file descriptor, so we
+ * need to make sure the call is valid before going further.
+ *
+ * This function looks up the request and associated data and performs the
+ * following sanity checks:
+ *
+ * * Make sure that the entity supports requests,
+ * * Make sure that the entity belongs to the media_device managing the passed
+ *   request,
+ * * Make sure that the entity data (if any) is associated to the current file
+ *   handler.
+ *
+ * This function returns a pointer to the valid request, or and error code in
+ * case of failure. When successful, a reference to the request is acquired and
+ * must be properly released.
+ */
+#ifdef CONFIG_MEDIA_CONTROLLER
+static struct media_request *
+check_request(int request, struct file *file, void *fh)
+{
+   struct media_request *req = NULL;
+   struct video_device *vfd = video_devdata(file);
+   struct v4l2_fh *vfh =
+   test_bit(V4L2_FL_USES_V4L2_FH, >flags) ? fh : NULL;
+   struct media_entity *entity = >entity;
+   const struct media_entity *ent;
+   struct media_request_entity_data *data;
+   bool found = false;
+
+   if (!entity)
+   return ERR_PTR(-EINVAL);
+
+   /* Check that the entity supports requests */
+   if (!entity->req_ops)
+   return ERR_PTR(-ENOTSUPP);
+
+   req = media_request_get_from_fd(request);
+   if (!req)
+   return ERR_PTR(-EINVAL);
+
+   /* Validate that the entity belongs to the media_device managing
+* the request queue */
+   media_device_for_each_entity(ent, req->queue->mdev) {
+   if (entity == ent) {
+   found = true;
+   break;
+   }
+   }
+   if (!found) {
+   media_request_put(req);
+   return ERR_PTR(-EINVAL);
+   }
+
+   /* Validate that the entity's data belongs to the correct fh */
+   data = media_request_get_entity_data(req, entity, vfh);
+   if (IS_ERR(data)) {
+   media_request_put(req);
+   return ERR_PTR(PTR_ERR(data));
+   }
+
+   return req;
+}
+#else /* CONFIG_MEDIA_CONTROLLER */
+static struct media_request *
+check_request(int request, struct file *file, void *fh)
+{
+   return ERR_PTR(-ENOTSUPP);
+}
+
+#endif /* CONFIG_MEDIA_CONTROLLER */
+
 static void v4l_sanitize_format(struct v4l2_format *fmt)
 {
unsigned int offset;
@@ -1902,10 +1978,25 @@ static int v4l_querybuf(const struct v4l2_ioctl_ops 
*ops,
 static int v4l_qbuf(const struct v4l2_ioctl_ops *ops,
struct file *file, void *fh, void *arg)
 {
+   struct media_request *req = NULL;
struct v4l2_buffer *p = arg;
int ret = check_fmt(file, p->type);
 
-   return ret ? ret : ops->vidioc_qbuf(file, fh, p);
+   if (ret)
+   return ret;
+
+   if (p->request > 0) {
+   req = check_request(p->request, file, fh);
+   if (IS_ERR(req))
+   return PTR_ERR(req);
+   }
+
+   ret = ops->vidioc_qbuf(file, fh, p);
+
+   if (req)
+   media_request_put(req);
+
+   return ret;
 }
 
 static int v4l_dqbuf(const struct v4l2_ioctl_ops *ops,
-- 
2.15.1.504.g5279b80103-goog



[RFC PATCH 5/9] media: vb2: add support for requests

2017-12-14 Thread Alexandre Courbot
Add throttling support for buffers when requests are in use on a given
queue. Buffers associated to a request are kept into the vb2 queue until
the request becomes active, at which point all the buffers are passed to
the driver. The queue can also signal that is has processed all of a
request's buffers.

Also add support for the request parameter when handling the QBUF ioctl.

Signed-off-by: Alexandre Courbot 
---
 drivers/media/v4l2-core/videobuf2-core.c | 59 
 drivers/media/v4l2-core/videobuf2-v4l2.c | 29 +++-
 include/media/videobuf2-core.h   | 25 +-
 3 files changed, 104 insertions(+), 9 deletions(-)

diff --git a/drivers/media/v4l2-core/videobuf2-core.c 
b/drivers/media/v4l2-core/videobuf2-core.c
index cb115ba6a1d2..c01038b7962a 100644
--- a/drivers/media/v4l2-core/videobuf2-core.c
+++ b/drivers/media/v4l2-core/videobuf2-core.c
@@ -898,6 +898,8 @@ void vb2_buffer_done(struct vb2_buffer *vb, enum 
vb2_buffer_state state)
state != VB2_BUF_STATE_REQUEUEING))
state = VB2_BUF_STATE_ERROR;
 
+   WARN_ON(vb->request != q->cur_req);
+
 #ifdef CONFIG_VIDEO_ADV_DEBUG
/*
 * Although this is not a callback, it still does have to balance
@@ -920,6 +922,13 @@ void vb2_buffer_done(struct vb2_buffer *vb, enum 
vb2_buffer_state state)
/* Add the buffer to the done buffers list */
list_add_tail(>done_entry, >done_list);
vb->state = state;
+
+   if (q->cur_req) {
+   WARN_ON(q->req_buf_cnt < 1);
+
+   if (--q->req_buf_cnt == 0)
+   q->cur_req = NULL;
+   }
}
atomic_dec(>owned_by_drv_count);
spin_unlock_irqrestore(>done_lock, flags);
@@ -1298,6 +1307,16 @@ int vb2_core_prepare_buf(struct vb2_queue *q, unsigned 
int index, void *pb)
 }
 EXPORT_SYMBOL_GPL(vb2_core_prepare_buf);
 
+static void vb2_queue_enqueue_current_buffers(struct vb2_queue *q)
+{
+   struct vb2_buffer *vb;
+
+   list_for_each_entry(vb, >queued_list, queued_entry) {
+   if (vb->request == q->cur_req)
+   __enqueue_in_driver(vb);
+   }
+}
+
 /**
  * vb2_start_streaming() - Attempt to start streaming.
  * @q: videobuf2 queue
@@ -1318,8 +1337,7 @@ static int vb2_start_streaming(struct vb2_queue *q)
 * If any buffers were queued before streamon,
 * we can now pass them to driver for processing.
 */
-   list_for_each_entry(vb, >queued_list, queued_entry)
-   __enqueue_in_driver(vb);
+   vb2_queue_enqueue_current_buffers(q);
 
/* Tell the driver to start streaming */
q->start_streaming_called = 1;
@@ -1361,7 +1379,8 @@ static int vb2_start_streaming(struct vb2_queue *q)
return ret;
 }
 
-int vb2_core_qbuf(struct vb2_queue *q, unsigned int index, void *pb)
+int vb2_core_qbuf(struct vb2_queue *q, unsigned int index,
+ struct media_request *req, void *pb)
 {
struct vb2_buffer *vb;
int ret;
@@ -1392,6 +1411,7 @@ int vb2_core_qbuf(struct vb2_queue *q, unsigned int 
index, void *pb)
q->queued_count++;
q->waiting_for_buffers = false;
vb->state = VB2_BUF_STATE_QUEUED;
+   vb->request = req;
 
if (pb)
call_void_bufop(q, copy_timestamp, vb, pb);
@@ -1401,8 +1421,11 @@ int vb2_core_qbuf(struct vb2_queue *q, unsigned int 
index, void *pb)
/*
 * If already streaming, give the buffer to driver for processing.
 * If not, the buffer will be given to driver on next streamon.
+*
+* If using the request API, the buffer will be given to the driver
+* when the request becomes active.
 */
-   if (q->start_streaming_called)
+   if (q->start_streaming_called && !req)
__enqueue_in_driver(vb);
 
/* Fill buffer information for the userspace */
@@ -1427,6 +1450,28 @@ int vb2_core_qbuf(struct vb2_queue *q, unsigned int 
index, void *pb)
 }
 EXPORT_SYMBOL_GPL(vb2_core_qbuf);
 
+void vb2_queue_start_request(struct vb2_queue *q, struct media_request *req)
+{
+   struct vb2_buffer *vb;
+
+   q->req_buf_cnt = 0;
+   list_for_each_entry(vb, >queued_list, queued_entry) {
+   if (vb->request == req)
+   ++q->req_buf_cnt;
+   }
+
+   /* only consider the request if we actually have buffers for it */
+   if (q->req_buf_cnt == 0)
+   return;
+
+   q->cur_req = req;
+
+   /* If not streaming yet, we will enqueue the buffers later */
+   if (q->start_streaming_called)
+   vb2_queue_enqueue_current_buffers(q);
+}
+EXPORT_SYMBOL_GPL(vb2_queue_start_request);
+
 /**
  * __vb2_wait_for_done_vb() - wait for a buffer to become available
  * for dequeuing
@@ -2242,7 +2287,7 @@ static int __vb2_init_fileio(struct vb2_queue *q, int 

[RFC PATCH 7/9] media: v4l2-mem2mem: add request support

2017-12-14 Thread Alexandre Courbot
Support request API in the mem2mem framework. Drivers that specify ops
for the queue and entities can support requests seamlessly.

Signed-off-by: Alexandre Courbot 
---
 drivers/media/v4l2-core/v4l2-mem2mem.c | 34 ++
 include/media/v4l2-mem2mem.h   | 19 +++
 2 files changed, 53 insertions(+)

diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c 
b/drivers/media/v4l2-core/v4l2-mem2mem.c
index f62e68aa04c4..eb52bee8e06a 100644
--- a/drivers/media/v4l2-core/v4l2-mem2mem.c
+++ b/drivers/media/v4l2-core/v4l2-mem2mem.c
@@ -22,6 +22,7 @@
 #include 
 #include 
 #include 
+#include 
 
 MODULE_DESCRIPTION("Mem to mem device framework for videobuf");
 MODULE_AUTHOR("Pawel Osciak, ");
@@ -219,6 +220,15 @@ void v4l2_m2m_try_schedule(struct v4l2_m2m_ctx *m2m_ctx)
m2m_dev = m2m_ctx->m2m_dev;
dprintk("Trying to schedule a job for m2m_ctx: %p\n", m2m_ctx);
 
+#ifdef CONFIG_MEDIA_CONTROLLER
+   /* request is completed if all queues are done with it */
+   if (m2m_ctx->req_queue && m2m_ctx->req_queue->active_request &&
+   m2m_ctx->cap_q_ctx.q.cur_req == NULL &&
+   m2m_ctx->out_q_ctx.q.cur_req == NULL)
+   media_request_entity_complete(m2m_ctx->req_queue,
+ m2m_ctx->entity);
+#endif
+
if (!m2m_ctx->out_q_ctx.q.streaming
|| !m2m_ctx->cap_q_ctx.q.streaming) {
dprintk("Streaming needs to be on for both queues\n");
@@ -665,6 +675,15 @@ struct v4l2_m2m_ctx *v4l2_m2m_ctx_init(struct v4l2_m2m_dev 
*m2m_dev,
 }
 EXPORT_SYMBOL_GPL(v4l2_m2m_ctx_init);
 
+void v4l2_mem_ctx_request_init(struct v4l2_m2m_ctx *ctx,
+  struct media_request_queue *req_queue,
+  struct media_entity *entity)
+{
+   ctx->entity = entity;
+   ctx->req_queue = req_queue;
+}
+EXPORT_SYMBOL_GPL(v4l2_mem_ctx_request_init);
+
 void v4l2_m2m_ctx_release(struct v4l2_m2m_ctx *m2m_ctx)
 {
/* wait until the current context is dequeued from job_queue */
@@ -810,3 +829,18 @@ unsigned int v4l2_m2m_fop_poll(struct file *file, 
poll_table *wait)
 }
 EXPORT_SYMBOL_GPL(v4l2_m2m_fop_poll);
 
+int v4l2_m2m_process_request(struct media_request *req,
+struct media_request_entity_data *data)
+{
+#ifdef CONFIG_MEDIA_CONTROLLER
+   struct v4l2_fh *fh = data->fh;
+   struct v4l2_m2m_ctx *ctx = fh->m2m_ctx;
+
+   vb2_queue_start_request(>cap_q_ctx.q, req);
+   vb2_queue_start_request(>out_q_ctx.q, req);
+
+   v4l2_m2m_try_schedule(ctx);
+#endif
+   return 0;
+}
+EXPORT_SYMBOL_GPL(v4l2_m2m_process_request);
diff --git a/include/media/v4l2-mem2mem.h b/include/media/v4l2-mem2mem.h
index e157d5c9b224..1c9925c3d4ce 100644
--- a/include/media/v4l2-mem2mem.h
+++ b/include/media/v4l2-mem2mem.h
@@ -19,6 +19,10 @@
 
 #include 
 
+struct media_entity;
+struct media_request;
+struct media_request_entity_data;
+
 /**
  * struct v4l2_m2m_ops - mem-to-mem device driver callbacks
  * @device_run:required. Begin the actual job (transaction) inside this
@@ -83,6 +87,7 @@ struct v4l2_m2m_queue_ctx {
  *
  * @q_lock: struct  lock
  * @m2m_dev: opaque pointer to the internal data to handle M2M context
+ * @state: Pointer to state handler for channel support
  * @cap_q_ctx: Capture (output to memory) queue context
  * @out_q_ctx: Output (input from memory) queue context
  * @queue: List of memory to memory contexts
@@ -100,6 +105,8 @@ struct v4l2_m2m_ctx {
 
/* internal use only */
struct v4l2_m2m_dev *m2m_dev;
+   struct media_request_queue  *req_queue;
+   struct media_entity *entity;
 
struct v4l2_m2m_queue_ctx   cap_q_ctx;
 
@@ -351,6 +358,16 @@ struct v4l2_m2m_ctx *v4l2_m2m_ctx_init(struct v4l2_m2m_dev 
*m2m_dev,
void *drv_priv,
int (*queue_init)(void *priv, struct vb2_queue *src_vq, struct 
vb2_queue *dst_vq));
 
+/**
+ * v4l2_mem_ctx_request_init() - enable a context to be used with requests
+ *
+ * @ctx: context to potentially use within a channel
+ * @req_queue: request queue that will be used with this context
+ */
+void v4l2_mem_ctx_request_init(struct v4l2_m2m_ctx *ctx,
+  struct media_request_queue *req_queue,
+  struct media_entity *entity);
+
 static inline void v4l2_m2m_set_src_buffered(struct v4l2_m2m_ctx *m2m_ctx,
 bool buffered)
 {
@@ -602,6 +619,8 @@ int v4l2_m2m_ioctl_streamoff(struct file *file, void *fh,
enum v4l2_buf_type type);
 int v4l2_m2m_fop_mmap(struct file *file, struct vm_area_struct *vma);
 unsigned int v4l2_m2m_fop_poll(struct file *file, poll_table *wait);
+int v4l2_m2m_process_request(struct media_request *req,
+struct media_request_entity_data *data);
 
 #endif /* 

[RFC PATCH 9/9] media: vim2m: add request support

2017-12-14 Thread Alexandre Courbot
Set the necessary ops for supporting requests in vim2m.

Signed-off-by: Alexandre Courbot 
---
 drivers/media/platform/vim2m.c | 22 ++
 1 file changed, 22 insertions(+)

diff --git a/drivers/media/platform/vim2m.c b/drivers/media/platform/vim2m.c
index a32e8a7950eb..ffe94ef9214d 100644
--- a/drivers/media/platform/vim2m.c
+++ b/drivers/media/platform/vim2m.c
@@ -30,6 +30,7 @@
 #include 
 #include 
 #include 
+#include 
 
 MODULE_DESCRIPTION("Virtual device for mem2mem framework testing");
 MODULE_AUTHOR("Pawel Osciak, ");
@@ -142,6 +143,7 @@ struct vim2m_dev {
struct video_device vfd;
 #ifdef CONFIG_MEDIA_CONTROLLER
struct media_device mdev;
+   struct media_request_queue *req_queue;
 #endif
 
atomic_tnum_inst;
@@ -937,6 +939,11 @@ static int vim2m_open(struct file *file)
goto open_unlock;
}
 
+#ifdef CONFIG_MEDIA_CONTROLLER
+   v4l2_mem_ctx_request_init(ctx->fh.m2m_ctx, dev->req_queue,
+ >vfd.entity);
+#endif
+
v4l2_fh_add(>fh);
atomic_inc(>num_inst);
 
@@ -992,6 +999,12 @@ static const struct v4l2_m2m_ops m2m_ops = {
.job_abort  = job_abort,
 };
 
+#ifdef CONFIG_MEDIA_CONTROLLER
+static const struct media_entity_operations vim2m_entity_ops = {
+   .process_request = v4l2_m2m_process_request,
+};
+#endif
+
 static int vim2m_probe(struct platform_device *pdev)
 {
struct vim2m_dev *dev;
@@ -1006,6 +1019,10 @@ static int vim2m_probe(struct platform_device *pdev)
 
 #ifdef CONFIG_MEDIA_CONTROLLER
dev->mdev.dev = >dev;
+   dev->req_queue = media_request_queue_generic_alloc(>mdev);
+   if (IS_ERR(dev->req_queue))
+   return PTR_ERR(dev->req_queue);
+   dev->mdev.req_queue = dev->req_queue;
strlcpy(dev->mdev.model, "vim2m", sizeof(dev->mdev.model));
media_device_init(>mdev);
dev->v4l2_dev.mdev = >mdev;
@@ -1023,6 +1040,11 @@ static int vim2m_probe(struct platform_device *pdev)
vfd->lock = >dev_mutex;
vfd->v4l2_dev = >v4l2_dev;
 
+#ifdef CONFIG_MEDIA_CONTROLLER
+   vfd->entity.ops = _entity_ops;
+   vfd->entity.req_ops = _entity_request_generic_ops;
+#endif
+
ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0);
if (ret) {
v4l2_err(>v4l2_dev, "Failed to register video device\n");
-- 
2.15.1.504.g5279b80103-goog



[RFC PATCH 3/9] media: request: add generic entity ops

2017-12-14 Thread Alexandre Courbot
Add skeleton ops for generic entities. The intent is to provide a
generic mechanism to apply request parameters to entities using regular
media/v4l2 functions.

Signed-off-by: Alexandre Courbot 
---
 drivers/media/Makefile   |  3 +-
 drivers/media/media-request-entity-generic.c | 56 
 include/media/media-request.h|  5 +++
 3 files changed, 63 insertions(+), 1 deletion(-)
 create mode 100644 drivers/media/media-request-entity-generic.c

diff --git a/drivers/media/Makefile b/drivers/media/Makefile
index 90117fff1339..dea482f6ab72 100644
--- a/drivers/media/Makefile
+++ b/drivers/media/Makefile
@@ -4,7 +4,8 @@
 #
 
 media-objs := media-device.o media-devnode.o media-entity.o \
-  media-request.o media-request-queue-generic.o
+  media-request.o media-request-queue-generic.o \
+  media-request-entity-generic.o
 
 #
 # I2C drivers should come before other drivers, otherwise they'll fail
diff --git a/drivers/media/media-request-entity-generic.c 
b/drivers/media/media-request-entity-generic.c
new file mode 100644
index ..18e53f9ce525
--- /dev/null
+++ b/drivers/media/media-request-entity-generic.c
@@ -0,0 +1,56 @@
+/*
+ * Media generic entity ops
+ *
+ * Copyright (C) 2017, The Chromium OS Authors.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include 
+
+#include 
+#include 
+
+struct media_request_entity_data_generic {
+   struct media_request_entity_data base;
+};
+
+static struct media_request_entity_data *
+alloc_req_data(struct media_request *req, struct media_entity *entity)
+{
+   struct media_request_entity_data_generic *ret;
+
+   ret = kzalloc(sizeof(*ret), GFP_KERNEL);
+   if (!ret)
+   return ERR_PTR(-ENOMEM);
+
+   return >base;
+}
+
+static void release_req_data(struct media_request_entity_data *_data)
+{
+   struct media_request_entity_data_generic *data;
+
+   data = container_of(_data, typeof(*data), base);
+   kfree(data);
+}
+
+static int apply_req_data(struct media_request_entity_data *_data)
+{
+   return 0;
+}
+
+const struct media_request_entity_ops
+media_entity_request_generic_ops = {
+   .alloc_data = alloc_req_data,
+   .release_data = release_req_data,
+   .apply_data = apply_req_data,
+};
+EXPORT_SYMBOL_GPL(media_entity_request_generic_ops);
diff --git a/include/media/media-request.h b/include/media/media-request.h
index 583a1116f735..de3d6d824ffd 100644
--- a/include/media/media-request.h
+++ b/include/media/media-request.h
@@ -240,6 +240,11 @@ struct media_request_entity_ops {
int (*apply_data)(struct media_request_entity_data *data);
 };
 
+/*
+ * Generic entity request support, built on top of standard V4L2 functions
+ */
+extern const struct media_request_entity_ops media_entity_request_generic_ops;
+
 /**
  * media_device_request_cmd() - perform the REQUEST_CMD ioctl
  *
-- 
2.15.1.504.g5279b80103-goog



Re: [PATCH] uvcvideo: Apply flags from device to actual properties

2017-12-14 Thread Edgar Thier
Hi,

Another month, another mail. Are there still issues keeping this from being 
merged?

Regards,

Edgar

On 11/15/2017 12:54 PM, Kieran Bingham wrote:
> Hi Edgar,
> 
> Thanks for addressing my concerns in this updated patch.
> 
> On 12/10/17 08:54, Edgar Thier wrote:
>>
>> Use flags the device exposes for UVC controls.
>> This allows the device to define which property flags are set.
>>
>> Since some cameras offer auto-adjustments for properties (e.g. auto-gain),
>> the values of other properties (e.g. gain) can change in the camera.
>> Examining the flags ensures that the driver is aware of such properties.
>>
>> Signed-off-by: Edgar Thier 
> 
> Reviewed-by: Kieran Bingham 
> 
>> ---
>>  drivers/media/usb/uvc/uvc_ctrl.c | 64 
>> ++--
>>  1 file changed, 49 insertions(+), 15 deletions(-)
>>
>> diff --git a/drivers/media/usb/uvc/uvc_ctrl.c 
>> b/drivers/media/usb/uvc/uvc_ctrl.c
>> index 20397aba..8f902a41 100644
>> --- a/drivers/media/usb/uvc/uvc_ctrl.c
>> +++ b/drivers/media/usb/uvc/uvc_ctrl.c
>> @@ -1629,6 +1629,40 @@ static void uvc_ctrl_fixup_xu_info(struct uvc_device 
>> *dev,
>>  }
>>  }
>>
>> +/*
>> + * Retrieve flags for a given control
>> + */
>> +static int uvc_ctrl_get_flags(struct uvc_device *dev, const struct 
>> uvc_control *ctrl,
>> +const struct uvc_control_info *info)
>> +{
>> +u8 *data;
>> +int ret = 0;
>> +int flags = 0;
>> +
>> +data = kmalloc(2, GFP_KERNEL);
>> +if (data == NULL)
>> +return -ENOMEM;
>> +
>> +ret = uvc_query_ctrl(dev, UVC_GET_INFO, ctrl->entity->id, dev->intfnum,
>> + info->selector, data, 1);
>> +if (ret < 0) {
>> +uvc_trace(UVC_TRACE_CONTROL,
>> +  "GET_INFO failed on control %pUl/%u (%d).\n",
>> +  info->entity, info->selector, ret);
>> +} else {
>> +flags = UVC_CTRL_FLAG_GET_MIN | UVC_CTRL_FLAG_GET_MAX
>> +| UVC_CTRL_FLAG_GET_RES | UVC_CTRL_FLAG_GET_DEF
>> +| (data[0] & UVC_CONTROL_CAP_GET ?
>> +   UVC_CTRL_FLAG_GET_CUR : 0)
>> +| (data[0] & UVC_CONTROL_CAP_SET ?
>> +   UVC_CTRL_FLAG_SET_CUR : 0)
>> +| (data[0] & UVC_CONTROL_CAP_AUTOUPDATE ?
>> +   UVC_CTRL_FLAG_AUTO_UPDATE : 0);
>> +}
>> +kfree(data);
>> +return flags;
>> +}
>> +
>>  /*
>>   * Query control information (size and flags) for XU controls.
>>   */
>> @@ -1636,6 +1670,7 @@ static int uvc_ctrl_fill_xu_info(struct uvc_device 
>> *dev,
>>  const struct uvc_control *ctrl, struct uvc_control_info *info)
>>  {
>>  u8 *data;
>> +int flags;
>>  int ret;
>>
>>  data = kmalloc(2, GFP_KERNEL);
>> @@ -1659,24 +1694,15 @@ static int uvc_ctrl_fill_xu_info(struct uvc_device 
>> *dev,
>>
>>  info->size = le16_to_cpup((__le16 *)data);
>>
>> -/* Query the control information (GET_INFO) */
>> -ret = uvc_query_ctrl(dev, UVC_GET_INFO, ctrl->entity->id, dev->intfnum,
>> - info->selector, data, 1);
>> -if (ret < 0) {
>> +flags = uvc_ctrl_get_flags(dev, ctrl, info);
>> +
>> +if (flags < 0) {
>>  uvc_trace(UVC_TRACE_CONTROL,
>> -  "GET_INFO failed on control %pUl/%u (%d).\n",
>> -  info->entity, info->selector, ret);
>> +  "Failed to retrieve flags (%d).\n", ret);
>> +ret = flags;
>>  goto done;
>>  }
>> -
>> -info->flags = UVC_CTRL_FLAG_GET_MIN | UVC_CTRL_FLAG_GET_MAX
>> -| UVC_CTRL_FLAG_GET_RES | UVC_CTRL_FLAG_GET_DEF
>> -| (data[0] & UVC_CONTROL_CAP_GET ?
>> -   UVC_CTRL_FLAG_GET_CUR : 0)
>> -| (data[0] & UVC_CONTROL_CAP_SET ?
>> -   UVC_CTRL_FLAG_SET_CUR : 0)
>> -| (data[0] & UVC_CONTROL_CAP_AUTOUPDATE ?
>> -   UVC_CTRL_FLAG_AUTO_UPDATE : 0);
>> +info->flags = flags;
>>
>>  uvc_ctrl_fixup_xu_info(dev, ctrl, info);
>>
>> @@ -1890,6 +1916,7 @@ static int uvc_ctrl_add_info(struct uvc_device *dev, 
>> struct uvc_control *ctrl,
>>  const struct uvc_control_info *info)
>>  {
>>  int ret = 0;
>> +int flags = 0;
>>
>>  ctrl->info = *info;
>>  INIT_LIST_HEAD(>info.mappings);
>> @@ -1902,6 +1929,13 @@ static int uvc_ctrl_add_info(struct uvc_device *dev, 
>> struct uvc_control *ctrl,
>>  goto done;
>>  }
>>
>> +flags = uvc_ctrl_get_flags(dev, ctrl, info);
>> +if (flags < 0)
>> +uvc_trace(UVC_TRACE_CONTROL,
>> +  "Failed to retrieve flags (%d).\n", ret);
>> +else
>> +ctrl->info.flags = flags;
>> +
>>  ctrl->initialized = 1;
>>
>>  uvc_trace(UVC_TRACE_CONTROL, "Added control %pUl/%u to device %s "
>>


Re: [PATCH] media: v4l: xilinx: Use SPDX-License-Identifier

2017-12-14 Thread Dhaval Shah
Hi Laurent/Mauro/Greg,

On Fri, Dec 15, 2017 at 3:32 AM, Laurent Pinchart
 wrote:
> Hi Mauro,
>
> On Thursday, 14 December 2017 23:50:03 EET Mauro Carvalho Chehab wrote:
>> Em Thu, 14 Dec 2017 21:57:06 +0100 Greg KH escreveu:
>> > On Thu, Dec 14, 2017 at 10:44:16PM +0200, Laurent Pinchart wrote:
>> >> On Thursday, 14 December 2017 22:08:51 EET Greg KH wrote:
>> >>> On Thu, Dec 14, 2017 at 09:05:27PM +0200, Laurent Pinchart wrote:
>>  On Thursday, 14 December 2017 20:54:39 EET Joe Perches wrote:
>> > On Thu, 2017-12-14 at 20:37 +0200, Laurent Pinchart wrote:
>> >> On Thursday, 14 December 2017 20:32:20 EET Joe Perches wrote:
>> >>> On Thu, 2017-12-14 at 20:28 +0200, Laurent Pinchart wrote:
>>  On Thursday, 14 December 2017 19:05:27 EET Mauro Carvalho Chehab
>>  wrote:
>> > Em Fri,  8 Dec 2017 18:05:37 +0530 Dhaval Shah escreveu:
>> >> SPDX-License-Identifier is used for the Xilinx Video IP and
>> >> related drivers.
>> >>
>> >> Signed-off-by: Dhaval Shah 
>> >
>> > Hi Dhaval,
>> >
>> > You're not listed as one of the Xilinx driver maintainers. I'm
>> > afraid that, without their explicit acks, sent to the ML, I
>> > can't accept a patch touching at the driver's license tags.
>> 
>>  The patch doesn't change the license, I don't see why it would
>>  cause any issue. Greg isn't listed as the maintainer or copyright
>>  holder of any of the 10k+ files to which he added an SPDX license
>>  header in the last kernel release.
>> >>>
>> >>> Adding a comment line that describes an implicit or
>> >>> explicit license is different than removing the license
>> >>> text itself.
>> >>
>> >> The SPDX license header is meant to be equivalent to the license
>> >> text.
>> >
>> > I understand that.
>> > At a minimum, removing BSD license text is undesirable
>> >
>> > as that license states:
>> >  ** Redistributions of source code must retain the above copyright
>> >  *  notice, this list of conditions and the following disclaimer.
>> >
>> > etc...
>> 
>>  But this patch only removes the following text:
>> 
>>  - * This program is free software; you can redistribute it and/or
>>  modify
>>  - * it under the terms of the GNU General Public License version 2 as
>>  - * published by the Free Software Foundation.
>> 
>>  and replaces it by the corresponding SPDX header.
>> 
>> >> The only reason why the large SPDX patch didn't touch the whole
>> >> kernel in one go was that it was easier to split in in multiple
>> >> chunks.
>> >
>> > Not really, it was scripted.
>> 
>>  But still manually reviewed as far as I know.
>> 
>> >> This is no different than not including the full GPL license in
>> >> every header file but only pointing to it through its name and
>> >> reference, as every kernel source file does.
>> >
>> > Not every kernel source file had a license text
>> > or a reference to another license file.
>> 
>>  Correct, but the files touched by this patch do.
>> 
>>  This issue is in no way specific to linux-media and should be
>>  decided upon at the top level, not on a per-subsystem basis. Greg,
>>  could you comment on this ?
>> >>>
>> >>> Comment on what exactly?  I don't understand the problem here, care to
>> >>> summarize it?
>> >>
>> >> In a nutshell (if I understand it correctly), Dhaval Shah submitted
>> >> https:// patchwork.kernel.org/patch/10102451/ which replaces
>> >>
>> >> +// SPDX-License-Identifier: GPL-2.0
>> >> [...]
>> >> - *
>> >> - * This program is free software; you can redistribute it and/or modify
>> >> - * it under the terms of the GNU General Public License version 2 as
>> >> - * published by the Free Software Foundation.
>> >>
>> >> in all .c and .h files of the Xilinx V4L2 driver
>> >> (drivers/media/platform/
>> >> xilinx). I have reviewed the patch and acked it. Mauro then rejected it,
>> >> stating that he can't accept a change to license text without an
>> >> explicit ack from the official driver's maintainers. My position is
>> >> that such a change doesn't change the license and thus doesn't need to
>> >> track all copyright holders, and can be merged without an explicit ack
>> >> from the respective maintainers.
>> >
>> > Yes, I agree with you, no license is being changed here, and no
>> > copyright is either.
>> >
>> > BUT, I know that most major companies are reviewing this process right
>> > now.  We have gotten approval from almost all of the major kernel
>> > developer companies to do this, which is great, and supports this work
>> > as being acceptable.
>> >
>> > So it's nice to ask Xilinx if they object to this happening, which I
>> > guess Mauro is trying to say here (in 

cron job: media_tree daily build: ERRORS

2017-12-14 Thread Hans Verkuil
This message is generated daily by a cron job that builds media_tree for
the kernels and architectures in the list below.

Results of the daily build of media_tree:

date:   Fri Dec 15 05:00:29 CET 2017
media-tree git hash:0ca4e3130402caea8731a7b54afde56a6edb17c9
media_build git hash:   4058fea6b2507661d66af5298c048d7c55338f42
v4l-utils git hash: 3561d59c1adf5faf3e29e9fd103ca5d8d4e855d4
gcc version:i686-linux-gcc (GCC) 7.1.0
sparse version: v0.5.0-3911-g6f737e1f
smatch version: v0.5.0-3911-g6f737e1f
host hardware:  x86_64
host os:4.13.0-164

linux-git-arm-at91: OK
linux-git-arm-davinci: ERRORS
linux-git-arm-multi: ERRORS
linux-git-arm-pxa: OK
linux-git-arm-stm32: OK
linux-git-blackfin-bf561: OK
linux-git-i686: OK
linux-git-m32r: OK
linux-git-mips: OK
linux-git-powerpc64: OK
linux-git-sh: ERRORS
linux-git-x86_64: OK
linux-2.6.36.4-i686: ERRORS
linux-2.6.37.6-i686: ERRORS
linux-2.6.38.8-i686: ERRORS
linux-2.6.39.4-i686: ERRORS
linux-3.0.60-i686: ERRORS
linux-3.1.10-i686: ERRORS
linux-3.2.37-i686: ERRORS
linux-3.3.8-i686: ERRORS
linux-3.4.27-i686: ERRORS
linux-3.5.7-i686: ERRORS
linux-3.6.11-i686: ERRORS
linux-3.7.4-i686: ERRORS
linux-3.8-i686: ERRORS
linux-3.9.2-i686: ERRORS
linux-3.10.1-i686: ERRORS
linux-3.11.1-i686: ERRORS
linux-3.12.67-i686: ERRORS
linux-3.13.11-i686: ERRORS
linux-3.14.9-i686: ERRORS
linux-3.15.2-i686: ERRORS
linux-3.16.7-i686: ERRORS
linux-3.17.8-i686: ERRORS
linux-3.18.7-i686: ERRORS
linux-3.19-i686: ERRORS
linux-4.0.9-i686: ERRORS
linux-4.1.33-i686: ERRORS
linux-4.2.8-i686: ERRORS
linux-4.3.6-i686: ERRORS
linux-4.4.22-i686: ERRORS
linux-4.5.7-i686: ERRORS
linux-4.6.7-i686: ERRORS
linux-4.7.5-i686: ERRORS
linux-4.8-i686: ERRORS
linux-4.9.26-i686: ERRORS
linux-4.10.14-i686: ERRORS
linux-4.11-i686: ERRORS
linux-4.12.1-i686: ERRORS
linux-4.13-i686: ERRORS
linux-4.14-i686: ERRORS
linux-2.6.36.4-x86_64: ERRORS
linux-2.6.37.6-x86_64: ERRORS
linux-2.6.38.8-x86_64: ERRORS
linux-2.6.39.4-x86_64: ERRORS
linux-3.0.60-x86_64: ERRORS
linux-3.1.10-x86_64: ERRORS
linux-3.2.37-x86_64: ERRORS
linux-3.3.8-x86_64: ERRORS
linux-3.4.27-x86_64: ERRORS
linux-3.5.7-x86_64: ERRORS
linux-3.6.11-x86_64: ERRORS
linux-3.7.4-x86_64: ERRORS
linux-3.8-x86_64: ERRORS
linux-3.9.2-x86_64: ERRORS
linux-3.10.1-x86_64: ERRORS
linux-3.11.1-x86_64: ERRORS
linux-3.12.67-x86_64: ERRORS
linux-3.13.11-x86_64: ERRORS
linux-3.14.9-x86_64: ERRORS
linux-3.15.2-x86_64: ERRORS
linux-3.16.7-x86_64: ERRORS
linux-3.17.8-x86_64: ERRORS
linux-3.18.7-x86_64: ERRORS
linux-3.19-x86_64: ERRORS
linux-4.0.9-x86_64: ERRORS
linux-4.1.33-x86_64: ERRORS
linux-4.2.8-x86_64: ERRORS
linux-4.3.6-x86_64: ERRORS
linux-4.4.22-x86_64: ERRORS
linux-4.5.7-x86_64: ERRORS
linux-4.6.7-x86_64: ERRORS
linux-4.7.5-x86_64: ERRORS
linux-4.8-x86_64: ERRORS
linux-4.9.26-x86_64: ERRORS
linux-4.10.14-x86_64: ERRORS
linux-4.11-x86_64: ERRORS
linux-4.12.1-x86_64: ERRORS
linux-4.13-x86_64: ERRORS
linux-4.14-x86_64: ERRORS
apps: OK
spec-git: OK
smatch: OK

Detailed results are available here:

http://www.xs4all.nl/~hverkuil/logs/Friday.log

Full logs are available here:

http://www.xs4all.nl/~hverkuil/logs/Friday.tar.bz2

The Media Infrastructure API from this daily build is here:

http://www.xs4all.nl/~hverkuil/spec/index.html


[RFC PATCH] media: v4l2-device: Link subdevices to their parent devices if available

2017-12-14 Thread Tomasz Figa
Currently v4l2_device_register_subdev_nodes() does not initialize the
dev_parent field of the video_device structs it creates for subdevices
being registered. This leads to __video_register_device() falling back
to the parent device of associated v4l2_device struct, which often does
not match the physical device the subdevice is registered for.

Due to the problem above, the links between real devices and v4l-subdev
nodes cannot be obtained from sysfs, which might be confusing for the
userspace trying to identify the hardware.

Fix this by initializing the dev_parent field of the video_device struct
with the value of dev field of the v4l2_subdev struct. In case of
subdevices without a parent struct device, the field will be NULL and the
old behavior will be preserved by the semantics of
__video_register_device().

Signed-off-by: Tomasz Figa 
---
 drivers/media/v4l2-core/v4l2-device.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/media/v4l2-core/v4l2-device.c 
b/drivers/media/v4l2-core/v4l2-device.c
index 937c6de85606..450c97caf2c6 100644
--- a/drivers/media/v4l2-core/v4l2-device.c
+++ b/drivers/media/v4l2-core/v4l2-device.c
@@ -246,6 +246,7 @@ int v4l2_device_register_subdev_nodes(struct v4l2_device 
*v4l2_dev)
 
video_set_drvdata(vdev, sd);
strlcpy(vdev->name, sd->name, sizeof(vdev->name));
+   vdev->dev_parent = sd->dev;
vdev->v4l2_dev = v4l2_dev;
vdev->fops = _subdev_fops;
vdev->release = v4l2_device_release_subdev_node;
-- 
2.15.1.504.g5279b80103-goog



Re: [bug report] drx: add initial drx-d driver

2017-12-14 Thread Devin Heitmueller
> I think I wrote the driver more than 10 years ago and somebody later 
> submitted it
> to the kernel.

I'm pretty sure that was me, or perhaps I was the first person to get
it to work with a device upstream - it was so long ago.

> I don't know if there is a anybody still maintaining this. Is it even used 
> anymore?
> I could write a patch but cannot test it (e.g. to see if it really always
> loops 1000 times ...)

Pretty sure the register was a status register that had bits set for
pending writes, and when the transfer was complete all the bits would
be zero (at which point it should stop polling the register and bail
out).

I would have to test it to be sure, but I'm 80% confident that in
normal operation that loop only does a few iterations.

Devin

-- 
Devin J. Heitmueller - Kernel Labs
http://www.kernellabs.com


[PATCH v2 5/9] media: staging/imx: pass fwnode handle to find/add async subdev

2017-12-14 Thread Steve Longerbeam
Pass the subdev's fwnode_handle to imx_media_find_async_subdev() and
imx_media_add_async_subdev(), instead of a device_node.

Signed-off-by: Steve Longerbeam 
---
 drivers/staging/media/imx/imx-media-dev.c | 20 ++--
 drivers/staging/media/imx/imx-media-of.c  |  7 +++
 drivers/staging/media/imx/imx-media.h |  4 ++--
 3 files changed, 15 insertions(+), 16 deletions(-)

diff --git a/drivers/staging/media/imx/imx-media-dev.c 
b/drivers/staging/media/imx/imx-media-dev.c
index ab0617d6..0369c35 100644
--- a/drivers/staging/media/imx/imx-media-dev.c
+++ b/drivers/staging/media/imx/imx-media-dev.c
@@ -33,15 +33,14 @@ static inline struct imx_media_dev *notifier2dev(struct 
v4l2_async_notifier *n)
 }
 
 /*
- * Find a subdev by device node or device name. This is called during
+ * Find a subdev by fwnode or device name. This is called during
  * driver load to form the async subdev list and bind them.
  */
 struct imx_media_subdev *
 imx_media_find_async_subdev(struct imx_media_dev *imxmd,
-   struct device_node *np,
+   struct fwnode_handle *fwnode,
const char *devname)
 {
-   struct fwnode_handle *fwnode = np ? of_fwnode_handle(np) : NULL;
struct imx_media_subdev *imxsd;
int i;
 
@@ -67,7 +66,7 @@ imx_media_find_async_subdev(struct imx_media_dev *imxmd,
 
 
 /*
- * Adds a subdev to the async subdev list. If np is non-NULL, adds
+ * Adds a subdev to the async subdev list. If fwnode is non-NULL, adds
  * the async as a V4L2_ASYNC_MATCH_FWNODE match type, otherwise as
  * a V4L2_ASYNC_MATCH_DEVNAME match type using the dev_name of the
  * given platform_device. This is called during driver load when
@@ -75,9 +74,10 @@ imx_media_find_async_subdev(struct imx_media_dev *imxmd,
  */
 struct imx_media_subdev *
 imx_media_add_async_subdev(struct imx_media_dev *imxmd,
-  struct device_node *np,
+  struct fwnode_handle *fwnode,
   struct platform_device *pdev)
 {
+   struct device_node *np = to_of_node(fwnode);
struct imx_media_subdev *imxsd;
struct v4l2_async_subdev *asd;
const char *devname = NULL;
@@ -89,7 +89,7 @@ imx_media_add_async_subdev(struct imx_media_dev *imxmd,
devname = dev_name(>dev);
 
/* return -EEXIST if this subdev already added */
-   if (imx_media_find_async_subdev(imxmd, np, devname)) {
+   if (imx_media_find_async_subdev(imxmd, fwnode, devname)) {
dev_dbg(imxmd->md.dev, "%s: already added %s\n",
__func__, np ? np->name : devname);
imxsd = ERR_PTR(-EEXIST);
@@ -107,9 +107,9 @@ imx_media_add_async_subdev(struct imx_media_dev *imxmd,
imxsd = >subdev[sd_idx];
 
asd = >asd;
-   if (np) {
+   if (fwnode) {
asd->match_type = V4L2_ASYNC_MATCH_FWNODE;
-   asd->match.fwnode.fwnode = of_fwnode_handle(np);
+   asd->match.fwnode.fwnode = fwnode;
} else {
asd->match_type = V4L2_ASYNC_MATCH_DEVNAME;
asd->match.device_name.name = devname;
@@ -162,13 +162,13 @@ static int imx_media_subdev_bound(struct 
v4l2_async_notifier *notifier,
  struct v4l2_async_subdev *asd)
 {
struct imx_media_dev *imxmd = notifier2dev(notifier);
-   struct device_node *np = to_of_node(sd->fwnode);
struct imx_media_subdev *imxsd;
int ret = 0;
 
mutex_lock(>mutex);
 
-   imxsd = imx_media_find_async_subdev(imxmd, np, dev_name(sd->dev));
+   imxsd = imx_media_find_async_subdev(imxmd, sd->fwnode,
+   dev_name(sd->dev));
if (!imxsd) {
ret = -EINVAL;
goto out;
diff --git a/drivers/staging/media/imx/imx-media-of.c 
b/drivers/staging/media/imx/imx-media-of.c
index a085e52..eb7a7f2 100644
--- a/drivers/staging/media/imx/imx-media-of.c
+++ b/drivers/staging/media/imx/imx-media-of.c
@@ -87,7 +87,8 @@ of_parse_subdev(struct imx_media_dev *imxmd, struct 
device_node *sd_np,
}
 
/* register this subdev with async notifier */
-   imxsd = imx_media_add_async_subdev(imxmd, sd_np, NULL);
+   imxsd = imx_media_add_async_subdev(imxmd, of_fwnode_handle(sd_np),
+  NULL);
ret = PTR_ERR_OR_ZERO(imxsd);
if (ret) {
if (ret == -EEXIST) {
@@ -176,9 +177,7 @@ static int create_of_link(struct imx_media_dev *imxmd,
if (link->local_port >= sd->entity.num_pads)
return -EINVAL;
 
-   remote = imx_media_find_async_subdev(imxmd,
-to_of_node(link->remote_node),
-NULL);
+   remote = imx_media_find_async_subdev(imxmd, link->remote_node, NULL);
if (!remote)

[PATCH v2 6/9] media: staging/imx: remove static subdev arrays

2017-12-14 Thread Steve Longerbeam
For more complex OF graphs, there will be more async subdevices
registered. Remove the static subdev[IMX_MEDIA_MAX_SUBDEVS] array,
so that imx-media places no limits on the number of async subdevs
that can be added and registered.

There were two uses for 'struct imx_media_subdev'. First was to act
as the async subdev list to be passed to v4l2_async_notifier_register().

Second was to aid in inheriting subdev controls to the capture devices,
and this is done by creating a list of capture devices that can be reached
from a subdev's source pad. So 'struct imx_media_subdev' also contained
a static array of 'struct imx_media_pad' for placing the capture device
lists at each pad.

'struct imx_media_subdev' has been completely removed. Instead, at async
completion, allocate an array of 'struct imx_media_pad' and attach it to
the subdev's host_priv pointer, in order to support subdev controls
inheritance.

Likewise, remove static async_ptrs[IMX_MEDIA_MAX_SUBDEVS] array.
Instead, allocate a 'struct imx_media_async_subdev' when forming
the async list, and add it to an asd_list list_head in
imx_media_add_async_subdev(). At async completion, allocate the
asd pointer list and pull the asd's off asd_list for
v4l2_async_notifier_register().

Signed-off-by: Steve Longerbeam 
---
 drivers/staging/media/imx/imx-ic-prp.c|   4 +-
 drivers/staging/media/imx/imx-media-csi.c |   9 +-
 drivers/staging/media/imx/imx-media-dev.c | 215 --
 drivers/staging/media/imx/imx-media-internal-sd.c |  51 +++--
 drivers/staging/media/imx/imx-media-of.c  |  31 ++--
 drivers/staging/media/imx/imx-media-utils.c   |  43 ++---
 drivers/staging/media/imx/imx-media.h |  81 
 7 files changed, 216 insertions(+), 218 deletions(-)

diff --git a/drivers/staging/media/imx/imx-ic-prp.c 
b/drivers/staging/media/imx/imx-ic-prp.c
index 9e41987..c6d7e80 100644
--- a/drivers/staging/media/imx/imx-ic-prp.c
+++ b/drivers/staging/media/imx/imx-ic-prp.c
@@ -300,7 +300,7 @@ static int prp_link_validate(struct v4l2_subdev *sd,
 {
struct imx_ic_priv *ic_priv = v4l2_get_subdevdata(sd);
struct prp_priv *priv = ic_priv->prp_priv;
-   struct imx_media_subdev *csi;
+   struct v4l2_subdev *csi;
int ret;
 
ret = v4l2_subdev_link_validate_default(sd, link,
@@ -333,7 +333,7 @@ static int prp_link_validate(struct v4l2_subdev *sd,
}
 
if (csi) {
-   switch (csi->sd->grp_id) {
+   switch (csi->grp_id) {
case IMX_MEDIA_GRP_ID_CSI0:
priv->csi_id = 0;
break;
diff --git a/drivers/staging/media/imx/imx-media-csi.c 
b/drivers/staging/media/imx/imx-media-csi.c
index d7a4b7c..eb7be50 100644
--- a/drivers/staging/media/imx/imx-media-csi.c
+++ b/drivers/staging/media/imx/imx-media-csi.c
@@ -138,7 +138,6 @@ static int csi_get_upstream_endpoint(struct csi_priv *priv,
 struct v4l2_fwnode_endpoint *ep)
 {
struct device_node *endpoint, *port;
-   struct imx_media_subdev *imxsd;
struct media_entity *src;
struct v4l2_subdev *sd;
struct media_pad *pad;
@@ -154,10 +153,10 @@ static int csi_get_upstream_endpoint(struct csi_priv 
*priv,
 * CSI-2 receiver if it is in the path, otherwise stay
 * with video mux.
 */
-   imxsd = imx_media_find_upstream_subdev(priv->md, src,
-  IMX_MEDIA_GRP_ID_CSI2);
-   if (!IS_ERR(imxsd))
-   src = >sd->entity;
+   sd = imx_media_find_upstream_subdev(priv->md, src,
+   IMX_MEDIA_GRP_ID_CSI2);
+   if (!IS_ERR(sd))
+   src = >entity;
}
 
/* get source pad of entity directly upstream from src */
diff --git a/drivers/staging/media/imx/imx-media-dev.c 
b/drivers/staging/media/imx/imx-media-dev.c
index 0369c35..71586ae 100644
--- a/drivers/staging/media/imx/imx-media-dev.c
+++ b/drivers/staging/media/imx/imx-media-dev.c
@@ -33,28 +33,28 @@ static inline struct imx_media_dev *notifier2dev(struct 
v4l2_async_notifier *n)
 }
 
 /*
- * Find a subdev by fwnode or device name. This is called during
+ * Find an asd by fwnode or device name. This is called during
  * driver load to form the async subdev list and bind them.
  */
-struct imx_media_subdev *
-imx_media_find_async_subdev(struct imx_media_dev *imxmd,
-   struct fwnode_handle *fwnode,
-   const char *devname)
+static struct v4l2_async_subdev *
+find_async_subdev(struct imx_media_dev *imxmd,
+ struct fwnode_handle *fwnode,
+ const char *devname)
 {
-   struct imx_media_subdev *imxsd;
-   int i;
+   struct imx_media_async_subdev *imxasd;
+   struct 

[PATCH v2 1/9] media: staging/imx: get CSI bus type from nearest upstream entity

2017-12-14 Thread Steve Longerbeam
The imx-media driver currently supports a device tree graph of
limited complexity. This patch is a first step in allowing imx-media
to work with more general OF graphs.

The CSI subdevice assumes the originating upstream subdevice (the
"sensor") is connected directly to either the CSI mux or the MIPI
CSI-2 receiver. But for more complex graphs, the sensor can be distant,
with possible bridge entities in between. Thus the sensor's bus type
could be quite different from what is entering the CSI. For example
a distant sensor could have a parallel interface, but the stream
entering the i.MX is MIPI CSI-2.

To remove this assumption, get the entering bus config from the entity
that is directly upstream from either the CSI mux, or the CSI-2 receiver.
If the CSI-2 receiver is not in the enabled pipeline, the bus type to the
CSI is parallel, otherwise the CSI is receiving MIPI CSI-2.

Note that we can't use the direct upstream source connected to CSI
(which is either the CSI mux or the CSI-2 receiver) to determine
bus type. The bus entering the CSI from the CSI-2 receiver is a 32-bit
parallel bus containing the demultiplexed MIPI CSI-2 virtual channels.
But the CSI and its IDMAC channels must be configured based on whether
it is receiving data from the CSI-2 receiver or from the CSI mux's
parallel interface pins.

The function csi_get_upstream_endpoint() is used to find this
endpoint. It makes use of a new utility function
imx_media_find_upstream_pad(), that if given a grp_id of 0, will
return the closest upstream pad from start_entity.

With these changes, imx_media_find_sensor() is no longer used and
is removed. As a result there is also no longer a need to identify
any sensor or set the sensor subdev's group id as a method to search
for it. So IMX_MEDIA_GRP_ID_SENSOR is removed. Also the video-mux group
id IMX_MEDIA_GRP_ID_VIDMUX was never used so that is removed as well.
The remaining IMX_MEDIA_GRP_ID_* definitions are entities internal
to the i.MX.

Another use of imx_media_find_sensor() in the CSI was to call the
sensor's g_skip_frames op to determine if a delay was needed before
enabling the CSI at stream on. If necessary this will have to be
re-addressed at a later time.

Signed-off-by: Steve Longerbeam 
---
 drivers/staging/media/imx/imx-media-csi.c   | 188 
 drivers/staging/media/imx/imx-media-dev.c   |  12 --
 drivers/staging/media/imx/imx-media-of.c|  21 
 drivers/staging/media/imx/imx-media-utils.c |  63 +-
 drivers/staging/media/imx/imx-media.h   |  27 ++--
 5 files changed, 150 insertions(+), 161 deletions(-)

diff --git a/drivers/staging/media/imx/imx-media-csi.c 
b/drivers/staging/media/imx/imx-media-csi.c
index d90cfda..d7a4b7c 100644
--- a/drivers/staging/media/imx/imx-media-csi.c
+++ b/drivers/staging/media/imx/imx-media-csi.c
@@ -13,6 +13,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -99,8 +100,8 @@ struct csi_priv {
/* the mipi virtual channel number at link validate */
int vc_num;
 
-   /* the attached sensor at stream on */
-   struct imx_media_subdev *sensor;
+   /* the upstream endpoint CSI is receiving from */
+   struct v4l2_fwnode_endpoint upstream_ep;
 
spinlock_t irqlock; /* protect eof_irq handler */
struct timer_list eof_timeout_timer;
@@ -120,6 +121,71 @@ static inline struct csi_priv *sd_to_dev(struct 
v4l2_subdev *sdev)
return container_of(sdev, struct csi_priv, sd);
 }
 
+static inline bool is_parallel_16bit_bus(struct v4l2_fwnode_endpoint *ep)
+{
+   return ep->bus_type != V4L2_MBUS_CSI2 &&
+   ep->bus.parallel.bus_width >= 16;
+}
+
+/*
+ * Parses the fwnode endpoint from the source pad of the entity
+ * connected to this CSI. This will either be the entity directly
+ * upstream from the CSI-2 receiver, or directly upstream from the
+ * video mux. The endpoint is needed to determine the bus type and
+ * bus config coming into the CSI.
+ */
+static int csi_get_upstream_endpoint(struct csi_priv *priv,
+struct v4l2_fwnode_endpoint *ep)
+{
+   struct device_node *endpoint, *port;
+   struct imx_media_subdev *imxsd;
+   struct media_entity *src;
+   struct v4l2_subdev *sd;
+   struct media_pad *pad;
+
+   if (!priv->src_sd)
+   return -EPIPE;
+
+   src = >src_sd->entity;
+
+   if (src->function == MEDIA_ENT_F_VID_MUX) {
+   /*
+* CSI is connected directly to video mux, skip up to
+* CSI-2 receiver if it is in the path, otherwise stay
+* with video mux.
+*/
+   imxsd = imx_media_find_upstream_subdev(priv->md, src,
+  IMX_MEDIA_GRP_ID_CSI2);
+   if (!IS_ERR(imxsd))
+   src = >sd->entity;
+   }
+
+   /* get source pad of entity directly 

[PATCH v2 0/9] media: imx: Add better OF graph support

2017-12-14 Thread Steve Longerbeam
This is a set of patches that improve support for more complex OF
graphs. Currently the imx-media driver only supports a single device
with a single port connected directly to either the CSI muxes or the
MIPI CSI-2 receiver input ports. There can't be a multi-port device in
between. This patch set removes those limitations.

For an example taken from automotive, a camera sensor or decoder could
be literally a remote device accessible over a FPD-III link, via TI
DS90Ux9xx deserializer/serializer pairs. This patch set would support
such OF graphs.

There are still some assumptions and restrictions, regarding the equivalence
of device-tree ports, port parents, and endpoints to media pads, entities,
and links that have been enumerated in the TODO file.

This patch set supersedes the following patch submitted earlier:

"[PATCH v2] media: staging/imx: do not return error in link_notify for unknown 
sources"

Tested by: Steve Longerbeam 
on SabreLite with the OV5640

Tested-by: Philipp Zabel 
on Nitrogen6X with the TC358743.

Tested-by: Russell King 
with the IMX219

History:
v2:
- this version is to resolve merge conflicts only, no functional
  changes since v1.


Steve Longerbeam (9):
  media: staging/imx: get CSI bus type from nearest upstream entity
  media: staging/imx: remove static media link arrays
  media: staging/imx: of: allow for recursing downstream
  media: staging/imx: remove devname string from imx_media_subdev
  media: staging/imx: pass fwnode handle to find/add async subdev
  media: staging/imx: remove static subdev arrays
  media: staging/imx: convert static vdev lists to list_head
  media: staging/imx: reorder function prototypes
  media: staging/imx: update TODO

 drivers/staging/media/imx/TODO|  63 +++-
 drivers/staging/media/imx/imx-ic-prp.c|   4 +-
 drivers/staging/media/imx/imx-media-capture.c |   2 +
 drivers/staging/media/imx/imx-media-csi.c | 187 +-
 drivers/staging/media/imx/imx-media-dev.c | 401 +-
 drivers/staging/media/imx/imx-media-internal-sd.c | 253 +++---
 drivers/staging/media/imx/imx-media-of.c  | 278 ---
 drivers/staging/media/imx/imx-media-utils.c   | 122 +++
 drivers/staging/media/imx/imx-media.h | 187 --
 9 files changed, 721 insertions(+), 776 deletions(-)

-- 
2.7.4



[PATCH v2 4/9] media: staging/imx: remove devname string from imx_media_subdev

2017-12-14 Thread Steve Longerbeam
A separate string for the device name, for DEVNAME async match, was
never needed. Just assign the asd device name to the passed platform
device name pointer in imx_media_add_async_subdev().

Signed-off-by: Steve Longerbeam 
---
 drivers/staging/media/imx/imx-media-dev.c | 3 +--
 drivers/staging/media/imx/imx-media.h | 2 --
 2 files changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/staging/media/imx/imx-media-dev.c 
b/drivers/staging/media/imx/imx-media-dev.c
index 09d2deb..ab0617d6 100644
--- a/drivers/staging/media/imx/imx-media-dev.c
+++ b/drivers/staging/media/imx/imx-media-dev.c
@@ -112,8 +112,7 @@ imx_media_add_async_subdev(struct imx_media_dev *imxmd,
asd->match.fwnode.fwnode = of_fwnode_handle(np);
} else {
asd->match_type = V4L2_ASYNC_MATCH_DEVNAME;
-   strncpy(imxsd->devname, devname, sizeof(imxsd->devname));
-   asd->match.device_name.name = imxsd->devname;
+   asd->match.device_name.name = devname;
imxsd->pdev = pdev;
}
 
diff --git a/drivers/staging/media/imx/imx-media.h 
b/drivers/staging/media/imx/imx-media.h
index 08e34f9..c6cea27 100644
--- a/drivers/staging/media/imx/imx-media.h
+++ b/drivers/staging/media/imx/imx-media.h
@@ -128,8 +128,6 @@ struct imx_media_subdev {
 
/* the platform device if this is an IPU-internal subdev */
struct platform_device *pdev;
-   /* the devname is needed for async devname match */
-   char devname[32];
 };
 
 struct imx_media_dev {
-- 
2.7.4



[PATCH v2 2/9] media: staging/imx: remove static media link arrays

2017-12-14 Thread Steve Longerbeam
Remove the static list of media links that were formed at probe time.
These links can instead be created after all registered async subdevices
have been bound in imx_media_probe_complete().

The media links between subdevices that exist in the device tree, can
be created post-async completion by using v4l2_fwnode_parse_link() for
each endpoint node of that subdevice. Note this approach assumes
device-tree ports are equivalent to media pads (pad index equals
port id), and that device-tree endpoints are equivalent to media
links between pads.

Because links are no longer parsed by imx_media_of_parse(), its sole
function is now only to add subdevices that it encounters by walking
the OF graph to the async list, so the function has been renamed
imx_media_add_of_subdevs().

Similarly, the media links between the IPU-internal subdevice pads (the
CSI source pads, and all pads between the vdic, ic-prp, ic-prpenc, and
ic-prpvf subdevices), can be created post-async completion by looping
through the subdevice's media pads and using the const internal_subdev
table.

Because links are no longer parsed by imx_media_add_internal_subdevs(),
this function no longer needs an array of CSI subdevs to form links
from.

In summary, the following functions, which were used to form a list
of media links at probe time, are removed:

imx_media_add_pad_link()
add_internal_links()
of_add_pad_link()

replaced by these functions, called at probe time, which only populate
the async subdev list:

imx_media_add_of_subdevs()
imx_media_add_internal_subdevs()

and these functions, called at async completion, which create the
media links:

imx_media_create_of_links()
imx_media_create_csi_of_links()
imx_media_create_internal_links()

Signed-off-by: Steve Longerbeam 
---
 drivers/staging/media/imx/imx-media-dev.c | 130 +++--
 drivers/staging/media/imx/imx-media-internal-sd.c | 219 +-
 drivers/staging/media/imx/imx-media-of.c  | 189 ---
 drivers/staging/media/imx/imx-media.h |  39 +---
 4 files changed, 281 insertions(+), 296 deletions(-)

diff --git a/drivers/staging/media/imx/imx-media-dev.c 
b/drivers/staging/media/imx/imx-media-dev.c
index c483b1d..09d2deb 100644
--- a/drivers/staging/media/imx/imx-media-dev.c
+++ b/drivers/staging/media/imx/imx-media-dev.c
@@ -11,6 +11,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -128,50 +129,6 @@ imx_media_add_async_subdev(struct imx_media_dev *imxmd,
 }
 
 /*
- * Adds an imx-media link to a subdev pad's link list. This is called
- * during driver load when forming the links between subdevs.
- *
- * @pad: the local pad
- * @remote_node: the device node of the remote subdev
- * @remote_devname: the device name of the remote subdev
- * @local_pad: local pad index
- * @remote_pad: remote pad index
- */
-int imx_media_add_pad_link(struct imx_media_dev *imxmd,
-  struct imx_media_pad *pad,
-  struct device_node *remote_node,
-  const char *remote_devname,
-  int local_pad, int remote_pad)
-{
-   struct imx_media_link *link;
-   int link_idx, ret = 0;
-
-   mutex_lock(>mutex);
-
-   link_idx = pad->num_links;
-   if (link_idx >= IMX_MEDIA_MAX_LINKS) {
-   dev_err(imxmd->md.dev, "%s: too many links!\n", __func__);
-   ret = -ENOSPC;
-   goto out;
-   }
-
-   link = >link[link_idx];
-
-   link->remote_sd_node = remote_node;
-   if (remote_devname)
-   strncpy(link->remote_devname, remote_devname,
-   sizeof(link->remote_devname));
-
-   link->local_pad = local_pad;
-   link->remote_pad = remote_pad;
-
-   pad->num_links++;
-out:
-   mutex_unlock(>mutex);
-   return ret;
-}
-
-/*
  * get IPU from this CSI and add it to the list of IPUs
  * the media driver will control.
  */
@@ -240,76 +197,38 @@ static int imx_media_subdev_bound(struct 
v4l2_async_notifier *notifier,
 }
 
 /*
- * Create a single source->sink media link given a subdev and a single
- * link from one of its source pads. Called after all subdevs have
- * registered.
- */
-static int imx_media_create_link(struct imx_media_dev *imxmd,
-struct imx_media_subdev *src,
-struct imx_media_link *link)
-{
-   struct imx_media_subdev *sink;
-   u16 source_pad, sink_pad;
-   int ret;
-
-   sink = imx_media_find_async_subdev(imxmd, link->remote_sd_node,
-  link->remote_devname);
-   if (!sink) {
-   v4l2_warn(>v4l2_dev, "%s: no sink for %s:%d\n",
- __func__, src->sd->name, link->local_pad);
-   return 0;
-   }
-
-   source_pad = link->local_pad;
-   sink_pad = link->remote_pad;
-
-   v4l2_info(>v4l2_dev, "%s: %s:%d -> 

[PATCH v2 9/9] media: staging/imx: update TODO

2017-12-14 Thread Steve Longerbeam
Update TODO file:

- Remove TODO info about the OV564x driver, while this still needs
  to be done (add a OV5642 driver or merge with OV5640 driver), it
  is not relevant here.

- Update TODO about methods for retrieving CSI bus config.

- Add some TODO's about OF graph parsing restrictions.

Signed-off-by: Steve Longerbeam 
---
 drivers/staging/media/imx/TODO | 63 ++
 1 file changed, 51 insertions(+), 12 deletions(-)

diff --git a/drivers/staging/media/imx/TODO b/drivers/staging/media/imx/TODO
index 0bee313..9eb7326 100644
--- a/drivers/staging/media/imx/TODO
+++ b/drivers/staging/media/imx/TODO
@@ -1,19 +1,14 @@
 
-- Clean up and move the ov5642 subdev driver to drivers/media/i2c, or
-  merge support for OV5642 into drivers/media/i2c/ov5640.c, and create
-  the binding docs for it.
-
 - The Frame Interval Monitor could be exported to v4l2-core for
   general use.
 
-- At driver load time, the device-tree node that is the original source
-  (the "sensor"), is parsed to record its media bus configuration, and
-  this info is required in imx-media-csi.c to setup the CSI.
-  Laurent Pinchart argues that instead the CSI subdev should call its
-  neighbor's g_mbus_config op (which should be propagated if necessary)
-  to get this info. However Hans Verkuil is planning to remove the
-  g_mbus_config op. For now this driver uses the parsed DT mbus config
-  method until this issue is resolved.
+- The CSI subdevice parses its nearest upstream neighbor's device-tree
+  bus config in order to setup the CSI. Laurent Pinchart argues that
+  instead the CSI subdev should call its neighbor's g_mbus_config op
+  (which should be propagated if necessary) to get this info. However
+  Hans Verkuil is planning to remove the g_mbus_config op. For now this
+  driver uses the parsed DT bus config method until this issue is
+  resolved.
 
 - This media driver supports inheriting V4L2 controls to the
   video capture devices, from the subdevices in the capture device's
@@ -21,3 +16,47 @@
   link_notify callback when the pipeline is modified. It should be
   decided whether this feature is useful enough to make it generally
   available by exporting to v4l2-core.
+
+- The OF graph is walked at probe time to form the list of fwnodes to
+  be passed to v4l2_async_notifier_register(), starting from the IPU
+  CSI ports. And after all async subdevices have been bound,
+  v4l2_fwnode_parse_link() is used to form the media links between
+  the entities discovered by walking the OF graph.
+
+  While this approach allows support for arbitrary OF graphs, there
+  are some assumptions for this to work:
+
+  1. All port parent nodes reachable in the graph from the IPU CSI
+ ports bind to V4L2 async subdevice drivers.
+
+ If a device has mixed-use ports such as video plus audio, the
+ endpoints from the audio ports are followed to devices that must
+ bind to V4L2 subdevice drivers, and not for example, to an ALSA
+ driver or a non-V4L2 media driver. If the device were bound to
+ such a driver, imx-media would never get an async completion
+ notification because the device fwnode was added to the async
+ list, but the driver does not interface with the V4L2 async
+ framework.
+
+  2. Every port reachable in the graph is treated as a media pad,
+ owned by the V4L2 subdevice that is bound to the port's parent.
+
+ This presents problems for devices that don't make this port = pad
+ assumption. Examples are SMIAPP compatible cameras which define only
+ a single output port node, but which define multiple pads owned
+ by multiple subdevices (pixel-array, binner, scaler). Or video
+ decoders (entity function MEDIA_ENT_F_ATV_DECODER), which also define
+ only a single output port node, but define multiple pads for video,
+ VBI, and audio out.
+
+ A workaround at present is to set the port reg properties to
+ correspond to the media pad index that the port represents. A
+ possible long-term solution is to implement a subdev API that
+ maps a port id to a media pad index.
+
+  3. Every endpoint of a port reachable in the graph is treated as
+ a media link, between V4L2 subdevices that are bound to the
+ port parents of the local and remote endpoints.
+
+ Which means a port must not contain mixed-use endpoints, they
+ must all refer to media links between V4L2 subdevices.
-- 
2.7.4



[PATCH v2 7/9] media: staging/imx: convert static vdev lists to list_head

2017-12-14 Thread Steve Longerbeam
Although not technically necessary because imx-media has only a
maximum of 8 video devices, and once setup the video device lists
are static, in anticipation of moving control ineritance to
v4l2-core, make the vdev lists more generic by converting to
dynamic list_head's.

After doing that, 'struct imx_media_pad' is now just a list_head
of video devices reachable from a pad. Allocate an array of list_head's,
one list_head for each pad, and attach that array to sd->host_priv.
An entry in the pad lists is of type 'struct imx_media_pad_vdev', and
points to a video device from the master list.

Signed-off-by: Steve Longerbeam 
---
 drivers/staging/media/imx/imx-media-capture.c |  2 +
 drivers/staging/media/imx/imx-media-dev.c | 77 +++
 drivers/staging/media/imx/imx-media-utils.c   | 16 +-
 drivers/staging/media/imx/imx-media.h | 39 +++---
 4 files changed, 68 insertions(+), 66 deletions(-)

diff --git a/drivers/staging/media/imx/imx-media-capture.c 
b/drivers/staging/media/imx/imx-media-capture.c
index 7b67638..576bdc7 100644
--- a/drivers/staging/media/imx/imx-media-capture.c
+++ b/drivers/staging/media/imx/imx-media-capture.c
@@ -748,6 +748,8 @@ imx_media_capture_device_init(struct v4l2_subdev *src_sd, 
int pad)
vfd->queue = >q;
priv->vdev.vfd = vfd;
 
+   INIT_LIST_HEAD(>vdev.list);
+
video_set_drvdata(vfd, priv);
 
v4l2_ctrl_handler_init(>ctrl_hdlr, 0);
diff --git a/drivers/staging/media/imx/imx-media-dev.c 
b/drivers/staging/media/imx/imx-media-dev.c
index 71586ae..2800700 100644
--- a/drivers/staging/media/imx/imx-media-dev.c
+++ b/drivers/staging/media/imx/imx-media-dev.c
@@ -229,10 +229,11 @@ static int imx_media_add_vdev_to_pad(struct imx_media_dev 
*imxmd,
 struct media_pad *srcpad)
 {
struct media_entity *entity = srcpad->entity;
-   struct imx_media_pad *imxpad;
+   struct imx_media_pad_vdev *pad_vdev;
+   struct list_head *pad_vdev_list;
struct media_link *link;
struct v4l2_subdev *sd;
-   int i, vdev_idx, ret;
+   int i, ret;
 
/* skip this entity if not a v4l2_subdev */
if (!is_media_entity_v4l2_subdev(entity))
@@ -240,8 +241,8 @@ static int imx_media_add_vdev_to_pad(struct imx_media_dev 
*imxmd,
 
sd = media_entity_to_v4l2_subdev(entity);
 
-   imxpad = to_imx_media_pad(sd, srcpad->index);
-   if (!imxpad) {
+   pad_vdev_list = to_pad_vdev_list(sd, srcpad->index);
+   if (!pad_vdev_list) {
v4l2_warn(>v4l2_dev, "%s:%u has no vdev list!\n",
  entity->name, srcpad->index);
/*
@@ -251,23 +252,22 @@ static int imx_media_add_vdev_to_pad(struct imx_media_dev 
*imxmd,
return 0;
}
 
-   vdev_idx = imxpad->num_vdevs;
-
/* just return if we've been here before */
-   for (i = 0; i < vdev_idx; i++)
-   if (vdev == imxpad->vdev[i])
+   list_for_each_entry(pad_vdev, pad_vdev_list, list) {
+   if (pad_vdev->vdev == vdev)
return 0;
-
-   if (vdev_idx >= IMX_MEDIA_MAX_VDEVS) {
-   dev_err(imxmd->md.dev, "can't add %s to pad %s:%u\n",
-   vdev->vfd->entity.name, entity->name, srcpad->index);
-   return -ENOSPC;
}
 
dev_dbg(imxmd->md.dev, "adding %s to pad %s:%u\n",
vdev->vfd->entity.name, entity->name, srcpad->index);
-   imxpad->vdev[vdev_idx] = vdev;
-   imxpad->num_vdevs++;
+
+   pad_vdev = devm_kzalloc(imxmd->md.dev, sizeof(*pad_vdev), GFP_KERNEL);
+   if (!pad_vdev)
+   return -ENOMEM;
+
+   /* attach this vdev to this pad */
+   pad_vdev->vdev = vdev;
+   list_add_tail(_vdev->list, pad_vdev_list);
 
/* move upstream from this entity's sink pads */
for (i = 0; i < entity->num_pads; i++) {
@@ -289,22 +289,32 @@ static int imx_media_add_vdev_to_pad(struct imx_media_dev 
*imxmd,
return 0;
 }
 
+/*
+ * For every subdevice, allocate an array of list_head's, one list_head
+ * for each pad, to hold the list of video devices reachable from that
+ * pad.
+ */
 static int imx_media_alloc_pad_vdev_lists(struct imx_media_dev *imxmd)
 {
-   struct imx_media_pad *imxpads;
+   struct list_head *vdev_lists;
struct media_entity *entity;
struct v4l2_subdev *sd;
+   int i;
 
list_for_each_entry(sd, >v4l2_dev.subdevs, list) {
entity = >entity;
-   imxpads = devm_kzalloc(imxmd->md.dev,
-  entity->num_pads * sizeof(*imxpads),
-  GFP_KERNEL);
-   if (!imxpads)
+   vdev_lists = devm_kzalloc(
+   imxmd->md.dev,
+   entity->num_pads * sizeof(*vdev_lists),
+   GFP_KERNEL);
+   if 

[PATCH v2 8/9] media: staging/imx: reorder function prototypes

2017-12-14 Thread Steve Longerbeam
Re-order some of the function prototypes in imx-media.h to
group them correctly by source file. No functional changes.

Signed-off-by: Steve Longerbeam 
---
 drivers/staging/media/imx/imx-media.h | 21 -
 1 file changed, 12 insertions(+), 9 deletions(-)

diff --git a/drivers/staging/media/imx/imx-media.h 
b/drivers/staging/media/imx/imx-media.h
index ebb24b1..2fd6dfd 100644
--- a/drivers/staging/media/imx/imx-media.h
+++ b/drivers/staging/media/imx/imx-media.h
@@ -157,6 +157,7 @@ enum codespace_sel {
CS_SEL_ANY,
 };
 
+/* imx-media-utils.c */
 const struct imx_media_pixfmt *
 imx_media_find_format(u32 fourcc, enum codespace_sel cs_sel, bool allow_bayer);
 int imx_media_enum_format(u32 *fourcc, u32 index, enum codespace_sel cs_sel);
@@ -181,17 +182,8 @@ int imx_media_mbus_fmt_to_ipu_image(struct ipu_image 
*image,
struct v4l2_mbus_framefmt *mbus);
 int imx_media_ipu_image_to_mbus_fmt(struct v4l2_mbus_framefmt *mbus,
struct ipu_image *image);
-int imx_media_add_async_subdev(struct imx_media_dev *imxmd,
-  struct fwnode_handle *fwnode,
-  struct platform_device *pdev);
 void imx_media_grp_id_to_sd_name(char *sd_name, int sz,
 u32 grp_id, int ipu_id);
-
-int imx_media_add_internal_subdevs(struct imx_media_dev *imxmd);
-int imx_media_create_internal_links(struct imx_media_dev *imxmd,
-   struct v4l2_subdev *sd);
-void imx_media_remove_internal_subdevs(struct imx_media_dev *imxmd);
-
 struct v4l2_subdev *
 imx_media_find_subdev_by_fwnode(struct imx_media_dev *imxmd,
struct fwnode_handle *fwnode);
@@ -227,6 +219,11 @@ int imx_media_pipeline_set_stream(struct imx_media_dev 
*imxmd,
  struct media_entity *entity,
  bool on);
 
+/* imx-media-dev.c */
+int imx_media_add_async_subdev(struct imx_media_dev *imxmd,
+  struct fwnode_handle *fwnode,
+  struct platform_device *pdev);
+
 /* imx-media-fim.c */
 struct imx_media_fim;
 void imx_media_fim_eof_monitor(struct imx_media_fim *fim, ktime_t timestamp);
@@ -237,6 +234,12 @@ int imx_media_fim_add_controls(struct imx_media_fim *fim);
 struct imx_media_fim *imx_media_fim_init(struct v4l2_subdev *sd);
 void imx_media_fim_free(struct imx_media_fim *fim);
 
+/* imx-media-internal-sd.c */
+int imx_media_add_internal_subdevs(struct imx_media_dev *imxmd);
+int imx_media_create_internal_links(struct imx_media_dev *imxmd,
+   struct v4l2_subdev *sd);
+void imx_media_remove_internal_subdevs(struct imx_media_dev *imxmd);
+
 /* imx-media-of.c */
 int imx_media_add_of_subdevs(struct imx_media_dev *dev,
 struct device_node *np);
-- 
2.7.4



[PATCH v2 3/9] media: staging/imx: of: allow for recursing downstream

2017-12-14 Thread Steve Longerbeam
Calling of_parse_subdev() recursively to a downstream path that has
already been followed is ok, it just means that call will return
immediately since the subdevice was already added to the async list.

With that there is no need to determine whether a subdevice's port
is a sink or source, so 'num_{sink|src}_pads' is no longer used and
is removed.

Signed-off-by: Steve Longerbeam 
---
 drivers/staging/media/imx/imx-media-internal-sd.c | 17 -
 drivers/staging/media/imx/imx-media-of.c  | 78 ++-
 drivers/staging/media/imx/imx-media.h | 14 
 3 files changed, 21 insertions(+), 88 deletions(-)

diff --git a/drivers/staging/media/imx/imx-media-internal-sd.c 
b/drivers/staging/media/imx/imx-media-internal-sd.c
index 3e60df5..53f2383 100644
--- a/drivers/staging/media/imx/imx-media-internal-sd.c
+++ b/drivers/staging/media/imx/imx-media-internal-sd.c
@@ -78,13 +78,9 @@ struct internal_pad {
 static const struct internal_subdev {
const struct internal_subdev_id *id;
struct internal_pad pad[IMX_MEDIA_MAX_PADS];
-   int num_sink_pads;
-   int num_src_pads;
 } int_subdev[num_isd] = {
[isd_csi0] = {
.id = _id[isd_csi0],
-   .num_sink_pads = CSI_NUM_SINK_PADS,
-   .num_src_pads = CSI_NUM_SRC_PADS,
.pad[CSI_SRC_PAD_DIRECT] = {
.link = {
{
@@ -102,8 +98,6 @@ static const struct internal_subdev {
 
[isd_csi1] = {
.id = _id[isd_csi1],
-   .num_sink_pads = CSI_NUM_SINK_PADS,
-   .num_src_pads = CSI_NUM_SRC_PADS,
.pad[CSI_SRC_PAD_DIRECT] = {
.link = {
{
@@ -121,8 +115,6 @@ static const struct internal_subdev {
 
[isd_vdic] = {
.id = _id[isd_vdic],
-   .num_sink_pads = VDIC_NUM_SINK_PADS,
-   .num_src_pads = VDIC_NUM_SRC_PADS,
.pad[VDIC_SRC_PAD_DIRECT] = {
.link = {
{
@@ -136,8 +128,6 @@ static const struct internal_subdev {
 
[isd_ic_prp] = {
.id = _id[isd_ic_prp],
-   .num_sink_pads = PRP_NUM_SINK_PADS,
-   .num_src_pads = PRP_NUM_SRC_PADS,
.pad[PRP_SRC_PAD_PRPENC] = {
.link = {
{
@@ -160,14 +150,10 @@ static const struct internal_subdev {
 
[isd_ic_prpenc] = {
.id = _id[isd_ic_prpenc],
-   .num_sink_pads = PRPENCVF_NUM_SINK_PADS,
-   .num_src_pads = PRPENCVF_NUM_SRC_PADS,
},
 
[isd_ic_prpvf] = {
.id = _id[isd_ic_prpvf],
-   .num_sink_pads = PRPENCVF_NUM_SINK_PADS,
-   .num_src_pads = PRPENCVF_NUM_SRC_PADS,
},
 };
 
@@ -312,9 +298,6 @@ static int add_internal_subdev(struct imx_media_dev *imxmd,
if (IS_ERR(imxsd))
return PTR_ERR(imxsd);
 
-   imxsd->num_sink_pads = isd->num_sink_pads;
-   imxsd->num_src_pads = isd->num_src_pads;
-
return 0;
 }
 
diff --git a/drivers/staging/media/imx/imx-media-of.c 
b/drivers/staging/media/imx/imx-media-of.c
index d35c99e..a085e52 100644
--- a/drivers/staging/media/imx/imx-media-of.c
+++ b/drivers/staging/media/imx/imx-media-of.c
@@ -41,11 +41,12 @@ static int of_get_port_count(const struct device_node *np)
 /*
  * find the remote device node given local endpoint node
  */
-static void of_get_remote(struct device_node *epnode,
+static bool of_get_remote(struct device_node *epnode,
  struct device_node **remote_node)
 {
struct device_node *rp, *rpp;
struct device_node *remote;
+   bool is_csi_port;
 
rp = of_graph_get_remote_port(epnode);
rpp = of_graph_get_remote_port_parent(epnode);
@@ -54,9 +55,11 @@ static void of_get_remote(struct device_node *epnode,
/* the remote is one of the CSI ports */
remote = rp;
of_node_put(rpp);
+   is_csi_port = true;
} else {
remote = rpp;
of_node_put(rp);
+   is_csi_port = false;
}
 
if (!of_device_is_available(remote)) {
@@ -65,6 +68,8 @@ static void of_get_remote(struct device_node *epnode,
} else {
*remote_node = remote;
}
+
+   return is_csi_port;
 }
 
 static int
@@ -72,7 +77,7 @@ of_parse_subdev(struct imx_media_dev *imxmd, struct 
device_node *sd_np,
bool is_csi_port)
 {
struct imx_media_subdev *imxsd;
-   int i, num_pads, ret;
+   int i, num_ports, ret;
 
if (!of_device_is_available(sd_np)) {
dev_dbg(imxmd->md.dev, "%s: %s not enabled\n", __func__,
@@ -94,77 +99,36 @@ of_parse_subdev(struct imx_media_dev *imxmd, struct 
device_node *sd_np,

Re: [media] hdpvr: Fix an error handling path in hdpvr_probe()

2017-12-14 Thread Andrey Konovalov
On Fri, Dec 15, 2017 at 12:25 AM, Guenter Roeck  wrote:
> On Fri, Sep 22, 2017 at 06:37:06PM +0530, Arvind Yadav wrote:
>> Here, hdpvr_register_videodev() is responsible for setup and
>> register a video device. Also defining and initializing a worker.
>> hdpvr_register_videodev() is calling by hdpvr_probe at last.
>> So No need to flash any work here.
>> Unregister v4l2, free buffers and memory. If hdpvr_probe() will fail.
>>
>> Signed-off-by: Arvind Yadav 
>> Reported-by: Andrey Konovalov 
>> Tested-by: Andrey Konovalov 
>
> It looks like this patch was never applied upstream. It fixes
> CVE-2017-16644 [1].
>
> Did it get lost, or is there some reason for not applying it ?

Hi!

I got an email that It was queued to the media tree about a week ago.
I guess that means that it's going to be applied upstream eventually.
It took quite a lot of time for some reason though.

Thanks!

>
> Thanks,
> Guenter
>
> ---
> [1] https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-16644
>
>> ---
>>  drivers/media/usb/hdpvr/hdpvr-core.c | 26 +++---
>>  1 file changed, 15 insertions(+), 11 deletions(-)
>>
>> diff --git a/drivers/media/usb/hdpvr/hdpvr-core.c 
>> b/drivers/media/usb/hdpvr/hdpvr-core.c
>> index dbe29c6..1e8cbaf 100644
>> --- a/drivers/media/usb/hdpvr/hdpvr-core.c
>> +++ b/drivers/media/usb/hdpvr/hdpvr-core.c
>> @@ -292,7 +292,7 @@ static int hdpvr_probe(struct usb_interface *interface,
>>   /* register v4l2_device early so it can be used for printks */
>>   if (v4l2_device_register(>dev, >v4l2_dev)) {
>>   dev_err(>dev, "v4l2_device_register failed\n");
>> - goto error;
>> + goto error_free_dev;
>>   }
>>
>>   mutex_init(>io_mutex);
>> @@ -301,7 +301,7 @@ static int hdpvr_probe(struct usb_interface *interface,
>>   dev->usbc_buf = kmalloc(64, GFP_KERNEL);
>>   if (!dev->usbc_buf) {
>>   v4l2_err(>v4l2_dev, "Out of memory\n");
>> - goto error;
>> + goto error_v4l2_unregister;
>>   }
>>
>>   init_waitqueue_head(>wait_buffer);
>> @@ -339,13 +339,13 @@ static int hdpvr_probe(struct usb_interface *interface,
>>   }
>>   if (!dev->bulk_in_endpointAddr) {
>>   v4l2_err(>v4l2_dev, "Could not find bulk-in endpoint\n");
>> - goto error;
>> + goto error_put_usb;
>>   }
>>
>>   /* init the device */
>>   if (hdpvr_device_init(dev)) {
>>   v4l2_err(>v4l2_dev, "device init failed\n");
>> - goto error;
>> + goto error_put_usb;
>>   }
>>
>>   mutex_lock(>io_mutex);
>> @@ -353,7 +353,7 @@ static int hdpvr_probe(struct usb_interface *interface,
>>   mutex_unlock(>io_mutex);
>>   v4l2_err(>v4l2_dev,
>>"allocating transfer buffers failed\n");
>> - goto error;
>> + goto error_put_usb;
>>   }
>>   mutex_unlock(>io_mutex);
>>
>> @@ -361,7 +361,7 @@ static int hdpvr_probe(struct usb_interface *interface,
>>   retval = hdpvr_register_i2c_adapter(dev);
>>   if (retval < 0) {
>>   v4l2_err(>v4l2_dev, "i2c adapter register failed\n");
>> - goto error;
>> + goto error_free_buffers;
>>   }
>>
>>   client = hdpvr_register_ir_rx_i2c(dev);
>> @@ -394,13 +394,17 @@ static int hdpvr_probe(struct usb_interface *interface,
>>  reg_fail:
>>  #if IS_ENABLED(CONFIG_I2C)
>>   i2c_del_adapter(>i2c_adapter);
>> +error_free_buffers:
>>  #endif
>> + hdpvr_free_buffers(dev);
>> +error_put_usb:
>> + usb_put_dev(dev->udev);
>> + kfree(dev->usbc_buf);
>> +error_v4l2_unregister:
>> + v4l2_device_unregister(>v4l2_dev);
>> +error_free_dev:
>> + kfree(dev);
>>  error:
>> - if (dev) {
>> - flush_work(>worker);
>> - /* this frees allocated memory */
>> - hdpvr_delete(dev);
>> - }
>>   return retval;
>>  }
>>


Re: [PATCH/RFC v2 14/15] adv748x: csi2: add get_routing support

2017-12-14 Thread Kieran Bingham
Hi Niklas,

On 14/12/17 19:08, Niklas Söderlund wrote:
> To support multiplexed streams the internal routing between the
> adv748x sink pad and its source pad needs to be described.

The adv748x has quite a few sink and source pads... I presume here you mean the
adv748x csi2 sink and source pad :D

> 
> Signed-off-by: Niklas Söderlund 
> ---
>  drivers/media/i2c/adv748x/adv748x-csi2.c | 22 ++
>  1 file changed, 22 insertions(+)
> 
> diff --git a/drivers/media/i2c/adv748x/adv748x-csi2.c 
> b/drivers/media/i2c/adv748x/adv748x-csi2.c
> index 291b35bef49d41fb..dbefb53f5b8c414d 100644
> --- a/drivers/media/i2c/adv748x/adv748x-csi2.c
> +++ b/drivers/media/i2c/adv748x/adv748x-csi2.c
> @@ -262,10 +262,32 @@ static int adv748x_csi2_get_frame_desc(struct 
> v4l2_subdev *sd, unsigned int pad,
>   return 0;
>  }
>  
> +static int adv748x_csi2_get_routing(struct v4l2_subdev *subdev,
> + struct v4l2_subdev_routing *routing)
> +{
> + struct v4l2_subdev_route *r = routing->routes;
> +
> + if (routing->num_routes < 1) {
> + routing->num_routes = 1;
> + return -ENOSPC;
> + }
> +
> + routing->num_routes = 1;
> +
> + r->sink_pad = ADV748X_CSI2_SINK;
> + r->sink_stream = 0;
> + r->source_pad = ADV748X_CSI2_SOURCE;
> + r->source_stream = 0;
> + r->flags = V4L2_SUBDEV_ROUTE_FL_ACTIVE | V4L2_SUBDEV_ROUTE_FL_IMMUTABLE;
> +
> + return 0;
> +}
> +

So - I think this is fine - but it seems a lot of code to define a static
default route which describes a single link between it's sink pad - and its
source pad ...

I suspect this should/could be wrapped by some helpers in core for cases like
this, as it's the simple case - but as we don't currently have that I guess we
have to put this in here for now ?

Maybe we should have a helper to make this

return v4l2_subdev_single_route(subdev, routing,
ADV748X_CS2_SINK, 0,
ADV748X_CSI2_SOURCE, 0,
  V4L2_SUBDEV_ROUTE_FL_ACTIVE | V4L2_SUBDEV_ROUTE_FL_IMMUTABLE);

Or maybe even define these static routes in a struct somehow?

>  static const struct v4l2_subdev_pad_ops adv748x_csi2_pad_ops = {
>   .get_fmt = adv748x_csi2_get_format,
>   .set_fmt = adv748x_csi2_set_format,
>   .get_frame_desc = adv748x_csi2_get_frame_desc,
> + .get_routing = adv748x_csi2_get_routing,
>   .s_stream = adv748x_csi2_s_stream,
>  };
>  
> 


Re: [media] hdpvr: Fix an error handling path in hdpvr_probe()

2017-12-14 Thread Guenter Roeck
On Fri, Sep 22, 2017 at 06:37:06PM +0530, Arvind Yadav wrote:
> Here, hdpvr_register_videodev() is responsible for setup and
> register a video device. Also defining and initializing a worker.
> hdpvr_register_videodev() is calling by hdpvr_probe at last.
> So No need to flash any work here.
> Unregister v4l2, free buffers and memory. If hdpvr_probe() will fail.
> 
> Signed-off-by: Arvind Yadav 
> Reported-by: Andrey Konovalov 
> Tested-by: Andrey Konovalov 

It looks like this patch was never applied upstream. It fixes
CVE-2017-16644 [1].

Did it get lost, or is there some reason for not applying it ?

Thanks,
Guenter

---
[1] https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-16644

> ---
>  drivers/media/usb/hdpvr/hdpvr-core.c | 26 +++---
>  1 file changed, 15 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/media/usb/hdpvr/hdpvr-core.c 
> b/drivers/media/usb/hdpvr/hdpvr-core.c
> index dbe29c6..1e8cbaf 100644
> --- a/drivers/media/usb/hdpvr/hdpvr-core.c
> +++ b/drivers/media/usb/hdpvr/hdpvr-core.c
> @@ -292,7 +292,7 @@ static int hdpvr_probe(struct usb_interface *interface,
>   /* register v4l2_device early so it can be used for printks */
>   if (v4l2_device_register(>dev, >v4l2_dev)) {
>   dev_err(>dev, "v4l2_device_register failed\n");
> - goto error;
> + goto error_free_dev;
>   }
>  
>   mutex_init(>io_mutex);
> @@ -301,7 +301,7 @@ static int hdpvr_probe(struct usb_interface *interface,
>   dev->usbc_buf = kmalloc(64, GFP_KERNEL);
>   if (!dev->usbc_buf) {
>   v4l2_err(>v4l2_dev, "Out of memory\n");
> - goto error;
> + goto error_v4l2_unregister;
>   }
>  
>   init_waitqueue_head(>wait_buffer);
> @@ -339,13 +339,13 @@ static int hdpvr_probe(struct usb_interface *interface,
>   }
>   if (!dev->bulk_in_endpointAddr) {
>   v4l2_err(>v4l2_dev, "Could not find bulk-in endpoint\n");
> - goto error;
> + goto error_put_usb;
>   }
>  
>   /* init the device */
>   if (hdpvr_device_init(dev)) {
>   v4l2_err(>v4l2_dev, "device init failed\n");
> - goto error;
> + goto error_put_usb;
>   }
>  
>   mutex_lock(>io_mutex);
> @@ -353,7 +353,7 @@ static int hdpvr_probe(struct usb_interface *interface,
>   mutex_unlock(>io_mutex);
>   v4l2_err(>v4l2_dev,
>"allocating transfer buffers failed\n");
> - goto error;
> + goto error_put_usb;
>   }
>   mutex_unlock(>io_mutex);
>  
> @@ -361,7 +361,7 @@ static int hdpvr_probe(struct usb_interface *interface,
>   retval = hdpvr_register_i2c_adapter(dev);
>   if (retval < 0) {
>   v4l2_err(>v4l2_dev, "i2c adapter register failed\n");
> - goto error;
> + goto error_free_buffers;
>   }
>  
>   client = hdpvr_register_ir_rx_i2c(dev);
> @@ -394,13 +394,17 @@ static int hdpvr_probe(struct usb_interface *interface,
>  reg_fail:
>  #if IS_ENABLED(CONFIG_I2C)
>   i2c_del_adapter(>i2c_adapter);
> +error_free_buffers:
>  #endif
> + hdpvr_free_buffers(dev);
> +error_put_usb:
> + usb_put_dev(dev->udev);
> + kfree(dev->usbc_buf);
> +error_v4l2_unregister:
> + v4l2_device_unregister(>v4l2_dev);
> +error_free_dev:
> + kfree(dev);
>  error:
> - if (dev) {
> - flush_work(>worker);
> - /* this frees allocated memory */
> - hdpvr_delete(dev);
> - }
>   return retval;
>  }
>  


Re: [PATCH/RFC v2 13/15] adv748x: csi2: only allow formats on sink pads

2017-12-14 Thread Kieran Bingham
Hi Niklas,

On 14/12/17 19:08, Niklas Söderlund wrote:
> The driver is now pad and stream aware, only allow to get/set format on
> sink pads.

Ok - I can see the patch is doing this ...

> Also record a different format for each sink pad since it's
> no longer true that they are all the same

But I can't see how the patch is doing this ^ ?

What have I missed?

--
Kieran

> Signed-off-by: Niklas Söderlund 
> ---
>  drivers/media/i2c/adv748x/adv748x-csi2.c | 6 ++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/drivers/media/i2c/adv748x/adv748x-csi2.c 
> b/drivers/media/i2c/adv748x/adv748x-csi2.c
> index 39f993282dd3bb5c..291b35bef49d41fb 100644
> --- a/drivers/media/i2c/adv748x/adv748x-csi2.c
> +++ b/drivers/media/i2c/adv748x/adv748x-csi2.c
> @@ -176,6 +176,9 @@ static int adv748x_csi2_get_format(struct v4l2_subdev *sd,
>   struct adv748x_state *state = tx->state;
>   struct v4l2_mbus_framefmt *mbusformat;
>  
> + if (sdformat->pad != ADV748X_CSI2_SINK)
> + return -EINVAL;
> +
>   mbusformat = adv748x_csi2_get_pad_format(sd, cfg, sdformat->pad,
>sdformat->which);
>   if (!mbusformat)
> @@ -199,6 +202,9 @@ static int adv748x_csi2_set_format(struct v4l2_subdev *sd,
>   struct v4l2_mbus_framefmt *mbusformat;
>   int ret = 0;
>  
> + if (sdformat->pad != ADV748X_CSI2_SINK)
> + return -EINVAL;
> +
>   mbusformat = adv748x_csi2_get_pad_format(sd, cfg, sdformat->pad,
>sdformat->which);
>   if (!mbusformat)
> 


Re: [PATCH/RFC v2 12/15] adv748x: csi2: switch to pad and stream aware s_stream

2017-12-14 Thread Kieran Bingham
Hi Niklas,

On 14/12/17 19:08, Niklas Söderlund wrote:
> Switch the driver to implement the pad and stream aware s_stream
> operation. This is needed to enable to support to start and stop
> individual streams on a multiplexed pad

"This is needed to enable support for starting and stopping individual streams
on a multiplexed pad."

> Signed-off-by: Niklas Söderlund 

Otherwise,

Reviewed-by: Kieran Bingham 

> ---
>  drivers/media/i2c/adv748x/adv748x-csi2.c | 16 ++--
>  1 file changed, 10 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/media/i2c/adv748x/adv748x-csi2.c 
> b/drivers/media/i2c/adv748x/adv748x-csi2.c
> index a43b251d0bc67a43..39f993282dd3bb5c 100644
> --- a/drivers/media/i2c/adv748x/adv748x-csi2.c
> +++ b/drivers/media/i2c/adv748x/adv748x-csi2.c
> @@ -128,22 +128,26 @@ static const struct v4l2_subdev_internal_ops 
> adv748x_csi2_internal_ops = {
>   * v4l2_subdev_video_ops
>   */
>  
> -static int adv748x_csi2_s_stream(struct v4l2_subdev *sd, int enable)
> +static int adv748x_csi2_s_stream(struct v4l2_subdev *sd, unsigned int pad,
> +  unsigned int stream, int enable)
>  {
>   struct adv748x_csi2 *tx = adv748x_sd_to_csi2(sd);
> + struct adv748x_state *state = tx->state;
>   struct v4l2_subdev *src;
>  
> + if (pad != ADV748X_CSI2_SOURCE || stream != 0)
> + return -EINVAL;
> +
>   src = adv748x_get_remote_sd(>pads[ADV748X_CSI2_SINK]);
>   if (!src)
>   return -EPIPE;
>  
> + adv_dbg(state, "%s: pad: %u stream: %u enable: %d\n", sd->name,
> + pad, stream, enable);
> +
>   return v4l2_subdev_call(src, video, s_stream, enable);
>  }
>  
> -static const struct v4l2_subdev_video_ops adv748x_csi2_video_ops = {
> - .s_stream = adv748x_csi2_s_stream,
> -};
> -
>  /* 
> -
>   * v4l2_subdev_pad_ops
>   *
> @@ -256,6 +260,7 @@ static const struct v4l2_subdev_pad_ops 
> adv748x_csi2_pad_ops = {
>   .get_fmt = adv748x_csi2_get_format,
>   .set_fmt = adv748x_csi2_set_format,
>   .get_frame_desc = adv748x_csi2_get_frame_desc,
> + .s_stream = adv748x_csi2_s_stream,
>  };
>  
>  /* 
> -
> @@ -263,7 +268,6 @@ static const struct v4l2_subdev_pad_ops 
> adv748x_csi2_pad_ops = {
>   */
>  
>  static const struct v4l2_subdev_ops adv748x_csi2_ops = {
> - .video = _csi2_video_ops,
>   .pad = _csi2_pad_ops,
>  };
>  
> 


Re: [PATCH/RFC v2 15/15] adv748x: afe: add routing support

2017-12-14 Thread Kieran Bingham
One more ...

On 14/12/17 22:56, Kieran Bingham wrote:
> Hi Niklas,
> 
> On 14/12/17 19:08, Niklas Söderlund wrote:
>> The adv748x afe have eight analog sink pads, currently one of them is
> 
> s/have/has/
> 
>> chosen to be the active route based on device tree configuration. Whit
> 
> s/Whit/With/
> 
>> the new routeing API it's possible to control which of the eight sink

While routeing is correctly spelt, it is used as routing everywhere else...

s/routeing/routing/

>> pads are routed to the source pad.
> 
>> Signed-off-by: Niklas Söderlund 
> 
> Aha, I had been wondering how we would handle this...
> 
> Other than the minor nits, this is otherwise looking good
> 
> Reviewed-by: Kieran Bingham 
> 
>> ---
>>  drivers/media/i2c/adv748x/adv748x-afe.c | 66 
>> +
>>  1 file changed, 66 insertions(+)
>>
>> diff --git a/drivers/media/i2c/adv748x/adv748x-afe.c 
>> b/drivers/media/i2c/adv748x/adv748x-afe.c
>> index 5188178588c9067d..5dda85c707f6efd7 100644
>> --- a/drivers/media/i2c/adv748x/adv748x-afe.c
>> +++ b/drivers/media/i2c/adv748x/adv748x-afe.c
>> @@ -43,6 +43,9 @@
>>  #define ADV748X_AFE_STD_PAL_SECAM   0xe
>>  #define ADV748X_AFE_STD_PAL_SECAM_PED   0xf
>>  
>> +#define ADV748X_AFE_ROUTES_MAX ((ADV748X_AFE_SINK_AIN7 - \
>> +ADV748X_AFE_SINK_AIN0) + 1)
>> +
>>  static int adv748x_afe_read_ro_map(struct adv748x_state *state, u8 reg)
>>  {
>>  int ret;
>> @@ -386,10 +389,73 @@ static int adv748x_afe_set_format(struct v4l2_subdev 
>> *sd,
>>  return 0;
>>  }
>>  
>> +
> 
> No need for that extra line..
> 
>> +static int adv748x_afe_get_routing(struct v4l2_subdev *sd,
>> +   struct v4l2_subdev_routing *routing)
>> +{
>> +struct adv748x_afe *afe = adv748x_sd_to_afe(sd);
>> +struct v4l2_subdev_route *r = routing->routes;
>> +unsigned int i;
>> +
>> +/* There are one possible route from each sink */
> 
>   There is one possible ...
> 
>> +if (routing->num_routes < ADV748X_AFE_ROUTES_MAX) {
>> +routing->num_routes = ADV748X_AFE_ROUTES_MAX;
>> +return -ENOSPC;
>> +}
>> +
>> +routing->num_routes = ADV748X_AFE_ROUTES_MAX;
>> +
>> +for (i = ADV748X_AFE_SINK_AIN0; i <= ADV748X_AFE_SINK_AIN7; i++) {
>> +r->sink_pad = i;
>> +r->sink_stream = 0;
>> +r->source_pad = ADV748X_AFE_SOURCE;
>> +r->source_stream = 0;
>> +r->flags = afe->input == i ? V4L2_SUBDEV_ROUTE_FL_ACTIVE : 0;
>> +r++;
>> +}
>> +
>> +return 0;
>> +}
>> +
>> +static int adv748x_afe_set_routing(struct v4l2_subdev *sd,
>> +   struct v4l2_subdev_routing *routing)
>> +{
>> +struct adv748x_afe *afe = adv748x_sd_to_afe(sd);
>> +struct v4l2_subdev_route *r = routing->routes;
>> +int input = -1;
>> +unsigned int i;
>> +
>> +if (routing->num_routes > ADV748X_AFE_ROUTES_MAX)
>> +return -ENOSPC;
>> +
>> +for (i = 0; i < routing->num_routes; i++) {
>> +if (r->sink_pad > ADV748X_AFE_SINK_AIN7 ||
>> +r->sink_stream != 0 ||
>> +r->source_pad != ADV748X_AFE_SOURCE ||
>> +r->source_stream != 0)
>> +return -EINVAL;
>> +
>> +if (r->flags & V4L2_SUBDEV_ROUTE_FL_ACTIVE) {
>> +if (input != -1)
>> +return -EMLINK;
>> +
>> +input = r->sink_pad;
>> +}
>> +r++;
>> +}
>> +
>> +if (input != -1)
>> +afe->input = input;> +
>> +return 0;
>> +}
>> +
>>  static const struct v4l2_subdev_pad_ops adv748x_afe_pad_ops = {
>>  .enum_mbus_code = adv748x_afe_enum_mbus_code,
>>  .set_fmt = adv748x_afe_set_format,
>>  .get_fmt = adv748x_afe_get_format,
>> +.get_routing = adv748x_afe_get_routing,
>> +.set_routing = adv748x_afe_set_routing,
>>  };
>>  
>>  /* 
>> -
>>


Re: [PATCH/RFC v2 15/15] adv748x: afe: add routing support

2017-12-14 Thread Kieran Bingham
Hi Niklas,

On 14/12/17 19:08, Niklas Söderlund wrote:
> The adv748x afe have eight analog sink pads, currently one of them is

s/have/has/

> chosen to be the active route based on device tree configuration. Whit

s/Whit/With/

> the new routeing API it's possible to control which of the eight sink
> pads are routed to the source pad.

> Signed-off-by: Niklas Söderlund 

Aha, I had been wondering how we would handle this...

Other than the minor nits, this is otherwise looking good

Reviewed-by: Kieran Bingham 

> ---
>  drivers/media/i2c/adv748x/adv748x-afe.c | 66 
> +
>  1 file changed, 66 insertions(+)
> 
> diff --git a/drivers/media/i2c/adv748x/adv748x-afe.c 
> b/drivers/media/i2c/adv748x/adv748x-afe.c
> index 5188178588c9067d..5dda85c707f6efd7 100644
> --- a/drivers/media/i2c/adv748x/adv748x-afe.c
> +++ b/drivers/media/i2c/adv748x/adv748x-afe.c
> @@ -43,6 +43,9 @@
>  #define ADV748X_AFE_STD_PAL_SECAM0xe
>  #define ADV748X_AFE_STD_PAL_SECAM_PED0xf
>  
> +#define ADV748X_AFE_ROUTES_MAX ((ADV748X_AFE_SINK_AIN7 - \
> + ADV748X_AFE_SINK_AIN0) + 1)
> +
>  static int adv748x_afe_read_ro_map(struct adv748x_state *state, u8 reg)
>  {
>   int ret;
> @@ -386,10 +389,73 @@ static int adv748x_afe_set_format(struct v4l2_subdev 
> *sd,
>   return 0;
>  }
>  
> +

No need for that extra line..

> +static int adv748x_afe_get_routing(struct v4l2_subdev *sd,
> +struct v4l2_subdev_routing *routing)
> +{
> + struct adv748x_afe *afe = adv748x_sd_to_afe(sd);
> + struct v4l2_subdev_route *r = routing->routes;
> + unsigned int i;
> +
> + /* There are one possible route from each sink */

There is one possible ...

> + if (routing->num_routes < ADV748X_AFE_ROUTES_MAX) {
> + routing->num_routes = ADV748X_AFE_ROUTES_MAX;
> + return -ENOSPC;
> + }
> +
> + routing->num_routes = ADV748X_AFE_ROUTES_MAX;
> +
> + for (i = ADV748X_AFE_SINK_AIN0; i <= ADV748X_AFE_SINK_AIN7; i++) {
> + r->sink_pad = i;
> + r->sink_stream = 0;
> + r->source_pad = ADV748X_AFE_SOURCE;
> + r->source_stream = 0;
> + r->flags = afe->input == i ? V4L2_SUBDEV_ROUTE_FL_ACTIVE : 0;
> + r++;
> + }
> +
> + return 0;
> +}
> +
> +static int adv748x_afe_set_routing(struct v4l2_subdev *sd,
> +struct v4l2_subdev_routing *routing)
> +{
> + struct adv748x_afe *afe = adv748x_sd_to_afe(sd);
> + struct v4l2_subdev_route *r = routing->routes;
> + int input = -1;
> + unsigned int i;
> +
> + if (routing->num_routes > ADV748X_AFE_ROUTES_MAX)
> + return -ENOSPC;
> +
> + for (i = 0; i < routing->num_routes; i++) {
> + if (r->sink_pad > ADV748X_AFE_SINK_AIN7 ||
> + r->sink_stream != 0 ||
> + r->source_pad != ADV748X_AFE_SOURCE ||
> + r->source_stream != 0)
> + return -EINVAL;
> +
> + if (r->flags & V4L2_SUBDEV_ROUTE_FL_ACTIVE) {
> + if (input != -1)
> + return -EMLINK;
> +
> + input = r->sink_pad;
> + }
> + r++;
> + }
> +
> + if (input != -1)
> + afe->input = input;> +
> + return 0;
> +}
> +
>  static const struct v4l2_subdev_pad_ops adv748x_afe_pad_ops = {
>   .enum_mbus_code = adv748x_afe_enum_mbus_code,
>   .set_fmt = adv748x_afe_set_format,
>   .get_fmt = adv748x_afe_get_format,
> + .get_routing = adv748x_afe_get_routing,
> + .set_routing = adv748x_afe_set_routing,
>  };
>  
>  /* 
> -
> 


Re: [PATCH/RFC v2 10/15] adv748x: csi2: add translation from pixelcode to CSI-2 datatype

2017-12-14 Thread Kieran Bingham
Hi Niklas,

On 14/12/17 19:08, Niklas Söderlund wrote:
> This will be needed to fill out the frame descriptor information
> correctly.
> 
> Signed-off-by: Niklas Söderlund 
> ---
>  drivers/media/i2c/adv748x/adv748x-csi2.c | 22 ++
>  1 file changed, 22 insertions(+)
> 
> diff --git a/drivers/media/i2c/adv748x/adv748x-csi2.c 
> b/drivers/media/i2c/adv748x/adv748x-csi2.c
> index 2a5dff8c571013bf..a2a6d93077204731 100644
> --- a/drivers/media/i2c/adv748x/adv748x-csi2.c
> +++ b/drivers/media/i2c/adv748x/adv748x-csi2.c
> @@ -18,6 +18,28 @@
>  
>  #include "adv748x.h"
>  
> +struct adv748x_csi2_format {
> + unsigned int code;
> + unsigned int datatype;
> +};
> +
> +static const struct adv748x_csi2_format adv748x_csi2_formats[] = {
> + { .code = MEDIA_BUS_FMT_RGB888_1X24,.datatype = 0x24, },
> + { .code = MEDIA_BUS_FMT_UYVY8_1X16, .datatype = 0x1e, },
> + { .code = MEDIA_BUS_FMT_UYVY8_2X8,  .datatype = 0x1e, },
> + { .code = MEDIA_BUS_FMT_YUYV10_2X10,.datatype = 0x1e, },
> +};

Is the datatype mapping specific to the ADV748x here?
or are these generic/common CSI2 mappings?

What do those datatype magic numbers represent?

--
Kieran

> +
> +static unsigned int adv748x_csi2_code_to_datatype(unsigned int code)
> +{
> + unsigned int i;
> +
> + for (i = 0; i < ARRAY_SIZE(adv748x_csi2_formats); i++)
> + if (adv748x_csi2_formats[i].code == code)
> + return adv748x_csi2_formats[i].datatype;
> + return 0;
> +}
> +
>  static bool is_txa(struct adv748x_csi2 *tx)
>  {
>   return tx == >state->txa;
> 


Re: [PATCH/RFC v2 09/15] adv748x: csi2: add module param for virtual channel

2017-12-14 Thread Kieran Bingham
Hi Niklas,

On 14/12/17 19:08, Niklas Söderlund wrote:
> The hardware can output on any of the 4 (0-3) Virtual Channels of the
> CSI-2 bus. Add a module parameter each for TXA and TXB to allow the user
> to specify which channel should be used.

This patch only configures the channel at initialisation time, (which is a valid
thing to do here at the moment I think) - but will we expect to provide
functionality to change the virtual channel later ?

Do we need to communicate the virtual channel in use across the media pad links
somehow? (or does that already happen?)

Perhaps the commit message could be clear on the fact that this only sets the
channels initialisation value - and that modifying the module parameter after
module load will have no effect?

Regards

Kieran


> Signed-off-by: Niklas Söderlund 
>
> ---
>  drivers/media/i2c/adv748x/adv748x-core.c | 10 ++
>  drivers/media/i2c/adv748x/adv748x-csi2.c |  2 +-
>  drivers/media/i2c/adv748x/adv748x.h  |  1 +
>  3 files changed, 12 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/media/i2c/adv748x/adv748x-core.c 
> b/drivers/media/i2c/adv748x/adv748x-core.c
> index fd92c9e4b519d2c5..3cad52532ead2e34 100644
> --- a/drivers/media/i2c/adv748x/adv748x-core.c
> +++ b/drivers/media/i2c/adv748x/adv748x-core.c
> @@ -31,6 +31,9 @@
>  
>  #include "adv748x.h"
>  
> +static unsigned int txavc;
> +static unsigned int txbvc;
> +
>  /* 
> -
>   * Register manipulation
>   */
> @@ -747,6 +750,7 @@ static int adv748x_probe(struct i2c_client *client,
>   }
>  
>   /* Initialise TXA */
> + state->txa.vc = txavc;
>   ret = adv748x_csi2_init(state, >txa);
>   if (ret) {
>   adv_err(state, "Failed to probe TXA");
> @@ -754,6 +758,7 @@ static int adv748x_probe(struct i2c_client *client,
>   }
>  
>   /* Initialise TXB */
> + state->txb.vc = txbvc;
>   ret = adv748x_csi2_init(state, >txb);
>   if (ret) {
>   adv_err(state, "Failed to probe TXB");
> @@ -824,6 +829,11 @@ static struct i2c_driver adv748x_driver = {
>  
>  module_i2c_driver(adv748x_driver);
>  
> +module_param(txavc, uint, 0644);
> +MODULE_PARM_DESC(txavc, "Virtual Channel for TXA");
> +module_param(txbvc, uint, 0644);
> +MODULE_PARM_DESC(txbvc, "Virtual Channel for TXB");
> +
>  MODULE_AUTHOR("Kieran Bingham ");
>  MODULE_DESCRIPTION("ADV748X video decoder");
>  MODULE_LICENSE("GPL v2");
> diff --git a/drivers/media/i2c/adv748x/adv748x-csi2.c 
> b/drivers/media/i2c/adv748x/adv748x-csi2.c
> index 820b44ed56a8679f..2a5dff8c571013bf 100644
> --- a/drivers/media/i2c/adv748x/adv748x-csi2.c
> +++ b/drivers/media/i2c/adv748x/adv748x-csi2.c
> @@ -281,7 +281,7 @@ int adv748x_csi2_init(struct adv748x_state *state, struct 
> adv748x_csi2 *tx)
>   }
>  
>   /* Initialise the virtual channel */
> - adv748x_csi2_set_virtual_channel(tx, 0);
> + adv748x_csi2_set_virtual_channel(tx, tx->vc);
>  
>   adv748x_subdev_init(>sd, state, _csi2_ops,
>   MEDIA_ENT_F_UNKNOWN,
> diff --git a/drivers/media/i2c/adv748x/adv748x.h 
> b/drivers/media/i2c/adv748x/adv748x.h
> index 6789e2f3bc8c2b49..f6e40ee3924e8f12 100644
> --- a/drivers/media/i2c/adv748x/adv748x.h
> +++ b/drivers/media/i2c/adv748x/adv748x.h
> @@ -92,6 +92,7 @@ enum adv748x_csi2_pads {
>  
>  struct adv748x_csi2 {
>   struct adv748x_state *state;
> + unsigned int vc;
>   struct v4l2_mbus_framefmt format;
>   unsigned int page;
>  
> 


Re: [PATCH] media: v4l: xilinx: Use SPDX-License-Identifier

2017-12-14 Thread Laurent Pinchart
Hi Mauro,

On Thursday, 14 December 2017 23:50:03 EET Mauro Carvalho Chehab wrote:
> Em Thu, 14 Dec 2017 21:57:06 +0100 Greg KH escreveu:
> > On Thu, Dec 14, 2017 at 10:44:16PM +0200, Laurent Pinchart wrote:
> >> On Thursday, 14 December 2017 22:08:51 EET Greg KH wrote:
> >>> On Thu, Dec 14, 2017 at 09:05:27PM +0200, Laurent Pinchart wrote:
>  On Thursday, 14 December 2017 20:54:39 EET Joe Perches wrote:
> > On Thu, 2017-12-14 at 20:37 +0200, Laurent Pinchart wrote:
> >> On Thursday, 14 December 2017 20:32:20 EET Joe Perches wrote:
> >>> On Thu, 2017-12-14 at 20:28 +0200, Laurent Pinchart wrote:
>  On Thursday, 14 December 2017 19:05:27 EET Mauro Carvalho Chehab
>  wrote:
> > Em Fri,  8 Dec 2017 18:05:37 +0530 Dhaval Shah escreveu:
> >> SPDX-License-Identifier is used for the Xilinx Video IP and
> >> related drivers.
> >> 
> >> Signed-off-by: Dhaval Shah 
> > 
> > Hi Dhaval,
> > 
> > You're not listed as one of the Xilinx driver maintainers. I'm
> > afraid that, without their explicit acks, sent to the ML, I
> > can't accept a patch touching at the driver's license tags.
>  
>  The patch doesn't change the license, I don't see why it would
>  cause any issue. Greg isn't listed as the maintainer or copyright
>  holder of any of the 10k+ files to which he added an SPDX license
>  header in the last kernel release.
> >>> 
> >>> Adding a comment line that describes an implicit or
> >>> explicit license is different than removing the license
> >>> text itself.
> >> 
> >> The SPDX license header is meant to be equivalent to the license
> >> text.
> > 
> > I understand that.
> > At a minimum, removing BSD license text is undesirable
> > 
> > as that license states:
> >  ** Redistributions of source code must retain the above copyright
> >  *  notice, this list of conditions and the following disclaimer.
> > 
> > etc...
>  
>  But this patch only removes the following text:
>  
>  - * This program is free software; you can redistribute it and/or
>  modify
>  - * it under the terms of the GNU General Public License version 2 as
>  - * published by the Free Software Foundation.
>  
>  and replaces it by the corresponding SPDX header.
>  
> >> The only reason why the large SPDX patch didn't touch the whole
> >> kernel in one go was that it was easier to split in in multiple
> >> chunks.
> > 
> > Not really, it was scripted.
>  
>  But still manually reviewed as far as I know.
>  
> >> This is no different than not including the full GPL license in
> >> every header file but only pointing to it through its name and
> >> reference, as every kernel source file does.
> > 
> > Not every kernel source file had a license text
> > or a reference to another license file.
>  
>  Correct, but the files touched by this patch do.
>  
>  This issue is in no way specific to linux-media and should be
>  decided upon at the top level, not on a per-subsystem basis. Greg,
>  could you comment on this ?
> >>> 
> >>> Comment on what exactly?  I don't understand the problem here, care to
> >>> summarize it?
> >> 
> >> In a nutshell (if I understand it correctly), Dhaval Shah submitted
> >> https:// patchwork.kernel.org/patch/10102451/ which replaces
> >> 
> >> +// SPDX-License-Identifier: GPL-2.0
> >> [...]
> >> - *
> >> - * This program is free software; you can redistribute it and/or modify
> >> - * it under the terms of the GNU General Public License version 2 as
> >> - * published by the Free Software Foundation.
> >> 
> >> in all .c and .h files of the Xilinx V4L2 driver
> >> (drivers/media/platform/
> >> xilinx). I have reviewed the patch and acked it. Mauro then rejected it,
> >> stating that he can't accept a change to license text without an
> >> explicit ack from the official driver's maintainers. My position is
> >> that such a change doesn't change the license and thus doesn't need to
> >> track all copyright holders, and can be merged without an explicit ack
> >> from the respective maintainers.
> > 
> > Yes, I agree with you, no license is being changed here, and no
> > copyright is either.
> > 
> > BUT, I know that most major companies are reviewing this process right
> > now.  We have gotten approval from almost all of the major kernel
> > developer companies to do this, which is great, and supports this work
> > as being acceptable.
> > 
> > So it's nice to ask Xilinx if they object to this happening, which I
> > guess Mauro is trying to say here (in not so many words...)  To at least
> > give them the heads-up that this is what is going to be going on
> > throughout the kernel tree soon, and if they object, it would be good to
> > speak up as to why 

[bug report] drx: add initial drx-d driver

2017-12-14 Thread Ralph Metzler
Hello Dan Carpenter,

Dan Carpenter writes:
 > Hello Ralph Metzler,
 > 
 > The patch 126f1e618870: "drx: add initial drx-d driver" from Mar 12,
 > 2011, leads to the following static checker warning:
 > 
 >  drivers/media/dvb-frontends/drxd_hard.c:1305 SC_WaitForReady()
 >  info: return a literal instead of 'status'
 > 
 > drivers/media/dvb-frontends/drxd_hard.c
 >   1298  static int SC_WaitForReady(struct drxd_state *state)
 >   1299  {
 >   1300  int i;
 >   1301  
 >   1302  for (i = 0; i < DRXD_MAX_RETRIES; i += 1) {
 >   1303  int status = Read16(state, SC_RA_RAM_CMD__A, NULL, 
 > 0);
 >   1304  if (status == 0)
 >   1305  return status;
 > ^
 > The register is set to zero when ready?  The answer should obviously be
 > yes, but it wouldn't totally surprise me if this function just always
 > looped 1000 times...  Few of the callers check the return.  Anyway, it's
 > more clear to just "return 0;"
 > 
 >   1306  }
 >   1307  return -1;
 >^^
 > -1 is not a proper error code.
 > 
 >   1308  }
 > 
 > regards,
 > dan carpenter

I think I wrote the driver more than 10 years ago and somebody later submitted 
it
to the kernel.

I don't know if there is a anybody still maintaining this. Is it even used 
anymore?
I could write a patch but cannot test it (e.g. to see if it really always
loops 1000 times ...)


Regards,
Ralph Metzler

-- 
--


Re: [PATCH] media: v4l: xilinx: Use SPDX-License-Identifier

2017-12-14 Thread Mauro Carvalho Chehab
Em Thu, 14 Dec 2017 21:57:06 +0100
Greg KH  escreveu:

> On Thu, Dec 14, 2017 at 10:44:16PM +0200, Laurent Pinchart wrote:
> > Hi Greg,
> > 
> > On Thursday, 14 December 2017 22:08:51 EET Greg KH wrote:  
> > > On Thu, Dec 14, 2017 at 09:05:27PM +0200, Laurent Pinchart wrote:  
> > > > On Thursday, 14 December 2017 20:54:39 EET Joe Perches wrote:  
> > > >> On Thu, 2017-12-14 at 20:37 +0200, Laurent Pinchart wrote:  
> > > >>> On Thursday, 14 December 2017 20:32:20 EET Joe Perches wrote:  
> > >  On Thu, 2017-12-14 at 20:28 +0200, Laurent Pinchart wrote:  
> > > > On Thursday, 14 December 2017 19:05:27 EET Mauro Carvalho Chehab   
> > wrote:  
> > > >> Em Fri,  8 Dec 2017 18:05:37 +0530 Dhaval Shah escreveu:  
> > > >>> SPDX-License-Identifier is used for the Xilinx Video IP and
> > > >>> related drivers.
> > > >>> 
> > > >>> Signed-off-by: Dhaval Shah   
> > > >> 
> > > >> Hi Dhaval,
> > > >> 
> > > >> You're not listed as one of the Xilinx driver maintainers. I'm
> > > >> afraid that, without their explicit acks, sent to the ML, I can't
> > > >> accept a patch touching at the driver's license tags.  
> > > > 
> > > > The patch doesn't change the license, I don't see why it would cause
> > > > any issue. Greg isn't listed as the maintainer or copyright holder
> > > > of any of the 10k+ files to which he added an SPDX license header in
> > > > the last kernel release.  
> > >  
> > >  Adding a comment line that describes an implicit or
> > >  explicit license is different than removing the license
> > >  text itself.  
> > > >>> 
> > > >>> The SPDX license header is meant to be equivalent to the license 
> > > >>> text.  
> > > >> 
> > > >> I understand that.
> > > >> At a minimum, removing BSD license text is undesirable
> > > >> 
> > > >> as that license states:
> > > >>  ** Redistributions of source code must retain the above copyright
> > > >>  *  notice, this list of conditions and the following disclaimer.
> > > >> 
> > > >> etc...  
> > > > 
> > > > But this patch only removes the following text:
> > > > 
> > > > - * This program is free software; you can redistribute it and/or modify
> > > > - * it under the terms of the GNU General Public License version 2 as
> > > > - * published by the Free Software Foundation.
> > > > 
> > > > and replaces it by the corresponding SPDX header.
> > > >   
> > > >>> The only reason why the large SPDX patch didn't touch the whole kernel
> > > >>> in one go was that it was easier to split in in multiple chunks.  
> > > >> 
> > > >> Not really, it was scripted.  
> > > > 
> > > > But still manually reviewed as far as I know.
> > > >   
> > > >>> This is no different than not including the full GPL license in every
> > > >>> header file but only pointing to it through its name and reference, as
> > > >>> every kernel source file does.  
> > > >> 
> > > >> Not every kernel source file had a license text
> > > >> or a reference to another license file.  
> > > > 
> > > > Correct, but the files touched by this patch do.
> > > > 
> > > > This issue is in no way specific to linux-media and should be decided 
> > > > upon
> > > > at the top level, not on a per-subsystem basis. Greg, could you comment
> > > > on this ?  
> > > 
> > > Comment on what exactly?  I don't understand the problem here, care to
> > > summarize it?  
> > 
> > In a nutshell (if I understand it correctly), Dhaval Shah submitted https://
> > patchwork.kernel.org/patch/10102451/ which replaces
> > 
> > +// SPDX-License-Identifier: GPL-2.0
> > [...]
> > - *
> > - * This program is free software; you can redistribute it and/or modify
> > - * it under the terms of the GNU General Public License version 2 as
> > - * published by the Free Software Foundation.
> > 
> > in all .c and .h files of the Xilinx V4L2 driver (drivers/media/platform/
> > xilinx). I have reviewed the patch and acked it. Mauro then rejected it, 
> > stating that he can't accept a change to license text without an explicit 
> > ack 
> > from the official driver's maintainers. My position is that such a change 
> > doesn't change the license and thus doesn't need to track all copyright 
> > holders, and can be merged without an explicit ack from the respective 
> > maintainers.  
> 
> Yes, I agree with you, no license is being changed here, and no
> copyright is either.
> 
> BUT, I know that most major companies are reviewing this process right
> now.  We have gotten approval from almost all of the major kernel
> developer companies to do this, which is great, and supports this work
> as being acceptable.
> 
> So it's nice to ask Xilinx if they object to this happening, which I
> guess Mauro is trying to say here (in not so many words...)  To at least
> give them the heads-up that this is what is going to be going on
> throughout the kernel tree soon, and if they object, it would be good to

Re: [PATCH] media: v4l: xilinx: Use SPDX-License-Identifier

2017-12-14 Thread Greg KH
On Thu, Dec 14, 2017 at 10:44:16PM +0200, Laurent Pinchart wrote:
> Hi Greg,
> 
> On Thursday, 14 December 2017 22:08:51 EET Greg KH wrote:
> > On Thu, Dec 14, 2017 at 09:05:27PM +0200, Laurent Pinchart wrote:
> > > On Thursday, 14 December 2017 20:54:39 EET Joe Perches wrote:
> > >> On Thu, 2017-12-14 at 20:37 +0200, Laurent Pinchart wrote:
> > >>> On Thursday, 14 December 2017 20:32:20 EET Joe Perches wrote:
> >  On Thu, 2017-12-14 at 20:28 +0200, Laurent Pinchart wrote:
> > > On Thursday, 14 December 2017 19:05:27 EET Mauro Carvalho Chehab 
> wrote:
> > >> Em Fri,  8 Dec 2017 18:05:37 +0530 Dhaval Shah escreveu:
> > >>> SPDX-License-Identifier is used for the Xilinx Video IP and
> > >>> related drivers.
> > >>> 
> > >>> Signed-off-by: Dhaval Shah 
> > >> 
> > >> Hi Dhaval,
> > >> 
> > >> You're not listed as one of the Xilinx driver maintainers. I'm
> > >> afraid that, without their explicit acks, sent to the ML, I can't
> > >> accept a patch touching at the driver's license tags.
> > > 
> > > The patch doesn't change the license, I don't see why it would cause
> > > any issue. Greg isn't listed as the maintainer or copyright holder
> > > of any of the 10k+ files to which he added an SPDX license header in
> > > the last kernel release.
> >  
> >  Adding a comment line that describes an implicit or
> >  explicit license is different than removing the license
> >  text itself.
> > >>> 
> > >>> The SPDX license header is meant to be equivalent to the license text.
> > >> 
> > >> I understand that.
> > >> At a minimum, removing BSD license text is undesirable
> > >> 
> > >> as that license states:
> > >>  ** Redistributions of source code must retain the above copyright
> > >>  *  notice, this list of conditions and the following disclaimer.
> > >> 
> > >> etc...
> > > 
> > > But this patch only removes the following text:
> > > 
> > > - * This program is free software; you can redistribute it and/or modify
> > > - * it under the terms of the GNU General Public License version 2 as
> > > - * published by the Free Software Foundation.
> > > 
> > > and replaces it by the corresponding SPDX header.
> > > 
> > >>> The only reason why the large SPDX patch didn't touch the whole kernel
> > >>> in one go was that it was easier to split in in multiple chunks.
> > >> 
> > >> Not really, it was scripted.
> > > 
> > > But still manually reviewed as far as I know.
> > > 
> > >>> This is no different than not including the full GPL license in every
> > >>> header file but only pointing to it through its name and reference, as
> > >>> every kernel source file does.
> > >> 
> > >> Not every kernel source file had a license text
> > >> or a reference to another license file.
> > > 
> > > Correct, but the files touched by this patch do.
> > > 
> > > This issue is in no way specific to linux-media and should be decided upon
> > > at the top level, not on a per-subsystem basis. Greg, could you comment
> > > on this ?
> > 
> > Comment on what exactly?  I don't understand the problem here, care to
> > summarize it?
> 
> In a nutshell (if I understand it correctly), Dhaval Shah submitted https://
> patchwork.kernel.org/patch/10102451/ which replaces
> 
> +// SPDX-License-Identifier: GPL-2.0
> [...]
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License version 2 as
> - * published by the Free Software Foundation.
> 
> in all .c and .h files of the Xilinx V4L2 driver (drivers/media/platform/
> xilinx). I have reviewed the patch and acked it. Mauro then rejected it, 
> stating that he can't accept a change to license text without an explicit ack 
> from the official driver's maintainers. My position is that such a change 
> doesn't change the license and thus doesn't need to track all copyright 
> holders, and can be merged without an explicit ack from the respective 
> maintainers.

Yes, I agree with you, no license is being changed here, and no
copyright is either.

BUT, I know that most major companies are reviewing this process right
now.  We have gotten approval from almost all of the major kernel
developer companies to do this, which is great, and supports this work
as being acceptable.

So it's nice to ask Xilinx if they object to this happening, which I
guess Mauro is trying to say here (in not so many words...)  To at least
give them the heads-up that this is what is going to be going on
throughout the kernel tree soon, and if they object, it would be good to
speak up as to why (and if they do, I can put their lawyers in contact
with some lawyers to explain it all to them.)

> On a side note, Joe pointed out that some files contains BSD license text 
> similar to
> 
>  ** Redistributions of source code must retain the above copyright
>  *  notice, this list of conditions and the following disclaimer.
> 
> If 

Re: [PATCH] media: v4l: xilinx: Use SPDX-License-Identifier

2017-12-14 Thread Laurent Pinchart
Hi Greg,

On Thursday, 14 December 2017 22:08:51 EET Greg KH wrote:
> On Thu, Dec 14, 2017 at 09:05:27PM +0200, Laurent Pinchart wrote:
> > On Thursday, 14 December 2017 20:54:39 EET Joe Perches wrote:
> >> On Thu, 2017-12-14 at 20:37 +0200, Laurent Pinchart wrote:
> >>> On Thursday, 14 December 2017 20:32:20 EET Joe Perches wrote:
>  On Thu, 2017-12-14 at 20:28 +0200, Laurent Pinchart wrote:
> > On Thursday, 14 December 2017 19:05:27 EET Mauro Carvalho Chehab 
wrote:
> >> Em Fri,  8 Dec 2017 18:05:37 +0530 Dhaval Shah escreveu:
> >>> SPDX-License-Identifier is used for the Xilinx Video IP and
> >>> related drivers.
> >>> 
> >>> Signed-off-by: Dhaval Shah 
> >> 
> >> Hi Dhaval,
> >> 
> >> You're not listed as one of the Xilinx driver maintainers. I'm
> >> afraid that, without their explicit acks, sent to the ML, I can't
> >> accept a patch touching at the driver's license tags.
> > 
> > The patch doesn't change the license, I don't see why it would cause
> > any issue. Greg isn't listed as the maintainer or copyright holder
> > of any of the 10k+ files to which he added an SPDX license header in
> > the last kernel release.
>  
>  Adding a comment line that describes an implicit or
>  explicit license is different than removing the license
>  text itself.
> >>> 
> >>> The SPDX license header is meant to be equivalent to the license text.
> >> 
> >> I understand that.
> >> At a minimum, removing BSD license text is undesirable
> >> 
> >> as that license states:
> >>  ** Redistributions of source code must retain the above copyright
> >>  *  notice, this list of conditions and the following disclaimer.
> >> 
> >> etc...
> > 
> > But this patch only removes the following text:
> > 
> > - * This program is free software; you can redistribute it and/or modify
> > - * it under the terms of the GNU General Public License version 2 as
> > - * published by the Free Software Foundation.
> > 
> > and replaces it by the corresponding SPDX header.
> > 
> >>> The only reason why the large SPDX patch didn't touch the whole kernel
> >>> in one go was that it was easier to split in in multiple chunks.
> >> 
> >> Not really, it was scripted.
> > 
> > But still manually reviewed as far as I know.
> > 
> >>> This is no different than not including the full GPL license in every
> >>> header file but only pointing to it through its name and reference, as
> >>> every kernel source file does.
> >> 
> >> Not every kernel source file had a license text
> >> or a reference to another license file.
> > 
> > Correct, but the files touched by this patch do.
> > 
> > This issue is in no way specific to linux-media and should be decided upon
> > at the top level, not on a per-subsystem basis. Greg, could you comment
> > on this ?
> 
> Comment on what exactly?  I don't understand the problem here, care to
> summarize it?

In a nutshell (if I understand it correctly), Dhaval Shah submitted https://
patchwork.kernel.org/patch/10102451/ which replaces

+// SPDX-License-Identifier: GPL-2.0
[...]
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.

in all .c and .h files of the Xilinx V4L2 driver (drivers/media/platform/
xilinx). I have reviewed the patch and acked it. Mauro then rejected it, 
stating that he can't accept a change to license text without an explicit ack 
from the official driver's maintainers. My position is that such a change 
doesn't change the license and thus doesn't need to track all copyright 
holders, and can be merged without an explicit ack from the respective 
maintainers.

On a side note, Joe pointed out that some files contains BSD license text 
similar to

 ** Redistributions of source code must retain the above copyright
 *  notice, this list of conditions and the following disclaimer.

If we follow the text of the license strictly it can be argued that such text 
can't be replaced by an SPDX license identifier without breaching the license.

-- 
Regards,

Laurent Pinchart



Re: [PATCH] media: v4l: xilinx: Use SPDX-License-Identifier

2017-12-14 Thread Greg KH
On Thu, Dec 14, 2017 at 09:05:27PM +0200, Laurent Pinchart wrote:
> Hi Joe,
> 
> (CC'ing Greg and adding context for easier understanding)
> 
> On Thursday, 14 December 2017 20:54:39 EET Joe Perches wrote:
> > On Thu, 2017-12-14 at 20:37 +0200, Laurent Pinchart wrote:
> > > On Thursday, 14 December 2017 20:32:20 EET Joe Perches wrote:
> > >> On Thu, 2017-12-14 at 20:28 +0200, Laurent Pinchart wrote:
> > >>> On Thursday, 14 December 2017 19:05:27 EET Mauro Carvalho Chehab wrote:
> >  Em Fri,  8 Dec 2017 18:05:37 +0530 Dhaval Shah escreveu:
> > > SPDX-License-Identifier is used for the Xilinx Video IP and
> > > related drivers.
> > > 
> > > Signed-off-by: Dhaval Shah 
> >  
> >  Hi Dhaval,
> >  
> >  You're not listed as one of the Xilinx driver maintainers. I'm afraid
> >  that, without their explicit acks, sent to the ML, I can't accept a
> >  patch touching at the driver's license tags.
> > >>> 
> > >>> The patch doesn't change the license, I don't see why it would cause
> > >>> any issue. Greg isn't listed as the maintainer or copyright holder of
> > >>> any of the 10k+ files to which he added an SPDX license header in the
> > >>> last kernel release.
> > >> Adding a comment line that describes an implicit or
> > >> explicit license is different than removing the license
> > >> text itself.
> > > 
> > > The SPDX license header is meant to be equivalent to the license text.
> > 
> > I understand that.
> > At a minimum, removing BSD license text is undesirable
> > as that license states:
> > 
> >  ** Redistributions of source code must retain the above copyright
> >  *  notice, this list of conditions and the following disclaimer.
> > etc...
> 
> But this patch only removes the following text:
> 
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License version 2 as
> - * published by the Free Software Foundation.
> 
> and replaces it by the corresponding SPDX header.
> 
> > > The only reason why the large SPDX patch didn't touch the whole kernel in
> > > one go was that it was easier to split in in multiple chunks.
> > 
> > Not really, it was scripted.
> 
> But still manually reviewed as far as I know.
> 
> > > This is no different than not including the full GPL license in every
> > > header file but only pointing to it through its name and reference, as
> > > every kernel source file does.
> > 
> > Not every kernel source file had a license text
> > or a reference to another license file.
> 
> Correct, but the files touched by this patch do.
> 
> This issue is in no way specific to linux-media and should be decided upon at 
> the top level, not on a per-subsystem basis. Greg, could you comment on this ?

Comment on what exactly?  I don't understand the problem here, care to
summarize it?

thanks,

greg k-h


[PATCH/RFC v2 07/15] rcar-csi2: use frame description information to configure CSI-2 bus

2017-12-14 Thread Niklas Söderlund
The driver now have access to frame descriptor information, use it. Only
enable the virtual channels which are described in the frame descriptor
and calculate the link based on all enabled streams.

With multiplexed stream support it's now possible to have different
formats on the different source pads. Make source formats independent
off each other and disallowing a format on the multiplexed sink.

Signed-off-by: Niklas Söderlund 
---
 drivers/media/platform/rcar-vin/rcar-csi2.c | 112 ++--
 1 file changed, 58 insertions(+), 54 deletions(-)

diff --git a/drivers/media/platform/rcar-vin/rcar-csi2.c 
b/drivers/media/platform/rcar-vin/rcar-csi2.c
index 6b607b2e31e26063..2dd7d03d622d5510 100644
--- a/drivers/media/platform/rcar-vin/rcar-csi2.c
+++ b/drivers/media/platform/rcar-vin/rcar-csi2.c
@@ -296,24 +296,22 @@ static const struct phtw_testdin_data 
testdin_data_v3m_e3[] = {
 #define CSI0CLKFREQRANGE(n)((n & 0x3f) << 16)
 
 struct rcar_csi2_format {
-   unsigned int code;
unsigned int datatype;
unsigned int bpp;
 };
 
 static const struct rcar_csi2_format rcar_csi2_formats[] = {
-   { .code = MEDIA_BUS_FMT_RGB888_1X24,.datatype = 0x24, .bpp = 24 },
-   { .code = MEDIA_BUS_FMT_UYVY8_1X16, .datatype = 0x1e, .bpp = 16 },
-   { .code = MEDIA_BUS_FMT_UYVY8_2X8,  .datatype = 0x1e, .bpp = 16 },
-   { .code = MEDIA_BUS_FMT_YUYV10_2X10,.datatype = 0x1e, .bpp = 16 },
+   { .datatype = 0x1e, .bpp = 16 },
+   { .datatype = 0x24, .bpp = 24 },
 };
 
-static const struct rcar_csi2_format *rcar_csi2_code_to_fmt(unsigned int code)
+static const struct rcar_csi2_format
+*rcar_csi2_datatype_to_fmt(unsigned int datatype)
 {
unsigned int i;
 
for (i = 0; i < ARRAY_SIZE(rcar_csi2_formats); i++)
-   if (rcar_csi2_formats[i].code == code)
+   if (rcar_csi2_formats[i].datatype == datatype)
return rcar_csi2_formats + i;
 
return NULL;
@@ -355,7 +353,7 @@ struct rcar_csi2 {
struct v4l2_async_notifier notifier;
struct v4l2_async_subdev remote;
 
-   struct v4l2_mbus_framefmt mf;
+   struct v4l2_mbus_framefmt mf[4];
 
struct mutex lock;
int stream_count[4];
@@ -411,25 +409,14 @@ static int rcar_csi2_wait_phy_start(struct rcar_csi2 
*priv)
return -ETIMEDOUT;
 }
 
-static int rcar_csi2_calc_mbps(struct rcar_csi2 *priv, unsigned int bpp)
+static int rcar_csi2_calc_mbps(struct rcar_csi2 *priv,
+  struct v4l2_subdev *source,
+  struct v4l2_mbus_frame_desc *fd)
 {
-   struct media_pad *pad, *source_pad;
-   struct v4l2_subdev *source = NULL;
struct v4l2_ctrl *ctrl;
+   unsigned int i, bpp = 0;
u64 mbps;
 
-   /* Get remote subdevice */
-   pad = >subdev.entity.pads[RCAR_CSI2_SINK];
-   source_pad = media_entity_remote_pad(pad);
-   if (!source_pad) {
-   dev_err(priv->dev, "Could not find remote source pad\n");
-   return -ENODEV;
-   }
-   source = media_entity_to_v4l2_subdev(source_pad->entity);
-
-   dev_dbg(priv->dev, "Using source %s pad: %u\n", source->name,
-   source_pad->index);
-
/* Read the pixel rate control from remote */
ctrl = v4l2_ctrl_find(source->ctrl_handler, V4L2_CID_PIXEL_RATE);
if (!ctrl) {
@@ -438,6 +425,21 @@ static int rcar_csi2_calc_mbps(struct rcar_csi2 *priv, 
unsigned int bpp)
return -EINVAL;
}
 
+   /* Calculate total bpp */
+   for (i = 0; i < fd->num_entries; i++) {
+   const struct rcar_csi2_format *format;
+
+   format = rcar_csi2_datatype_to_fmt(
+   fd->entry[i].bus.csi2.data_type);
+   if (!format) {
+   dev_err(priv->dev, "Unknown data type: %d\n",
+   fd->entry[i].bus.csi2.data_type);
+   return -EINVAL;
+   }
+
+   bpp += format->bpp;
+   }
+
/* Calculate the phypll */
mbps = v4l2_ctrl_g_ctrl_int64(ctrl) * bpp;
do_div(mbps, priv->lanes * 100);
@@ -489,39 +491,33 @@ static int rcar_csi2_set_phtw(struct rcar_csi2 *priv, 
unsigned int mbps)
return 0;
 }
 
-static int rcar_csi2_start(struct rcar_csi2 *priv)
+static int rcar_csi2_start(struct rcar_csi2 *priv, struct v4l2_subdev *source,
+  struct v4l2_mbus_frame_desc *fd)
 {
-   const struct rcar_csi2_format *format;
-   u32 phycnt, tmp;
-   u32 vcdt = 0, vcdt2 = 0;
+   u32 phycnt, vcdt = 0, vcdt2 = 0;
unsigned int i;
int mbps, ret;
 
-   dev_dbg(priv->dev, "Input size (%ux%u%c)\n",
-   priv->mf.width, priv->mf.height,
-   priv->mf.field == V4L2_FIELD_NONE ? 'p' : 'i');
-
-   /* Code is validated in set_ftm */
-   

[RFC 2/2] v4l2-ctl: add ROUTING get and set options

2017-12-14 Thread Niklas Söderlund
Signed-off-by: Niklas Söderlund 
---
 utils/v4l2-ctl/Android.mk   |   2 +-
 utils/v4l2-ctl/Makefile.am  |   2 +-
 utils/v4l2-ctl/v4l2-ctl-routing.cpp | 154 
 utils/v4l2-ctl/v4l2-ctl.cpp |  10 +++
 utils/v4l2-ctl/v4l2-ctl.h   |   9 +++
 5 files changed, 175 insertions(+), 2 deletions(-)
 create mode 100644 utils/v4l2-ctl/v4l2-ctl-routing.cpp

diff --git a/utils/v4l2-ctl/Android.mk b/utils/v4l2-ctl/Android.mk
index 707895026f88962d..f83347e04ff477c7 100644
--- a/utils/v4l2-ctl/Android.mk
+++ b/utils/v4l2-ctl/Android.mk
@@ -21,5 +21,5 @@ LOCAL_SRC_FILES := \
 v4l2-ctl-io.cpp v4l2-ctl-stds.cpp v4l2-ctl-vidcap.cpp v4l2-ctl-vidout.cpp \
 v4l2-ctl-overlay.cpp v4l2-ctl-vbi.cpp v4l2-ctl-selection.cpp 
v4l2-ctl-misc.cpp \
 v4l2-ctl-streaming.cpp v4l2-ctl-sdr.cpp v4l2-ctl-edid.cpp 
v4l2-ctl-modes.cpp \
-v4l2-tpg-colors.c v4l2-tpg-core.c v4l-stream.c
+v4l2-tpg-colors.c v4l2-tpg-core.c v4l-stream.c v4l2-ctl-routing.cpp
 include $(BUILD_EXECUTABLE)
diff --git a/utils/v4l2-ctl/Makefile.am b/utils/v4l2-ctl/Makefile.am
index cae4e747a0afa047..69bf466e89bbf72e 100644
--- a/utils/v4l2-ctl/Makefile.am
+++ b/utils/v4l2-ctl/Makefile.am
@@ -6,7 +6,7 @@ v4l2_ctl_SOURCES = v4l2-ctl.cpp v4l2-ctl.h v4l2-ctl-common.cpp 
v4l2-ctl-tuner.cp
v4l2-ctl-io.cpp v4l2-ctl-stds.cpp v4l2-ctl-vidcap.cpp 
v4l2-ctl-vidout.cpp \
v4l2-ctl-overlay.cpp v4l2-ctl-vbi.cpp v4l2-ctl-selection.cpp 
v4l2-ctl-misc.cpp \
v4l2-ctl-streaming.cpp v4l2-ctl-sdr.cpp v4l2-ctl-edid.cpp 
v4l2-ctl-modes.cpp \
-   v4l2-tpg-colors.c v4l2-tpg-core.c v4l-stream.c v4l2-ctl-meta.cpp
+   v4l2-tpg-colors.c v4l2-tpg-core.c v4l-stream.c v4l2-ctl-meta.cpp 
v4l2-ctl-routing.cpp
 v4l2_ctl_CPPFLAGS = -I$(top_srcdir)/utils/common
 
 if WITH_LIBV4L
diff --git a/utils/v4l2-ctl/v4l2-ctl-routing.cpp 
b/utils/v4l2-ctl/v4l2-ctl-routing.cpp
new file mode 100644
index ..55a2e44949785015
--- /dev/null
+++ b/utils/v4l2-ctl/v4l2-ctl-routing.cpp
@@ -0,0 +1,154 @@
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "v4l2-ctl.h"
+
+#include 
+
+/*
+ * The max value comes from a check in the kernel source code
+ * drivers/media/v4l2-core/v4l2-ioctl.c check_array_args()
+ */
+#define NUM_ROUTES_MAX 256
+
+#define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0]))
+
+struct v4l2_subdev_routing routing;
+struct v4l2_subdev_route routes[NUM_ROUTES_MAX];
+
+struct flag_name {
+   __u32 flag;
+   const char *name;
+};
+
+static void print_flags(const struct flag_name *flag_names, unsigned int 
num_entries, __u32 flags)
+{
+   bool first = true;
+   unsigned int i;
+
+   for (i = 0; i < num_entries; i++) {
+   if (!(flags & flag_names[i].flag))
+   continue;
+   if (!first)
+   printf(",");
+   printf("%s", flag_names[i].name);
+   flags &= ~flag_names[i].flag;
+   first = false;
+   }
+
+   if (flags) {
+   if (!first)
+   printf(",");
+   printf("0x%x", flags);
+   }
+}
+
+static void print_routes(const struct v4l2_subdev_routing *r)
+{
+   unsigned int i;
+
+   static const struct flag_name route_flags[] = {
+   { V4L2_SUBDEV_ROUTE_FL_ACTIVE, "ENABLED" },
+   { V4L2_SUBDEV_ROUTE_FL_IMMUTABLE, "IMMUTABLE" },
+   };
+
+   for (i = 0; i < r->num_routes; i++) {
+   printf("%d/%d -> %d/%d [",
+  r->routes[i].sink_pad, r->routes[i].sink_stream,
+  r->routes[i].source_pad, r->routes[i].source_stream);
+   print_flags(route_flags, ARRAY_SIZE(route_flags), 
r->routes[i].flags);
+   printf("]\n");
+   }
+}
+
+void routing_usage(void)
+{
+   printf("\nRoute options:\n"
+  "  --get-routing Print the route topology\n"
+  "  --set-routing routes  Comma-separated list of route 
descriptors to setup\n"
+  "\n"
+  "Routes are defined as\n"
+  "routes  = route { ',' route } ;\n"
+  "route   = sink '->' source '[' flags ']' ;\n"
+  "sink= sink-pad '/' sink-stream ;\n"
+  "source  = source-pad '/' source-stream ;\n"
+  "\n"
+  "where the fields are\n"
+  "sink-pad= Pad numeric identifier for sink\n"
+  "sink-stream = Stream numeric identifier for sink\n"
+  "source-pad  = Pad numeric identifier for source\n"
+  "source-stream   = Stream numeric identifier for 
source\n"
+  "flags   = Route flags (0: inactive, 1: 
active)\n"
+  );
+}
+

[PATCH/RFC v2 05/15] rcar-csi2: count usage for each source pad

2017-12-14 Thread Niklas Söderlund
The R-Car CSI-2 hardware can output the same virtual channel
simultaneously to more then one R-Car VIN. For this reason we need to
move the usage counting from the global device to each source pad.

If a source pads usage count go from 0 to 1 we need to signal that a new
stream should start, likewise if it go from 1 to 0 we need to stop a
stream. At the same time we only want to start or stop the R-Car
CSI-2 device only on the first or last stream.

Signed-off-by: Niklas Söderlund 
---
 drivers/media/platform/rcar-vin/rcar-csi2.c | 38 +++--
 1 file changed, 30 insertions(+), 8 deletions(-)

diff --git a/drivers/media/platform/rcar-vin/rcar-csi2.c 
b/drivers/media/platform/rcar-vin/rcar-csi2.c
index 8ce0bfeef1113f9c..e0f56cc3d25179a9 100644
--- a/drivers/media/platform/rcar-vin/rcar-csi2.c
+++ b/drivers/media/platform/rcar-vin/rcar-csi2.c
@@ -328,6 +328,14 @@ enum rcar_csi2_pads {
NR_OF_RCAR_CSI2_PAD,
 };
 
+static int rcar_csi2_pad_to_vc(unsigned int pad)
+{
+   if (pad < RCAR_CSI2_SOURCE_VC0 || pad > RCAR_CSI2_SOURCE_VC3)
+   return -EINVAL;
+
+   return pad - RCAR_CSI2_SOURCE_VC0;
+}
+
 struct rcar_csi2_info {
const struct phypll_hsfreqrange *hsfreqrange;
const struct phtw_testdin_data *testdin_data;
@@ -350,7 +358,7 @@ struct rcar_csi2 {
struct v4l2_mbus_framefmt mf;
 
struct mutex lock;
-   int stream_count;
+   int stream_count[4];
 
unsigned short lanes;
unsigned char lane_swap[4];
@@ -630,7 +638,13 @@ static int rcar_csi2_s_stream(struct v4l2_subdev *sd, 
unsigned int pad,
 {
struct rcar_csi2 *priv = sd_to_csi2(sd);
struct v4l2_subdev *nextsd;
-   int ret;
+   unsigned int i, count = 0;
+   int ret, vc;
+
+   /* Only allow stream control on source pads and valid vc */
+   vc = rcar_csi2_pad_to_vc(pad);
+   if (vc < 0)
+   return vc;
 
/* Only one stream on each source pad */
if (stream != 0)
@@ -642,7 +656,10 @@ static int rcar_csi2_s_stream(struct v4l2_subdev *sd, 
unsigned int pad,
if (ret)
goto out;
 
-   if (enable && priv->stream_count == 0) {
+   for (i = 0; i < 4; i++)
+   count += priv->stream_count[i];
+
+   if (enable && count == 0) {
pm_runtime_get_sync(priv->dev);
 
ret = rcar_csi2_start(priv);
@@ -650,20 +667,23 @@ static int rcar_csi2_s_stream(struct v4l2_subdev *sd, 
unsigned int pad,
pm_runtime_put(priv->dev);
goto out;
}
+   } else if (!enable && count == 1) {
+   rcar_csi2_stop(priv);
+   pm_runtime_put(priv->dev);
+   }
 
+   if (enable && priv->stream_count[vc] == 0) {
ret = v4l2_subdev_call(nextsd, video, s_stream, 1);
if (ret) {
rcar_csi2_stop(priv);
pm_runtime_put(priv->dev);
goto out;
}
-   } else if (!enable && priv->stream_count == 1) {
-   rcar_csi2_stop(priv);
+   } else if (!enable && priv->stream_count[vc] == 1) {
ret = v4l2_subdev_call(nextsd, video, s_stream, 0);
-   pm_runtime_put(priv->dev);
}
 
-   priv->stream_count += enable ? 1 : -1;
+   priv->stream_count[vc] += enable ? 1 : -1;
 out:
mutex_unlock(>lock);
 
@@ -919,7 +939,9 @@ static int rcar_csi2_probe(struct platform_device *pdev)
priv->dev = >dev;
 
mutex_init(>lock);
-   priv->stream_count = 0;
+
+   for (i = 0; i < 4; i++)
+   priv->stream_count[i] = 0;
 
ret = rcar_csi2_probe_resources(priv, pdev);
if (ret) {
-- 
2.15.1



[PATCH/RFC v2 08/15] rcar-csi2: add get_routing support

2017-12-14 Thread Niklas Söderlund
To support multiplexed streams the internal routing between the
rcar-csi2 sink pad and its source pads needs to be described.

Signed-off-by: Niklas Söderlund 
---
 drivers/media/platform/rcar-vin/rcar-csi2.c | 54 +
 1 file changed, 54 insertions(+)

diff --git a/drivers/media/platform/rcar-vin/rcar-csi2.c 
b/drivers/media/platform/rcar-vin/rcar-csi2.c
index 2dd7d03d622d5510..fd1133e72482fc19 100644
--- a/drivers/media/platform/rcar-vin/rcar-csi2.c
+++ b/drivers/media/platform/rcar-vin/rcar-csi2.c
@@ -334,6 +334,14 @@ static int rcar_csi2_pad_to_vc(unsigned int pad)
return pad - RCAR_CSI2_SOURCE_VC0;
 }
 
+static int rcar_csi2_vc_to_pad(unsigned int vc)
+{
+   if (vc > 3)
+   return -EINVAL;
+
+   return vc + RCAR_CSI2_SOURCE_VC0;
+}
+
 struct rcar_csi2_info {
const struct phypll_hsfreqrange *hsfreqrange;
const struct phtw_testdin_data *testdin_data;
@@ -752,9 +760,55 @@ static int rcar_csi2_get_pad_format(struct v4l2_subdev *sd,
return 0;
 }
 
+static int rcar_csi2_get_routing(struct v4l2_subdev *sd,
+struct v4l2_subdev_routing *routing)
+{
+   struct rcar_csi2 *priv = sd_to_csi2(sd);
+   struct v4l2_mbus_frame_desc fd;
+   struct v4l2_subdev_route *r = routing->routes;
+   struct v4l2_subdev *rsubdev;
+   unsigned int i, rpad;
+   int ret;
+
+   /* Get information about multiplexed link */
+   ret = rcar_csi2_get_source_info(priv, , , );
+   if (ret)
+   return ret;
+
+   if (routing->num_routes < fd.num_entries) {
+   routing->num_routes = fd.num_entries;
+   return -ENOSPC;
+   }
+
+   routing->num_routes = fd.num_entries;
+
+   for (i = 0; i < fd.num_entries; i++) {
+   struct v4l2_mbus_frame_desc_entry *entry = [i];
+   int source_pad;
+
+   source_pad = rcar_csi2_vc_to_pad(entry->bus.csi2.channel);
+   if (source_pad < 0) {
+   dev_err(priv->dev, "Virtual Channel out of range: %u\n",
+   entry->bus.csi2.channel);
+   return -ENOSPC;
+   }
+
+   r->sink_pad = RCAR_CSI2_SINK;
+   r->sink_stream = entry->stream;
+   r->source_pad = source_pad;
+   r->source_stream = 0;
+   r->flags = V4L2_SUBDEV_ROUTE_FL_ACTIVE |
+   V4L2_SUBDEV_ROUTE_FL_IMMUTABLE;
+   r++;
+   }
+
+   return 0;
+}
+
 static const struct v4l2_subdev_pad_ops rcar_csi2_pad_ops = {
.set_fmt = rcar_csi2_set_pad_format,
.get_fmt = rcar_csi2_get_pad_format,
+   .get_routing = rcar_csi2_get_routing,
.s_stream = rcar_csi2_s_stream,
 };
 
-- 
2.15.1



[RFC 0/2] v4l2-ctl: add ROUTING get and set options

2017-12-14 Thread Niklas Söderlund
Hi,

This small series adds support for the [GS]_ROUTING subdev ioctls 
introduced in Sakari's vc branch.

git://linuxtv.org/sailus/media_tree.git#vc

The use-case for this is to control the internal routing between pads 
inside a subdevice. Currently this is used on the ADV7482 to select 
which of it's 8 analog inputs are routed to the source pad. It is also 
used in the R-Car CSI-2, ADV7482 and MAX9286 drivers to deserve which 
pad is routed to which stream of the multiplexed link between the R-Car 
CSI-2 and either the ADV7482 or the MAX9286.

Niklas Söderlund (2):
  Synchronize with the Kernel headers for routing operations
  v4l2-ctl: add ROUTING get and set options

 include/linux/v4l2-subdev.h |  41 ++
 utils/v4l2-ctl/Android.mk   |   2 +-
 utils/v4l2-ctl/Makefile.am  |   2 +-
 utils/v4l2-ctl/v4l2-ctl-routing.cpp | 154 
 utils/v4l2-ctl/v4l2-ctl.cpp |  10 +++
 utils/v4l2-ctl/v4l2-ctl.h   |   9 +++
 6 files changed, 216 insertions(+), 2 deletions(-)
 create mode 100644 utils/v4l2-ctl/v4l2-ctl-routing.cpp

-- 
2.14.2



[PATCH/RFC v2 12/15] adv748x: csi2: switch to pad and stream aware s_stream

2017-12-14 Thread Niklas Söderlund
Switch the driver to implement the pad and stream aware s_stream
operation. This is needed to enable to support to start and stop
individual streams on a multiplexed pad.

Signed-off-by: Niklas Söderlund 
---
 drivers/media/i2c/adv748x/adv748x-csi2.c | 16 ++--
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/drivers/media/i2c/adv748x/adv748x-csi2.c 
b/drivers/media/i2c/adv748x/adv748x-csi2.c
index a43b251d0bc67a43..39f993282dd3bb5c 100644
--- a/drivers/media/i2c/adv748x/adv748x-csi2.c
+++ b/drivers/media/i2c/adv748x/adv748x-csi2.c
@@ -128,22 +128,26 @@ static const struct v4l2_subdev_internal_ops 
adv748x_csi2_internal_ops = {
  * v4l2_subdev_video_ops
  */
 
-static int adv748x_csi2_s_stream(struct v4l2_subdev *sd, int enable)
+static int adv748x_csi2_s_stream(struct v4l2_subdev *sd, unsigned int pad,
+unsigned int stream, int enable)
 {
struct adv748x_csi2 *tx = adv748x_sd_to_csi2(sd);
+   struct adv748x_state *state = tx->state;
struct v4l2_subdev *src;
 
+   if (pad != ADV748X_CSI2_SOURCE || stream != 0)
+   return -EINVAL;
+
src = adv748x_get_remote_sd(>pads[ADV748X_CSI2_SINK]);
if (!src)
return -EPIPE;
 
+   adv_dbg(state, "%s: pad: %u stream: %u enable: %d\n", sd->name,
+   pad, stream, enable);
+
return v4l2_subdev_call(src, video, s_stream, enable);
 }
 
-static const struct v4l2_subdev_video_ops adv748x_csi2_video_ops = {
-   .s_stream = adv748x_csi2_s_stream,
-};
-
 /* 
-
  * v4l2_subdev_pad_ops
  *
@@ -256,6 +260,7 @@ static const struct v4l2_subdev_pad_ops 
adv748x_csi2_pad_ops = {
.get_fmt = adv748x_csi2_get_format,
.set_fmt = adv748x_csi2_set_format,
.get_frame_desc = adv748x_csi2_get_frame_desc,
+   .s_stream = adv748x_csi2_s_stream,
 };
 
 /* 
-
@@ -263,7 +268,6 @@ static const struct v4l2_subdev_pad_ops 
adv748x_csi2_pad_ops = {
  */
 
 static const struct v4l2_subdev_ops adv748x_csi2_ops = {
-   .video = _csi2_video_ops,
.pad = _csi2_pad_ops,
 };
 
-- 
2.15.1



[PATCH/RFC v2 11/15] adv748x: csi2: implement get_frame_desc

2017-12-14 Thread Niklas Söderlund
Provide CSI-2 bus information for the multiplexed source pad using the
frame descriptor.

Signed-off-by: Niklas Söderlund 
---
 drivers/media/i2c/adv748x/adv748x-csi2.c | 28 
 1 file changed, 28 insertions(+)

diff --git a/drivers/media/i2c/adv748x/adv748x-csi2.c 
b/drivers/media/i2c/adv748x/adv748x-csi2.c
index a2a6d93077204731..a43b251d0bc67a43 100644
--- a/drivers/media/i2c/adv748x/adv748x-csi2.c
+++ b/drivers/media/i2c/adv748x/adv748x-csi2.c
@@ -225,9 +225,37 @@ static int adv748x_csi2_set_format(struct v4l2_subdev *sd,
return ret;
 }
 
+static int adv748x_csi2_get_frame_desc(struct v4l2_subdev *sd, unsigned int 
pad,
+  struct v4l2_mbus_frame_desc *fd)
+{
+   struct adv748x_csi2 *tx = adv748x_sd_to_csi2(sd);
+   struct v4l2_mbus_framefmt *mbusformat;
+
+   memset(fd, 0, sizeof(*fd));
+
+   if (pad != ADV748X_CSI2_SOURCE)
+   return -EINVAL;
+
+   mbusformat = adv748x_csi2_get_pad_format(sd, NULL, ADV748X_CSI2_SINK,
+V4L2_SUBDEV_FORMAT_ACTIVE);
+   if (!mbusformat)
+   return -EINVAL;
+
+   fd->entry->stream = 0;
+   fd->entry->bus.csi2.channel = tx->vc;
+   fd->entry->bus.csi2.data_type =
+   adv748x_csi2_code_to_datatype(mbusformat->code);
+
+   fd->type = V4L2_MBUS_FRAME_DESC_TYPE_CSI2;
+   fd->num_entries = 1;
+
+   return 0;
+}
+
 static const struct v4l2_subdev_pad_ops adv748x_csi2_pad_ops = {
.get_fmt = adv748x_csi2_get_format,
.set_fmt = adv748x_csi2_set_format,
+   .get_frame_desc = adv748x_csi2_get_frame_desc,
 };
 
 /* 
-
-- 
2.15.1



[PATCH/RFC v2 14/15] adv748x: csi2: add get_routing support

2017-12-14 Thread Niklas Söderlund
To support multiplexed streams the internal routing between the
adv748x sink pad and its source pad needs to be described.

Signed-off-by: Niklas Söderlund 
---
 drivers/media/i2c/adv748x/adv748x-csi2.c | 22 ++
 1 file changed, 22 insertions(+)

diff --git a/drivers/media/i2c/adv748x/adv748x-csi2.c 
b/drivers/media/i2c/adv748x/adv748x-csi2.c
index 291b35bef49d41fb..dbefb53f5b8c414d 100644
--- a/drivers/media/i2c/adv748x/adv748x-csi2.c
+++ b/drivers/media/i2c/adv748x/adv748x-csi2.c
@@ -262,10 +262,32 @@ static int adv748x_csi2_get_frame_desc(struct v4l2_subdev 
*sd, unsigned int pad,
return 0;
 }
 
+static int adv748x_csi2_get_routing(struct v4l2_subdev *subdev,
+   struct v4l2_subdev_routing *routing)
+{
+   struct v4l2_subdev_route *r = routing->routes;
+
+   if (routing->num_routes < 1) {
+   routing->num_routes = 1;
+   return -ENOSPC;
+   }
+
+   routing->num_routes = 1;
+
+   r->sink_pad = ADV748X_CSI2_SINK;
+   r->sink_stream = 0;
+   r->source_pad = ADV748X_CSI2_SOURCE;
+   r->source_stream = 0;
+   r->flags = V4L2_SUBDEV_ROUTE_FL_ACTIVE | V4L2_SUBDEV_ROUTE_FL_IMMUTABLE;
+
+   return 0;
+}
+
 static const struct v4l2_subdev_pad_ops adv748x_csi2_pad_ops = {
.get_fmt = adv748x_csi2_get_format,
.set_fmt = adv748x_csi2_set_format,
.get_frame_desc = adv748x_csi2_get_frame_desc,
+   .get_routing = adv748x_csi2_get_routing,
.s_stream = adv748x_csi2_s_stream,
 };
 
-- 
2.15.1



[PATCH/RFC v2 04/15] rcar-csi2: switch to pad and stream aware s_stream

2017-12-14 Thread Niklas Söderlund
Switch the driver to implement the pad and stream aware s_stream
operation. This is needed to enable to support to start and stop
individual streams on a multiplexed pad.

Signed-off-by: Niklas Söderlund 
---
 drivers/media/platform/rcar-vin/rcar-csi2.c | 13 +++--
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/drivers/media/platform/rcar-vin/rcar-csi2.c 
b/drivers/media/platform/rcar-vin/rcar-csi2.c
index d8751add48fc1322..8ce0bfeef1113f9c 100644
--- a/drivers/media/platform/rcar-vin/rcar-csi2.c
+++ b/drivers/media/platform/rcar-vin/rcar-csi2.c
@@ -625,12 +625,17 @@ static int rcar_csi2_sd_info(struct rcar_csi2 *priv, 
struct v4l2_subdev **sd)
return 0;
 }
 
-static int rcar_csi2_s_stream(struct v4l2_subdev *sd, int enable)
+static int rcar_csi2_s_stream(struct v4l2_subdev *sd, unsigned int pad,
+ unsigned int stream, int enable)
 {
struct rcar_csi2 *priv = sd_to_csi2(sd);
struct v4l2_subdev *nextsd;
int ret;
 
+   /* Only one stream on each source pad */
+   if (stream != 0)
+   return -EINVAL;
+
mutex_lock(>lock);
 
ret = rcar_csi2_sd_info(priv, );
@@ -699,17 +704,13 @@ static int rcar_csi2_get_pad_format(struct v4l2_subdev 
*sd,
return 0;
 }
 
-static const struct v4l2_subdev_video_ops rcar_csi2_video_ops = {
-   .s_stream = rcar_csi2_s_stream,
-};
-
 static const struct v4l2_subdev_pad_ops rcar_csi2_pad_ops = {
.set_fmt = rcar_csi2_set_pad_format,
.get_fmt = rcar_csi2_get_pad_format,
+   .s_stream = rcar_csi2_s_stream,
 };
 
 static const struct v4l2_subdev_ops rcar_csi2_subdev_ops = {
-   .video  = _csi2_video_ops,
.pad= _csi2_pad_ops,
 };
 
-- 
2.15.1



[PATCH/RFC v2 01/15] v4l2-subdev.h: add pad and stream aware s_stream

2017-12-14 Thread Niklas Söderlund
To be able to start and stop individual streams of a multiplexed pad the
s_stream operation needs to be both pad and stream aware. Add a new
operation to pad ops to facilitate this.

Signed-off-by: Niklas Söderlund 
---
 include/media/v4l2-subdev.h | 5 +
 1 file changed, 5 insertions(+)

diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h
index a30a94fad8dbacde..7288209338a48fda 100644
--- a/include/media/v4l2-subdev.h
+++ b/include/media/v4l2-subdev.h
@@ -669,6 +669,9 @@ struct v4l2_subdev_pad_config {
  *
  * @set_frame_desc: set the low level media bus frame parameters, @fd array
  *  may be adjusted by the subdev driver to device 
capabilities.
+ *
+ * @s_stream: used to notify the driver that a stream will start or has
+ * stopped.
  */
 struct v4l2_subdev_pad_ops {
int (*init_cfg)(struct v4l2_subdev *sd,
@@ -713,6 +716,8 @@ struct v4l2_subdev_pad_ops {
   struct v4l2_subdev_routing *route);
int (*set_routing)(struct v4l2_subdev *sd,
   struct v4l2_subdev_routing *route);
+   int (*s_stream)(struct v4l2_subdev *sd, unsigned int pad,
+   unsigned int stream, int enable);
 };
 
 /**
-- 
2.15.1



[RFC 1/2] Synchronize with the Kernel headers for routing operations

2017-12-14 Thread Niklas Söderlund
Signed-off-by: Niklas Söderlund 
---
 include/linux/v4l2-subdev.h | 41 +
 1 file changed, 41 insertions(+)

diff --git a/include/linux/v4l2-subdev.h b/include/linux/v4l2-subdev.h
index dbce2b554e026869..e19ee64075d6cbdf 100644
--- a/include/linux/v4l2-subdev.h
+++ b/include/linux/v4l2-subdev.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
 /*
  * V4L2 subdev userspace API
  *
@@ -154,6 +155,44 @@ struct v4l2_subdev_selection {
__u32 reserved[8];
 };
 
+#define V4L2_SUBDEV_ROUTE_FL_ACTIVE(1 << 0)
+#define V4L2_SUBDEV_ROUTE_FL_IMMUTABLE (1 << 1)
+
+/**
+ * struct v4l2_subdev_route - A signal route inside a subdev
+ * @sink_pad: the sink pad
+ * @sink_stream: the sink stream
+ * @source_pad: the source pad
+ * @source_stream: the source stream
+ * @flags: route flags:
+ *
+ * V4L2_SUBDEV_ROUTE_FL_ACTIVE: Is the stream in use or not? An
+ * active stream will start when streaming is enabled on a video
+ * node. Set by the user.
+ *
+ * V4L2_SUBDEV_ROUTE_FL_IMMUTABLE: Is the stream immutable, i.e.
+ * can it be activated and inactivated? Set by the driver.
+ */
+struct v4l2_subdev_route {
+   __u32 sink_pad;
+   __u32 sink_stream;
+   __u32 source_pad;
+   __u32 source_stream;
+   __u32 flags;
+   __u32 reserved[5];
+};
+
+/**
+ * struct v4l2_subdev_routing - Routing information
+ * @routes: the routes array
+ * @num_routes: the total number of routes in the routes array
+ */
+struct v4l2_subdev_routing {
+   struct v4l2_subdev_route *routes;
+   __u32 num_routes;
+   __u32 reserved[5];
+};
+
 /* Backwards compatibility define --- to be removed */
 #define v4l2_subdev_edid v4l2_edid
 
@@ -176,5 +215,7 @@ struct v4l2_subdev_selection {
 #define VIDIOC_SUBDEV_ENUM_DV_TIMINGS  _IOWR('V', 98, struct 
v4l2_enum_dv_timings)
 #define VIDIOC_SUBDEV_QUERY_DV_TIMINGS _IOR('V', 99, struct 
v4l2_dv_timings)
 #define VIDIOC_SUBDEV_DV_TIMINGS_CAP   _IOWR('V', 100, struct 
v4l2_dv_timings_cap)
+#define VIDIOC_SUBDEV_G_ROUTING_IOWR('V', 38, struct 
v4l2_subdev_routing)
+#define VIDIOC_SUBDEV_S_ROUTING_IOWR('V', 39, struct 
v4l2_subdev_routing)
 
 #endif
-- 
2.14.2



[PATCH/RFC v2 15/15] adv748x: afe: add routing support

2017-12-14 Thread Niklas Söderlund
The adv748x afe have eight analog sink pads, currently one of them is
chosen to be the active route based on device tree configuration. Whit
the new routeing API it's possible to control which of the eight sink
pads are routed to the source pad.

Signed-off-by: Niklas Söderlund 
---
 drivers/media/i2c/adv748x/adv748x-afe.c | 66 +
 1 file changed, 66 insertions(+)

diff --git a/drivers/media/i2c/adv748x/adv748x-afe.c 
b/drivers/media/i2c/adv748x/adv748x-afe.c
index 5188178588c9067d..5dda85c707f6efd7 100644
--- a/drivers/media/i2c/adv748x/adv748x-afe.c
+++ b/drivers/media/i2c/adv748x/adv748x-afe.c
@@ -43,6 +43,9 @@
 #define ADV748X_AFE_STD_PAL_SECAM  0xe
 #define ADV748X_AFE_STD_PAL_SECAM_PED  0xf
 
+#define ADV748X_AFE_ROUTES_MAX ((ADV748X_AFE_SINK_AIN7 - \
+   ADV748X_AFE_SINK_AIN0) + 1)
+
 static int adv748x_afe_read_ro_map(struct adv748x_state *state, u8 reg)
 {
int ret;
@@ -386,10 +389,73 @@ static int adv748x_afe_set_format(struct v4l2_subdev *sd,
return 0;
 }
 
+
+static int adv748x_afe_get_routing(struct v4l2_subdev *sd,
+  struct v4l2_subdev_routing *routing)
+{
+   struct adv748x_afe *afe = adv748x_sd_to_afe(sd);
+   struct v4l2_subdev_route *r = routing->routes;
+   unsigned int i;
+
+   /* There are one possible route from each sink */
+   if (routing->num_routes < ADV748X_AFE_ROUTES_MAX) {
+   routing->num_routes = ADV748X_AFE_ROUTES_MAX;
+   return -ENOSPC;
+   }
+
+   routing->num_routes = ADV748X_AFE_ROUTES_MAX;
+
+   for (i = ADV748X_AFE_SINK_AIN0; i <= ADV748X_AFE_SINK_AIN7; i++) {
+   r->sink_pad = i;
+   r->sink_stream = 0;
+   r->source_pad = ADV748X_AFE_SOURCE;
+   r->source_stream = 0;
+   r->flags = afe->input == i ? V4L2_SUBDEV_ROUTE_FL_ACTIVE : 0;
+   r++;
+   }
+
+   return 0;
+}
+
+static int adv748x_afe_set_routing(struct v4l2_subdev *sd,
+  struct v4l2_subdev_routing *routing)
+{
+   struct adv748x_afe *afe = adv748x_sd_to_afe(sd);
+   struct v4l2_subdev_route *r = routing->routes;
+   int input = -1;
+   unsigned int i;
+
+   if (routing->num_routes > ADV748X_AFE_ROUTES_MAX)
+   return -ENOSPC;
+
+   for (i = 0; i < routing->num_routes; i++) {
+   if (r->sink_pad > ADV748X_AFE_SINK_AIN7 ||
+   r->sink_stream != 0 ||
+   r->source_pad != ADV748X_AFE_SOURCE ||
+   r->source_stream != 0)
+   return -EINVAL;
+
+   if (r->flags & V4L2_SUBDEV_ROUTE_FL_ACTIVE) {
+   if (input != -1)
+   return -EMLINK;
+
+   input = r->sink_pad;
+   }
+   r++;
+   }
+
+   if (input != -1)
+   afe->input = input;
+
+   return 0;
+}
+
 static const struct v4l2_subdev_pad_ops adv748x_afe_pad_ops = {
.enum_mbus_code = adv748x_afe_enum_mbus_code,
.set_fmt = adv748x_afe_set_format,
.get_fmt = adv748x_afe_get_format,
+   .get_routing = adv748x_afe_get_routing,
+   .set_routing = adv748x_afe_set_routing,
 };
 
 /* 
-
-- 
2.15.1



[PATCH/RFC v2 06/15] rcar-csi2: use frame description information when propagating .s_stream()

2017-12-14 Thread Niklas Söderlund
Use the frame description from the remote subdevice of the rcar-csi2's
sink pad to get the remote pad and stream pad needed to propagate the
.s_stream() operation.

The CSI-2 virtual channel which should be acted upon can be determined
by looking at which of the rcar-csi2 source pad the .s_stream() was
called on. This is because the rcar-csi2 acts as a demultiplexer for the
CSI-2 link on the one sink pad and outputs each virtual channel on a
distinct and known source pad.

Signed-off-by: Niklas Söderlund 
---
 drivers/media/platform/rcar-vin/rcar-csi2.c | 58 -
 1 file changed, 41 insertions(+), 17 deletions(-)

diff --git a/drivers/media/platform/rcar-vin/rcar-csi2.c 
b/drivers/media/platform/rcar-vin/rcar-csi2.c
index e0f56cc3d25179a9..6b607b2e31e26063 100644
--- a/drivers/media/platform/rcar-vin/rcar-csi2.c
+++ b/drivers/media/platform/rcar-vin/rcar-csi2.c
@@ -614,20 +614,31 @@ static void rcar_csi2_stop(struct rcar_csi2 *priv)
rcar_csi2_reset(priv);
 }
 
-static int rcar_csi2_sd_info(struct rcar_csi2 *priv, struct v4l2_subdev **sd)
+static int rcar_csi2_get_source_info(struct rcar_csi2 *priv,
+struct v4l2_subdev **subdev,
+unsigned int *pad,
+struct v4l2_mbus_frame_desc *fd)
 {
-   struct media_pad *pad;
+   struct media_pad *remote_pad;
 
-   pad = media_entity_remote_pad(>pads[RCAR_CSI2_SINK]);
-   if (!pad) {
-   dev_err(priv->dev, "Could not find remote pad\n");
+   /* Get source subdevice and pad */
+   remote_pad = media_entity_remote_pad(>pads[RCAR_CSI2_SINK]);
+   if (!remote_pad) {
+   dev_err(priv->dev, "Could not find remote source pad\n");
return -ENODEV;
}
+   *subdev = media_entity_to_v4l2_subdev(remote_pad->entity);
+   *pad = remote_pad->index;
 
-   *sd = media_entity_to_v4l2_subdev(pad->entity);
-   if (!*sd) {
-   dev_err(priv->dev, "Could not find remote subdevice\n");
-   return -ENODEV;
+   /* Get frame descriptor */
+   if (v4l2_subdev_call(*subdev, pad, get_frame_desc, *pad, fd)) {
+   dev_err(priv->dev, "Could not read frame desc\n");
+   return -EINVAL;
+   }
+
+   if (fd->type != V4L2_MBUS_FRAME_DESC_TYPE_CSI2) {
+   dev_err(priv->dev, "Frame desc do not describe CSI-2 link");
+   return -EINVAL;
}
 
return 0;
@@ -637,9 +648,10 @@ static int rcar_csi2_s_stream(struct v4l2_subdev *sd, 
unsigned int pad,
  unsigned int stream, int enable)
 {
struct rcar_csi2 *priv = sd_to_csi2(sd);
+   struct v4l2_mbus_frame_desc fd;
struct v4l2_subdev *nextsd;
-   unsigned int i, count = 0;
-   int ret, vc;
+   unsigned int i, rpad, count = 0;
+   int ret, vc, rstream = -1;
 
/* Only allow stream control on source pads and valid vc */
vc = rcar_csi2_pad_to_vc(pad);
@@ -650,11 +662,23 @@ static int rcar_csi2_s_stream(struct v4l2_subdev *sd, 
unsigned int pad,
if (stream != 0)
return -EINVAL;
 
-   mutex_lock(>lock);
-
-   ret = rcar_csi2_sd_info(priv, );
+   /* Get information about multiplexed link */
+   ret = rcar_csi2_get_source_info(priv, , , );
if (ret)
-   goto out;
+   return ret;
+
+   /* Get stream on multiplexed link */
+   for (i = 0; i < fd.num_entries; i++)
+   if (fd.entry[i].bus.csi2.channel == vc)
+   rstream = fd.entry[i].stream;
+
+   if (rstream < 0) {
+   dev_err(priv->dev, "Could not find stream for vc %u\n", vc);
+   return -EINVAL;
+   }
+
+   /* Start or stop the requested stream */
+   mutex_lock(>lock);
 
for (i = 0; i < 4; i++)
count += priv->stream_count[i];
@@ -673,14 +697,14 @@ static int rcar_csi2_s_stream(struct v4l2_subdev *sd, 
unsigned int pad,
}
 
if (enable && priv->stream_count[vc] == 0) {
-   ret = v4l2_subdev_call(nextsd, video, s_stream, 1);
+   ret = v4l2_subdev_call(nextsd, pad, s_stream, rpad, rstream, 1);
if (ret) {
rcar_csi2_stop(priv);
pm_runtime_put(priv->dev);
goto out;
}
} else if (!enable && priv->stream_count[vc] == 1) {
-   ret = v4l2_subdev_call(nextsd, video, s_stream, 0);
+   ret = v4l2_subdev_call(nextsd, pad, s_stream, rpad, rstream, 0);
}
 
priv->stream_count[vc] += enable ? 1 : -1;
-- 
2.15.1



[PATCH/RFC v2 09/15] adv748x: csi2: add module param for virtual channel

2017-12-14 Thread Niklas Söderlund
The hardware can output on any of the 4 (0-3) Virtual Channels of the
CSI-2 bus. Add a module parameter each for TXA and TXB to allow the user
to specify which channel should be used.

Signed-off-by: Niklas Söderlund 
---
 drivers/media/i2c/adv748x/adv748x-core.c | 10 ++
 drivers/media/i2c/adv748x/adv748x-csi2.c |  2 +-
 drivers/media/i2c/adv748x/adv748x.h  |  1 +
 3 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/drivers/media/i2c/adv748x/adv748x-core.c 
b/drivers/media/i2c/adv748x/adv748x-core.c
index fd92c9e4b519d2c5..3cad52532ead2e34 100644
--- a/drivers/media/i2c/adv748x/adv748x-core.c
+++ b/drivers/media/i2c/adv748x/adv748x-core.c
@@ -31,6 +31,9 @@
 
 #include "adv748x.h"
 
+static unsigned int txavc;
+static unsigned int txbvc;
+
 /* 
-
  * Register manipulation
  */
@@ -747,6 +750,7 @@ static int adv748x_probe(struct i2c_client *client,
}
 
/* Initialise TXA */
+   state->txa.vc = txavc;
ret = adv748x_csi2_init(state, >txa);
if (ret) {
adv_err(state, "Failed to probe TXA");
@@ -754,6 +758,7 @@ static int adv748x_probe(struct i2c_client *client,
}
 
/* Initialise TXB */
+   state->txb.vc = txbvc;
ret = adv748x_csi2_init(state, >txb);
if (ret) {
adv_err(state, "Failed to probe TXB");
@@ -824,6 +829,11 @@ static struct i2c_driver adv748x_driver = {
 
 module_i2c_driver(adv748x_driver);
 
+module_param(txavc, uint, 0644);
+MODULE_PARM_DESC(txavc, "Virtual Channel for TXA");
+module_param(txbvc, uint, 0644);
+MODULE_PARM_DESC(txbvc, "Virtual Channel for TXB");
+
 MODULE_AUTHOR("Kieran Bingham ");
 MODULE_DESCRIPTION("ADV748X video decoder");
 MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/i2c/adv748x/adv748x-csi2.c 
b/drivers/media/i2c/adv748x/adv748x-csi2.c
index 820b44ed56a8679f..2a5dff8c571013bf 100644
--- a/drivers/media/i2c/adv748x/adv748x-csi2.c
+++ b/drivers/media/i2c/adv748x/adv748x-csi2.c
@@ -281,7 +281,7 @@ int adv748x_csi2_init(struct adv748x_state *state, struct 
adv748x_csi2 *tx)
}
 
/* Initialise the virtual channel */
-   adv748x_csi2_set_virtual_channel(tx, 0);
+   adv748x_csi2_set_virtual_channel(tx, tx->vc);
 
adv748x_subdev_init(>sd, state, _csi2_ops,
MEDIA_ENT_F_UNKNOWN,
diff --git a/drivers/media/i2c/adv748x/adv748x.h 
b/drivers/media/i2c/adv748x/adv748x.h
index 6789e2f3bc8c2b49..f6e40ee3924e8f12 100644
--- a/drivers/media/i2c/adv748x/adv748x.h
+++ b/drivers/media/i2c/adv748x/adv748x.h
@@ -92,6 +92,7 @@ enum adv748x_csi2_pads {
 
 struct adv748x_csi2 {
struct adv748x_state *state;
+   unsigned int vc;
struct v4l2_mbus_framefmt format;
unsigned int page;
 
-- 
2.15.1



[PATCH/RFC v2 03/15] rcar-vin: use the pad and stream aware s_stream

2017-12-14 Thread Niklas Söderlund
To work with multiplexed streams the pad and stream aware s_stream
operation needs to be used.

Signed-off-by: Niklas Söderlund 
---
 drivers/media/platform/rcar-vin/rcar-dma.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c 
b/drivers/media/platform/rcar-vin/rcar-dma.c
index cf30e5fceb1d493a..8435491535060eae 100644
--- a/drivers/media/platform/rcar-vin/rcar-dma.c
+++ b/drivers/media/platform/rcar-vin/rcar-dma.c
@@ -1180,7 +1180,7 @@ static int rvin_set_stream(struct rvin_dev *vin, int on)
 
if (!on) {
media_pipeline_stop(vin->vdev.entity.pads);
-   return v4l2_subdev_call(sd, video, s_stream, 0);
+   return v4l2_subdev_call(sd, pad, s_stream, pad->index, 0, 0);
}
 
fmt.pad = pad->index;
@@ -1239,12 +1239,14 @@ static int rvin_set_stream(struct rvin_dev *vin, int on)
if (media_pipeline_start(vin->vdev.entity.pads, pipe))
return -EPIPE;
 
-   ret = v4l2_subdev_call(sd, video, s_stream, 1);
+   ret = v4l2_subdev_call(sd, pad, s_stream, pad->index, 0, 1);
if (ret == -ENOIOCTLCMD)
ret = 0;
if (ret)
media_pipeline_stop(vin->vdev.entity.pads);
 
+   vin_dbg(vin, "pad: %u stream: 0 enable: %d\n", pad->index, on);
+
return ret;
 }
 
-- 
2.15.1



[PATCH/RFC v2 00/15] Add multiplexed pad streaming support

2017-12-14 Thread Niklas Söderlund
Hi,

This is the second attempt to add streaming support to multiplexed pads.  
The first attempt was not aware of Sakari's work. His work have now been 
taken into account and this series depends on his series together with 
the master of media-tree.

git://linuxtv.org/sailus/media_tree.git#vc

It also depends on the latest out-of-tree patches for R-Car VIN and 
CSI-2 as these drivers together with the in-tree driver adv748x have 
been used to prove functionality of this series. Test procedure includes 
changing which CSI-2 VC the adv7482 outputs on (using the module 
parameter introduced in this patch-set) and verify that the R-Car CSI-2 
and VIN can receive that particular VC.

A second hardware setup have also been used to verify functionality 
based on the MAX9286 chip, which in contrast to the outputs multiple 
CSI-2 virtual channels. Unfortunate the driver side for the MAX9286 and 
the sensors RDACM20 is still in a prototype stage so the patches to 
enable multiplexed pads on that setup is not included in this patch-set.

The problem this patch-set is trying to solve is that there is no way in 
the v4l2 framework to describe and control links between subdevices 
which carry more then one video stream, for example a CSI-2 bus which 
can have 4 virtual channels carrying different video streams.

The idea is that on both sides of the multiplexed media link there are
one multiplexer subdevice and one demultiplexer subdevice. These two
subdevices can't do any format conversions, there sole purpose is to
(de)multiplex the CSI-2 link. If there is hardware which can do both
CSI-2 multiplexing and format conversions they can be modeled as two
subdevices from the same device driver.

+--+  +--+
 +---+  subdev 1   |  |  subdev 2   +---+
  +--+ Pad 1 | |  | | Pad 3 +---+
 +--++   +-+---+  +---+-+   ++--+
|| Muxed pad A +--+ Muxed pad B ||
 +--++   +-+---+  +---+-+   ++--+
  +--+ Pad 2 | |  | | Pad 4 +---+
 +---+ |  | +---+
+--+  +--+

In the example above Pad 1 is routed to Pad 3 and Pad 2 to Pad 4,
and the video data for both of them travels the link between pad A and
B. The routing between the pads inside subdev 1 and subdev 2 are 
controlled and communicated to user-space using the [GS]_ROUTING subdev 
ioctls (from Sakari's patch-set). I have patches for v4l2-ctl which 
creates a user-space interface for these now ioctls which I will post in 
a separate thread. These routes are also used to perform format 
validation between pad 1-3 and pad 2-4, the format validation is also 
part of Sakari's patch-set.

Obviously PATCH 01/15 is a RFC and if it is judged to be OK it should be 
split out to a separate patch and updated to move the .s_stream() 
operation from video ops to pad ops instead of adding a new one. I have 
posted a similar patch for this last year but it did not get much 
attention. For this RFC it's enough to add a new operation as to prove 
functionality.

A big thanks to Laurent and Sakari for being really nice and taking time
helping me grasp all the possibilities and issues with this problem, all
cred to them and all blame to me for misunderstanding there guidance :-)

Niklas Söderlund (15):
  v4l2-subdev.h: add pad and stream aware s_stream
  rcar-vin: use pad as the starting point for a pipeline
  rcar-vin: use the pad and stream aware s_stream
  rcar-csi2: switch to pad and stream aware s_stream
  rcar-csi2: count usage for each source pad
  rcar-csi2: use frame description information when propagating
.s_stream()
  rcar-csi2: use frame description information to configure CSI-2 bus
  rcar-csi2: add get_routing support
  adv748x: csi2: add module param for virtual channel
  adv748x: csi2: add translation from pixelcode to CSI-2 datatype
  adv748x: csi2: implement get_frame_desc
  adv748x: csi2: switch to pad and stream aware s_stream
  adv748x: csi2: only allow formats on sink pads
  adv748x: csi2: add get_routing support
  adv748x: afe: add routing support

 drivers/media/i2c/adv748x/adv748x-afe.c |  66 +++
 drivers/media/i2c/adv748x/adv748x-core.c|  10 ++
 drivers/media/i2c/adv748x/adv748x-csi2.c|  96 +-
 drivers/media/i2c/adv748x/adv748x.h |   1 +
 drivers/media/platform/rcar-vin/rcar-csi2.c | 267 +++-
 drivers/media/platform/rcar-vin/rcar-dma.c  |  14 +-
 include/media/v4l2-subdev.h |   5 +
 7 files changed, 365 insertions(+), 94 deletions(-)

-- 
2.15.1



[PATCH/RFC v2 13/15] adv748x: csi2: only allow formats on sink pads

2017-12-14 Thread Niklas Söderlund
The driver is now pad and stream aware, only allow to get/set format on
sink pads. Also record a different format for each sink pad since it's
no longer true that they are all the same

Signed-off-by: Niklas Söderlund 
---
 drivers/media/i2c/adv748x/adv748x-csi2.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/media/i2c/adv748x/adv748x-csi2.c 
b/drivers/media/i2c/adv748x/adv748x-csi2.c
index 39f993282dd3bb5c..291b35bef49d41fb 100644
--- a/drivers/media/i2c/adv748x/adv748x-csi2.c
+++ b/drivers/media/i2c/adv748x/adv748x-csi2.c
@@ -176,6 +176,9 @@ static int adv748x_csi2_get_format(struct v4l2_subdev *sd,
struct adv748x_state *state = tx->state;
struct v4l2_mbus_framefmt *mbusformat;
 
+   if (sdformat->pad != ADV748X_CSI2_SINK)
+   return -EINVAL;
+
mbusformat = adv748x_csi2_get_pad_format(sd, cfg, sdformat->pad,
 sdformat->which);
if (!mbusformat)
@@ -199,6 +202,9 @@ static int adv748x_csi2_set_format(struct v4l2_subdev *sd,
struct v4l2_mbus_framefmt *mbusformat;
int ret = 0;
 
+   if (sdformat->pad != ADV748X_CSI2_SINK)
+   return -EINVAL;
+
mbusformat = adv748x_csi2_get_pad_format(sd, cfg, sdformat->pad,
 sdformat->which);
if (!mbusformat)
-- 
2.15.1



[PATCH/RFC v2 02/15] rcar-vin: use pad as the starting point for a pipeline

2017-12-14 Thread Niklas Söderlund
The pipeline will be moved from the entity to the pads; reflect this in
the media pipeline function API.

Signed-off-by: Niklas Söderlund 
---
 drivers/media/platform/rcar-vin/rcar-dma.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c 
b/drivers/media/platform/rcar-vin/rcar-dma.c
index 03a914361a33125c..cf30e5fceb1d493a 100644
--- a/drivers/media/platform/rcar-vin/rcar-dma.c
+++ b/drivers/media/platform/rcar-vin/rcar-dma.c
@@ -1179,7 +1179,7 @@ static int rvin_set_stream(struct rvin_dev *vin, int on)
return -EPIPE;
 
if (!on) {
-   media_pipeline_stop(>vdev.entity);
+   media_pipeline_stop(vin->vdev.entity.pads);
return v4l2_subdev_call(sd, video, s_stream, 0);
}
 
@@ -1235,15 +1235,15 @@ static int rvin_set_stream(struct rvin_dev *vin, int on)
fmt.format.height != vin->format.height)
return -EPIPE;
 
-   pipe = sd->entity.pipe ? sd->entity.pipe : >vdev.pipe;
-   if (media_pipeline_start(>vdev.entity, pipe))
+   pipe = sd->entity.pads->pipe ? sd->entity.pads->pipe : >vdev.pipe;
+   if (media_pipeline_start(vin->vdev.entity.pads, pipe))
return -EPIPE;
 
ret = v4l2_subdev_call(sd, video, s_stream, 1);
if (ret == -ENOIOCTLCMD)
ret = 0;
if (ret)
-   media_pipeline_stop(>vdev.entity);
+   media_pipeline_stop(vin->vdev.entity.pads);
 
return ret;
 }
-- 
2.15.1



[PATCH/RFC v2 10/15] adv748x: csi2: add translation from pixelcode to CSI-2 datatype

2017-12-14 Thread Niklas Söderlund
This will be needed to fill out the frame descriptor information
correctly.

Signed-off-by: Niklas Söderlund 
---
 drivers/media/i2c/adv748x/adv748x-csi2.c | 22 ++
 1 file changed, 22 insertions(+)

diff --git a/drivers/media/i2c/adv748x/adv748x-csi2.c 
b/drivers/media/i2c/adv748x/adv748x-csi2.c
index 2a5dff8c571013bf..a2a6d93077204731 100644
--- a/drivers/media/i2c/adv748x/adv748x-csi2.c
+++ b/drivers/media/i2c/adv748x/adv748x-csi2.c
@@ -18,6 +18,28 @@
 
 #include "adv748x.h"
 
+struct adv748x_csi2_format {
+   unsigned int code;
+   unsigned int datatype;
+};
+
+static const struct adv748x_csi2_format adv748x_csi2_formats[] = {
+   { .code = MEDIA_BUS_FMT_RGB888_1X24,.datatype = 0x24, },
+   { .code = MEDIA_BUS_FMT_UYVY8_1X16, .datatype = 0x1e, },
+   { .code = MEDIA_BUS_FMT_UYVY8_2X8,  .datatype = 0x1e, },
+   { .code = MEDIA_BUS_FMT_YUYV10_2X10,.datatype = 0x1e, },
+};
+
+static unsigned int adv748x_csi2_code_to_datatype(unsigned int code)
+{
+   unsigned int i;
+
+   for (i = 0; i < ARRAY_SIZE(adv748x_csi2_formats); i++)
+   if (adv748x_csi2_formats[i].code == code)
+   return adv748x_csi2_formats[i].datatype;
+   return 0;
+}
+
 static bool is_txa(struct adv748x_csi2 *tx)
 {
return tx == >state->txa;
-- 
2.15.1



Re: [PATCH] media: v4l: xilinx: Use SPDX-License-Identifier

2017-12-14 Thread Laurent Pinchart
Hi Joe,

(CC'ing Greg and adding context for easier understanding)

On Thursday, 14 December 2017 20:54:39 EET Joe Perches wrote:
> On Thu, 2017-12-14 at 20:37 +0200, Laurent Pinchart wrote:
> > On Thursday, 14 December 2017 20:32:20 EET Joe Perches wrote:
> >> On Thu, 2017-12-14 at 20:28 +0200, Laurent Pinchart wrote:
> >>> On Thursday, 14 December 2017 19:05:27 EET Mauro Carvalho Chehab wrote:
>  Em Fri,  8 Dec 2017 18:05:37 +0530 Dhaval Shah escreveu:
> > SPDX-License-Identifier is used for the Xilinx Video IP and
> > related drivers.
> > 
> > Signed-off-by: Dhaval Shah 
>  
>  Hi Dhaval,
>  
>  You're not listed as one of the Xilinx driver maintainers. I'm afraid
>  that, without their explicit acks, sent to the ML, I can't accept a
>  patch touching at the driver's license tags.
> >>> 
> >>> The patch doesn't change the license, I don't see why it would cause
> >>> any issue. Greg isn't listed as the maintainer or copyright holder of
> >>> any of the 10k+ files to which he added an SPDX license header in the
> >>> last kernel release.
> >> 
> >> Adding a comment line that describes an implicit or
> >> explicit license is different than removing the license
> >> text itself.
> > 
> > The SPDX license header is meant to be equivalent to the license text.
> 
> I understand that.
> At a minimum, removing BSD license text is undesirable
> as that license states:
> 
>  ** Redistributions of source code must retain the above copyright
>  *  notice, this list of conditions and the following disclaimer.
> etc...

But this patch only removes the following text:

- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.

and replaces it by the corresponding SPDX header.

> > The only reason why the large SPDX patch didn't touch the whole kernel in
> > one go was that it was easier to split in in multiple chunks.
> 
> Not really, it was scripted.

But still manually reviewed as far as I know.

> > This is no different than not including the full GPL license in every
> > header file but only pointing to it through its name and reference, as
> > every kernel source file does.
> 
> Not every kernel source file had a license text
> or a reference to another license file.

Correct, but the files touched by this patch do.

This issue is in no way specific to linux-media and should be decided upon at 
the top level, not on a per-subsystem basis. Greg, could you comment on this ?

-- 
Regards,

Laurent Pinchart


Re: [PATCH] media: v4l: xilinx: Use SPDX-License-Identifier

2017-12-14 Thread Joe Perches
On Thu, 2017-12-14 at 20:37 +0200, Laurent Pinchart wrote:
> Hi Joe,

Hi Laurent.

> On Thursday, 14 December 2017 20:32:20 EET Joe Perches wrote:
> > Adding a comment line that describes an implicit or
> > explicit license is different than removing the license
> > text itself.
> 
> The SPDX license header is meant to be equivalent to the license text.

I understand that.
At a minimum, removing BSD license text is undesirable
as that license states:

 ** Redistributions of source code must retain the above copyright
 *  notice, this list of conditions and the following disclaimer.
etc...

> The only reason why the large SPDX patch didn't touch the whole kernel in one 
> go 
> was that it was easier to split in in multiple chunks.

Not really, it was scripted.

> This is no different 
> than not including the full GPL license in every header file but only 
> pointing 
> to it through its name and reference, as every kernel source file does.

Not every kernel source file had a license text
or a reference to another license file.



Re: [PATCH] media: v4l: xilinx: Use SPDX-License-Identifier

2017-12-14 Thread Laurent Pinchart
Hi Joe,

On Thursday, 14 December 2017 20:32:20 EET Joe Perches wrote:
> On Thu, 2017-12-14 at 20:28 +0200, Laurent Pinchart wrote:
> > On Thursday, 14 December 2017 19:05:27 EET Mauro Carvalho Chehab wrote:
> >> Em Fri,  8 Dec 2017 18:05:37 +0530 Dhaval Shah escreveu:
> >>> SPDX-License-Identifier is used for the Xilinx Video IP and
> >>> related drivers.
> >>> 
> >>> Signed-off-by: Dhaval Shah 
> >> 
> >> Hi Dhaval,
> >> 
> >> You're not listed as one of the Xilinx driver maintainers. I'm afraid
> >> that, without their explicit acks, sent to the ML, I can't accept a patch
> >> touching at the driver's license tags.
> > 
> > The patch doesn't change the license, I don't see why it would cause any
> > issue. Greg isn't listed as the maintainer or copyright holder of any of
> > the 10k+ files to which he added an SPDX license header in the last
> > kernel release.
> 
> Adding a comment line that describes an implicit or
> explicit license is different than removing the license
> text itself.

The SPDX license header is meant to be equivalent to the license text. The 
only reason why the large SPDX patch didn't touch the whole kernel in one go 
was that it was easier to split in in multiple chunks. This is no different 
than not including the full GPL license in every header file but only pointing 
to it through its name and reference, as every kernel source file does.

-- 
Regards,

Laurent Pinchart



Re: [PATCH] media: v4l: xilinx: Use SPDX-License-Identifier

2017-12-14 Thread Joe Perches
On Thu, 2017-12-14 at 20:28 +0200, Laurent Pinchart wrote:
> Hi Mauro,
> 
> On Thursday, 14 December 2017 19:05:27 EET Mauro Carvalho Chehab wrote:
> > Em Fri,  8 Dec 2017 18:05:37 +0530 Dhaval Shah escreveu:
> > > SPDX-License-Identifier is used for the Xilinx Video IP and
> > > related drivers.
> > > 
> > > Signed-off-by: Dhaval Shah 
> > 
> > Hi Dhaval,
> > 
> > You're not listed as one of the Xilinx driver maintainers. I'm afraid that,
> > without their explicit acks, sent to the ML, I can't accept a patch
> > touching at the driver's license tags.
> 
> The patch doesn't change the license, I don't see why it would cause any 
> issue. Greg isn't listed as the maintainer or copyright holder of any of the 
> 10k+ files to which he added an SPDX license header in the last kernel 
> release.

Adding a comment line that describes an implicit or
explicit license is different than removing the license
text itself.


Re: [PATCH v4 00/12] [dt-bindings] [media] Add document file and driver for Sony CXD2880 DVB-T2/T tuner + demodulator

2017-12-14 Thread Philippe Ombredanne
On Thu, Dec 14, 2017 at 7:04 PM, Mauro Carvalho Chehab
 wrote:
> Em Thu, 14 Dec 2017 17:32:34 +
> "Bird, Timothy"  escreveu:
>
>> > -Original Message-
>> > From: Philippe on Thursday, December 14, 2017 6:25 AM
>> > Dear Mauro,
>> >
>> > On Thu, Dec 14, 2017 at 11:55 AM, Mauro Carvalho Chehab
>> >  wrote:
>> >
>> > > SPDX is a new requirement that started late on Kernel 4.14 development
>> > > cycle (and whose initial changes were merged directly at Linus tree).
>> > > Not all existing files have it yet, as identifying the right license
>> > > on existing files is a complex task, but if you do a:
>> > >
>> > > $ git grep SPDX $(find . -name Makefile) $(find . -name Kconfig)
>> > >
>> > > You'll see that lot of such files have it already.
>> >
>> > FWIW, short of having SPDX tags, identifying the right license on
>> > existing files is not a super complex task: if boils down to running
>> > many diffs.
>> >
>> > Take the ~60K files in kernel, and about 6K license and notices
>> > reference texts. Then compute a pairwise diff of each of the 60K file
>> > against the 6K reference texts. Repeat the pairwise diff a few more
>> > times, say 10 times, as multiple licenses may appear in any given
>> > kernel file. And keep the diffs that have the fewest
>> > difference/highest similarity with the reference texts as the detected
>> > license. Done!
>>
>> You can't do license detection and assignment in this automated fashion -
>> at least not generally.
>>
>> Even a single word of difference between the notice in the source
>> code and the reference license notice or text may have legal implications
>> that are not conveyed by the simplified SPDX tag.  When differences are
>> found, we're going to have to kick the discrepancies to a human for review.
>> This is especially true for files with multiple licenses.
>>
>> For a work of original authorship, or a single copyright holder, the author
>> or copyright holder may be able to change the notice or text, or gloss
>> over any difference from the reference text, and make the SPDX  assignment
>> (or even change the license, if they want).  This would apply to something
>> new like this Sony driver.  However, for code that is already in the kernel
>> tree, with likely multiple contributors, the legal situation gets a little
>> more murky.
>
> Precisely. This is easily fixable when the code author changes the
> license text, or when someone from the Company that holds copyrights sends
> the SPDX markups (as emails @company can be seen as official e-mails, except
> if explicitly noticed otherwise). So, from my side, I'm now requiring
> SPDX for new drivers.
>
> However, if someone else is doing the changes, it can be tricky and risky
> to pick up the patch, adding my SOB, if not endorsed by the copyright
> owners, or by LF legal counseling. So, I prefer to not pick those myself,
> except from people I trust.

Exactly, and this why --after the first batch that Greg pushed and
Linus pulled and that had been carefully reviewed--, I am trying to
gently nit the submitters of new patches, one at a time to use the new
SPDX tags. Eventually if I can find the time, I could also submit some
bigger patches to add SPDX tags to a bunch of files at once but that
would have to be organized in small batches by copyright holder and
these would be only RFCs until reviewed by and agreed to by the actual
copyright holders.

-- 
Cordially
Philippe Ombredanne


Re: [PATCH] media: v4l: xilinx: Use SPDX-License-Identifier

2017-12-14 Thread Laurent Pinchart
Hi Mauro,

On Thursday, 14 December 2017 19:05:27 EET Mauro Carvalho Chehab wrote:
> Em Fri,  8 Dec 2017 18:05:37 +0530 Dhaval Shah escreveu:
> > SPDX-License-Identifier is used for the Xilinx Video IP and
> > related drivers.
> > 
> > Signed-off-by: Dhaval Shah 
> 
> Hi Dhaval,
> 
> You're not listed as one of the Xilinx driver maintainers. I'm afraid that,
> without their explicit acks, sent to the ML, I can't accept a patch
> touching at the driver's license tags.

The patch doesn't change the license, I don't see why it would cause any 
issue. Greg isn't listed as the maintainer or copyright holder of any of the 
10k+ files to which he added an SPDX license header in the last kernel 
release.

-- 
Regards,

Laurent Pinchart



Re: [PATCH v4 00/12] [dt-bindings] [media] Add document file and driver for Sony CXD2880 DVB-T2/T tuner + demodulator

2017-12-14 Thread Philippe Ombredanne
Tim,

On Thu, Dec 14, 2017 at 6:32 PM, Bird, Timothy  wrote:
>
>
>> -Original Message-
>> From: Philippe on Thursday, December 14, 2017 6:25 AM
>> Dear Mauro,
>>
>> On Thu, Dec 14, 2017 at 11:55 AM, Mauro Carvalho Chehab
>>  wrote:
>>
>> > SPDX is a new requirement that started late on Kernel 4.14 development
>> > cycle (and whose initial changes were merged directly at Linus tree).
>> > Not all existing files have it yet, as identifying the right license
>> > on existing files is a complex task, but if you do a:
>> >
>> > $ git grep SPDX $(find . -name Makefile) $(find . -name Kconfig)
>> >
>> > You'll see that lot of such files have it already.
>>
>> FWIW, short of having SPDX tags, identifying the right license on
>> existing files is not a super complex task: if boils down to running
>> many diffs.
>>
>> Take the ~60K files in kernel, and about 6K license and notices
>> reference texts. Then compute a pairwise diff of each of the 60K file
>> against the 6K reference texts. Repeat the pairwise diff a few more
>> times, say 10 times, as multiple licenses may appear in any given
>> kernel file. And keep the diffs that have the fewest
>> difference/highest similarity with the reference texts as the detected
>> license. Done!
>
> You can't do license detection and assignment in this automated fashion -
> at least not generally.
>
> Even a single word of difference between the notice in the source
> code and the reference license notice or text may have legal implications
> that are not conveyed by the simplified SPDX tag.  When differences are
> found, we're going to have to kick the discrepancies to a human for review.
> This is especially true for files with multiple licenses.
>
> For a work of original authorship, or a single copyright holder, the author
> or copyright holder may be able to change the notice or text, or gloss
> over any difference from the reference text, and make the SPDX  assignment
> (or even change the license, if they want).  This would apply to something
> new like this Sony driver.  However, for code that is already in the kernel
> tree, with likely multiple contributors, the legal situation gets a little
> more murky.
>
> I suspect the vast majority of the ~60k files will probably fall neatly into 
> an
> SPDX category, but I'm guessing a fair number (maybe hundreds) will require
> some review and discussion.

You are completely and 100% right. I was just describing the mechanics
of the license detection side. The actual process has been and always
will be scan then review carefully and then discuss. There is no sane
automated tool that could do it all for sure.

As a funny side note, there are over 80+ licenses in the kernel and
there is (or rather was before starting adding SPDX tags) 1000+
different license notices and over 700+ variations of "this file in
under the GPL"... This starts to diminish a bit with the addition of
SPDX tags and eventually most or all boilerplate could be removed over
time with reviews and discussions, IMHO for the better: I will then be
able to trash my tool and use a good ole grep instead ;)

-- 
Cordially
Philippe Ombredanne


Re: [RESEND PATCH] partial revert of "[media] tvp5150: add HW input connectors support"

2017-12-14 Thread Mauro Carvalho Chehab
Em Thu, 14 Dec 2017 18:37:30 +0100
Javier Martinez Canillas  escreveu:

> Hello Mauro,
> 
> On 12/14/2017 06:02 PM, Mauro Carvalho Chehab wrote:
> > Em Wed,  6 Dec 2017 01:33:05 +0100
> > Javier Martinez Canillas  escreveu:
> >   
> >> Commit f7b4b54e6364 ("[media] tvp5150: add HW input connectors support")
> >> added input signals support for the tvp5150, but the approach was found
> >> to be incorrect so the corresponding DT binding commit 82c2ffeb217a
> >> ("[media] tvp5150: document input connectors DT bindings") was reverted.
> >>
> >> This left the driver with an undocumented (and wrong) DT parsing logic,
> >> so lets get rid of this code as well until the input connectors support
> >> is implemented properly.
> >>
> >> It's a partial revert due other patches added on top of mentioned commit
> >> not allowing the commit to be reverted cleanly anymore. But all the code
> >> related to the DT parsing logic and input entities creation are removed.
> >>
> >> Suggested-by: Laurent Pinchart 
> >> Signed-off-by: Javier Martinez Canillas 
> >> Acked-by: Laurent Pinchart   
> >   
> >>
> >> ---
> >>
> >> This patch was posted about a year ago but was never merged:
> >>
> >> https://patchwork.kernel.org/patch/9472623/  
> > 
> > It was a RFT, on that time.
> >   
> 
> Yes, sorry if it sounded as if I was complaining. I was just mentioning and
> part of the patch falling through the cracks is that I also forgot about it.
> 
> > I guess I told that before. Maybe not. Anyway, reverting it doesn't seem 
> > to be the proper fix, as it will break support for existing devices, by
> > removing functionality from tvp5150 driver. You should remind that, since
> > the code was added, someone could be already using it, as all it is  
> 
> I'm not sure about this. What I'm removing is basically dead code (unless
> someone is using an undocumented Device Tree binding), since the DT binding
> got already removed by commit 31e717dba1e1 ("[media] Revert "[media] tvp5150:
> document input connectors DT bindings").
> 
> > needed is to have some dtb. Also, it gets rid of a lot of good work for
> > no good reason. Reinserting them later while preserving the code
> > copyrights could be painful.
> >  
> 
> I would normally agree with you, although I think that in this particular case
> is better to just revert this (unused) code for the reasons I mentioned above.
> 
> But don't really have a strong opinion on this, so I'm OK with either 
> approach.
> 
> > IMHO, the best here is to move ahead, agreeing with a DT structure
> > that represents the connectors and then change the driver to
> > implement it, if needed.
> >  
> 
> There was some agreement on the DT binding, it's just that I never found time
> to implement the logic in the driver. Let's see if I can get some during the
> winter holidays and finally fix this.

Ok. This was pending for a long time to be touched. Waiting for a couple
of weeks for a final solution seems worth.

If you can't do that, by then, please ping us for us to seek for an
alternative way to move forward.



Thanks,
Mauro


Re: [PATCH v4 00/12] [dt-bindings] [media] Add document file and driver for Sony CXD2880 DVB-T2/T tuner + demodulator

2017-12-14 Thread Mauro Carvalho Chehab
Em Thu, 14 Dec 2017 17:32:34 +
"Bird, Timothy"  escreveu:

> > -Original Message-
> > From: Philippe on Thursday, December 14, 2017 6:25 AM
> > Dear Mauro,
> > 
> > On Thu, Dec 14, 2017 at 11:55 AM, Mauro Carvalho Chehab
> >  wrote:
> >   
> > > SPDX is a new requirement that started late on Kernel 4.14 development
> > > cycle (and whose initial changes were merged directly at Linus tree).
> > > Not all existing files have it yet, as identifying the right license
> > > on existing files is a complex task, but if you do a:
> > >
> > > $ git grep SPDX $(find . -name Makefile) $(find . -name Kconfig)
> > >
> > > You'll see that lot of such files have it already.  
> > 
> > FWIW, short of having SPDX tags, identifying the right license on
> > existing files is not a super complex task: if boils down to running
> > many diffs.
> > 
> > Take the ~60K files in kernel, and about 6K license and notices
> > reference texts. Then compute a pairwise diff of each of the 60K file
> > against the 6K reference texts. Repeat the pairwise diff a few more
> > times, say 10 times, as multiple licenses may appear in any given
> > kernel file. And keep the diffs that have the fewest
> > difference/highest similarity with the reference texts as the detected
> > license. Done!  
> 
> You can't do license detection and assignment in this automated fashion - 
> at least not generally.
> 
> Even a single word of difference between the notice in the source
> code and the reference license notice or text may have legal implications
> that are not conveyed by the simplified SPDX tag.  When differences are
> found, we're going to have to kick the discrepancies to a human for review.
> This is especially true for files with multiple licenses.
> 
> For a work of original authorship, or a single copyright holder, the author
> or copyright holder may be able to change the notice or text, or gloss
> over any difference from the reference text, and make the SPDX  assignment
> (or even change the license, if they want).  This would apply to something
> new like this Sony driver.  However, for code that is already in the kernel
> tree, with likely multiple contributors, the legal situation gets a little
> more murky.

Precisely. This is easily fixable when the code author changes the
license text, or when someone from the Company that holds copyrights sends
the SPDX markups (as emails @company can be seen as official e-mails, except
if explicitly noticed otherwise). So, from my side, I'm now requiring
SPDX for new drivers.

However, if someone else is doing the changes, it can be tricky and risky
to pick up the patch, adding my SOB, if not endorsed by the copyright
owners, or by LF legal counseling. So, I prefer to not pick those myself,
except from people I trust.

> I suspect the vast majority of the ~60k files will probably fall neatly into 
> an
> SPDX category, but I'm guessing a fair number (maybe hundreds) will require
> some review and discussion.

Thanks,
Mauro


Re: [RESEND PATCH] partial revert of "[media] tvp5150: add HW input connectors support"

2017-12-14 Thread Javier Martinez Canillas
Hello Mauro,

On 12/14/2017 06:02 PM, Mauro Carvalho Chehab wrote:
> Em Wed,  6 Dec 2017 01:33:05 +0100
> Javier Martinez Canillas  escreveu:
> 
>> Commit f7b4b54e6364 ("[media] tvp5150: add HW input connectors support")
>> added input signals support for the tvp5150, but the approach was found
>> to be incorrect so the corresponding DT binding commit 82c2ffeb217a
>> ("[media] tvp5150: document input connectors DT bindings") was reverted.
>>
>> This left the driver with an undocumented (and wrong) DT parsing logic,
>> so lets get rid of this code as well until the input connectors support
>> is implemented properly.
>>
>> It's a partial revert due other patches added on top of mentioned commit
>> not allowing the commit to be reverted cleanly anymore. But all the code
>> related to the DT parsing logic and input entities creation are removed.
>>
>> Suggested-by: Laurent Pinchart 
>> Signed-off-by: Javier Martinez Canillas 
>> Acked-by: Laurent Pinchart 
> 
>>
>> ---
>>
>> This patch was posted about a year ago but was never merged:
>>
>> https://patchwork.kernel.org/patch/9472623/
> 
> It was a RFT, on that time.
> 

Yes, sorry if it sounded as if I was complaining. I was just mentioning and
part of the patch falling through the cracks is that I also forgot about it.

> I guess I told that before. Maybe not. Anyway, reverting it doesn't seem 
> to be the proper fix, as it will break support for existing devices, by
> removing functionality from tvp5150 driver. You should remind that, since
> the code was added, someone could be already using it, as all it is

I'm not sure about this. What I'm removing is basically dead code (unless
someone is using an undocumented Device Tree binding), since the DT binding
got already removed by commit 31e717dba1e1 ("[media] Revert "[media] tvp5150:
document input connectors DT bindings").

> needed is to have some dtb. Also, it gets rid of a lot of good work for
> no good reason. Reinserting them later while preserving the code
> copyrights could be painful.
>

I would normally agree with you, although I think that in this particular case
is better to just revert this (unused) code for the reasons I mentioned above.

But don't really have a strong opinion on this, so I'm OK with either approach.

> IMHO, the best here is to move ahead, agreeing with a DT structure
> that represents the connectors and then change the driver to
> implement it, if needed.
>

There was some agreement on the DT binding, it's just that I never found time
to implement the logic in the driver. Let's see if I can get some during the
winter holidays and finally fix this.

> Thanks,
> Mauro
> 

Best regards,
-- 
Javier Martinez Canillas
Software Engineer - Desktop Hardware Enablement
Red Hat


Re: [PATCH] media: v4l: xilinx: Use SPDX-License-Identifier

2017-12-14 Thread Mauro Carvalho Chehab
Em Thu, 14 Dec 2017 09:26:27 -0800
Joe Perches  escreveu:

> On Thu, 2017-12-14 at 15:05 -0200, Mauro Carvalho Chehab wrote:
> > Em Fri,  8 Dec 2017 18:05:37 +0530
> > Dhaval Shah  escreveu:
> >   
> > > SPDX-License-Identifier is used for the Xilinx Video IP and
> > > related drivers.
> > > 
> > > Signed-off-by: Dhaval Shah   
> > 
> > Hi Dhaval,
> > 
> > You're not listed as one of the Xilinx driver maintainers. I'm afraid that,
> > without their explicit acks, sent to the ML, I can't accept a patch
> > touching at the driver's license tags.  
> 
> And even a maintainer may not have the sole right
> to modify a license.

Very true. I was actually expecting a patch like that either authored
or explicitly sanctioned by either one of those developers:

Hyun Kwon  (supporter:XILINX VIDEO IP CORES)
Michal Simek  (supporter:ARM/ZYNQ ARCHITECTURE)

As they own an @xilinx.com, we could assume that an email from
their corporate accounts to be official.

Thanks,
Mauro


RE: [PATCH v4 00/12] [dt-bindings] [media] Add document file and driver for Sony CXD2880 DVB-T2/T tuner + demodulator

2017-12-14 Thread Bird, Timothy


> -Original Message-
> From: Philippe on Thursday, December 14, 2017 6:25 AM
> Dear Mauro,
> 
> On Thu, Dec 14, 2017 at 11:55 AM, Mauro Carvalho Chehab
>  wrote:
> 
> > SPDX is a new requirement that started late on Kernel 4.14 development
> > cycle (and whose initial changes were merged directly at Linus tree).
> > Not all existing files have it yet, as identifying the right license
> > on existing files is a complex task, but if you do a:
> >
> > $ git grep SPDX $(find . -name Makefile) $(find . -name Kconfig)
> >
> > You'll see that lot of such files have it already.
> 
> FWIW, short of having SPDX tags, identifying the right license on
> existing files is not a super complex task: if boils down to running
> many diffs.
> 
> Take the ~60K files in kernel, and about 6K license and notices
> reference texts. Then compute a pairwise diff of each of the 60K file
> against the 6K reference texts. Repeat the pairwise diff a few more
> times, say 10 times, as multiple licenses may appear in any given
> kernel file. And keep the diffs that have the fewest
> difference/highest similarity with the reference texts as the detected
> license. Done!

You can't do license detection and assignment in this automated fashion - 
at least not generally.

Even a single word of difference between the notice in the source
code and the reference license notice or text may have legal implications
that are not conveyed by the simplified SPDX tag.  When differences are
found, we're going to have to kick the discrepancies to a human for review.
This is especially true for files with multiple licenses.

For a work of original authorship, or a single copyright holder, the author
or copyright holder may be able to change the notice or text, or gloss
over any difference from the reference text, and make the SPDX  assignment
(or even change the license, if they want).  This would apply to something
new like this Sony driver.  However, for code that is already in the kernel
tree, with likely multiple contributors, the legal situation gets a little
more murky.

I suspect the vast majority of the ~60k files will probably fall neatly into an
SPDX category, but I'm guessing a fair number (maybe hundreds) will require
some review and discussion.

 -- Tim




Re: [PATCH] media: v4l: xilinx: Use SPDX-License-Identifier

2017-12-14 Thread Joe Perches
On Thu, 2017-12-14 at 15:05 -0200, Mauro Carvalho Chehab wrote:
> Em Fri,  8 Dec 2017 18:05:37 +0530
> Dhaval Shah  escreveu:
> 
> > SPDX-License-Identifier is used for the Xilinx Video IP and
> > related drivers.
> > 
> > Signed-off-by: Dhaval Shah 
> 
> Hi Dhaval,
> 
> You're not listed as one of the Xilinx driver maintainers. I'm afraid that,
> without their explicit acks, sent to the ML, I can't accept a patch
> touching at the driver's license tags.

And even a maintainer may not have the sole right
to modify a license.



[PATCH 03/10] media: imon: remove unused function tv2int

2017-12-14 Thread Sean Young
Since commit 9c7fd60e951d ("media: rc: Replace timeval with ktime_t in
imon.c"), the function tv2int() is no longer used. Remove it.

Signed-off-by: Sean Young 
---
 drivers/media/rc/imon.c | 23 ---
 1 file changed, 23 deletions(-)

diff --git a/drivers/media/rc/imon.c b/drivers/media/rc/imon.c
index 6c873a3c4720..950d068ba806 100644
--- a/drivers/media/rc/imon.c
+++ b/drivers/media/rc/imon.c
@@ -1168,29 +1168,6 @@ static int imon_ir_change_protocol(struct rc_dev *rc, 
u64 *rc_proto)
return retval;
 }
 
-static inline int tv2int(const struct timeval *a, const struct timeval *b)
-{
-   int usecs = 0;
-   int sec   = 0;
-
-   if (b->tv_usec > a->tv_usec) {
-   usecs = 100;
-   sec--;
-   }
-
-   usecs += a->tv_usec - b->tv_usec;
-
-   sec += a->tv_sec - b->tv_sec;
-   sec *= 1000;
-   usecs /= 1000;
-   sec += usecs;
-
-   if (sec < 0)
-   sec = 1000;
-
-   return sec;
-}
-
 /*
  * The directional pad behaves a bit differently, depending on whether this is
  * one of the older ffdc devices or a newer device. Newer devices appear to
-- 
2.14.3



[PATCH 04/10] media: rc: bang in ir_do_keyup

2017-12-14 Thread Sean Young
rc_keydown() can be called from interrupt context, by e.g. an rc scancode
driver. Since commit b2c96ba352b5 ("media: cec: move cec autorepeat
handling to rc-core"), the del_timer_sync() call is not happy about
being called in interrupt connect. del_timer() will suffice.

WARNING: CPU: 0 PID: 0 at kernel/time/timer.c:1285 del_timer_sync+0x1d/0x40
CPU: 0 PID: 0 Comm: swapper/0 Tainted: GW4.15.0-rc1+ #1
Hardware name:  /DG45ID, BIOS IDG4510H.86A.0135.2011.0225.1100 
02/25/2011
task: a3e10480 task.stack: a3e0
RIP: 0010:del_timer_sync+0x1d/0x40
RSP: 0018:8b396bc03db0 EFLAGS: 00010046
RAX: 8001 RBX: 8b394d70e410 RCX: 0073
RDX: 0001 RSI: 0001 RDI: 8b394d70e410
RBP: 0001 R08: c0616000 R09: 8b396bfa3000
R10:  R11: 0390 R12: 8b394f003800
R13:  R14: 8b3771c19630 R15: 
FS:  () GS:8b396bc0() knlGS:
CS:  0010 DS:  ES:  CR0: 80050033
CR2: 7f1944469000 CR3: 0001ebe09000 CR4: 06f0
Call Trace:
 
 ir_do_keyup.part.5+0x22/0x90 [rc_core]
 rc_keyup+0x37/0x50 [rc_core]
 usb_rx_callback_intf0+0x79/0x90 [imon]
 __usb_hcd_giveback_urb+0x90/0x130
 uhci_giveback_urb+0xab/0x250
 uhci_scan_schedule.part.34+0x806/0xb00
 uhci_irq+0xab/0x150
 usb_hcd_irq+0x22/0x30
 __handle_irq_event_percpu+0x3a/0x180
 handle_irq_event_percpu+0x30/0x70
 handle_irq_event+0x27/0x50
 handle_fasteoi_irq+0x6b/0x110
 handle_irq+0xa5/0x100
 do_IRQ+0x41/0xc0
 common_interrupt+0x96/0x96
 
RIP: 0010:cpuidle_enter_state+0x9a/0x2d0
RSP: 0018:a3e03e88 EFLAGS: 0246 ORIG_RAX: ffda
RAX: 8b396bc1a000 RBX: 0010da7bcd63 RCX: 0010da7bccf6
RDX: 0010da7bcd63 RSI: 0010da7bcd63 RDI: 
RBP: 8b394f587400 R08:  R09: 0002
R10: a3e03e48 R11: 0390 R12: 0003
R13: a3ebf018 R14:  R15: 0010da7ba772
 ? cpuidle_enter_state+0x8d/0x2d0
 do_idle+0x17b/0x1d0
 cpu_startup_entry+0x6f/0x80
 start_kernel+0x4a7/0x4c7
 secondary_startup_64+0xa5/0xb0
Code: e7 5b 5d 41 5c e9 84 88 05 00 0f 1f 40 00 66 66 66 66 90 65 8b 05 e4 6f 
ef 5c a9 00 00 0f 00 53 48 89 fb 74 16 f6 47 22 20 75 10 <0f> ff 48 89 df e8 89 
f1 ff ff 85 c0 79 0e f3 90 48 89 df e8 7b

Fixes: b2c96ba352b5 ("media: cec: move cec autorepeat handling to rc-core")

Signed-off-by: Sean Young 
---
 drivers/media/rc/rc-main.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c
index 1870b7999062..1db8d38fed7c 100644
--- a/drivers/media/rc/rc-main.c
+++ b/drivers/media/rc/rc-main.c
@@ -597,7 +597,7 @@ static void ir_do_keyup(struct rc_dev *dev, bool sync)
return;
 
IR_dprintk(1, "keyup key 0x%04x\n", dev->last_keycode);
-   del_timer_sync(>timer_repeat);
+   del_timer(>timer_repeat);
input_report_key(dev->input_dev, dev->last_keycode, 0);
led_trigger_event(led_feedback, LED_OFF);
if (sync)
-- 
2.14.3



[PATCH 08/10] media: lirc: no need to recalculate duration

2017-12-14 Thread Sean Young
This is code existed for when drivers would send less than the whole
buffer; no driver does this any more, so this is redundant. Drivers
should return -EINVAL if they cannot send the entire buffer.

Signed-off-by: Sean Young 
---
 drivers/media/rc/lirc_dev.c | 10 +-
 1 file changed, 1 insertion(+), 9 deletions(-)

diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c
index 8618aba152c6..1fc1fd665bce 100644
--- a/drivers/media/rc/lirc_dev.c
+++ b/drivers/media/rc/lirc_dev.c
@@ -347,15 +347,6 @@ static ssize_t ir_lirc_transmit_ir(struct file *file, 
const char __user *buf,
if (ret < 0)
goto out_kfree;
 
-   if (fh->send_mode == LIRC_MODE_SCANCODE) {
-   ret = n;
-   } else {
-   for (duration = i = 0; i < ret; i++)
-   duration += txbuf[i];
-
-   ret *= sizeof(unsigned int);
-   }
-
/*
 * The lircd gap calculation expects the write function to
 * wait for the actual IR signal to be transmitted before
@@ -368,6 +359,7 @@ static ssize_t ir_lirc_transmit_ir(struct file *file, const 
char __user *buf,
schedule_timeout(usecs_to_jiffies(towait));
}
 
+   ret = n;
 out_kfree:
kfree(txbuf);
kfree(raw);
-- 
2.14.3



[PATCH 05/10] media: lirc: when transmitting scancodes, block until transmit is done

2017-12-14 Thread Sean Young
The semantics for lirc IR transmit with raw IR is that the write call
should block until the IR is transmitted. Some drivers have no idea
when this actually is (e.g. mceusb), so there is a wait.

This is useful for userspace, as it might want to send a IR button press,
a gap of a predefined number of milliseconds, and then send a repeat
message.

It turns out that for transmitting scancodes this feature is even more
useful, as user space has no idea how long the IR is. So, maintain
the existing semantics for IR scancode transmit.

Signed-off-by: Sean Young 
---
 Documentation/media/uapi/rc/lirc-write.rst |  4 ++--
 drivers/media/rc/lirc_dev.c| 22 +++---
 2 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/Documentation/media/uapi/rc/lirc-write.rst 
b/Documentation/media/uapi/rc/lirc-write.rst
index dd3d1fe807a6..d4566b0a2015 100644
--- a/Documentation/media/uapi/rc/lirc-write.rst
+++ b/Documentation/media/uapi/rc/lirc-write.rst
@@ -60,8 +60,8 @@ When in :ref:`LIRC_MODE_SCANCODE ` mode, 
one
 and the protocol in the :c:type:`rc_proto`: member. All other members must be
 set to 0, else ``EINVAL`` is returned. If there is no protocol encoder
 for the protocol or the scancode is not valid for the specified protocol,
-``EINVAL`` is returned. The write function may not wait until the scancode
-is transmitted.
+``EINVAL`` is returned. The write function blocks until the scancode
+is transmitted by the hardware.
 
 
 Return Value
diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c
index 218658917cf6..6cedb546c3e0 100644
--- a/drivers/media/rc/lirc_dev.c
+++ b/drivers/media/rc/lirc_dev.c
@@ -354,18 +354,18 @@ static ssize_t ir_lirc_transmit_ir(struct file *file, 
const char __user *buf,
duration += txbuf[i];
 
ret *= sizeof(unsigned int);
+   }
 
-   /*
-* The lircd gap calculation expects the write function to
-* wait for the actual IR signal to be transmitted before
-* returning.
-*/
-   towait = ktime_us_delta(ktime_add_us(start, duration),
-   ktime_get());
-   if (towait > 0) {
-   set_current_state(TASK_INTERRUPTIBLE);
-   schedule_timeout(usecs_to_jiffies(towait));
-   }
+   /*
+* The lircd gap calculation expects the write function to
+* wait for the actual IR signal to be transmitted before
+* returning.
+*/
+   towait = ktime_us_delta(ktime_add_us(start, duration),
+   ktime_get());
+   if (towait > 0) {
+   set_current_state(TASK_INTERRUPTIBLE);
+   schedule_timeout(usecs_to_jiffies(towait));
}
 
 out:
-- 
2.14.3



[PATCH 09/10] media: lirc: release lock before sleep

2017-12-14 Thread Sean Young
There is no reason to hold the lock while we wait for the IR to transmit.

Reported-by: Dan Carpenter 
Signed-off-by: Sean Young 
---
 drivers/media/rc/lirc_dev.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c
index 1fc1fd665bce..713d42e4b661 100644
--- a/drivers/media/rc/lirc_dev.c
+++ b/drivers/media/rc/lirc_dev.c
@@ -347,6 +347,10 @@ static ssize_t ir_lirc_transmit_ir(struct file *file, 
const char __user *buf,
if (ret < 0)
goto out_kfree;
 
+   kfree(txbuf);
+   kfree(raw);
+   mutex_unlock(>lock);
+
/*
 * The lircd gap calculation expects the write function to
 * wait for the actual IR signal to be transmitted before
@@ -359,7 +363,7 @@ static ssize_t ir_lirc_transmit_ir(struct file *file, const 
char __user *buf,
schedule_timeout(usecs_to_jiffies(towait));
}
 
-   ret = n;
+   return n;
 out_kfree:
kfree(txbuf);
kfree(raw);
-- 
2.14.3



[PATCH 06/10] media: rc: iguanair: simplify tx loop

2017-12-14 Thread Sean Young
Signed-off-by: Sean Young 
---
 drivers/media/rc/iguanair.c | 19 ---
 1 file changed, 8 insertions(+), 11 deletions(-)

diff --git a/drivers/media/rc/iguanair.c b/drivers/media/rc/iguanair.c
index 30e24da67226..7daac8bab83b 100644
--- a/drivers/media/rc/iguanair.c
+++ b/drivers/media/rc/iguanair.c
@@ -347,26 +347,23 @@ static int iguanair_set_tx_mask(struct rc_dev *dev, 
uint32_t mask)
 static int iguanair_tx(struct rc_dev *dev, unsigned *txbuf, unsigned count)
 {
struct iguanair *ir = dev->priv;
-   uint8_t space;
-   unsigned i, size, periods, bytes;
+   unsigned int i, size, p, periods;
int rc;
 
mutex_lock(>lock);
 
/* convert from us to carrier periods */
-   for (i = space = size = 0; i < count; i++) {
+   for (i = size = 0; i < count; i++) {
periods = DIV_ROUND_CLOSEST(txbuf[i] * ir->carrier, 100);
-   bytes = DIV_ROUND_UP(periods, 127);
-   if (size + bytes > ir->bufsize) {
-   rc = -EINVAL;
-   goto out;
-   }
while (periods) {
-   unsigned p = min(periods, 127u);
-   ir->packet->payload[size++] = p | space;
+   p = min(periods, 127u);
+   if (size >= ir->bufsize) {
+   rc = -EINVAL;
+   goto out;
+   }
+   ir->packet->payload[size++] = p | ((i & 1) ? 0x80 : 0);
periods -= p;
}
-   space ^= 0x80;
}
 
ir->packet->header.start = 0;
-- 
2.14.3



[PATCH 07/10] media: lirc: do not pass ERR_PTR to kfree

2017-12-14 Thread Sean Young
If memdup_user() fails, txbuf will be an error pointer and passed
to kfree.

Reported-by: Dan Carpenter 
Signed-off-by: Sean Young 
---
 drivers/media/rc/lirc_dev.c | 35 ++-
 1 file changed, 18 insertions(+), 17 deletions(-)

diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c
index 6cedb546c3e0..8618aba152c6 100644
--- a/drivers/media/rc/lirc_dev.c
+++ b/drivers/media/rc/lirc_dev.c
@@ -231,7 +231,7 @@ static ssize_t ir_lirc_transmit_ir(struct file *file, const 
char __user *buf,
 {
struct lirc_fh *fh = file->private_data;
struct rc_dev *dev = fh->rc;
-   unsigned int *txbuf = NULL;
+   unsigned int *txbuf;
struct ir_raw_event *raw = NULL;
ssize_t ret;
size_t count;
@@ -246,14 +246,14 @@ static ssize_t ir_lirc_transmit_ir(struct file *file, 
const char __user *buf,
 
if (!dev->registered) {
ret = -ENODEV;
-   goto out;
+   goto out_unlock;
}
 
start = ktime_get();
 
if (!dev->tx_ir) {
ret = -EINVAL;
-   goto out;
+   goto out_unlock;
}
 
if (fh->send_mode == LIRC_MODE_SCANCODE) {
@@ -261,17 +261,17 @@ static ssize_t ir_lirc_transmit_ir(struct file *file, 
const char __user *buf,
 
if (n != sizeof(scan)) {
ret = -EINVAL;
-   goto out;
+   goto out_unlock;
}
 
if (copy_from_user(, buf, sizeof(scan))) {
ret = -EFAULT;
-   goto out;
+   goto out_unlock;
}
 
if (scan.flags || scan.keycode || scan.timestamp) {
ret = -EINVAL;
-   goto out;
+   goto out_unlock;
}
 
/*
@@ -283,26 +283,26 @@ static ssize_t ir_lirc_transmit_ir(struct file *file, 
const char __user *buf,
if (scan.scancode > U32_MAX ||
!rc_validate_scancode(scan.rc_proto, scan.scancode)) {
ret = -EINVAL;
-   goto out;
+   goto out_unlock;
}
 
raw = kmalloc_array(LIRCBUF_SIZE, sizeof(*raw), GFP_KERNEL);
if (!raw) {
ret = -ENOMEM;
-   goto out;
+   goto out_unlock;
}
 
ret = ir_raw_encode_scancode(scan.rc_proto, scan.scancode,
 raw, LIRCBUF_SIZE);
if (ret < 0)
-   goto out;
+   goto out_kfree;
 
count = ret;
 
txbuf = kmalloc_array(count, sizeof(unsigned int), GFP_KERNEL);
if (!txbuf) {
ret = -ENOMEM;
-   goto out;
+   goto out_kfree;
}
 
for (i = 0; i < count; i++)
@@ -318,26 +318,26 @@ static ssize_t ir_lirc_transmit_ir(struct file *file, 
const char __user *buf,
} else {
if (n < sizeof(unsigned int) || n % sizeof(unsigned int)) {
ret = -EINVAL;
-   goto out;
+   goto out_unlock;
}
 
count = n / sizeof(unsigned int);
if (count > LIRCBUF_SIZE || count % 2 == 0) {
ret = -EINVAL;
-   goto out;
+   goto out_unlock;
}
 
txbuf = memdup_user(buf, n);
if (IS_ERR(txbuf)) {
ret = PTR_ERR(txbuf);
-   goto out;
+   goto out_unlock;
}
}
 
for (i = 0; i < count; i++) {
if (txbuf[i] > IR_MAX_DURATION / 1000 - duration || !txbuf[i]) {
ret = -EINVAL;
-   goto out;
+   goto out_kfree;
}
 
duration += txbuf[i];
@@ -345,7 +345,7 @@ static ssize_t ir_lirc_transmit_ir(struct file *file, const 
char __user *buf,
 
ret = dev->tx_ir(dev, txbuf, count);
if (ret < 0)
-   goto out;
+   goto out_kfree;
 
if (fh->send_mode == LIRC_MODE_SCANCODE) {
ret = n;
@@ -368,10 +368,11 @@ static ssize_t ir_lirc_transmit_ir(struct file *file, 
const char __user *buf,
schedule_timeout(usecs_to_jiffies(towait));
}
 
-out:
-   mutex_unlock(>lock);
+out_kfree:
kfree(txbuf);
kfree(raw);
+out_unlock:
+   mutex_unlock(>lock);
return ret;
 }
 
-- 
2.14.3



[PATCH 01/10] media: imon: auto-config ffdc 26 device

2017-12-14 Thread Sean Young
Another device with the 0xffdc device id, this one with 0x26 in the
config byte. Its an iMON Inside + iMON IR. It does respond to rc-6,
but seems to produce random garbage rather than a scancode.

Signed-off-by: Sean Young 
---
 drivers/media/rc/imon.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/media/rc/imon.c b/drivers/media/rc/imon.c
index 2c26d917fe0f..6c873a3c4720 100644
--- a/drivers/media/rc/imon.c
+++ b/drivers/media/rc/imon.c
@@ -1975,6 +1975,11 @@ static void imon_get_ffdc_type(struct imon_context *ictx)
detected_display_type = IMON_DISPLAY_TYPE_LCD;
allowed_protos = RC_PROTO_BIT_RC6_MCE;
break;
+   /* no display, iMON IR */
+   case 0x26:
+   dev_info(ictx->dev, "0xffdc iMON Inside, iMON IR");
+   ictx->display_supported = false;
+   break;
default:
dev_info(ictx->dev, "Unknown 0xffdc device, defaulting to VFD 
and iMON IR");
detected_display_type = IMON_DISPLAY_TYPE_VFD;
-- 
2.14.3



[PATCH 02/10] media: rc: mce_kbd: simplify key up

2017-12-14 Thread Sean Young
For key up, rather than iterating over 224 keys, just remember which key
was pressed.

Signed-off-by: Sean Young 
---
 drivers/media/rc/ir-mce_kbd-decoder.c | 23 ++-
 drivers/media/rc/rc-core-priv.h   |  1 +
 2 files changed, 15 insertions(+), 9 deletions(-)

diff --git a/drivers/media/rc/ir-mce_kbd-decoder.c 
b/drivers/media/rc/ir-mce_kbd-decoder.c
index 8cf4cf358052..b851583d2d94 100644
--- a/drivers/media/rc/ir-mce_kbd-decoder.c
+++ b/drivers/media/rc/ir-mce_kbd-decoder.c
@@ -128,8 +128,10 @@ static void mce_kbd_rx_timeout(struct timer_list *t)
input_report_key(mce_kbd->idev, maskcode, 0);
}
 
-   for (i = 0; i < MCIR2_MASK_KEYS_START; i++)
-   input_report_key(mce_kbd->idev, kbd_keycodes[i], 0);
+   if (mce_kbd->last_key != KEY_RESERVED) {
+   input_report_key(mce_kbd->idev, mce_kbd->last_key, 0);
+   mce_kbd->last_key = KEY_RESERVED;
+   }
 }
 
 static enum mce_kbd_mode mce_kbd_mode(struct mce_kbd_dec *data)
@@ -144,7 +146,7 @@ static enum mce_kbd_mode mce_kbd_mode(struct mce_kbd_dec 
*data)
}
 }
 
-static void ir_mce_kbd_process_keyboard_data(struct input_dev *idev,
+static void ir_mce_kbd_process_keyboard_data(struct mce_kbd_dec *data,
 u32 scancode)
 {
u8 keydata   = (scancode >> 8) & 0xff;
@@ -161,15 +163,18 @@ static void ir_mce_kbd_process_keyboard_data(struct 
input_dev *idev,
keystate = 1;
else
keystate = 0;
-   input_report_key(idev, maskcode, keystate);
+   input_report_key(data->idev, maskcode, keystate);
+   }
+
+   if (data->last_key != KEY_RESERVED) {
+   input_report_key(data->idev, data->last_key, 0);
+   data->last_key = KEY_RESERVED;
}
 
if (keydata) {
keycode = kbd_keycodes[keydata];
-   input_report_key(idev, keycode, 1);
-   } else {
-   for (i = 0; i < MCIR2_MASK_KEYS_START; i++)
-   input_report_key(idev, kbd_keycodes[i], 0);
+   input_report_key(data->idev, keycode, 1);
+   data->last_key = keycode;
}
 }
 
@@ -326,7 +331,7 @@ static int ir_mce_kbd_decode(struct rc_dev *dev, struct 
ir_raw_event ev)
delay = msecs_to_jiffies(100);
mod_timer(>rx_timeout, jiffies + delay);
/* Pass data to keyboard buffer parser */
-   ir_mce_kbd_process_keyboard_data(data->idev, scancode);
+   ir_mce_kbd_process_keyboard_data(data, scancode);
lsc.rc_proto = RC_PROTO_MCIR2_KBD;
break;
case MCIR2_MOUSE_NBITS:
diff --git a/drivers/media/rc/rc-core-priv.h b/drivers/media/rc/rc-core-priv.h
index 915434855a63..035f3ffc19f7 100644
--- a/drivers/media/rc/rc-core-priv.h
+++ b/drivers/media/rc/rc-core-priv.h
@@ -106,6 +106,7 @@ struct ir_raw_event_ctrl {
char phys[64];
int state;
u8 header;
+   u8 last_key;
u32 body;
unsigned count;
unsigned wanted_bits;
-- 
2.14.3



[PATCH 10/10] media: ir-spi: add SPDX identifier

2017-12-14 Thread Sean Young
From: Andi Shyti 

Replace the original license statement with the SPDX identifier.

Update also the copyright owner adding myself as co-owner of the
copyright.

Signed-off-by: Andi Shyti 
Signed-off-by: Sean Young 
---
 drivers/media/rc/ir-spi.c | 15 +--
 1 file changed, 5 insertions(+), 10 deletions(-)

diff --git a/drivers/media/rc/ir-spi.c b/drivers/media/rc/ir-spi.c
index 29ed0638cb74..a32a84ae2d0b 100644
--- a/drivers/media/rc/ir-spi.c
+++ b/drivers/media/rc/ir-spi.c
@@ -1,13 +1,8 @@
-/*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
- * Author: Andi Shyti 
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * SPI driven IR LED device driver
- */
+// SPDX-License-Identifier: GPL-2.0
+// SPI driven IR LED device driver
+//
+// Copyright (c) 2016 Samsung Electronics Co., Ltd.
+// Copyright (c) Andi Shyti 
 
 #include 
 #include 
-- 
2.14.3



Re: [PATCH] em28xx: split up em28xx_dvb_init to reduce stack size

2017-12-14 Thread Mauro Carvalho Chehab
Em Mon, 11 Dec 2017 13:05:02 +0100
Arnd Bergmann  escreveu:

> With CONFIG_KASAN, the init function uses a large amount of kernel stack:
> 
> drivers/media/usb/em28xx/em28xx-dvb.c: In function 'em28xx_dvb_init.part.4':
> drivers/media/usb/em28xx/em28xx-dvb.c:2061:1: error: the frame size of 3232 
> bytes is larger than 2048 bytes [-Werror=frame-larger-than=]
> 
> Using gcc-7 with -fsanitize-address-use-after-scope makes this even worse:
> 
> drivers/media/usb/em28xx/em28xx-dvb.c: In function 'em28xx_dvb_init':
> drivers/media/usb/em28xx/em28xx-dvb.c:2069:1: error: the frame size of 4280 
> bytes is larger than 3072 bytes [-Werror=frame-larger-than=]
> 
> By splitting out each part of the switch/case statement that has its own local
> variables into a separate function, no single one of them uses more than 500 
> bytes,
> and with a noinline_for_stack annotation we can ensure that they are not 
> merged
> back together.

The right fix here is really to find a way to simplify the new method
of binding I2C devices by using some ancillary routines.

I'll keep this patch on my queue for now, but my plan is to try to solve
this issue instead of applying it, maybe on the next weeks (as the
volume of patches reduce due to end of year vacations and Seasons).

> 
> Signed-off-by: Arnd Bergmann 
> ---
>  drivers/media/usb/em28xx/em28xx-dvb.c | 947 
> ++
>  1 file changed, 508 insertions(+), 439 deletions(-)
> 
> diff --git a/drivers/media/usb/em28xx/em28xx-dvb.c 
> b/drivers/media/usb/em28xx/em28xx-dvb.c
> index 9950a740e04e..6665885dbaa7 100644
> --- a/drivers/media/usb/em28xx/em28xx-dvb.c
> +++ b/drivers/media/usb/em28xx/em28xx-dvb.c
> @@ -934,7 +934,7 @@ static struct lgdt3306a_config 
> hauppauge_01595_lgdt3306a_config = {
>  
>  /* -- */
>  
> -static int em28xx_attach_xc3028(u8 addr, struct em28xx *dev)
> +static noinline_for_stack int em28xx_attach_xc3028(u8 addr, struct em28xx 
> *dev)
>  {
>   struct dvb_frontend *fe;
>   struct xc2028_config cfg;
> @@ -1126,6 +1126,492 @@ static void em28xx_unregister_dvb(struct em28xx_dvb 
> *dvb)
>   dvb_unregister_adapter(>adapter);
>  }
>  
> +static noinline_for_stack int em28174_dvb_init_pctv_460e(struct em28xx *dev)
> +{
> + struct em28xx_dvb *dvb = dev->dvb;
> + struct i2c_client *client;
> + struct i2c_board_info board_info;
> + struct tda10071_platform_data tda10071_pdata = {};
> + struct a8293_platform_data a8293_pdata = {};
> + int result;
> +
> + /* attach demod + tuner combo */
> + tda10071_pdata.clk = 40444000, /* 40.444 MHz */
> + tda10071_pdata.i2c_wr_max = 64,
> + tda10071_pdata.ts_mode = TDA10071_TS_SERIAL,
> + tda10071_pdata.pll_multiplier = 20,
> + tda10071_pdata.tuner_i2c_addr = 0x14,
> + memset(_info, 0, sizeof(board_info));
> + strlcpy(board_info.type, "tda10071_cx24118", I2C_NAME_SIZE);
> + board_info.addr = 0x55;
> + board_info.platform_data = _pdata;
> + request_module("tda10071");
> + client = i2c_new_device(>i2c_adap[dev->def_i2c_bus], _info);
> + if (client == NULL || client->dev.driver == NULL) {
> + result = -ENODEV;
> + goto out_free;
> + }
> + if (!try_module_get(client->dev.driver->owner)) {
> + i2c_unregister_device(client);
> + result = -ENODEV;
> + goto out_free;
> + }
> + dvb->fe[0] = tda10071_pdata.get_dvb_frontend(client);
> + dvb->i2c_client_demod = client;
> +
> + /* attach SEC */
> + a8293_pdata.dvb_frontend = dvb->fe[0];
> + memset(_info, 0, sizeof(board_info));
> + strlcpy(board_info.type, "a8293", I2C_NAME_SIZE);
> + board_info.addr = 0x08;
> + board_info.platform_data = _pdata;
> + request_module("a8293");
> + client = i2c_new_device(>i2c_adap[dev->def_i2c_bus], _info);
> + if (client == NULL || client->dev.driver == NULL) {
> + module_put(dvb->i2c_client_demod->dev.driver->owner);
> + i2c_unregister_device(dvb->i2c_client_demod);
> + result = -ENODEV;
> + goto out_free;
> + }
> + if (!try_module_get(client->dev.driver->owner)) {
> + i2c_unregister_device(client);
> + module_put(dvb->i2c_client_demod->dev.driver->owner);
> + i2c_unregister_device(dvb->i2c_client_demod);
> + result = -ENODEV;
> + goto out_free;
> + }
> + dvb->i2c_client_sec = client;
> + result = 0;
> +out_free:
> + return result;
> +}
> +
> +static noinline_for_stack int em28178_dvb_init_pctv_461e(struct em28xx *dev)
> +{
> + struct em28xx_dvb *dvb = dev->dvb;
> + struct i2c_client *client;
> + struct i2c_adapter *i2c_adapter;
> + struct i2c_board_info board_info;
> + struct m88ds3103_platform_data m88ds3103_pdata = {};
> + struct ts2020_config ts2020_config = {};
> + struct 

Re: [GIT PULL FOR v4.16] media: imx: Add better OF graph support

2017-12-14 Thread Steve Longerbeam



On 12/14/2017 04:13 AM, Hans Verkuil wrote:

On 08/12/17 23:48, Steve Longerbeam wrote:


On 12/08/2017 08:38 AM, Mauro Carvalho Chehab wrote:

Em Fri, 8 Dec 2017 11:56:58 +0100
Hans Verkuil  escreveu:


Note: the new v4l2-async work makes it possible to simplify this. That
will be done in follow-up patches. It's easier to do that if this is in
first.

Regards,

 Hans

The following changes since commit 781b045baefdabf7e0bc9f33672ca830d3db9f27:

media: imx274: Fix error handling, add MAINTAINERS entry (2017-11-30 
04:45:12 -0500)

are available in the git repository at:

git://linuxtv.org/hverkuil/media_tree.git imx

for you to fetch changes up to 82737cbb02f269b8eb608c7bd906a79072f6adad:

media: staging/imx: update TODO (2017-12-04 14:05:19 +0100)


Steve Longerbeam (9):
media: staging/imx: get CSI bus type from nearest upstream entity

There are some non-trivial conflicts on this patch.
Care to rebase it?

Attached is fixed-up version.

That still doesn't apply against the latest media_tree master.


Yeah, more merge conflicts from latest commits. I will just post a new
series.

Steve




Re: [PATCH] media: v4l: xilinx: Use SPDX-License-Identifier

2017-12-14 Thread Mauro Carvalho Chehab
Em Fri,  8 Dec 2017 18:05:37 +0530
Dhaval Shah  escreveu:

> SPDX-License-Identifier is used for the Xilinx Video IP and
> related drivers.
> 
> Signed-off-by: Dhaval Shah 

Hi Dhaval,

You're not listed as one of the Xilinx driver maintainers. I'm afraid that,
without their explicit acks, sent to the ML, I can't accept a patch
touching at the driver's license tags.

Sorry,
Mauro


Re: [RESEND PATCH] partial revert of "[media] tvp5150: add HW input connectors support"

2017-12-14 Thread Mauro Carvalho Chehab
Em Wed,  6 Dec 2017 01:33:05 +0100
Javier Martinez Canillas  escreveu:

> Commit f7b4b54e6364 ("[media] tvp5150: add HW input connectors support")
> added input signals support for the tvp5150, but the approach was found
> to be incorrect so the corresponding DT binding commit 82c2ffeb217a
> ("[media] tvp5150: document input connectors DT bindings") was reverted.
> 
> This left the driver with an undocumented (and wrong) DT parsing logic,
> so lets get rid of this code as well until the input connectors support
> is implemented properly.
> 
> It's a partial revert due other patches added on top of mentioned commit
> not allowing the commit to be reverted cleanly anymore. But all the code
> related to the DT parsing logic and input entities creation are removed.
> 
> Suggested-by: Laurent Pinchart 
> Signed-off-by: Javier Martinez Canillas 
> Acked-by: Laurent Pinchart 

> 
> ---
> 
> This patch was posted about a year ago but was never merged:
> 
> https://patchwork.kernel.org/patch/9472623/

It was a RFT, on that time.

I guess I told that before. Maybe not. Anyway, reverting it doesn't seem 
to be the proper fix, as it will break support for existing devices, by
removing functionality from tvp5150 driver. You should remind that, since
the code was added, someone could be already using it, as all it is
needed is to have some dtb. Also, it gets rid of a lot of good work for
no good reason. Reinserting them later while preserving the code
copyrights could be painful.

IMHO, the best here is to move ahead, agreeing with a DT structure
that represents the connectors and then change the driver to
implement it, if needed.

Thanks,
Mauro


Re: camss: camera controls missing on vfe interfaces

2017-12-14 Thread Mauro Carvalho Chehab
Em Mon, 20 Nov 2017 11:59:59 +0100
Daniel Mack  escreveu:

> Hi Todor,
> 
> Thanks for following up!
> 
> On Monday, November 20, 2017 09:32 AM, Todor Tomov wrote:
> > On 15.11.2017 21:31, Daniel Mack wrote:  
> >> Todor et all,
> >>
> >> Any hint on how to tackle this?
> >>
> >> I can contribute patches, but I'd like to understand what the idea is.
> >>
> >>
> >> Thanks,
> >> Daniel
> >>
> >>
> >> On Thursday, October 26, 2017 06:11 PM, Daniel Mack wrote:  
> >>> Hi Todor,
> >>>
> >>> When using the camss driver trough one of its /dev/videoX device nodes,
> >>> applications are currently unable to see the video controls the camera
> >>> sensor exposes.
> >>>
> >>> Same goes for other ioctls such as VIDIOC_ENUM_FMT, so the only valid
> >>> resolution setting for applications to use is the one that was
> >>> previously set through the media controller layer. Applications usually
> >>> query the available formats and then pick one using the standard V4L2
> >>> APIs, and many can't easily be forced to use a specific one.
> >>>
> >>> If I'm getting this right, could you explain what's the rationale here?
> >>> Is that simply a missing feature or was that approach chosen on purpose?
> >>>  
> > 
> > It is not a missing feature, it is more of a missing userspace 
> > implementation.
> > When working with a media oriented device driver, the userspace has to
> > config the media pipeline too and if controls are exposed by the subdev 
> > nodes,
> > the userspace has to configure them on the subdev nodes.
> > 
> > As there weren't a lot of media oriented drivers there is no generic
> > implementation/support for this in the userspace (at least I'm not aware of
> > any). There have been discussions about adding such functionality in libv4l
> > so that applications which do not support media configuration can still
> > use these drivers. I'm not sure if decision for this was taken or not or
> > is it just that there was noone to actually do the work. Probably Laurent,
> > Mauro or Hans know more about what were the plans for this.  
> 
> Hmm, that's not good.
> 
> Considering the use-case in our application, the pipeline is set up once
> and considered more or less static, and then applications such as the
> Chrome browsers make use of the high-level VFE interface. If there are
> no controls exposed on that interface, they are not available to the
> application. Patching all userspace applications is an uphill battle
> that can't be won I'm afraid.
> 
> Is there any good reason not to expose the sensor controls on the VFE? I
> guess it would be easy to do, right?

Sorry for a late answer. I'm usually very busy on 4Q, but this year, it
was atypical.

A little historic is needed in order to answer this question.
Up to very recently, V4L2 drivers that are media-controller centric, 
e. g. whose sub-devices are controlled directly by subdev devnodes,
were used only on specialized hardware, with special V4L2 applications
designed for them. In other words, it was designed to be used by generic
applications (although we always wanted a solution for it), and this
was never a real problem so far.

However, with the advent of cheap SoC hardware with complex media
processors on it, the scenario changed recently, and we need some
discussions upstream about the best way to solve it.

The original idea, back when the media controller was introduced,
were to add support at libv4l. But this never happened, and it turns
to be a way more complex than originally foreseen.

As you're pointing, on such scenarios, one alternative is to expose subdev
controls also to the /dev/video devnode that is controlling the pipeline
streaming. However, depending on the pipeline, this may not be possible,
as the same control could be implemented on more than on block inside
the pipeline. When such case happens, the proper solution is to pinpoint
what sub-device will handle the control via the subdev API.

However, on several scenarios (like, for instance, a RPi3 with
a single camera sensor), the pipeline is simple enough to either
avoid such conflicts, or to have an obvious subdevice that would
be handling such control.

From my PoV, on cases like RPi3, the best is to just implement control
propagation inside the pipelines. However, other media core developers
think otherwise.

If you can provide us a broader view about what are the issues that
you're facing, what's your use case scenario and what are the pipelines,
this could be valuable for us to improve our discussions about the
best way to solve it.

Please notice, however, that this is not the best time for taking
such discussions, as several core developers will be taking
vacations those days.

Thanks,
Mauro


Re: [PATCH v9 07/28] rcar-vin: change name of video device

2017-12-14 Thread Laurent Pinchart
Hi Sakari,

On Thursday, 14 December 2017 16:25:00 EET Sakari Ailus wrote:
> On Fri, Dec 08, 2017 at 10:17:36AM +0200, Laurent Pinchart wrote:
> > On Friday, 8 December 2017 03:08:21 EET Niklas Söderlund wrote:
> > > The rcar-vin driver needs to be part of a media controller to support
> > > Gen3. Give each VIN instance a unique name so it can be referenced from
> > > userspace.
> > > 
> > > Signed-off-by: Niklas Söderlund 
> > > Reviewed-by: Kieran Bingham 
> > > Reviewed-by: Hans Verkuil 
> > > ---
> > > 
> > >  drivers/media/platform/rcar-vin/rcar-v4l2.c | 3 ++-
> > >  1 file changed, 2 insertions(+), 1 deletion(-)
> > > 
> > > diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c
> > > b/drivers/media/platform/rcar-vin/rcar-v4l2.c index
> > > 59ec6d3d119590aa..19de99133f048960 100644
> > > --- a/drivers/media/platform/rcar-vin/rcar-v4l2.c
> > > +++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c
> > > @@ -876,7 +876,8 @@ int rvin_v4l2_register(struct rvin_dev *vin)
> > > 
> > >   vdev->fops = _fops;
> > >   vdev->v4l2_dev = >v4l2_dev;
> > >   vdev->queue = >queue;
> > > 
> > > - strlcpy(vdev->name, KBUILD_MODNAME, sizeof(vdev->name));
> > > + snprintf(vdev->name, sizeof(vdev->name), "%s %s", KBUILD_MODNAME,
> > > +  dev_name(vin->dev));
> > 
> > Do we need the module name here ? How about calling them "%s output",
> > dev_name(vin->dev) to emphasize the fact that this is a video node and not
> > a VIN subdev ? This is what the omap3isp and vsp1 drivers do.
> > 
> > We're suffering a bit from the fact that V4L2 has never standardized a
> > naming scheme for the devices. It wouldn't be fair to ask you to fix that
> > as a prerequisite to get the VIN driver merged, but we clearly have to
> > work on that at some point.
> 
> Agreed, this needs to be stable and I think aligning to what omap3isp or
> vsp1 do would be a good fix here.

Even omap3isp and vsp1 are not fully aligned, so I think we need to design a 
naming policy and document it.

-- 
Regards,

Laurent Pinchart



Re: [PATCH] Fix for hanging si2168 in PCTV 292e, making the code match

2017-12-14 Thread Mauro Carvalho Chehab
Em Tue, 19 Sep 2017 13:13:52 +0100
Nigel Kettlewell  escreveu:

> [re-sending as plain text]
> 
> Fix for hanging si2168 in PCTV 292e USB, making the code match the comment.
> 
> Using firmware v4.0.11 the 292e would work once and then hang on 
> subsequent attempts to view DVB channels, until physically unplugged and 
> plugged back in.
> 
> With this patch, the warm state is reset for v4.0.11 and it appears to 
> work both on the first attempt and on subsequent attempts.
> 
> (Patch basis Linux 4.11.9 f82a53b87594f460f2dd9983eeb851a5840e8df8)

Patch is missing a Signed-off-by. See:
https://elinux.org/Developer_Certificate_Of_Origin).


> 
> ---
>   drivers/media/dvb-frontends/si2168.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/media/dvb-frontends/si2168.c 
> b/drivers/media/dvb-frontends/si2168.c
> index 680ba06..523acd1 100644
> --- a/drivers/media/dvb-frontends/si2168.c
> +++ b/drivers/media/dvb-frontends/si2168.c
> @@ -582,7 +582,7 @@ static int si2168_sleep(struct dvb_frontend *fe)
>  dev->active = false;
> 
>  /* Firmware B 4.0-11 or later loses warm state during sleep */
> -   if (dev->version > ('B' << 24 | 4 << 16 | 0 << 8 | 11 << 0))
> +   if (dev->version >= ('B' << 24 | 4 << 16 | 0 << 8 | 11 << 0))
>  dev->warm = false;
> 
>  memcpy(cmd.args, "\x13", 1);
> --
> 2.9.4
> 



Thanks,
Mauro


Re: [PATCH v4 3/5] media: i2c: Add TDA1997x HDMI receiver driver

2017-12-14 Thread Hans Verkuil
On 14/12/17 00:35, Tim Harvey wrote:
>>> Close. What is missing is a check of the AVI InfoFrame: if it has an 
>>> explicit
>>> colorimetry then use that. E.g. check for HDMI_COLORIMETRY_ITU_601 or 
>>> ITU_709
>>> and set the colorspace accordingly. Otherwise fall back to what you have 
>>> here.
>>>
>>
>> This function currently matches adv7604/adv7842 where they don't look
>> at colorimetry (but I do see a TODO in adv748x_hdmi_fill_format to
>> look at this) so I don't have an example and may not understand.
>>
>> Do you mean:
>>
>>format->colorspace = V4L2_COLORSPACE_SRGB;
>>if (bt->flags & V4L2_DV_FL_IS_CE_VIDEO) {
>> if ((state->colorimetry == HDMI_COLORIMETRY_ITU_601) ||
>> (state->colorimetry == HDMI_COLORIMETRY_ITU_709))
>> format->colorspace = state->colorspace;
>> else
>> format->colorspace = is_sd(bt->height) ?
>> V4L2_COLORSPACE_SMPTE170M :
>> V4L2_COLORSPACE_REC709;
>> }
>>
>> Also during more testing I've found that I'm not capturing interlaced
>> properly and know I at least need:
>>
>> -format->field = V4L2_FIELD_NONE;
>> +format->field = (bt->interlaced) ?
>> +V4L2_FIELD_ALTERNATE : V4L2_FIELD_NONE;
>>
>> I'm still not quite capturing interlaced yet but I think its an issue
>> of setting up the media pipeline improperly.
>>
> 
> Hans,
> 
> Did you see this question above? I'm not quite understanding what you
> want me to do for filling in colorspace and don't see any examples in
> the existing drivers that appear to look at colorimetry for this.

Yeah, I missed that question. I started answering that yesterday, but then
I realized that it would be better if I would make a helper function for
v4l2-dv-timings. The rules are complex so coding that in a single place
that everyone can use is the smart thing to do.

I hope to finish it tomorrow (too many interruptions today).

Regards,

Hans



Re: [PATCH v4 00/12] [dt-bindings] [media] Add document file and driver for Sony CXD2880 DVB-T2/T tuner + demodulator

2017-12-14 Thread Philippe Ombredanne
Dear Mauro,

On Thu, Dec 14, 2017 at 11:55 AM, Mauro Carvalho Chehab
 wrote:

> SPDX is a new requirement that started late on Kernel 4.14 development
> cycle (and whose initial changes were merged directly at Linus tree).
> Not all existing files have it yet, as identifying the right license
> on existing files is a complex task, but if you do a:
>
> $ git grep SPDX $(find . -name Makefile) $(find . -name Kconfig)
>
> You'll see that lot of such files have it already.

FWIW, short of having SPDX tags, identifying the right license on
existing files is not a super complex task: if boils down to running
many diffs.

Take the ~60K files in kernel, and about 6K license and notices
reference texts. Then compute a pairwise diff of each of the 60K file
against the 6K reference texts. Repeat the pairwise diff a few more
times, say 10 times, as multiple licenses may appear in any given
kernel file. And keep the diffs that have the fewest
difference/highest similarity with the reference texts as the detected
license. Done!

The only complex thing is that if you have a fast diff that runs at
0.1 millisec end-to-end per diff, you still have 3.6B diffs to do and
this would take about 250 days on one thread. Even with a beefy 250
core CPU, that would still be a day (and quite few kilo watts) . So
the whole trick is to avoid doing a diffs if not really needed. This
is what I do in my scancode-toolkit (that I used/use to help Greg and
Thomas with kernel license scans). Net effect is that on a laptop on 8
threads it takes ~20 minutes to scan a whole kernel using this
diff-based approach and obtain a fairly accurate license detection.
-- 
Cordially
Philippe Ombredanne


Re: [PATCH v9 07/28] rcar-vin: change name of video device

2017-12-14 Thread Sakari Ailus
On Fri, Dec 08, 2017 at 10:17:36AM +0200, Laurent Pinchart wrote:
> Hi Niklas,
> 
> (CC'ing Sakari)
> 
> Thank you for the patch.
> 
> On Friday, 8 December 2017 03:08:21 EET Niklas Söderlund wrote:
> > The rcar-vin driver needs to be part of a media controller to support
> > Gen3. Give each VIN instance a unique name so it can be referenced from
> > userspace.
> > 
> > Signed-off-by: Niklas Söderlund 
> > Reviewed-by: Kieran Bingham 
> > Reviewed-by: Hans Verkuil 
> > ---
> >  drivers/media/platform/rcar-vin/rcar-v4l2.c | 3 ++-
> >  1 file changed, 2 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c
> > b/drivers/media/platform/rcar-vin/rcar-v4l2.c index
> > 59ec6d3d119590aa..19de99133f048960 100644
> > --- a/drivers/media/platform/rcar-vin/rcar-v4l2.c
> > +++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c
> > @@ -876,7 +876,8 @@ int rvin_v4l2_register(struct rvin_dev *vin)
> > vdev->fops = _fops;
> > vdev->v4l2_dev = >v4l2_dev;
> > vdev->queue = >queue;
> > -   strlcpy(vdev->name, KBUILD_MODNAME, sizeof(vdev->name));
> > +   snprintf(vdev->name, sizeof(vdev->name), "%s %s", KBUILD_MODNAME,
> > +dev_name(vin->dev));
> 
> Do we need the module name here ? How about calling them "%s output", 
> dev_name(vin->dev) to emphasize the fact that this is a video node and not a 
> VIN subdev ? This is what the omap3isp and vsp1 drivers do.
> 
> We're suffering a bit from the fact that V4L2 has never standardized a naming 
> scheme for the devices. It wouldn't be fair to ask you to fix that as a 
> prerequisite to get the VIN driver merged, but we clearly have to work on 
> that 
> at some point.

Agreed, this needs to be stable and I think aligning to what omap3isp or
vsp1 do would be a good fix here.

-- 
Sakari Ailus
e-mail: sakari.ai...@iki.fi


Re: [PATCH v2] media: s5p-mfc: Add support for V4L2_MEMORY_DMABUF type

2017-12-14 Thread Marek Szyprowski

Hi Hans,

I would like to get your opinion on this patch. Do you think it makes 
sense to:


1. add limited support for USERPTR and DMA-buf import? (limited means 
driver will accept setting buffer pointer/fd only once after reqbufs for 
each buffer index)


2. add a V4L2 device flag to let userspace to discover if device support 
queue buffer reconfiguration on-fly or not?


Here is the discussion: https://patchwork.linuxtv.org/patch/45305/

Best regards
Marek Szyprowski, PhD
Samsung R Institute Poland


On 2017-11-06 20:21, Nicolas Dufresne wrote:

Le lundi 06 novembre 2017 à 10:28 +0100, Marek Szyprowski a écrit :

On 2017-11-03 14:45, Nicolas Dufresne wrote:

Le vendredi 03 novembre 2017 à 09:11 +0100, Marek Szyprowski a écrit :

MFC driver supports only MMAP operation mode mainly due to the hardware
restrictions of the addresses of the DMA buffers (MFC v5 hardware can
access buffers only in 128MiB memory region starting from the base address
of its firmware). When IOMMU is available, this requirement is easily
fulfilled even for the buffers located anywhere in the memory - typically
by mapping them in the DMA address space as close as possible to the
firmware. Later hardware revisions don't have this limitations at all.

The second limitation of the MFC hardware related to the memory buffers
is constant buffer address. Once the hardware has been initialized for
operation on given buffer set, the addresses of the buffers cannot be
changed.

With the above assumptions, a limited support for USERPTR and DMABUF
operation modes can be added. The main requirement is to have all buffers
known when starting hardware. This has been achieved by postponing
hardware initialization once all the DMABUF or USERPTR buffers have been
queued for the first time. Once then, buffers cannot be modified to point
to other memory area.

I am concerned about enabling this support with existing userspace.
Userspace application will be left with some driver with this
limitation and other drivers without. I think it is harmful to enable
that feature without providing userspace the ability to know.

This is specially conflicting with let's say UVC driver providing
buffers, since UVC driver implementing CREATE_BUFS ioctl. So even if
userspace start making an effort to maintain the same DMABuf for the
same buffer index, if a new buffer is created, we won't be able to use
it.

Sorry, but I don't get this as an 'issue'. The typical use scenario is to
configure buffer queue and start streaming. Basically ReqBufs, stream on and
a sequence of bufq/bufdq. This is handled without any problem by MFC driver
with this patch. After releasing a queue with reqbufs(0), one can use
different set of buffers.

In real life, you often have capture code decorelated from the encoder
code. At least, it's the case in GStreamer. The encoder have no
information about how many buffers were pre-allocated by let's say the
capture driver. As a side effect, we cannot make sure the importation
queue is of the same size (amount of buffer). Specially if you have UVC
driver that allow allocating more buffers at run-time. This is used in
real-life to compensate additional latency that get's added when a
pipeline topology is changed (at run-time). Only workaround I had in
mind, would be to always prepare the queue with the maximum (32), and
use this as a cache size, but for now, this is not how the deployed
userspace works unfortunately.

Your reqbuf(0) technique cause a break in the stream (probably a new
keyframe), as you are forced to STREAMOFF. This is often unwanted, and
it may create a time discontinuity in case the allocation took time.


What is the point of changing the buffers during the streaming? IMHO it was
one of the biggest pathology of the V4L2 USERPTR API that the buffers
were in
fact 'created' on the first queue operation. By creating I mean creating all
the kernel all needed structures and mappings between the real memory (user
ptr value) and the buffer index. The result of this was userspace, which
don't
use buffer indices and always queues buffers with index = 0, what means that
kernel has to reacquire direct access to each buffer every single frame.
That
is highly inefficient approach. DMABUF operation mode inherited this
drawback.

This in fact is an implementation detail of the caching in the kernel
framework. There is nothing that prevent the framework to maintain a
validation cache that isn't bound to the queue size. DMABuf simply
makes the buffer identification easier and safer. I bet it is difficult
and it will stay like this, so it should at least be documented.

I am completely aware of the inefficiency of the GStreamer behaviour,
though it remains much faster in many case then copying raw frames
using the CPU. You can complain as much as you can about what this
userspace doing, but it as has been working better then nothing for
many users. It might not be like this forever, someone could optimize
this by signalling the missing 

Re: [PATCH] pvrusb2: correctly return V4L2_PIX_FMT_MPEG in enum_fmt

2017-12-14 Thread Sakari Ailus
On Thu, Dec 14, 2017 at 12:44:42AM +0100, Hans Verkuil wrote:
> The pvrusb2 code appears to have a some old workaround code for xawtv that 
> causes a
> WARN() due to an unrecognized pixelformat 0 in v4l2_ioctl.c.
> 
> Since all other MPEG drivers fill this in correctly, it is a safe assumption 
> that
> this particular problem no longer exists.
> 
> While I'm at it, clean up the code a bit.
> 
> Signed-off-by: Hans Verkuil 

Acked-by: Sakari Ailus 

-- 
Sakari Ailus
e-mail: sakari.ai...@iki.fi


Re: Kernel Oopses from v4l_enum_fmt

2017-12-14 Thread Sakari Ailus
On Wed, Dec 13, 2017 at 05:04:28PM -0500, Nicolas Dufresne wrote:
> Le mercredi 13 décembre 2017 à 22:33 +0100, Oleksandr Ostrenko a
> écrit :
> > Dear all,
> > 
> > There is an issue in v4l_enum_fmt leading to kernel panic under
> > certain 
> > circumstance. It happens while I try to capture video from my TV
> > tuner.
> > 
> > When I connect this USB TV tuner (WinTV HVR-1900) it gets recognized 
> > just fine. However, whenever I try to capture a video from the
> > device, 
> > it hangs the terminal and I end up with a lot of "Unknown
> > pixelformat 
> > 0x" errors from v4l_enum_fmt in dmesg that eventually lead
> > to 
> > kernel panic on a machine with Linux Mint. On another machine with 
> > openSUSE it does not hang but just keeps producing the error message 
> > below until I stop the video acquisition. I have already tried
> > several 
> > kernel versions (4.4, 4.8, 4.14) and two different distributions
> > (Mint, 
> > openSUSE) but to no avail.
> > 
> > Can somebody give me a hint on debugging this issue?
> > Below are sample outputs of lsusb and dmesg.
> > 
> > Thanks,
> > Oleksandr
> > 
> > lsusb
> > 
> > Bus 001 Device 002: ID 8087:8001 Intel Corp.
> > Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
> > Bus 003 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
> > Bus 002 Device 002: ID 8087:0a2a Intel Corp.
> > Bus 002 Device 005: ID 2040:7300 Hauppauge
> > Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
> > 
> > Relevant dmesg
> > 
> > [  515.920080] usb 2-3: new high-speed USB device number 4 using
> > xhci_hcd
> > [  516.072041] usb 2-3: New USB device found, idVendor=2040,
> > idProduct=7300
> > [  516.072045] usb 2-3: New USB device strings: Mfr=1, Product=2, 
> > SerialNumber=3
> > [  516.072047] usb 2-3: Product: WinTV
> > [  516.072049] usb 2-3: Manufacturer: Hauppauge
> > [  516.072051] usb 2-3: SerialNumber: 7300-00-F04BADA0
> > [  516.072474] pvrusb2: Hardware description: WinTV HVR-1900 Model
> > 73xxx
> > [  517.089290] pvrusb2: Device microcontroller firmware (re)loaded;
> > it 
> > should now reset and reconnect.
> > [  517.121228] usb 2-3: USB disconnect, device number 4
> > [  517.121436] pvrusb2: Device being rendered inoperable
> > [  518.908091] usb 2-3: new high-speed USB device number 5 using
> > xhci_hcd
> > [  519.065592] usb 2-3: New USB device found, idVendor=2040,
> > idProduct=7300
> > [  519.065597] usb 2-3: New USB device strings: Mfr=1, Product=2, 
> > SerialNumber=3
> > [  519.065600] usb 2-3: Product: WinTV
> > [  519.065602] usb 2-3: Manufacturer: Hauppauge
> > [  519.065605] usb 2-3: SerialNumber: 7300-00-F04BADA0
> > [  519.066862] pvrusb2: Hardware description: WinTV HVR-1900 Model
> > 73xxx
> > [  519.098815] pvrusb2: Binding ir_rx_z8f0811_haup to i2c address
> > 0x71.
> > [  519.098872] pvrusb2: Binding ir_tx_z8f0811_haup to i2c address
> > 0x70.
> > [  519.131651] cx25840 6-0044: cx25843-24 found @ 0x88 (pvrusb2_a)
> > [  519.133234] lirc_dev: IR Remote Control driver registered, major
> > 241
> > [  519.134192] lirc_zilog: module is from the staging directory, the 
> > quality is unknown, you have been warned.
> > [  519.134194] lirc_zilog: module is from the staging directory, the 
> > quality is unknown, you have been warned.
> > [  519.134564] Zilog/Hauppauge IR driver initializing
> > [  519.135628] probing IR Rx on pvrusb2_a (i2c-6)
> > [  519.135674] probe of IR Rx on pvrusb2_a (i2c-6) done. Waiting on
> > IR Tx.
> > [  519.135678] i2c i2c-6: probe of IR Rx on pvrusb2_a (i2c-6) done
> > [  519.135706] probing IR Tx on pvrusb2_a (i2c-6)
> > [  519.135728] i2c i2c-6: Direct firmware load for haup-ir-
> > blaster.bin 
> > failed with error -2
> > [  519.135730] i2c i2c-6: firmware haup-ir-blaster.bin not available
> > (-2)
> > [  519.135799] i2c i2c-6: lirc_dev: driver lirc_zilog registered at 
> > minor = 0
> > [  519.135800] i2c i2c-6: IR unit on pvrusb2_a (i2c-6) registered as 
> > lirc0 and ready
> > [  519.135802] i2c i2c-6: probe of IR Tx on pvrusb2_a (i2c-6) done
> > [  519.135826] initialization complete
> > [  519.140759] pvrusb2: Attached sub-driver cx25840
> > [  519.147644] tuner: 6-0042: Tuner -1 found with type(s) Radio TV.
> > [  519.147667] pvrusb2: Attached sub-driver tuner
> > [  521.029446] cx25840 6-0044: loaded v4l-cx25840.fw firmware (14264
> > bytes)
> > [  521.124582] tveeprom: Hauppauge model 73219, rev D1E9, serial#
> > 4031491488
> > [  521.124586] tveeprom: MAC address is 00:0d:fe:4b:ad:a0
> > [  521.124588] tveeprom: tuner model is Philips 18271_8295 (idx 149, 
> > type 54)
> > [  521.124591] tveeprom: TV standards PAL(B/G) PAL(I) SECAM(L/L') 
> > PAL(D/D1/K) ATSC/DVB Digital (eeprom 0xf4)
> > [  521.124593] tveeprom: audio processor is CX25843 (idx 37)
> > [  521.124594] tveeprom: decoder processor is CX25843 (idx 30)
> > [  521.124596] tveeprom: has radio, has IR receiver, has IR
> > transmitter
> > [  521.124606] pvrusb2: Supported video standard(s) reported
> > available 

Re: [PATCH] [media] vb2: clear V4L2_BUF_FLAG_LAST when filling vb2_buffer

2017-12-14 Thread Sakari Ailus
Hi Philipp,

On Fri, Dec 08, 2017 at 03:01:28PM +0100, Philipp Zabel wrote:
> V4L2_BUF_FLAG_LAST is a signal from the driver to userspace for buffers
> on the capture queue. When userspace queues back a capture buffer with
> the flag set, we should clear it.
> 
> Otherwise, if userspace restarts streaming after EOS, without
> reallocating the buffers, mem2mem devices will erroneously signal EOS
> prematurely, as soon as the already flagged buffer is dequeued.
> 
> Signed-off-by: Philipp Zabel 
> ---
>  drivers/media/v4l2-core/videobuf2-v4l2.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/drivers/media/v4l2-core/videobuf2-v4l2.c 
> b/drivers/media/v4l2-core/videobuf2-v4l2.c
> index 4075314a69893..fac3cd6f901d5 100644
> --- a/drivers/media/v4l2-core/videobuf2-v4l2.c
> +++ b/drivers/media/v4l2-core/videobuf2-v4l2.c
> @@ -434,6 +434,8 @@ static int __fill_vb2_buffer(struct vb2_buffer *vb,
>   } else {
>   /* Zero any output buffer flags as this is a capture buffer */
>   vbuf->flags &= ~V4L2_BUFFER_OUT_FLAGS;
> + /* Zero last flag, this is a signal from driver to userspace */
> + vbuf->flags &= ~V4L2_BUF_FLAG_LAST;

Thanks for the patch.

How about:

vbuf->flags &= ~(V4L2_BUFFER_OUT_FLAGS | V4L2_BUF_FLAG_LAST);

-- 
Sakari Ailus
e-mail: sakari.ai...@iki.fi


Re: [RFC 1/1] v4l: async: Use endpoint node, not device node, for fwnode match

2017-12-14 Thread Sakari Ailus
Hi Jacopo,

On Thu, Dec 14, 2017 at 12:44:38PM +0100, jacopo mondi wrote:
> Hi Sakari,
> 
> On Thu, Dec 14, 2017 at 12:53:42PM +0200, Sakari Ailus wrote:
> > Hi Jacopo,
> >
> > On Thu, Dec 07, 2017 at 03:29:40PM +0100, jacopo mondi wrote:
> > > Hi Sakari!
> > > thanks for proposing this
> > >
> > > While we all agree that full endpoint matching is the right
> > > thing to do (see also Kieran's last reply to his "v4l2-async: Match
> > > parent devices" patch) I have some perplexity on this proposal,
> > > please see below
> > >
> > > On Mon, Dec 04, 2017 at 11:03:02PM +0200, Sakari Ailus wrote:
> > > > V4L2 async framework can use both device's fwnode and endpoints's fwnode
> > > > for matching the async sub-device with the sub-device. In order to 
> > > > proceed
> > > > moving towards endpoint matching assign the endpoint to the async
> > > > sub-device.
> > > >
> > > > As most async sub-device drivers (and the related hardware) only 
> > > > supports
> > > > a single endpoint, use the first endpoint found. This works for all
> > > > current drivers --- we only ever supported a single async sub-device per
> > > > device to begin with.
> > > >
> > > > For async devices that have no endpoints, continue to use the fwnode
> > > > related to the device. This includes e.g. lens devices.
> > > >
> > > > Signed-off-by: Sakari Ailus 
> > > > ---
> > > > Hi Niklas,
> > > >
> > > > What do you think of this one? I've tested this on N9, both sensor and
> > > > flash devices work nicely there. No opportunistic checks for backwards
> > > > compatibility are needed.
> > > >
> > > > The changes were surprisingly simple, there are only two drivers that
> > > > weren't entirely trivial to change (this part is truly weird in 
> > > > exynos4-is
> > > > and xilinx-vipp). Converting the two to use the common parsing functions
> > > > would be quite a bit more work and would be very nice to test. The 
> > > > changes
> > > > in this patch were still relatively simple.
> > > >
> > > >  drivers/media/platform/am437x/am437x-vpfe.c|  2 +-
> > > >  drivers/media/platform/atmel/atmel-isc.c   |  2 +-
> > > >  drivers/media/platform/atmel/atmel-isi.c   |  2 +-
> > > >  drivers/media/platform/davinci/vpif_capture.c  |  2 +-
> > > >  drivers/media/platform/exynos4-is/media-dev.c  | 14 ++
> > > >  drivers/media/platform/pxa_camera.c|  2 +-
> > > >  drivers/media/platform/qcom/camss-8x16/camss.c |  2 +-
> > > >  drivers/media/platform/rcar_drif.c |  2 +-
> > > >  drivers/media/platform/stm32/stm32-dcmi.c  |  2 +-
> > > >  drivers/media/platform/ti-vpe/cal.c|  2 +-
> > > >  drivers/media/platform/xilinx/xilinx-vipp.c| 16 +---
> > > >  drivers/media/v4l2-core/v4l2-async.c   |  8 ++--
> > > >  drivers/media/v4l2-core/v4l2-fwnode.c  |  2 +-
> > > >  13 files changed, 39 insertions(+), 19 deletions(-)
> > > >
> > > > diff --git a/drivers/media/platform/am437x/am437x-vpfe.c 
> > > > b/drivers/media/platform/am437x/am437x-vpfe.c
> > > > index 0997c640191d..892d9e935d25 100644
> > > > --- a/drivers/media/platform/am437x/am437x-vpfe.c
> > > > +++ b/drivers/media/platform/am437x/am437x-vpfe.c
> > > > @@ -2493,7 +2493,7 @@ vpfe_get_pdata(struct platform_device *pdev)
> > > > if (flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH)
> > > > sdinfo->vpfe_param.vdpol = 1;
> > > >
> > > > -   rem = of_graph_get_remote_port_parent(endpoint);
> > > > +   rem = of_graph_get_remote_endpoint(endpoint);
> > > > if (!rem) {
> > > > dev_err(>dev, "Remote device at %pOF not 
> > > > found\n",
> > > > endpoint);
> > > > diff --git a/drivers/media/platform/atmel/atmel-isc.c 
> > > > b/drivers/media/platform/atmel/atmel-isc.c
> > > > index 13f1c1c797b0..c8bb60eeb629 100644
> > > > --- a/drivers/media/platform/atmel/atmel-isc.c
> > > > +++ b/drivers/media/platform/atmel/atmel-isc.c
> > > > @@ -2044,7 +2044,7 @@ static int isc_parse_dt(struct device *dev, 
> > > > struct isc_device *isc)
> > > > if (!epn)
> > > > break;
> > > >
> > > > -   rem = of_graph_get_remote_port_parent(epn);
> > > > +   rem = of_graph_get_remote_endpoint(epn);
> > > > if (!rem) {
> > > > dev_notice(dev, "Remote device at %pOF not 
> > > > found\n",
> > > >epn);
> > > > diff --git a/drivers/media/platform/atmel/atmel-isi.c 
> > > > b/drivers/media/platform/atmel/atmel-isi.c
> > > > index e900995143a3..eafdf91a4541 100644
> > > > --- a/drivers/media/platform/atmel/atmel-isi.c
> > > > +++ b/drivers/media/platform/atmel/atmel-isi.c
> > > > @@ -1119,7 +1119,7 @@ static int isi_graph_parse(struct atmel_isi *isi, 
> > > > struct device_node *node)
> > > > if (!ep)
> > > > 

Re: [PATCH/RFC 1/2] v4l: v4l2-dev: Add infrastructure to protect device unplug race

2017-12-14 Thread Sakari Ailus
Hi Laurent,

On Tue, Dec 12, 2017 at 04:42:23PM +0200, Laurent Pinchart wrote:
...
> > > diff --git a/drivers/media/v4l2-core/v4l2-dev.c
> > > b/drivers/media/v4l2-core/v4l2-dev.c index c647ba648805..c73c6d49e7cf
> > > 100644
> > > --- a/drivers/media/v4l2-core/v4l2-dev.c
> > > +++ b/drivers/media/v4l2-core/v4l2-dev.c
> > > @@ -156,6 +156,52 @@ void video_device_release_empty(struct video_device
> > > *vdev)> 
> > >  }
> > >  EXPORT_SYMBOL(video_device_release_empty);
> > > 
> > > +int video_device_enter(struct video_device *vdev)
> > > +{
> > > + bool unplugged;
> > > +
> > > + spin_lock(>unplug_lock);
> > > + unplugged = vdev->unplugged;
> > > + if (!unplugged)
> > > + vdev->access_refcount++;
> > > + spin_unlock(>unplug_lock);
> > > +
> > > + return unplugged ? -ENODEV : 0;
> > > +}
> > > +EXPORT_SYMBOL_GPL(video_device_enter);
> > > +
> > > +void video_device_exit(struct video_device *vdev)
> > > +{
> > > + bool wake_up;
> > > +
> > > + spin_lock(>unplug_lock);
> > > + WARN_ON(--vdev->access_refcount < 0);
> > > + wake_up = vdev->access_refcount == 0;
> > > + spin_unlock(>unplug_lock);
> > > +
> > > + if (wake_up)
> > > + wake_up(>unplug_wait);
> > > +}
> > > +EXPORT_SYMBOL_GPL(video_device_exit);
> > 
> > Is there a need to export the two, i.e. wouldn't you only call them from
> > the framework, or the same module?
> 
> There could be a need to call these functions from entry points that are not 
> controlled by the V4L2 core, such as sysfs or debugfs. We could keep the 
> functions internal for now and only export them when the need arises, but if 
> we want to document how drivers need to handle race conditions between device 
> access and device unbind, we need to have them exported.

Ack.

> 
> > > +
> > > +void video_device_unplug(struct video_device *vdev)
> > > +{
> > > + bool unplug_blocked;
> > > +
> > > + spin_lock(>unplug_lock);
> > > + unplug_blocked = vdev->access_refcount > 0;
> > > + vdev->unplugged = true;
> > 
> > Shouldn't this be set to false in video_register_device()?
> 
> Yes it should. I currently rely on the fact that the memory is zeroed when 
> allocated, but I shouldn't. I'll fix that.
> 
> > > + spin_unlock(>unplug_lock);
> > > +
> > > + if (!unplug_blocked)
> > > + return;
> > 
> > Not necessary, wait_event_timeout() handles this already.
> 
> I'll fix this as well.
> 
> > > +
> > > + if (!wait_event_timeout(vdev->unplug_wait, !vdev->access_refcount,
> > > + msecs_to_jiffies(15)))
> > > + WARN(1, "Timeout waiting for device access to complete\n");
> > 
> > Why a timeout? Does this get somehow less problematic over time? :-)
> 
> Not quite :-) This should never happen, but driver and/or core bugs could 
> cause a timeout. In that case I think proceeding after a timeout is a better 
> option than deadlocking forever.

This also depends on the frame rate; you could have a very low frame rate
configured on a sensor and the device could be actually in middle of a DMA
operation while the timeout is hit.

I'm not sure if there's a number that can be said to be safe here.

Wouldn't it be better to kill the user space process using the device
instead? Naturally the wait will have to be interruptible.

...

> > > @@ -221,6 +228,12 @@ struct video_device
> > > 
> > >   u32 device_caps;
> > > 
> > > + /* unplug handling */
> > > + bool unplugged;
> > > + int access_refcount;
> > 
> > Could you use refcount_t instead, to avoid integer overflow issues?
> 
> I'd love to, but refcount_t has no provision for refcounts that start at 0.
> 
> void refcount_inc(refcount_t *r)
> {
> WARN_ONCE(!refcount_inc_not_zero(r), "refcount_t: increment on 0; use-
> after-free.\n");
> }
> EXPORT_SYMBOL(refcount_inc);

Ah. I wonder if you could simply initialise in probe and decrement it again
in remove?

You could use refcount_inc_not_zero directly, too.

> 
> > > + spinlock_t unplug_lock;
> > > + wait_queue_head_t unplug_wait;
> > > +
> > >   /* sysfs */
> > >   struct device dev;
> > >   struct cdev *cdev;

-- 
Kind regards,

Sakari Ailus
sakari.ai...@linux.intel.com


Re: [GIT PULL FOR v4.16] media: imx: Add better OF graph support

2017-12-14 Thread Hans Verkuil
On 08/12/17 23:48, Steve Longerbeam wrote:
> 
> 
> On 12/08/2017 08:38 AM, Mauro Carvalho Chehab wrote:
>> Em Fri, 8 Dec 2017 11:56:58 +0100
>> Hans Verkuil  escreveu:
>>
>>> Note: the new v4l2-async work makes it possible to simplify this. That
>>> will be done in follow-up patches. It's easier to do that if this is in
>>> first.
>>>
>>> Regards,
>>>
>>> Hans
>>>
>>> The following changes since commit 781b045baefdabf7e0bc9f33672ca830d3db9f27:
>>>
>>>media: imx274: Fix error handling, add MAINTAINERS entry (2017-11-30 
>>> 04:45:12 -0500)
>>>
>>> are available in the git repository at:
>>>
>>>git://linuxtv.org/hverkuil/media_tree.git imx
>>>
>>> for you to fetch changes up to 82737cbb02f269b8eb608c7bd906a79072f6adad:
>>>
>>>media: staging/imx: update TODO (2017-12-04 14:05:19 +0100)
>>>
>>> 
>>> Steve Longerbeam (9):
>>>media: staging/imx: get CSI bus type from nearest upstream entity
>> There are some non-trivial conflicts on this patch.
>> Care to rebase it?
> 
> Attached is fixed-up version.

That still doesn't apply against the latest media_tree master.

Regards,

Hans


Re: [PATCH v2 08/26] media: v4l2-async: shut up an unitialized symbol warning

2017-12-14 Thread Sakari Ailus
Hi folks,

On Tue, Dec 12, 2017 at 12:13:59AM +0200, Laurent Pinchart wrote:
> Hi Mauro,
> 
> On Monday, 11 December 2017 20:10:58 EET Mauro Carvalho Chehab wrote:
> > Em Thu, 02 Nov 2017 04:51:40 +0200 Laurent Pinchart escreveu:
> > > On Wednesday, 1 November 2017 23:05:45 EET Mauro Carvalho Chehab wrote:
> > >> Smatch reports this warning:
> > >>  drivers/media/v4l2-core/v4l2-async.c:597 v4l2_async_register_subdev()
> > >> 
> > >> error: uninitialized symbol 'ret'.
> > >> 
> > >> However, there's nothing wrong there. So, just shut up the
> > >> warning.
> > > 
> > > Nothing wrong, really ? ret does seem to be used uninitialized when the
> > > function returns at the very last line.
> > 
> > There's nothing wrong. If you follow the logic, you'll see that
> > the line:
> > 
> > return ret;
> > 
> > is called only at "err_unbind" label, with is called only on
> > two places:
> > 
> > ret = v4l2_async_match_notify(notifier, v4l2_dev, sd, asd);
> > if (ret)
> > goto err_unbind;
> > 
> > ret = v4l2_async_notifier_try_complete(notifier);
> > if (ret)
> > goto err_unbind;
> > 
> > There, ret is defined.
> > 
> > Yeah, the logic there is confusing.
> 
> I had missed the return 0 just before the error label. Sorry for the noise.

I believe the matter has been addressed by this patch:

commit 580db6ca62c168733c6fd338cd2f0ebf39135283
Author: Colin Ian King 
Date:   Fri Nov 3 02:58:27 2017 -0400

media: v4l: async: fix return of unitialized variable ret

A shadow declaration of variable ret is being assigned a return error
status and this value is being lost when the error exit goto's jump
out of the local scope. This leads to an uninitalized error return value
in the outer scope being returned. Fix this by removing the inner scoped
declaration of variable ret.

Detected by CoverityScan, CID#1460380 ("Uninitialized scalar variable")

Fixes: fb45f436b818 ("media: v4l: async: Fix notifier complete callback 
error handling")

Signed-off-by: Colin Ian King 
Reviewed-by: Niklas Söderlund 
Signed-off-by: Sakari Ailus 
Signed-off-by: Mauro Carvalho Chehab 

-- 
Sakari Ailus
e-mail: sakari.ai...@iki.fi


Re: [PATCH 2/2] Added timers for dvb_ca_en50221_write_data

2017-12-14 Thread Mauro Carvalho Chehab
Em Sun, 17 Sep 2017 03:27:22 +0200
"Jasmin J."  escreveu:

> From: Jasmin Jessich 
> 
> Some (older) CAMs are really slow in accepting data. The CI interface
> specification doesn't define a handshake for accepted data. Thus, the
> en50221 protocol driver can't control if a data byte has been correctly
> written to the CAM.
> 
> The current implementation writes the length and the data quick after
> each other. Thus, the slow CAMs may generate a WR error, which leads to
> the known error logging
>"CAM tried to send a buffer larger than the ecount size".
> 
> To solve this issue the en50221 protocol driver needs to wait some CAM
> depending time between the different bytes to be written. Because the
> time is CAM dependent, an individual value per CAM needs to be set. For
> that SysFS is used in favor of ioctl's to allow the control of the timer
> values independent from any user space application.
> 
> This patch adds the timers and the SysFS nodes to set/get the timeout
> values and the timer waiting between the different steps of the CAM write
> access. A timer value of 0 (default) means "no timeout".

The patch series looks OK. However, I'm not seeing any documentation
patches explaining the new sysfs interface. I would be expecting an
update at linux DVB uAPI. Also, for all sysfs stuff, you need to add
it to Documentation/ABI/ using the format explained at its README.

Once you add it, I'll gladly apply it. Please add Ralph's ack on the
existing patches on your next submission.

Just a minor nitpick: on all patches, please prepend with "media: "
and the name of the part of the media subsystem that you're patching.

In this case, a good subject would be:

media: dvb-core: add timers for dvb_ca_en50221_write_data

Regards,
Mauro

> 
> Signed-off-by: Jasmin Jessich 
> ---
>  drivers/media/dvb-core/dvb_ca_en50221.c | 132 
> +++-
>  1 file changed, 131 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/media/dvb-core/dvb_ca_en50221.c 
> b/drivers/media/dvb-core/dvb_ca_en50221.c
> index 95b3723..50c4e45 100644
> --- a/drivers/media/dvb-core/dvb_ca_en50221.c
> +++ b/drivers/media/dvb-core/dvb_ca_en50221.c
> @@ -86,6 +86,13 @@ MODULE_PARM_DESC(cam_debug, "enable verbose debug 
> messages");
>  #define DVB_CA_SLOTSTATE_WAITFR 6
>  #define DVB_CA_SLOTSTATE_LINKINIT   7
>  
> +enum dvb_ca_timers {
> + DVB_CA_TIM_WR_HIGH  /* wait after writing length high */
> +,DVB_CA_TIM_WR_LOW   /* wait after writing length low */
> +,DVB_CA_TIM_WR_DATA  /* wait between data bytes */
> +,DVB_CA_TIM_MAX
> +};
> +
>  /* Information on a CA slot */
>  struct dvb_ca_slot {
>   /* current state of the CAM */
> @@ -119,6 +126,11 @@ struct dvb_ca_slot {
>   unsigned long timeout;
>  };
>  
> +struct dvb_ca_timer {
> + unsigned long min;
> + unsigned long max;
> +};
> +
>  /* Private CA-interface information */
>  struct dvb_ca_private {
>   struct kref refcount;
> @@ -161,6 +173,14 @@ struct dvb_ca_private {
>  
>   /* mutex serializing ioctls */
>   struct mutex ioctl_mutex;
> +
> + struct dvb_ca_timer timers[DVB_CA_TIM_MAX];
> +};
> +
> +static const char dvb_ca_tim_names[DVB_CA_TIM_MAX][15] = {
> + "tim_wr_high"
> +,"tim_wr_low"
> +,"tim_wr_data"
>  };
>  
>  static void dvb_ca_private_free(struct dvb_ca_private *ca)
> @@ -223,6 +243,14 @@ static char *findstr(char *haystack, int hlen, char 
> *needle, int nlen)
>   return NULL;
>  }
>  
> +static void dvb_ca_sleep(struct dvb_ca_private *ca, enum dvb_ca_timers tim)
> +{
> + unsigned long min = ca->timers[tim].min;
> +
> + if (min)
> + usleep_range(min, ca->timers[tim].max);
> +}
> +
>  /* 
> ** */
>  /* EN50221 physical interface functions */
>  
> @@ -868,10 +896,13 @@ static int dvb_ca_en50221_write_data(struct 
> dvb_ca_private *ca, int slot,
>   bytes_write >> 8);
>   if (status)
>   goto exit;
> + dvb_ca_sleep(ca, DVB_CA_TIM_WR_HIGH);
> +
>   status = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_SIZE_LOW,
>   bytes_write & 0xff);
>   if (status)
>   goto exit;
> + dvb_ca_sleep(ca, DVB_CA_TIM_WR_LOW);
>  
>   /* send the buffer */
>   for (i = 0; i < bytes_write; i++) {
> @@ -879,6 +910,7 @@ static int dvb_ca_en50221_write_data(struct 
> dvb_ca_private *ca, int slot,
>   buf[i]);
>   if (status)
>   goto exit;
> + dvb_ca_sleep(ca, DVB_CA_TIM_WR_DATA);
>   }
>  
>   /* check for write error (WE should now be 0) */
> @@ -1832,6 +1864,97 @@ static const struct dvb_device dvbdev_ca = {
>  };
>  
>  /* 
> ** */
> +/* EN50221 

  1   2   >