cron job: media_tree daily build: OK

2016-05-24 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:   Wed May 25 04:00:25 CEST 2016
git branch: test
git hash:   bc2b80ee3490651904f121eac1c8fb7652d48253
gcc version:i686-linux-gcc (GCC) 5.3.0
sparse version: v0.5.0-56-g7647c77
smatch version: v0.5.0-3428-gdfe27cf
host hardware:  x86_64
host os:4.5.0-264

linux-git-arm-at91: OK
linux-git-arm-davinci: OK
linux-git-arm-exynos: OK
linux-git-arm-mx: OK
linux-git-arm-omap: OK
linux-git-arm-omap1: OK
linux-git-arm-pxa: 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: OK
linux-git-x86_64: OK
linux-2.6.36.4-i686: OK
linux-2.6.37.6-i686: OK
linux-2.6.38.8-i686: OK
linux-2.6.39.4-i686: OK
linux-3.0.60-i686: OK
linux-3.1.10-i686: OK
linux-3.2.37-i686: OK
linux-3.3.8-i686: OK
linux-3.4.27-i686: OK
linux-3.5.7-i686: OK
linux-3.6.11-i686: OK
linux-3.7.4-i686: OK
linux-3.8-i686: OK
linux-3.9.2-i686: OK
linux-3.10.1-i686: OK
linux-3.11.1-i686: OK
linux-3.12.23-i686: OK
linux-3.13.11-i686: OK
linux-3.14.9-i686: OK
linux-3.15.2-i686: OK
linux-3.16.7-i686: OK
linux-3.17.8-i686: OK
linux-3.18.7-i686: OK
linux-3.19-i686: OK
linux-4.0-i686: OK
linux-4.1.1-i686: OK
linux-4.2-i686: OK
linux-4.3-i686: OK
linux-4.4-i686: OK
linux-4.5-i686: OK
linux-4.6-i686: OK
linux-2.6.36.4-x86_64: OK
linux-2.6.37.6-x86_64: OK
linux-2.6.38.8-x86_64: OK
linux-2.6.39.4-x86_64: OK
linux-3.0.60-x86_64: OK
linux-3.1.10-x86_64: OK
linux-3.2.37-x86_64: OK
linux-3.3.8-x86_64: OK
linux-3.4.27-x86_64: OK
linux-3.5.7-x86_64: OK
linux-3.6.11-x86_64: OK
linux-3.7.4-x86_64: OK
linux-3.8-x86_64: OK
linux-3.9.2-x86_64: OK
linux-3.10.1-x86_64: OK
linux-3.11.1-x86_64: OK
linux-3.12.23-x86_64: OK
linux-3.13.11-x86_64: OK
linux-3.14.9-x86_64: OK
linux-3.15.2-x86_64: OK
linux-3.16.7-x86_64: OK
linux-3.17.8-x86_64: OK
linux-3.18.7-x86_64: OK
linux-3.19-x86_64: OK
linux-4.0-x86_64: OK
linux-4.1.1-x86_64: OK
linux-4.2-x86_64: OK
linux-4.3-x86_64: OK
linux-4.4-x86_64: OK
linux-4.5-x86_64: OK
linux-4.6-x86_64: OK
apps: OK
spec-git: OK
sparse: WARNINGS
smatch: WARNINGS

Detailed results are available here:

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

Full logs are available here:

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

The Media Infrastructure API from this daily build is here:

http://www.xs4all.nl/~hverkuil/spec/media.html
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v3] [media] vimc: Virtual Media Controller core, capture and sensor

2016-05-24 Thread Helen Koike

Hi Jeremy,

On 24-05-2016 21:00, Jeremy Gebben wrote:

Helen,

I am more of a v4l2 newb than a reviewer, but I got your driver working
on a qemu arm64 system. Using it to play with mediactl -p was
a good way to get started.

I did have 2 minor include path problems. Maybe they come in implicitly
on other architectures? See below:

On 4/27/16 10:33 AM, Helen Fornazier wrote:




diff --git a/drivers/media/platform/vimc/vimc-core.h
b/drivers/media/platform/vimc/vimc-core.h
new file mode 100644
index 000..be05469
--- /dev/null
+++ b/drivers/media/platform/vimc/vimc-core.h
@@ -0,0 +1,55 @@
+/*
+ * vimc-core.h Virtual Media Controller Driver
+ *
+ * Copyright (C) 2015 Helen Fornazier 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.
+ *
+ */
+
+#ifndef _VIMC_CORE_H_
+#define _VIMC_CORE_H_
+
+#include 
+
+/* Struct which matches the MEDIA_BUS_FMT_ codes with the corresponding
+ * V4L2_PIX_FMT_ fourcc pixelformat and its bytes per pixel (bpp) */
+struct vimc_pix_map {
+   unsigned int code;
+   unsigned int bpp;
+   u32 pixelformat;
+};
+extern const struct vimc_pix_map vimc_pix_map_list[];
+
+struct vimc_ent_device {
+   struct media_entity *ent;
+   struct media_pad *pads;
+   void (*destroy)(struct vimc_ent_device *);
+   void (*process_frame)(struct vimc_ent_device *ved,
+ struct media_pad *sink, const void
*frame);
+};
+
+int vimc_propagate_frame(struct device *dev,
+struct media_pad *src, const void *frame);
+
+/* Helper functions to allocate/initialize pads and free them */
+struct media_pad *vimc_pads_init(u16 num_pads,
+const unsigned long *pads_flag);
+static inline void vimc_pads_cleanup(struct media_pad *pads)
+{
+   kfree(pads);


I needed  to be included in this file, so that kfree() was
defined.




+}
+
+const struct vimc_pix_map *vimc_pix_map_by_code(u32 code);
+
+const struct vimc_pix_map *vimc_pix_map_by_pixelformat(u32
pixelformat);
+
+#endif
diff --git a/drivers/media/platform/vimc/vimc-sensor.c
b/drivers/media/platform/vimc/vimc-sensor.c
new file mode 100644
index 000..ae70b9e
--- /dev/null
+++ b/drivers/media/platform/vimc/vimc-sensor.c
@@ -0,0 +1,277 @@
+/*
+ * vimc-sensor.c Virtual Media Controller Driver
+ *
+ * Copyright (C) 2015 Helen Fornazier 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 "vimc-sensor.h"
+
+struct vimc_sen_device {
+   struct vimc_ent_device ved;
+   struct v4l2_subdev sd;
+   struct v4l2_device *v4l2_dev;
+   struct device *dev;
+   struct task_struct *kthread_sen;
+   u8 *frame;
+   /* The active format */
+   struct v4l2_mbus_framefmt mbus_format;
+   int frame_size;
+};
+
+static int vimc_sen_enum_mbus_code(struct v4l2_subdev *sd,
+  struct v4l2_subdev_pad_config *cfg,
+  struct v4l2_subdev_mbus_code_enum
*code)
+{
+   struct vimc_sen_device *vsen = v4l2_get_subdevdata(sd);
+
+   /* Check if it is a valid pad */
+   if (code->pad >= vsen->sd.entity.num_pads)
+   return -EINVAL;
+
+   code->code = vsen->mbus_format.code;
+
+   return 0;
+}
+
+static int vimc_sen_enum_frame_size(struct v4l2_subdev *sd,
+   struct v4l2_subdev_pad_config *cfg,
+   struct
v4l2_subdev_frame_size_enum *fse)
+{
+   struct vimc_sen_device *vsen = v4l2_get_subdevdata(sd);
+
+   /* Check if it is a valid pad */
+   if (fse->pad >= vsen->sd.entity.num_pads ||
+   !(vsen->sd.entity.pads[fse->pad].flags &
MEDIA_PAD_FL_SOURCE))
+   return -EINVAL;
+
+   /* TODO: Add support to other formats */
+   if (fse->index)
+   return -EINVAL;
+
+   /* TODO: Add support for other codes */
+   if (fse->code != vsen->mbus_format.code)
+   return -EINVAL;
+
+   fse->min_width = 

Re: [PATCH v3] [media] vimc: Virtual Media Controller core, capture and sensor

2016-05-24 Thread Jeremy Gebben

Helen,

I am more of a v4l2 newb than a reviewer, but I got your driver working 
on a qemu arm64 system. Using it to play with mediactl -p was

a good way to get started.

I did have 2 minor include path problems. Maybe they come in implicitly 
on other architectures? See below:


On 4/27/16 10:33 AM, Helen Fornazier wrote:




diff --git a/drivers/media/platform/vimc/vimc-core.h 
b/drivers/media/platform/vimc/vimc-core.h
new file mode 100644
index 000..be05469
--- /dev/null
+++ b/drivers/media/platform/vimc/vimc-core.h
@@ -0,0 +1,55 @@
+/*
+ * vimc-core.h Virtual Media Controller Driver
+ *
+ * Copyright (C) 2015 Helen Fornazier 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.
+ *
+ */
+
+#ifndef _VIMC_CORE_H_
+#define _VIMC_CORE_H_
+
+#include 
+
+/* Struct which matches the MEDIA_BUS_FMT_ codes with the corresponding
+ * V4L2_PIX_FMT_ fourcc pixelformat and its bytes per pixel (bpp) */
+struct vimc_pix_map {
+   unsigned int code;
+   unsigned int bpp;
+   u32 pixelformat;
+};
+extern const struct vimc_pix_map vimc_pix_map_list[];
+
+struct vimc_ent_device {
+   struct media_entity *ent;
+   struct media_pad *pads;
+   void (*destroy)(struct vimc_ent_device *);
+   void (*process_frame)(struct vimc_ent_device *ved,
+ struct media_pad *sink, const void *frame);
+};
+
+int vimc_propagate_frame(struct device *dev,
+struct media_pad *src, const void *frame);
+
+/* Helper functions to allocate/initialize pads and free them */
+struct media_pad *vimc_pads_init(u16 num_pads,
+const unsigned long *pads_flag);
+static inline void vimc_pads_cleanup(struct media_pad *pads)
+{
+   kfree(pads);


I needed  to be included in this file, so that kfree() was 
defined.





+}
+
+const struct vimc_pix_map *vimc_pix_map_by_code(u32 code);
+
+const struct vimc_pix_map *vimc_pix_map_by_pixelformat(u32 pixelformat);
+
+#endif
diff --git a/drivers/media/platform/vimc/vimc-sensor.c 
b/drivers/media/platform/vimc/vimc-sensor.c
new file mode 100644
index 000..ae70b9e
--- /dev/null
+++ b/drivers/media/platform/vimc/vimc-sensor.c
@@ -0,0 +1,277 @@
+/*
+ * vimc-sensor.c Virtual Media Controller Driver
+ *
+ * Copyright (C) 2015 Helen Fornazier 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 "vimc-sensor.h"
+
+struct vimc_sen_device {
+   struct vimc_ent_device ved;
+   struct v4l2_subdev sd;
+   struct v4l2_device *v4l2_dev;
+   struct device *dev;
+   struct task_struct *kthread_sen;
+   u8 *frame;
+   /* The active format */
+   struct v4l2_mbus_framefmt mbus_format;
+   int frame_size;
+};
+
+static int vimc_sen_enum_mbus_code(struct v4l2_subdev *sd,
+  struct v4l2_subdev_pad_config *cfg,
+  struct v4l2_subdev_mbus_code_enum *code)
+{
+   struct vimc_sen_device *vsen = v4l2_get_subdevdata(sd);
+
+   /* Check if it is a valid pad */
+   if (code->pad >= vsen->sd.entity.num_pads)
+   return -EINVAL;
+
+   code->code = vsen->mbus_format.code;
+
+   return 0;
+}
+
+static int vimc_sen_enum_frame_size(struct v4l2_subdev *sd,
+   struct v4l2_subdev_pad_config *cfg,
+   struct v4l2_subdev_frame_size_enum *fse)
+{
+   struct vimc_sen_device *vsen = v4l2_get_subdevdata(sd);
+
+   /* Check if it is a valid pad */
+   if (fse->pad >= vsen->sd.entity.num_pads ||
+   !(vsen->sd.entity.pads[fse->pad].flags & MEDIA_PAD_FL_SOURCE))
+   return -EINVAL;
+
+   /* TODO: Add support to other formats */
+   if (fse->index)
+   return -EINVAL;
+
+   /* TODO: Add support for other codes */
+   if (fse->code != vsen->mbus_format.code)
+   return -EINVAL;
+
+   fse->min_width = vsen->mbus_format.width;
+   fse->max_width = 

[PATCH v2 0/2] Media Device Allocator API

2016-05-24 Thread Shuah Khan
Media Device Allocator API to allows multiple drivers share a media device.
Using this API, drivers can allocate a media device with the shared struct
device as the key. Once the media device is allocated by a driver, other
drivers can get a reference to it. The media device is released when all
the references are released.

This patch series has been tested with au0828 and snd-usb-audio drivers.
snd-us-audio patch isn't included in this series. Once this patch series
is reviews and gets a stable state, I will send out the snd-usb-audio
patch.

Changes since Patch v1 series: (based on Hans Virkuil's review)
- Removed media_device_get() and media_device_allocate(). These are
  unnecessary.
- media_device_usb_allocate() holds media_device_lock to do allocate
  and initialize the media device.
- Changed media_device_put() to media_device_delete() for symmetry with
  media_device_*_allocate().
- Dropped media_device_unregister_put(). au0828 calls media_device_delete()
  instead.

Shuah Khan (2):
  media: Media Device Allocator API
  media: change au0828 to use Media Device Allocator API

 drivers/media/Makefile |   3 +-
 drivers/media/media-dev-allocator.c| 120 +
 drivers/media/usb/au0828/au0828-core.c |  12 ++--
 drivers/media/usb/au0828/au0828.h  |   1 +
 include/media/media-dev-allocator.h|  85 +++
 5 files changed, 212 insertions(+), 9 deletions(-)
 create mode 100644 drivers/media/media-dev-allocator.c
 create mode 100644 include/media/media-dev-allocator.h

-- 
2.7.4

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 2/2] media: change au0828 to use Media Device Allocator API

2016-05-24 Thread Shuah Khan
Change au0828 to use Media Device Allocator API to allocate media device
with the parent usb struct device as the key, so it can be shared with the
snd usb audio driver.

Signed-off-by: Shuah Khan 
---
 drivers/media/usb/au0828/au0828-core.c | 12 
 drivers/media/usb/au0828/au0828.h  |  1 +
 2 files changed, 5 insertions(+), 8 deletions(-)

diff --git a/drivers/media/usb/au0828/au0828-core.c 
b/drivers/media/usb/au0828/au0828-core.c
index bf53553..fc5f122 100644
--- a/drivers/media/usb/au0828/au0828-core.c
+++ b/drivers/media/usb/au0828/au0828-core.c
@@ -157,9 +157,7 @@ static void au0828_unregister_media_device(struct 
au0828_dev *dev)
dev->media_dev->enable_source = NULL;
dev->media_dev->disable_source = NULL;
 
-   media_device_unregister(dev->media_dev);
-   media_device_cleanup(dev->media_dev);
-   kfree(dev->media_dev);
+   media_device_delete(dev->media_dev);
dev->media_dev = NULL;
 #endif
 }
@@ -212,14 +210,10 @@ static int au0828_media_device_init(struct au0828_dev 
*dev,
 #ifdef CONFIG_MEDIA_CONTROLLER
struct media_device *mdev;
 
-   mdev = kzalloc(sizeof(*mdev), GFP_KERNEL);
+   mdev = media_device_usb_allocate(udev, KBUILD_MODNAME);
if (!mdev)
return -ENOMEM;
 
-   /* check if media device is already initialized */
-   if (!mdev->dev)
-   media_device_usb_init(mdev, udev, udev->product);
-
dev->media_dev = mdev;
 #endif
return 0;
@@ -487,6 +481,8 @@ static int au0828_media_device_register(struct au0828_dev 
*dev,
/* register media device */
ret = media_device_register(dev->media_dev);
if (ret) {
+   media_device_delete(dev->media_dev);
+   dev->media_dev = NULL;
dev_err(>dev,
"Media Device Register Error: %d\n", ret);
return ret;
diff --git a/drivers/media/usb/au0828/au0828.h 
b/drivers/media/usb/au0828/au0828.h
index dd7b378..4bf1b0c 100644
--- a/drivers/media/usb/au0828/au0828.h
+++ b/drivers/media/usb/au0828/au0828.h
@@ -35,6 +35,7 @@
 #include 
 #include 
 #include 
+#include 
 
 /* DVB */
 #include "demux.h"
-- 
2.7.4

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 1/2] media: Media Device Allocator API

2016-05-24 Thread Shuah Khan
Media Device Allocator API to allows multiple drivers share a media device.
Using this API, drivers can allocate a media device with the shared struct
device as the key. Once the media device is allocated by a driver, other
drivers can get a reference to it. The media device is released when all
the references are released.

Signed-off-by: Shuah Khan 
---
 drivers/media/Makefile  |   3 +-
 drivers/media/media-dev-allocator.c | 120 
 include/media/media-dev-allocator.h |  85 +
 3 files changed, 207 insertions(+), 1 deletion(-)
 create mode 100644 drivers/media/media-dev-allocator.c
 create mode 100644 include/media/media-dev-allocator.h

diff --git a/drivers/media/Makefile b/drivers/media/Makefile
index e608bbc..b08f091 100644
--- a/drivers/media/Makefile
+++ b/drivers/media/Makefile
@@ -2,7 +2,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-dev-allocator.o
 
 #
 # I2C drivers should come before other drivers, otherwise they'll fail
diff --git a/drivers/media/media-dev-allocator.c 
b/drivers/media/media-dev-allocator.c
new file mode 100644
index 000..b8c9811
--- /dev/null
+++ b/drivers/media/media-dev-allocator.c
@@ -0,0 +1,120 @@
+/*
+ * media-dev-allocator.c - Media Controller Device Allocator API
+ *
+ * Copyright (c) 2016 Shuah Khan 
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * This file is released under the GPLv2.
+ * Credits: Suggested by Laurent Pinchart 
+ */
+
+/*
+ * This file adds a global refcounted Media Controller Device Instance API.
+ * A system wide global media device list is managed and each media device
+ * includes a kref count. The last put on the media device releases the media
+ * device instance.
+ *
+*/
+
+#include 
+#include 
+#include 
+#include 
+
+static LIST_HEAD(media_device_list);
+static DEFINE_MUTEX(media_device_lock);
+
+struct media_device_instance {
+   struct media_device mdev;
+   struct list_head list;
+   struct device *dev;
+   struct kref refcount;
+};
+
+static inline struct media_device_instance *
+to_media_device_instance(struct media_device *mdev)
+{
+   return container_of(mdev, struct media_device_instance, mdev);
+}
+
+static void media_device_instance_release(struct kref *kref)
+{
+   struct media_device_instance *mdi =
+   container_of(kref, struct media_device_instance, refcount);
+
+   dev_dbg(mdi->mdev.dev, "%s: mdev=%p\n", __func__, >mdev);
+
+   mutex_lock(_device_lock);
+
+   media_device_unregister(>mdev);
+   media_device_cleanup(>mdev);
+
+   list_del(>list);
+   mutex_unlock(_device_lock);
+
+   kfree(mdi);
+}
+
+static struct media_device *__media_device_get(struct device *dev,
+  bool allocate)
+{
+   struct media_device_instance *mdi;
+
+   list_for_each_entry(mdi, _device_list, list) {
+   if (mdi->dev == dev) {
+   kref_get(>refcount);
+   dev_dbg(dev, "%s: get mdev=%p\n",
+__func__, >mdev);
+   goto done;
+   }
+   }
+
+   if (!allocate) {
+   mdi = NULL;
+   goto done;
+   }
+
+   mdi = kzalloc(sizeof(*mdi), GFP_KERNEL);
+   if (!mdi)
+   goto done;
+
+   mdi->dev = dev;
+   kref_init(>refcount);
+   list_add_tail(>list, _device_list);
+
+   dev_dbg(dev, "%s: alloc mdev=%p\n", __func__, >mdev);
+done:
+   return mdi ? >mdev : NULL;
+}
+
+struct media_device *media_device_usb_allocate(struct usb_device *udev,
+  char *driver_name)
+{
+   struct media_device *mdev;
+
+   mutex_lock(_device_lock);
+   mdev = __media_device_get(>dev, true);
+   if (!mdev) {
+   mutex_unlock(_device_lock);
+   return ERR_PTR(-ENOMEM);
+   }
+
+   /* check if media device is already initialized */
+   if (!mdev->dev)
+   __media_device_usb_init(mdev, udev, udev->product,
+   driver_name);
+   mutex_unlock(_device_lock);
+
+   dev_dbg(>dev, "%s\n", __func__);
+   return mdev;
+}
+EXPORT_SYMBOL_GPL(media_device_usb_allocate);
+
+void media_device_delete(struct media_device *mdev)
+{
+   struct media_device_instance *mdi = to_media_device_instance(mdev);
+
+   dev_dbg(mdi->mdev.dev, "%s: mdev=%p\n", __func__, >mdev);
+   kref_put(>refcount, media_device_instance_release);
+}
+EXPORT_SYMBOL_GPL(media_device_delete);
diff --git a/include/media/media-dev-allocator.h 
b/include/media/media-dev-allocator.h
new file mode 100644
index 000..fda032b
--- 

Re: [v4l-utils PATCH v1.1 2/2] mediactl: Separate entity and pad parsing

2016-05-24 Thread Laurent Pinchart
Hi Sakari,

Thank you for the patch.

On Tuesday 24 May 2016 23:56:33 Sakari Ailus wrote:
> Sometimes it's useful to be able to parse the entity independent of the pad.
> Separate entity parsing into media_parse_entity().
> 
> Signed-off-by: Sakari Ailus 

Acked-by: Laurent Pinchart 

> ---
>  utils/media-ctl/libmediactl.c | 29 +
>  utils/media-ctl/mediactl.h| 14 ++
>  2 files changed, 39 insertions(+), 4 deletions(-)
> 
> diff --git a/utils/media-ctl/libmediactl.c b/utils/media-ctl/libmediactl.c
> index 78caa7c..498dfd1 100644
> --- a/utils/media-ctl/libmediactl.c
> +++ b/utils/media-ctl/libmediactl.c
> @@ -781,10 +781,10 @@ int media_device_add_entity(struct media_device
> *media, return 0;
>  }
> 
> -struct media_pad *media_parse_pad(struct media_device *media,
> -   const char *p, char **endp)
> +struct media_entity *media_parse_entity(struct media_device *media,
> + const char *p, char **endp)
>  {
> - unsigned int entity_id, pad;
> + unsigned int entity_id;
>   struct media_entity *entity;
>   char *end;
> 
> @@ -827,7 +827,28 @@ struct media_pad *media_parse_pad(struct media_device
> *media, return NULL;
>   }
>   }
> - for (; isspace(*end); ++end);
> + for (p = end; isspace(*p); ++p);
> +
> + *endp = (char *)p;
> +
> + return entity;
> +}
> +
> +struct media_pad *media_parse_pad(struct media_device *media,
> +   const char *p, char **endp)
> +{
> + unsigned int pad;
> + struct media_entity *entity;
> + char *end;
> +
> + if (endp == NULL)
> + endp = 
> +
> + entity = media_parse_entity(media, p, );
> + if (!entity) {
> + *endp = end;
> + return NULL;
> + }
> 
>   if (*end != ':') {
>   media_dbg(media, "Expected ':'\n", *end);
> diff --git a/utils/media-ctl/mediactl.h b/utils/media-ctl/mediactl.h
> index b5a92f5..af36051 100644
> --- a/utils/media-ctl/mediactl.h
> +++ b/utils/media-ctl/mediactl.h
> @@ -367,6 +367,20 @@ int media_setup_link(struct media_device *media,
>  int media_reset_links(struct media_device *media);
> 
>  /**
> + * @brief Parse string to an entity on the media device.
> + * @param media - media device.
> + * @param p - input string
> + * @param endp - pointer to string where parsing ended
> + *
> + * Parse NULL terminated string describing an entity and return its
> + * struct media_entity instance.
> + *
> + * @return Pointer to struct media_entity on success, NULL on failure.
> + */
> +struct media_entity *media_parse_entity(struct media_device *media,
> + const char *p, char **endp);
> +
> +/**
>   * @brief Parse string to a pad on the media device.
>   * @param media - media device.
>   * @param p - input string

-- 
Regards,

Laurent Pinchart

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


RFC: HSV format

2016-05-24 Thread Ricardo Ribalda Delgado
Hi

HSV is a  cylindrical-coordinate representation of a color. It is very
useful for computer vision because the Hue component can be used to
segment a scene.

My plan was to add a format in videodev2.h and then add support for
vivid, libv4l2-convert and qv4l2.

There are also plans to prepare a patch for opencv to use this format
without any software conversion, and also for Gstreamer... but all
these changes depend on the changes on videodev2.h

The question is how open would be the linux-media community for such a
change, considering that there is no real device driver using it in
tree ( Our hardware is currently out of tree_

Today we only have an HSV format on v4l2-mediabus.h
V4L2_MBUS_FROM_MEDIA_BUS_FMT(AHSV_1X32), but no HSV format on
videodev2.h


Thanks!!!



-- 
Ricardo Ribalda
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[v4l-utils PATCH v1.1 2/2] mediactl: Separate entity and pad parsing

2016-05-24 Thread Sakari Ailus
Sometimes it's useful to be able to parse the entity independent of the pad.
Separate entity parsing into media_parse_entity().

Signed-off-by: Sakari Ailus 
---
 utils/media-ctl/libmediactl.c | 29 +
 utils/media-ctl/mediactl.h| 14 ++
 2 files changed, 39 insertions(+), 4 deletions(-)

diff --git a/utils/media-ctl/libmediactl.c b/utils/media-ctl/libmediactl.c
index 78caa7c..498dfd1 100644
--- a/utils/media-ctl/libmediactl.c
+++ b/utils/media-ctl/libmediactl.c
@@ -781,10 +781,10 @@ int media_device_add_entity(struct media_device *media,
return 0;
 }
 
-struct media_pad *media_parse_pad(struct media_device *media,
- const char *p, char **endp)
+struct media_entity *media_parse_entity(struct media_device *media,
+   const char *p, char **endp)
 {
-   unsigned int entity_id, pad;
+   unsigned int entity_id;
struct media_entity *entity;
char *end;
 
@@ -827,7 +827,28 @@ struct media_pad *media_parse_pad(struct media_device 
*media,
return NULL;
}
}
-   for (; isspace(*end); ++end);
+   for (p = end; isspace(*p); ++p);
+
+   *endp = (char *)p;
+
+   return entity;
+}
+
+struct media_pad *media_parse_pad(struct media_device *media,
+ const char *p, char **endp)
+{
+   unsigned int pad;
+   struct media_entity *entity;
+   char *end;
+
+   if (endp == NULL)
+   endp = 
+
+   entity = media_parse_entity(media, p, );
+   if (!entity) {
+   *endp = end;
+   return NULL;
+   }
 
if (*end != ':') {
media_dbg(media, "Expected ':'\n", *end);
diff --git a/utils/media-ctl/mediactl.h b/utils/media-ctl/mediactl.h
index b5a92f5..af36051 100644
--- a/utils/media-ctl/mediactl.h
+++ b/utils/media-ctl/mediactl.h
@@ -367,6 +367,20 @@ int media_setup_link(struct media_device *media,
 int media_reset_links(struct media_device *media);
 
 /**
+ * @brief Parse string to an entity on the media device.
+ * @param media - media device.
+ * @param p - input string
+ * @param endp - pointer to string where parsing ended
+ *
+ * Parse NULL terminated string describing an entity and return its
+ * struct media_entity instance.
+ *
+ * @return Pointer to struct media_entity on success, NULL on failure.
+ */
+struct media_entity *media_parse_entity(struct media_device *media,
+   const char *p, char **endp);
+
+/**
  * @brief Parse string to a pad on the media device.
  * @param media - media device.
  * @param p - input string
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [v4l-utils PATCH 2/2] mediactl: Separate entity and pad parsing

2016-05-24 Thread Sakari Ailus
Hi Laurent,

On Tue, May 24, 2016 at 08:14:22PM +0300, Laurent Pinchart wrote:
...
> > +struct media_pad *media_parse_pad(struct media_device *media,
> > + const char *p, char **endp)
> > +{
> > +   unsigned int pad;
> > +   struct media_entity *entity;
> > +   char *end;
> > +
> > +   if (endp == NULL)
> > +   endp = 
> > +
> > +   entity = media_parse_entity(media, p, );
> > +   if (!entity)
> > +   return NULL;
> > +   *endp = end;
> 
> Did you mean
> 
>   if (!entity) {
>   *endp = end;
>   return NULL;
>   }
> 
> ? There's no need to assign endp after the check as all return paths below 
> assign it correctly, but it should be set when returning an error here.

Good catch! Yeah, it's a bug, I'll fix that.

-- 
Cheers,

Sakari Ailus
e-mail: sakari.ai...@iki.fi XMPP: sai...@retiisi.org.uk
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [v4l-utils PATCH 1/2] libmediactl: Drop length argument from media_get_entity_by_name()

2016-05-24 Thread Sakari Ailus
Hi Laurent,

Thanks for the review!

On Tue, May 24, 2016 at 08:09:37PM +0300, Laurent Pinchart wrote:
...
> > +   if (strcmp(entity->info.name, name) == 0)
> 
> While the kernel API guarantees that entity->info.name will be NULL-
> terminated, wouldn't it be safer to add a safety check here ?

The kernel implementation in media-device.c does use strlcpy() so this is
even not about drivers doing this right. If you insist, I'll change it. :-)

-- 
Cheers,

Sakari Ailus
e-mail: sakari.ai...@iki.fi XMPP: sai...@retiisi.org.uk
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCHv3] support for AD5820 camera auto-focus coil

2016-05-24 Thread Pavel Machek
Hi!

> >>devm_regulator_get()?
> >
> >I'd rather avoid devm_ here. Driver is simple enough to allow it.
> >
> 
> Now thinking about it, what would happen here if regulator_get() returns
> -EPROBE_DEFER? Wouldn't it be better to move regulator_get to the probe()
> function, something like:

Ok, I can do it.

Oh, and don't try to complain about newlines before returns. It looks
better this way.

> static int ad5820_probe(struct i2c_client *client,
>   const struct i2c_device_id *devid)
> {
>   struct ad5820_device *coil;
>   int ret = 0;
> 
>   coil = devm_kzalloc(sizeof(*coil), GFP_KERNEL);
>   if (coil == NULL)
>   return -ENOMEM;
> 
>   coil->vana = devm_regulator_get(>dev, NULL);
>   if (IS_ERR(coil->vana)) {
>   ret = PTR_ERR(coil->vana);
>   if (ret != -EPROBE_DEFER)
>   dev_err(>dev, "could not get regulator for 
> vana\n");
>   return ret;
>   }
> 
>   mutex_init(>power_lock);
> ...
> 
> with the appropriate changes to remove() because of the devm API
>   usage.

Something like this?

diff --git a/drivers/media/i2c/ad5820.c b/drivers/media/i2c/ad5820.c
index f956bd3..f871366 100644
--- a/drivers/media/i2c/ad5820.c
+++ b/drivers/media/i2c/ad5820.c
@@ -8,7 +8,7 @@
  * Copyright (C) 2016 Pavel Machek 
  *
  * Contact: Tuukka Toivonen
- *  Sakari Ailus
+ * Sakari Ailus
  *
  * Based on af_d88.c by Texas Instruments.
  *
@@ -263,13 +263,6 @@ static int ad5820_init_controls(struct ad5820_device *coil)
 static int ad5820_registered(struct v4l2_subdev *subdev)
 {
struct ad5820_device *coil = to_ad5820_device(subdev);
-   struct i2c_client *client = v4l2_get_subdevdata(subdev);
-
-   coil->vana = regulator_get(>dev, "VANA");
-   if (IS_ERR(coil->vana)) {
-   dev_err(>dev, "could not get regulator for vana\n");
-   return -ENODEV;
-   }
 
return ad5820_init_controls(coil);
 }
@@ -367,10 +360,18 @@ static int ad5820_probe(struct i2c_client *client,
struct ad5820_device *coil;
int ret = 0;
 
-   coil = kzalloc(sizeof(*coil), GFP_KERNEL);
+   coil = devm_kzalloc(sizeof(*coil), GFP_KERNEL);
if (!coil)
return -ENOMEM;
 
+   coil->vana = devm_regulator_get(>dev, NULL);
+   if (IS_ERR(coil->vana)) {
+   ret = PTR_ERR(coil->vana);
+   if (ret != -EPROBE_DEFER)
+   dev_err(>dev, "could not get regulator for 
vana\n");
+   return ret;
+   }
+   
mutex_init(>power_lock);
 
v4l2_i2c_subdev_init(>subdev, client, _ops);
@@ -390,10 +391,6 @@ static int ad5820_probe(struct i2c_client *client,
 
 cleanup:
media_entity_cleanup(>subdev.entity);
-
-free:
-   kfree(coil);
-
return ret;
 }
 
@@ -405,11 +402,6 @@ static int __exit ad5820_remove(struct i2c_client *client)
v4l2_device_unregister_subdev(>subdev);
v4l2_ctrl_handler_free(>ctrls);
media_entity_cleanup(>subdev.entity);
-   if (coil->vana)
-   regulator_put(coil->vana);
-
-   kfree(coil);
-
return 0;
 }
 


-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) 
http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC 0/2] Add support for OV5647 sensor

2016-05-24 Thread roliveir
Hello,

This RFC patch adds support for the Omnivision OV5647 sensor.

At the moment it only supports 640x480 in Raw 8.

Ramiro Oliveira (2):
  Add OV5647 device tree documentation
  Add support for Omnivision OV5647

 .../devicetree/bindings/media/i2c/ov5647.txt   |  29 +
 MAINTAINERS|   7 +
 drivers/media/i2c/Kconfig  |  11 +
 drivers/media/i2c/Makefile |   1 +
 drivers/media/i2c/ov5647.c | 891 +
 5 files changed, 939 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/media/i2c/ov5647.txt
 create mode 100644 drivers/media/i2c/ov5647.c

-- 
2.8.1


--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC 1/2] Add OV5647 device tree documentation

2016-05-24 Thread roliveir
Signed-off-by: roliveir 
---
 .../devicetree/bindings/media/i2c/ov5647.txt   | 29 ++
 1 file changed, 29 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/media/i2c/ov5647.txt

diff --git a/Documentation/devicetree/bindings/media/i2c/ov5647.txt 
b/Documentation/devicetree/bindings/media/i2c/ov5647.txt
new file mode 100644
index 000..fa6b09c
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/i2c/ov5647.txt
@@ -0,0 +1,29 @@
+Omnivision OV5657 raw image sensor
+-
+
+OV5657 is a raw image sensor with MIPI CSI-2 and CCP2 image data interfaces
+and CCI (I2C compatible) control bus.
+
+Required properties:
+
+- compatible   : "ov5647";
+- reg  : I2C slave address of the sensor;
+- clocks   : should contain list of phandle and clock specifier pairs
+ according to common clock bindings for the clocks described
+ in the clock-names property;
+- clock-names  : should contain "extclk" entry for the sensor's EXTCLK clock;
+
+Optional properties:
+
+- clock-frequency : the frequency at which the "extclk" clock should be
+   configured to operate, in Hz; if this property is not
+   specified default 27 MHz value will be used.
+
+The common video interfaces bindings (see video-interfaces.txt) should be
+used to specify link to the image data receiver. The OV5657 device
+node should contain one 'port' child node with an 'endpoint' subnode.
+
+Following properties are valid for the endpoint node:
+
+- data-lanes : (optional) specifies MIPI CSI-2 data lanes as covered in
+  video-interfaces.txt.  The sensor supports only two data lanes.
-- 
2.8.1


--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC 2/2] Add support for Omnivision OV5647

2016-05-24 Thread roliveir
Signed-off-by: roliveir 
---
 MAINTAINERS|   7 +
 drivers/media/i2c/Kconfig  |  11 +
 drivers/media/i2c/Makefile |   1 +
 drivers/media/i2c/ov5647.c | 891 +
 4 files changed, 910 insertions(+)
 create mode 100644 drivers/media/i2c/ov5647.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 81d940b..06697fc 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8106,6 +8106,13 @@ M:   Harald Welte 
 S: Maintained
 F: drivers/char/pcmcia/cm4040_cs.*
 
+OMNIVISION OV5647 SENSOR DRIVER
+M: Ramiro Oliveira 
+L: linux-media@vger.kernel.org
+T: git git://linuxtv.org/media_tree.git
+S: Maintained
+F: drivers/media/i2c/ov5647.c
+
 OMNIVISION OV7670 SENSOR DRIVER
 M: Jonathan Corbet 
 L: linux-media@vger.kernel.org
diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
index 993dc50..1d4891b 100644
--- a/drivers/media/i2c/Kconfig
+++ b/drivers/media/i2c/Kconfig
@@ -500,6 +500,17 @@ config VIDEO_OV2659
  To compile this driver as a module, choose M here: the
  module will be called ov2659.
 
+config VIDEO_OV5647
+   tristate "OmniVision OV5647 sensor support"
+   depends on I2C && VIDEO_V4L2
+   depends on MEDIA_CAMERA_SUPPORT
+   ---help---
+ This is a Video4Linux2 sensor-level driver for the OmniVision
+ OV5647 camera.
+
+ To compile this driver as a module, choose M here: the
+ module will be called ov5647.
+
 config VIDEO_OV7640
tristate "OmniVision OV7640 sensor support"
depends on I2C && VIDEO_V4L2
diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile
index 94f2c99..a732a0c 100644
--- a/drivers/media/i2c/Makefile
+++ b/drivers/media/i2c/Makefile
@@ -80,3 +80,4 @@ obj-$(CONFIG_VIDEO_IR_I2C)  += ir-kbd-i2c.o
 obj-$(CONFIG_VIDEO_ML86V7667)  += ml86v7667.o
 obj-$(CONFIG_VIDEO_OV2659) += ov2659.o
 obj-$(CONFIG_VIDEO_TC358743)   += tc358743.o
+obj-$(CONFIG_VIDEO_OV5647) += ov5647.o
diff --git a/drivers/media/i2c/ov5647.c b/drivers/media/i2c/ov5647.c
new file mode 100644
index 000..4c58339
--- /dev/null
+++ b/drivers/media/i2c/ov5647.c
@@ -0,0 +1,891 @@
+/*
+ * A V4L2 driver for OmniVision OV5647 cameras.
+ *
+ * Based on Samsung S5K6AAFX SXGA 1/6" 1.3M CMOS Image Sensor driver
+ * Copyright (C) 2011 Sylwester Nawrocki 
+ *
+ * Based on Omnivision OV7670 Camera Driver
+ * Copyright (C) 2006-7 Jonathan Corbet 
+ *
+ * Copyright (C) 2016, Synopsys, Inc.
+ *
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static bool debug;
+module_param(debug, bool, 0644);
+MODULE_PARM_DESC(debug, "Debug level (0-1)");
+
+/*
+ * The ov5647 sits on i2c with ID 0x6c
+ */
+#define OV5647_I2C_ADDR 0x6c
+#define SENSOR_NAME "ov5647"
+
+#define OV5647_REG_CHIPID_H0x300A
+#define OV5647_REG_CHIPID_L0x300B
+
+#define REG_TERM 0xfffe
+#define VAL_TERM 0xfe
+#define REG_DLY  0x
+
+/*define the voltage level of control signal*/
+#define CSI_STBY_ON1
+#define CSI_STBY_OFF   0
+#define CSI_RST_ON 0
+#define CSI_RST_OFF1
+#define CSI_PWR_ON 1
+#define CSI_PWR_OFF0
+#define CSI_AF_PWR_ON  1
+#define CSI_AF_PWR_OFF 0
+
+
+#define OV5647_ROW_START   0x01
+#define OV5647_ROW_START_MIN   0
+#define OV5647_ROW_START_MAX   2004
+#define OV5647_ROW_START_DEF   54
+
+#define OV5647_COLUMN_START0x02
+#define OV5647_COLUMN_START_MIN0
+#define OV5647_COLUMN_START_MAX2750
+#define OV5647_COLUMN_START_DEF16
+
+#define OV5647_WINDOW_HEIGHT   0x03
+#define OV5647_WINDOW_HEIGHT_MIN   2
+#define OV5647_WINDOW_HEIGHT_MAX   2006
+#define OV5647_WINDOW_HEIGHT_DEF   1944
+
+#define OV5647_WINDOW_WIDTH0x04
+#define OV5647_WINDOW_WIDTH_MIN2
+#define OV5647_WINDOW_WIDTH_MAX2752
+#define OV5647_WINDOW_WIDTH_DEF2592
+
+enum power_seq_cmd {
+   CSI_SUBDEV_PWR_OFF = 0x00,
+   CSI_SUBDEV_PWR_ON = 0x01,
+};
+
+struct regval_list {
+   uint16_t addr;
+   uint8_t data;
+};
+
+struct cfg_array {
+   struct regval_list *regs;
+   int size;
+};
+
+struct sensor_win_size {
+   int width;
+   int height;
+   unsigned int hoffset;
+   unsigned int voffset;
+   unsigned int hts;
+   unsigned int vts;
+   unsigned int pclk;
+   unsigned int mipi_bps;
+   unsigned int fps_fixed;
+   unsigned int bin_factor;
+   unsigned int intg_min;
+   unsigned int intg_max;
+   void *regs;
+   int regs_size;
+   int (*set_size)(struct v4l2_subdev *subdev);
+};
+
+
+struct ov5647 {
+   struct device   *dev;
+   struct 

Cross compiling v4l-utils for Android

2016-05-24 Thread Burt Poppenga
Hello,

I was hoping to get some tips on cross compiling v4l-utils for Android.  I
am targeting a Nexus 5 Marshmallow device (using the android-6.0.1_r41
branch) and have the complete AOSP tree, it is built and flashed in my
device.

  PLATFORM_VERSION_CODENAME=REL
  PLATFORM_VERSION=6.0.1
  TARGET_PRODUCT=aosp_hammerhead
  TARGET_BUILD_VARIANT=userdebug
  TARGET_BUILD_TYPE=release
  TARGET_ARCH=arm
  TARGET_ARCH_VARIANT=armv7-a-neon
  TARGET_CPU_VARIANT=krait
  BUILD_ID=MOB30H

Note that I have not built the Kernel or NDK.

The INSTALL document for v4l-utils says:
"v4l-utils will only build using the complete AOSP source tree, because of
the stlport dependency"

Which makes sense looking at the v4l2-ctl Android.mk file:

LOCAL_C_INCLUDES := \
  $(LOCAL_PATH)/../.. \
  $(LOCAL_PATH)/../../include \
  bionic \
  external/stlport/stlport

LOCAL_SHARED_LIBRARIES := libstlport

The problem arises because it appears that Google has deprecated stlport.
Stlport no longer appears in the "external" tree, only the library is
present in the "prebuilts" tree.

Any tips would be greatly appreciated.

Thanks,
Burt


--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 2/3] media: add media_device_unregister_put() interface

2016-05-24 Thread Shuah Khan
On 05/23/2016 05:39 AM, Hans Verkuil wrote:
> On 05/13/2016 07:09 PM, Shuah Khan wrote:
>> Add media_device_unregister_put() interface to release reference to a media
>> device allocated using the Media Device Allocator API. The media device is
>> unregistered and freed when the last driver that holds the reference to the
>> media device releases the reference. The media device is unregistered and
>> freed in the kref put handler.
>>
>> Signed-off-by: Shuah Khan 
>> ---
>>  drivers/media/media-device.c | 11 +++
>>  include/media/media-device.h | 15 +++
>>  2 files changed, 26 insertions(+)
>>
>> diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c
>> index 33a9952..b5c279a 100644
>> --- a/drivers/media/media-device.c
>> +++ b/drivers/media/media-device.c
>> @@ -36,6 +36,7 @@
>>  #include 
>>  #include 
>>  #include 
>> +#include 
>>  
>>  #ifdef CONFIG_MEDIA_CONTROLLER
>>  
>> @@ -818,6 +819,16 @@ void media_device_unregister(struct media_device *mdev)
>>  }
>>  EXPORT_SYMBOL_GPL(media_device_unregister);
>>  
>> +void media_device_unregister_put(struct media_device *mdev)
>> +{
>> +if (mdev == NULL)
>> +return;
>> +
>> +dev_dbg(mdev->dev, "%s: mdev %p\n", __func__, mdev);
>> +media_device_put(mdev);
>> +}
>> +EXPORT_SYMBOL_GPL(media_device_unregister_put);
>> +
> 
> I don't really see the need for a new unregister_put function. The only thing
> it adds compared to media_device_put is the 'if (mdev == NULL)' check.
> 
> Is that check needed at all?

Yeah. My reasoning for keeping this for symmetry in drivers
with _register() and _unregister(). However, drivers already
required to call media_device_put() in _register error legs.

> 
> I would probably go for an API like this:
> 
> 
> 
> /* Not sure if there should be a void *priv as the last argument */
> int (*mdev_init_fnc)(struct media_device *mdev, struct device *dev);
> 
> /* Perhaps a void *priv is needed to pass to mdev_init_fnc?
>The callback is there to initialize the media_device and it's called
>with the lock held.
> */
> struct media_device *media_device_allocate(struct device *dev, mdev_init_fnc 
> fnc);
> 
> /* Helper function for usb devices */
> struct media_device *media_device_usb_allocate(struct usb_device *udev,
>  char *driver_name);
> 
> /* counterpart of media_device_allocate, that makes more sense than 
> allocate/put IMHO */
> void media_device_release(struct media_device *mdev);

We already have a media_device_release() that gets used as devnode->release
back. I will use a different name, media_device_usb_free() or something
similar.

> 
> 
> 
> Regards,
> 
>   Hans
> 
>>  static void media_device_release_devres(struct device *dev, void *res)
>>  {
>>  }
>> diff --git a/include/media/media-device.h b/include/media/media-device.h
>> index f743ae2..8bd836e 100644
>> --- a/include/media/media-device.h
>> +++ b/include/media/media-device.h
>> @@ -499,6 +499,18 @@ int __must_check __media_device_register(struct 
>> media_device *mdev,
>>  void media_device_unregister(struct media_device *mdev);
>>  
>>  /**
>> + * media_device_unregister_put() - Unregisters a media device element
>> + *
>> + * @mdev:   pointer to struct _device
>> + *
>> + * Should be called to unregister media device allocated with Media Device
>> + * Allocator API media_device_get() interface.
>> + * It is safe to call this function on an unregistered (but initialised)
>> + * media device.
>> + */
>> +void media_device_unregister_put(struct media_device *mdev);
>> +
>> +/**
>>   * media_device_register_entity() - registers a media entity inside a
>>   *  previously registered media device.
>>   *
>> @@ -658,6 +670,9 @@ static inline int media_device_register(struct 
>> media_device *mdev)
>>  static inline void media_device_unregister(struct media_device *mdev)
>>  {
>>  }
>> +static inline void media_device_unregister_put(struct media_device *mdev)
>> +{
>> +}
>>  static inline int media_device_register_entity(struct media_device *mdev,
>>  struct media_entity *entity)
>>  {
>>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-media" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [v4l-utils PATCH 2/2] mediactl: Separate entity and pad parsing

2016-05-24 Thread Laurent Pinchart
Hi Sakari,

Thank you for the patch.

On Tuesday 24 May 2016 15:48:03 Sakari Ailus wrote:
> Sometimes it's useful to be able to parse the entity independent of the pad.
> Separate entity parsing into media_parse_entity().
> 
> Signed-off-by: Sakari Ailus 
> ---
>  utils/media-ctl/libmediactl.c | 28 
>  utils/media-ctl/mediactl.h| 14 ++
>  2 files changed, 38 insertions(+), 4 deletions(-)
> 
> diff --git a/utils/media-ctl/libmediactl.c b/utils/media-ctl/libmediactl.c
> index 78caa7c..14b17e6 100644
> --- a/utils/media-ctl/libmediactl.c
> +++ b/utils/media-ctl/libmediactl.c
> @@ -781,10 +781,10 @@ int media_device_add_entity(struct media_device
> *media, return 0;
>  }
> 
> -struct media_pad *media_parse_pad(struct media_device *media,
> -   const char *p, char **endp)
> +struct media_entity *media_parse_entity(struct media_device *media,
> + const char *p, char **endp)
>  {
> - unsigned int entity_id, pad;
> + unsigned int entity_id;
>   struct media_entity *entity;
>   char *end;
> 
> @@ -827,7 +827,27 @@ struct media_pad *media_parse_pad(struct media_device
> *media, return NULL;
>   }
>   }
> - for (; isspace(*end); ++end);
> + for (p = end; isspace(*p); ++p);
> +
> + *endp = (char *)p;
> +
> + return entity;
> +}
> +
> +struct media_pad *media_parse_pad(struct media_device *media,
> +   const char *p, char **endp)
> +{
> + unsigned int pad;
> + struct media_entity *entity;
> + char *end;
> +
> + if (endp == NULL)
> + endp = 
> +
> + entity = media_parse_entity(media, p, );
> + if (!entity)
> + return NULL;
> + *endp = end;

Did you mean

if (!entity) {
*endp = end;
return NULL;
}

? There's no need to assign endp after the check as all return paths below 
assign it correctly, but it should be set when returning an error here.

>   if (*end != ':') {
>   media_dbg(media, "Expected ':'\n", *end);
> diff --git a/utils/media-ctl/mediactl.h b/utils/media-ctl/mediactl.h
> index b5a92f5..af36051 100644
> --- a/utils/media-ctl/mediactl.h
> +++ b/utils/media-ctl/mediactl.h
> @@ -367,6 +367,20 @@ int media_setup_link(struct media_device *media,
>  int media_reset_links(struct media_device *media);
> 
>  /**
> + * @brief Parse string to an entity on the media device.
> + * @param media - media device.
> + * @param p - input string
> + * @param endp - pointer to string where parsing ended
> + *
> + * Parse NULL terminated string describing an entity and return its
> + * struct media_entity instance.
> + *
> + * @return Pointer to struct media_entity on success, NULL on failure.
> + */
> +struct media_entity *media_parse_entity(struct media_device *media,
> + const char *p, char **endp);
> +
> +/**
>   * @brief Parse string to a pad on the media device.
>   * @param media - media device.
>   * @param p - input string

-- 
Regards,

Laurent Pinchart

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [v4l-utils PATCH 1/2] libmediactl: Drop length argument from media_get_entity_by_name()

2016-05-24 Thread Laurent Pinchart
Hi Sakari,

Thank you for the patch.

On Tuesday 24 May 2016 15:48:02 Sakari Ailus wrote:
> Recently it was decided that the API dealing with string operations would
> be better to just receive a nul-terminated string rather than a string the
> length of which is defined. This change was implemented for
> v4l2_subdev_string_to_pixelcode() and v4l2_subdev_string_to_field()
> functions by patch "v4l: libv4l2subdev: Drop length argument from string
> conversion functions" (commit id
> 341f4343e6190a7ceb546f7c74fa67e1cc9ae79f).
> 
> Do the same change for media_get_entity_by_name() in libmediactl. No other
> functions using length argument for strings remain in libmediactl.
> 
> Signed-off-by: Sakari Ailus 
> ---
>  utils/media-ctl/libmediactl.c | 19 +--
>  utils/media-ctl/media-ctl.c   |  3 +--
>  utils/media-ctl/mediactl.h|  3 +--
>  3 files changed, 11 insertions(+), 14 deletions(-)
> 
> diff --git a/utils/media-ctl/libmediactl.c b/utils/media-ctl/libmediactl.c
> index 89ac11c..78caa7c 100644
> --- a/utils/media-ctl/libmediactl.c
> +++ b/utils/media-ctl/libmediactl.c
> @@ -66,21 +66,14 @@ struct media_pad *media_entity_remote_source(struct
> media_pad *pad) }
> 
>  struct media_entity *media_get_entity_by_name(struct media_device *media,
> -   const char *name, size_t length)
> +   const char *name)
>  {
>   unsigned int i;
> 
> - /* A match is impossible if the entity name is longer than the maximum
> -  * size we can get from the kernel.
> -  */
> - if (length >= FIELD_SIZEOF(struct media_entity_desc, name))
> - return NULL;
> -
>   for (i = 0; i < media->entities_count; ++i) {
>   struct media_entity *entity = >entities[i];
> 
> - if (strncmp(entity->info.name, name, length) == 0 &&
> - entity->info.name[length] == '\0')
> + if (strcmp(entity->info.name, name) == 0)

While the kernel API guarantees that entity->info.name will be NULL-
terminated, wouldn't it be safer to add a safety check here ?

>   return entity;
>   }
> 
> @@ -804,6 +797,8 @@ struct media_pad *media_parse_pad(struct media_device
> *media, for (; isspace(*p); ++p);
> 
>   if (*p == '"' || *p == '\'') {
> + char *name;
> +
>   for (end = (char *)p + 1; *end && *end != '"' && *end != '\''; 
> ++end);
>   if (*end != '"' && *end != '\'') {
>   media_dbg(media, "missing matching '\"'\n");
> @@ -811,7 +806,11 @@ struct media_pad *media_parse_pad(struct media_device
> *media, return NULL;
>   }
> 
> - entity = media_get_entity_by_name(media, p + 1, end - p - 1);
> + name = strndup(p + 1, end - p - 1);
> + if (!name)
> + return NULL;
> + entity = media_get_entity_by_name(media, name);
> + free(name);
>   if (entity == NULL) {
>   media_dbg(media, "no such entity \"%.*s\"\n", end - p - 
> 1, p + 1);
>   *endp = (char *)p + 1;
> diff --git a/utils/media-ctl/media-ctl.c b/utils/media-ctl/media-ctl.c
> index f45ca43..2f049c6 100644
> --- a/utils/media-ctl/media-ctl.c
> +++ b/utils/media-ctl/media-ctl.c
> @@ -559,8 +559,7 @@ int main(int argc, char **argv)
>   if (media_opts.entity) {
>   struct media_entity *entity;
> 
> - entity = media_get_entity_by_name(media, media_opts.entity,
> -   strlen(media_opts.entity));
> + entity = media_get_entity_by_name(media, media_opts.entity);
>   if (entity == NULL) {
>   printf("Entity '%s' not found\n", media_opts.entity);
>   goto out;
> diff --git a/utils/media-ctl/mediactl.h b/utils/media-ctl/mediactl.h
> index 77ac182..b5a92f5 100644
> --- a/utils/media-ctl/mediactl.h
> +++ b/utils/media-ctl/mediactl.h
> @@ -245,14 +245,13 @@ static inline unsigned int media_entity_type(struct
> media_entity *entity) * @brief Find an entity by its name.
>   * @param media - media device.
>   * @param name - entity name.
> - * @param length - size of @a name.
>   *
>   * Search for an entity with a name equal to @a name.
>   *
>   * @return A pointer to the entity if found, or NULL otherwise.
>   */
>  struct media_entity *media_get_entity_by_name(struct media_device *media,
> - const char *name, size_t length);
> + const char *name);
> 
>  /**
>   * @brief Find an entity by its ID.

-- 
Regards,

Laurent Pinchart

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/3] media: Media Device Allocator API

2016-05-24 Thread Shuah Khan
On 05/23/2016 05:26 AM, Hans Verkuil wrote:
> Hi Shuah,
> 
> Some comments below:

Thanks for the review.

> 
> On 05/13/2016 07:09 PM, Shuah Khan wrote:
>> Media Device Allocator API to allows multiple drivers share a media device.
>> Using this API, drivers can allocate a media device with the shared struct
>> device as the key. Once the media device is allocated by a driver, other
>> drivers can get a reference to it. The media device is released when all
>> the references are released.
>>
>> Signed-off-by: Shuah Khan 
>> ---
>>  drivers/media/Makefile  |   3 +-
>>  drivers/media/media-dev-allocator.c | 139 
>> 
>>  include/media/media-dev-allocator.h | 118 ++
>>  3 files changed, 259 insertions(+), 1 deletion(-)
>>  create mode 100644 drivers/media/media-dev-allocator.c
>>  create mode 100644 include/media/media-dev-allocator.h
>>
>> diff --git a/drivers/media/Makefile b/drivers/media/Makefile
>> index e608bbc..b08f091 100644
>> --- a/drivers/media/Makefile
>> +++ b/drivers/media/Makefile
>> @@ -2,7 +2,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-dev-allocator.o
>>  
>>  #
>>  # I2C drivers should come before other drivers, otherwise they'll fail
>> diff --git a/drivers/media/media-dev-allocator.c 
>> b/drivers/media/media-dev-allocator.c
>> new file mode 100644
>> index 000..b49ab55
>> --- /dev/null
>> +++ b/drivers/media/media-dev-allocator.c
>> @@ -0,0 +1,139 @@
>> +/*
>> + * media-dev-allocator.c - Media Controller Device Allocator API
>> + *
>> + * Copyright (c) 2016 Shuah Khan 
>> + * Copyright (c) 2016 Samsung Electronics Co., Ltd.
>> + *
>> + * This file is released under the GPLv2.
>> + * Credits: Suggested by Laurent Pinchart 
>> 
>> + */
>> +
>> +/*
>> + * This file adds a global refcounted Media Controller Device Instance API.
>> + * A system wide global media device list is managed and each media device
>> + * includes a kref count. The last put on the media device releases the 
>> media
>> + * device instance.
>> + *
>> +*/
>> +
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +
>> +static LIST_HEAD(media_device_list);
>> +static DEFINE_MUTEX(media_device_lock);
>> +
>> +struct media_device_instance {
>> +struct media_device mdev;
>> +struct list_head list;
>> +struct device *dev;
>> +struct kref refcount;
>> +};
>> +
>> +static inline struct media_device_instance *
>> +to_media_device_instance(struct media_device *mdev)
>> +{
>> +return container_of(mdev, struct media_device_instance, mdev);
>> +}
>> +
>> +static void media_device_instance_release(struct kref *kref)
>> +{
>> +struct media_device_instance *mdi =
>> +container_of(kref, struct media_device_instance, refcount);
>> +
>> +dev_dbg(mdi->mdev.dev, "%s: mdev=%p\n", __func__, >mdev);
>> +
>> +mutex_lock(_device_lock);
>> +
>> +media_device_unregister(>mdev);
>> +media_device_cleanup(>mdev);
>> +
>> +list_del(>list);
>> +mutex_unlock(_device_lock);
>> +
>> +kfree(mdi);
>> +}
>> +
>> +static struct media_device *__media_device_get(struct device *dev,
>> +   bool allocate)
>> +{
>> +struct media_device_instance *mdi;
>> +
>> +mutex_lock(_device_lock);
>> +
>> +list_for_each_entry(mdi, _device_list, list) {
>> +if (mdi->dev == dev) {
>> +kref_get(>refcount);
>> +dev_dbg(dev, "%s: get mdev=%p\n",
>> + __func__, >mdev);
>> +goto done;
>> +}
>> +}
>> +
>> +if (!allocate) {
>> +mdi = NULL;
>> +goto done;
>> +}
>> +
>> +mdi = kzalloc(sizeof(*mdi), GFP_KERNEL);
>> +if (!mdi)
>> +goto done;
>> +
>> +mdi->dev = dev;
>> +kref_init(>refcount);
>> +list_add_tail(>list, _device_list);
>> +
>> +dev_dbg(dev, "%s: alloc mdev=%p\n", __func__, >mdev);
>> +
>> +done:
>> +mutex_unlock(_device_lock);
>> +
>> +return mdi ? >mdev : NULL;
>> +}
>> +
>> +struct media_device *media_device_allocate(struct device *dev)
>> +{
>> +dev_dbg(dev, "%s\n", __func__);
>> +return __media_device_get(dev, true);
>> +}
>> +EXPORT_SYMBOL_GPL(media_device_allocate);
> 
> Do we need this function? Whenever a media device is allocated, you also need
> to initialize the media device with the media_device_lock held (as happens
> below in media_device_usb_allocate). You can't really use this function
> standalone as far as I can see.
> 
> An alternative might be to pass a callback function with media_device_allocate
> that initialized the media device. That would ensure that there are no race
> conditions since 

[RFC v2 01/21] media: Add request API

2016-05-24 Thread Sakari Ailus
From: Laurent Pinchart 

The request API allows bundling media device parameters with request
objects and applying them atomically, either synchronously or
asynchronously.

Signed-off-by: Laurent Pinchart 

---

Changes since v0:

- Make the request ID 32 bits wide internally

---

- Strip off the reserved fields

- Use __attribute__ ((packed)) for the IOCTL argument struct.

- Manage request ID space using ida_simple

- Fix compat handling for requests

- Release mdev->req_lock during media_device_request_put(). The change was
  present in a later patch but moved here.

- Delete request from media device request list on fh release

- Delete request from the file handle list on fh release

- Store filp pointer to a request, check that it's non-NULL on delete

Signed-off-by: Sakari Ailus 
---
 drivers/media/media-device.c | 223 ++-
 include/media/media-device.h |  44 -
 include/uapi/linux/media.h   |  11 +++
 3 files changed, 273 insertions(+), 5 deletions(-)

diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c
index 344921c..85b13db 100644
--- a/drivers/media/media-device.c
+++ b/drivers/media/media-device.c
@@ -25,7 +25,6 @@
 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -41,6 +40,7 @@
 
 struct media_device_fh {
struct media_devnode_fh fh;
+   struct list_head requests;
 };
 
 static inline struct media_device_fh *media_device_fh(struct file *filp)
@@ -49,6 +49,192 @@ static inline struct media_device_fh 
*media_device_fh(struct file *filp)
 }
 
 /* 
-
+ * Requests
+ */
+
+/**
+ * media_device_request_find - Find a request based from its ID
+ * @mdev: The media device
+ * @reqid: The request ID
+ *
+ * Find and return the request associated with the given ID, or NULL if no such
+ * request exists.
+ *
+ * When the function returns a non-NULL request it increases its reference
+ * count. The caller is responsible for releasing the reference by calling
+ * media_device_request_put() on the request.
+ */
+struct media_device_request *
+media_device_request_find(struct media_device *mdev, u16 reqid)
+{
+   struct media_device_request *req;
+   unsigned long flags;
+   bool found = false;
+
+   spin_lock_irqsave(>req_lock, flags);
+   list_for_each_entry(req, >requests, list) {
+   if (req->id == reqid) {
+   kref_get(>kref);
+   found = true;
+   break;
+   }
+   }
+   spin_unlock_irqrestore(>req_lock, flags);
+
+   if (!found) {
+   dev_dbg(mdev->dev,
+   "request: can't find %u\n", reqid);
+   return NULL;
+   }
+
+   return req;
+}
+EXPORT_SYMBOL_GPL(media_device_request_find);
+
+void media_device_request_get(struct media_device_request *req)
+{
+   kref_get(>kref);
+}
+EXPORT_SYMBOL_GPL(media_device_request_get);
+
+static void media_device_request_release(struct kref *kref)
+{
+   struct media_device_request *req =
+   container_of(kref, struct media_device_request, kref);
+   struct media_device *mdev = req->mdev;
+
+   dev_dbg(mdev->dev, "release request %u\n", req->id);
+
+   ida_simple_remove(>req_ids, req->id);
+
+   mdev->ops->req_free(mdev, req);
+}
+
+void media_device_request_put(struct media_device_request *req)
+{
+   kref_put(>kref, media_device_request_release);
+}
+EXPORT_SYMBOL_GPL(media_device_request_put);
+
+static int media_device_request_alloc(struct media_device *mdev,
+ struct file *filp,
+ struct media_request_cmd *cmd)
+{
+   struct media_device_fh *fh = media_device_fh(filp);
+   struct media_device_request *req;
+   unsigned long flags;
+   int id = ida_simple_get(>req_ids, 1, 0, GFP_KERNEL);
+   int ret;
+
+   if (id < 0) {
+   dev_dbg(mdev->dev, "request: unable to obtain new id\n");
+   return id;
+   }
+
+   req = mdev->ops->req_alloc(mdev);
+   if (!req) {
+   ret = -ENOMEM;
+   goto out_ida_simple_remove;
+   }
+
+   req->mdev = mdev;
+   req->id = id;
+   req->filp = filp;
+   kref_init(>kref);
+
+   spin_lock_irqsave(>req_lock, flags);
+   list_add_tail(>list, >requests);
+   list_add_tail(>fh_list, >requests);
+   spin_unlock_irqrestore(>req_lock, flags);
+
+   cmd->request = req->id;
+
+   dev_dbg(mdev->dev, "request: allocated id %u\n", req->id);
+
+   return 0;
+
+out_ida_simple_remove:
+   ida_simple_remove(>req_ids, id);
+
+   return ret;
+}
+
+static void media_device_request_delete(struct media_device *mdev,
+   struct 

[RFC v2 03/21] media: Prevent queueing queued requests

2016-05-24 Thread Sakari Ailus
Verify that the request state is IDLE before queueing it. Also mark
requests queued when they're queued, and return the request to IDLE if
queueing it failed.

Signed-off-by: Sakari Ailus 
---
 drivers/media/media-device.c | 55 +---
 1 file changed, 47 insertions(+), 8 deletions(-)

diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c
index 7781c49..247587b 100644
--- a/drivers/media/media-device.c
+++ b/drivers/media/media-device.c
@@ -189,6 +189,47 @@ static void media_device_request_delete(struct 
media_device *mdev,
media_device_request_put(req);
 }
 
+static int media_device_request_queue_apply(
+   struct media_device *mdev, struct media_device_request *req,
+   int (*fn)(struct media_device *mdev,
+ struct media_device_request *req), bool queue)
+{
+   char *str = queue ? "queue" : "apply";
+   unsigned long flags;
+   int rval = 0;
+
+   if (!fn)
+   return -ENOSYS;
+
+   spin_lock_irqsave(>req_lock, flags);
+   if (req->state != MEDIA_DEVICE_REQUEST_STATE_IDLE) {
+   rval = -EINVAL;
+   dev_dbg(mdev->dev,
+   "request: unable to %s %u, request in state %s\n",
+   str, req->id, request_state(req->state));
+   } else {
+   req->state = MEDIA_DEVICE_REQUEST_STATE_QUEUED;
+   }
+   spin_unlock_irqrestore(>req_lock, flags);
+
+   if (rval)
+   return rval;
+
+   rval = fn(mdev, req);
+   if (rval) {
+   spin_lock_irqsave(>req_lock, flags);
+   req->state = MEDIA_DEVICE_REQUEST_STATE_IDLE;
+   spin_unlock_irqrestore(>req_lock, flags);
+   dev_dbg(mdev->dev,
+   "request: can't %s %u\n", str, req->id);
+   } else {
+   dev_dbg(mdev->dev,
+   "request: %s %u\n", str, req->id);
+   }
+
+   return rval;
+}
+
 static long media_device_request_cmd(struct media_device *mdev,
 struct file *filp,
 struct media_request_cmd *cmd)
@@ -216,17 +257,15 @@ static long media_device_request_cmd(struct media_device 
*mdev,
break;
 
case MEDIA_REQ_CMD_APPLY:
-   if (!mdev->ops->req_apply)
-   return -ENOSYS;
-
-   ret = mdev->ops->req_apply(mdev, req);
+   ret = media_device_request_queue_apply(mdev, req,
+  mdev->ops->req_apply,
+  false);
break;
 
case MEDIA_REQ_CMD_QUEUE:
-   if (!mdev->ops->req_queue)
-   return -ENOSYS;
-
-   ret = mdev->ops->req_queue(mdev, req);
+   ret = media_device_request_queue_apply(mdev, req,
+  mdev->ops->req_queue,
+  true);
break;
 
default:
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC v2 06/21] media: Add per-entity request data support

2016-05-24 Thread Sakari Ailus
From: Laurent Pinchart 

Allow subsystems to associate data with entities in each request. This
will be used by the V4L2 subdev core to store pad formats in requests.

Signed-off-by: Laurent Pinchart 

---

Changes since v0:

- Dereference requests without holding the list lock
- Remove requests from global list when closing the fh
---
 drivers/media/media-device.c | 71 
 include/media/media-device.h |  7 +
 include/media/media-entity.h | 12 
 3 files changed, 90 insertions(+)

diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c
index 16fcc20..462823f 100644
--- a/drivers/media/media-device.c
+++ b/drivers/media/media-device.c
@@ -109,12 +109,18 @@ EXPORT_SYMBOL_GPL(media_device_request_get);
 
 static void media_device_request_release(struct kref *kref)
 {
+   struct media_entity_request_data *data, *next;
struct media_device_request *req =
container_of(kref, struct media_device_request, kref);
struct media_device *mdev = req->mdev;
 
dev_dbg(mdev->dev, "release request %u\n", req->id);
 
+   list_for_each_entry_safe(data, next, >data, list) {
+   list_del(>list);
+   data->release(data);
+   }
+
ida_simple_remove(>req_ids, req->id);
 
mdev->ops->req_free(mdev, req);
@@ -126,6 +132,70 @@ void media_device_request_put(struct media_device_request 
*req)
 }
 EXPORT_SYMBOL_GPL(media_device_request_put);
 
+/**
+ * media_device_request_get_entity_data - Get per-entity data
+ * @req: The request
+ * @entity: The entity
+ *
+ * Search and return per-entity data (as a struct media_entity_request_data
+ * instance) associated with the given entity for the request, as previously
+ * registered by a call to media_device_request_set_entity_data().
+ *
+ * The caller is expected to hold a reference to the request. Per-entity data 
is
+ * not reference counted, the returned pointer will be valid only as long as 
the
+ * reference to the request is held.
+ *
+ * Return the data instance pointer or NULL if no data could be found.
+ */
+struct media_entity_request_data *
+media_device_request_get_entity_data(struct media_device_request *req,
+struct media_entity *entity)
+{
+   struct media_entity_request_data *data;
+   unsigned long flags;
+
+   spin_lock_irqsave(>mdev->req_lock, flags);
+
+   list_for_each_entry(data, >data, list) {
+   if (data->entity == entity)
+   goto done;
+   }
+
+   data = NULL;
+
+done:
+   spin_unlock_irqrestore(>mdev->req_lock, flags);
+   return data;
+}
+EXPORT_SYMBOL_GPL(media_device_request_get_entity_data);
+
+/**
+ * media_device_request_set_entity_data - Set per-entity data
+ * @req: The request
+ * @entity: The entity
+ * @data: The data
+ *
+ * Record the given per-entity data as being associated with the entity for the
+ * request.
+ *
+ * Only one per-entity data instance can be associated with a request. The
+ * caller is responsible for enforcing this requirement.
+ *
+ * Ownership of the per-entity data is transferred to the request when calling
+ * this function. The data will be freed automatically when the last reference
+ * to the request is released.
+ */
+void media_device_request_set_entity_data(struct media_device_request *req,
+   struct media_entity *entity, struct media_entity_request_data *data)
+{
+   unsigned long flags;
+
+   spin_lock_irqsave(>mdev->req_lock, flags);
+   list_add_tail(>list, >data);
+   spin_unlock_irqrestore(>mdev->req_lock, flags);
+}
+EXPORT_SYMBOL_GPL(media_device_request_set_entity_data);
+
 static int media_device_request_alloc(struct media_device *mdev,
  struct file *filp,
  struct media_request_cmd *cmd)
@@ -152,6 +222,7 @@ static int media_device_request_alloc(struct media_device 
*mdev,
req->filp = filp;
req->state = MEDIA_DEVICE_REQUEST_STATE_IDLE;
kref_init(>kref);
+   INIT_LIST_HEAD(>data);
 
spin_lock_irqsave(>req_lock, flags);
list_add_tail(>list, >requests);
diff --git a/include/media/media-device.h b/include/media/media-device.h
index acb7181..d4e2929 100644
--- a/include/media/media-device.h
+++ b/include/media/media-device.h
@@ -281,6 +281,7 @@ enum media_device_request_state {
  * @fh_list: List entry in the media file handle requests list
  * @state: The state of the request, MEDIA_DEVICE_REQUEST_STATE_*,
  *access to state serialised by mdev->req_lock
+ * @data: Per-entity data list
  */
 struct media_device_request {
u32 id;
@@ -290,6 +291,7 @@ struct media_device_request {
struct list_head list;
struct list_head fh_list;
enum media_device_request_state state;
+   struct list_head data;
 };
 
 

[RFC v2 17/21] DocBook: media: Document the V4L2 request API

2016-05-24 Thread Sakari Ailus
From: Laurent Pinchart 

The V4L2 request API consists in extensions to existing V4L2 ioctls.
Document it.

Signed-off-by: Laurent Pinchart 
---
 Documentation/DocBook/media/v4l/common.xml |  2 +
 Documentation/DocBook/media/v4l/io.xml |  9 ++-
 Documentation/DocBook/media/v4l/request-api.xml| 90 ++
 .../DocBook/media/v4l/vidioc-prepare-buf.xml   |  9 +++
 Documentation/DocBook/media/v4l/vidioc-qbuf.xml|  6 ++
 5 files changed, 113 insertions(+), 3 deletions(-)
 create mode 100644 Documentation/DocBook/media/v4l/request-api.xml

diff --git a/Documentation/DocBook/media/v4l/common.xml 
b/Documentation/DocBook/media/v4l/common.xml
index 8b5e014..30cb0f2 100644
--- a/Documentation/DocBook/media/v4l/common.xml
+++ b/Documentation/DocBook/media/v4l/common.xml
@@ -1073,6 +1073,8 @@ dheight = format.fmt.pix.height;
 
   
 
+  
+
   
 Streaming Parameters
 
diff --git a/Documentation/DocBook/media/v4l/io.xml 
b/Documentation/DocBook/media/v4l/io.xml
index e09025d..5695bc8 100644
--- a/Documentation/DocBook/media/v4l/io.xml
+++ b/Documentation/DocBook/media/v4l/io.xml
@@ -833,10 +833,13 @@ is the file descriptor associated with a DMABUF 
buffer.
  
  
__u32
-   reserved2
+   request

-   A place holder for future extensions. Drivers and 
applications
-must set this to 0.
+   ID of the request to associate the buffer to. Set by the
+   application for  and . Set to zero
+   by the application and the driver in all other cases. See
+for more information.
+   
  
  
__u32
diff --git a/Documentation/DocBook/media/v4l/request-api.xml 
b/Documentation/DocBook/media/v4l/request-api.xml
new file mode 100644
index 000..992f25a
--- /dev/null
+++ b/Documentation/DocBook/media/v4l/request-api.xml
@@ -0,0 +1,90 @@
+
+
+  Experimental API for request handling
+
+  
+Experimental
+This is an experimental
+interface and may change in the future.
+  
+
+  
+Introduction
+
+It is often useful to apply certain settings when a buffer is about to be
+filled by the DMA capture of a video capture device, ensuring that those
+settings are applied in time for them to be used with that buffer.
+
+One of the prime use-cases of this is Android's CameraHAL v3 which
+requires per-frame configuration support. Other use-cases are possible as well:
+changing codec settings (bit rate, etc.) starting with a specific buffer,
+preparing a configuration to be applied at a certain time, etc.
+
+The request API is the way V4L2 solves this problem.
+
+  
+
+  
+Request Objects
+
+At the core of the request API is the request object. Applications store
+configuration parameters such as V4L2 controls, formats and selection 
rectangles
+in request objects and then associate those request objects for processing with
+specific buffers.
+
+Request objects are created and managed through the media controller
+device node. Details on request object management can be found in the
+media controller request API
+documentation and are outside the scope of the V4L2 request API. Once a request
+object is created it can be referenced by its ID in the V4L2 ioctls that 
support
+requests.
+
+Applications can store controls, subdev formats and subdev selection
+rectangles in requests. To do so they use the usual V4L2 ioctls
+,  and  
with
+the request field of the associated structure set to
+the request ID (for subdev formats and selection rectangles the
+which field need to be additionally set to
+V4L2_SUBDEV_FORMAT_REQUEST). Controls, formats and
+selection rectangles will be processed as usual but will be stored in the
+request instead of applied to the device.
+
+
+Parameters stored in requests can further be retrieved by calling the
+,  or 
+ioctls similarly with the request field of the
+associated structure set to the request ID.
+
+
+  
+
+  
+Applying Requests
+
+The simplest way to apply a request is to associated it with a buffer.
+This is done by setting the request field of the
+ to the request ID when queuing the buffer with the 
+ioctl.
+
+
+Once a buffer is queued with a non-zero request ID the driver will apply
+all parameters stored in the request atomically. The parameters are guaranteed
+to come in effect before the buffer starts being transferred and after all
+previous buffers have been complete.
+
+
+For devices with multiple video nodes requests might need to be applied
+synchronously with several buffers. This is achieved by first preparing (but 
not
+queuing) all the related buffers using the  ioctl with the
+request field of the  set to the 
request
+ID. Once this is done the request is queued using the
+MEDIA_REQ_CMD_QUEUE command of the 
+ioctl on the media controller device node. The driver will then queue all
+buffers prepared for the 

[RFC v2 13/21] media: Add MEDIA_IOC_DQEVENT

2016-05-24 Thread Sakari Ailus
Events on a media device tell about completion of requests. Blocking and
non-blocking operation is supported.

Signed-off-by: Sakari Ailus 
---
 drivers/media/media-device.c | 102 ++-
 include/media/media-device.h |  10 +
 include/uapi/linux/media.h   |  17 
 3 files changed, 128 insertions(+), 1 deletion(-)

diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c
index 462823f..d00d3fc 100644
--- a/drivers/media/media-device.c
+++ b/drivers/media/media-device.c
@@ -23,6 +23,7 @@
 /* We need to access legacy defines from linux/media.h */
 #define __NEED_MEDIA_LEGACY_API
 
+#include 
 #include 
 #include 
 #include 
@@ -31,6 +32,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -51,6 +53,11 @@ static char *__request_state[] = {
 struct media_device_fh {
struct media_devnode_fh fh;
struct list_head requests;
+   struct {
+   struct list_head head;
+   wait_queue_head_t wait;
+   atomic_t sequence;
+   } kevents;
 };
 
 static inline struct media_device_fh *media_device_fh(struct file *filp)
@@ -107,6 +114,25 @@ void media_device_request_get(struct media_device_request 
*req)
 }
 EXPORT_SYMBOL_GPL(media_device_request_get);
 
+static void media_device_request_queue_event(struct media_device *mdev,
+struct media_device_request *req,
+struct media_device_fh *fh)
+{
+   struct media_kevent *kev = req->kev;
+   struct media_event *ev = >ev;
+
+   lockdep_assert_held(>req_lock);
+
+   ev->sequence = atomic_inc_return(>kevents.sequence);
+   ev->type = MEDIA_EVENT_TYPE_REQUEST_COMPLETE;
+   ev->req_complete.id = req->id;
+
+   list_add(>list, >kevents.head);
+   req->kev = NULL;
+   req->state = MEDIA_DEVICE_REQUEST_STATE_COMPLETE;
+   wake_up(>kevents.wait);
+}
+
 static void media_device_request_release(struct kref *kref)
 {
struct media_entity_request_data *data, *next;
@@ -123,6 +149,9 @@ static void media_device_request_release(struct kref *kref)
 
ida_simple_remove(>req_ids, req->id);
 
+   kfree(req->kev);
+   req->kev = NULL;
+
mdev->ops->req_free(mdev, req);
 }
 
@@ -202,6 +231,7 @@ static int media_device_request_alloc(struct media_device 
*mdev,
 {
struct media_device_fh *fh = media_device_fh(filp);
struct media_device_request *req;
+   struct media_kevent *kev;
unsigned long flags;
int id = ida_simple_get(>req_ids, 1, 0, GFP_KERNEL);
int ret;
@@ -211,16 +241,23 @@ static int media_device_request_alloc(struct media_device 
*mdev,
return id;
}
 
+   kev = kzalloc(sizeof(*kev), GFP_KERNEL);
+   if (!kev) {
+   ret = -ENOMEM;
+   goto out_ida_simple_remove;
+   }
+
req = mdev->ops->req_alloc(mdev);
if (!req) {
ret = -ENOMEM;
-   goto out_ida_simple_remove;
+   goto out_kev_free;
}
 
req->mdev = mdev;
req->id = id;
req->filp = filp;
req->state = MEDIA_DEVICE_REQUEST_STATE_IDLE;
+   req->kev = kev;
kref_init(>kref);
INIT_LIST_HEAD(>data);
 
@@ -235,6 +272,9 @@ static int media_device_request_alloc(struct media_device 
*mdev,
 
return 0;
 
+out_kev_free:
+   kfree(kev);
+
 out_ida_simple_remove:
ida_simple_remove(>req_ids, id);
 
@@ -308,6 +348,8 @@ void media_device_request_complete(struct media_device 
*mdev,
 */
list_del(>list);
list_del(>fh_list);
+   media_device_request_queue_event(
+   mdev, req, media_device_fh(filp));
req->filp = NULL;
}
 
@@ -433,6 +475,9 @@ static int media_device_open(struct file *filp)
return -ENOMEM;
 
INIT_LIST_HEAD(>requests);
+   INIT_LIST_HEAD(>kevents.head);
+   init_waitqueue_head(>kevents.wait);
+   atomic_set(>kevents.sequence, -1);
filp->private_data = >fh;
 
return 0;
@@ -455,6 +500,16 @@ static int media_device_close(struct file *filp)
media_device_request_put(req);
spin_lock_irq(>req_lock);
}
+
+   while (!list_empty(>kevents.head)) {
+   struct media_kevent *kev =
+   list_first_entry(>kevents.head, typeof(*kev), list);
+
+   list_del(>list);
+   spin_unlock_irq(>req_lock);
+   kfree(kev);
+   spin_lock_irq(>req_lock);
+   }
spin_unlock_irq(>req_lock);
 
kfree(fh);
@@ -772,6 +827,49 @@ static long media_device_get_topology(struct media_device 
*mdev,
return ret;
 }
 
+static struct media_kevent *opportunistic_dqevent(struct media_device *mdev,
+   

[RFC v2 15/21] media: Add poll support

2016-05-24 Thread Sakari Ailus
Implement poll for events. POLLPRI is used to notify users on incoming
events.

Signed-off-by: Sakari Ailus 
---
 drivers/media/media-device.c | 28 
 1 file changed, 28 insertions(+)

diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c
index 2ff8b29..25f7aea 100644
--- a/drivers/media/media-device.c
+++ b/drivers/media/media-device.c
@@ -1041,6 +1041,33 @@ static long media_device_ioctl(struct file *filp, 
unsigned int cmd,
ioctl_info, ARRAY_SIZE(ioctl_info));
 }
 
+unsigned int media_device_poll(struct file *filp, struct poll_table_struct 
*wait)
+{
+   struct media_device_fh *fh = media_device_fh(filp);
+   struct media_device *mdev = to_media_device(fh->fh.devnode);
+   unsigned int poll_events = poll_requested_events(wait);
+   int ret = 0;
+
+   if (poll_events & (POLLIN | POLLOUT))
+   return POLLERR;
+
+   if (poll_events & POLLPRI) {
+   unsigned long flags;
+   bool empty;
+
+   spin_lock_irqsave(>req_lock, flags);
+   empty = list_empty(>kevents.head);
+   spin_unlock_irqrestore(>req_lock, flags);
+
+   if (empty)
+   poll_wait(filp, >kevents.wait, wait);
+   else
+   ret |= POLLPRI;
+   }
+
+   return ret;
+}
+
 #ifdef CONFIG_COMPAT
 
 struct media_links_enum32 {
@@ -1095,6 +1122,7 @@ static const struct media_file_operations 
media_device_fops = {
.owner = THIS_MODULE,
.open = media_device_open,
.ioctl = media_device_ioctl,
+   .poll = media_device_poll,
 #ifdef CONFIG_COMPAT
.compat_ioctl = media_device_compat_ioctl,
 #endif /* CONFIG_COMPAT */
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC v2 09/21] v4l2-subdev.h: Add request field to format and selection structures

2016-05-24 Thread Sakari Ailus
From: Laurent Pinchart 

Let userspace specify a request ID when getting or setting formats or
selection rectangles.

>From a userspace point of view the API change is minimized and doesn't
require any new ioctl.

Signed-off-by: Laurent Pinchart 
Signed-off-by: Sakari Ailus 
---
 include/uapi/linux/v4l2-subdev.h | 11 +--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/include/uapi/linux/v4l2-subdev.h b/include/uapi/linux/v4l2-subdev.h
index dbce2b554..dbb7c1d 100644
--- a/include/uapi/linux/v4l2-subdev.h
+++ b/include/uapi/linux/v4l2-subdev.h
@@ -32,10 +32,12 @@
  * enum v4l2_subdev_format_whence - Media bus format type
  * @V4L2_SUBDEV_FORMAT_TRY: try format, for negotiation only
  * @V4L2_SUBDEV_FORMAT_ACTIVE: active format, applied to the device
+ * @V4L2_SUBDEV_FORMAT_REQUEST: format stored in request
  */
 enum v4l2_subdev_format_whence {
V4L2_SUBDEV_FORMAT_TRY = 0,
V4L2_SUBDEV_FORMAT_ACTIVE = 1,
+   V4L2_SUBDEV_FORMAT_REQUEST = 2,
 };
 
 /**
@@ -43,12 +45,15 @@ enum v4l2_subdev_format_whence {
  * @which: format type (from enum v4l2_subdev_format_whence)
  * @pad: pad number, as reported by the media API
  * @format: media bus format (format code and frame size)
+ * @request: request ID (when which is set to V4L2_SUBDEV_FORMAT_REQUEST)
+ * @reserved: for future use, set to zero for now
  */
 struct v4l2_subdev_format {
__u32 which;
__u32 pad;
struct v4l2_mbus_framefmt format;
-   __u32 reserved[8];
+   __u32 request;
+   __u32 reserved[7];
 };
 
 /**
@@ -139,6 +144,7 @@ struct v4l2_subdev_frame_interval_enum {
  * defined in v4l2-common.h; V4L2_SEL_TGT_* .
  * @flags: constraint flags, defined in v4l2-common.h; V4L2_SEL_FLAG_*.
  * @r: coordinates of the selection window
+ * @request: request ID (when which is set to V4L2_SUBDEV_FORMAT_REQUEST)
  * @reserved: for future use, set to zero for now
  *
  * Hardware may use multiple helper windows to process a video stream.
@@ -151,7 +157,8 @@ struct v4l2_subdev_selection {
__u32 target;
__u32 flags;
struct v4l2_rect r;
-   __u32 reserved[8];
+   __u32 request;
+   __u32 reserved[7];
 };
 
 /* Backwards compatibility define --- to be removed */
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC v2 14/21] media: Make events on request completion optional, disabled by default

2016-05-24 Thread Sakari Ailus
Add flags to requests. The first defined flag, MEDIA_REQ_FL_COMPLETE_EVENT
is used to tell whether to queue an event on request completion. Unless
the flag is set, no event is generated when a request completes.

Signed-off-by: Sakari Ailus 
---
 drivers/media/media-device.c | 24 
 include/media/media-device.h |  2 ++
 include/uapi/linux/media.h   | 10 ++
 3 files changed, 28 insertions(+), 8 deletions(-)

diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c
index d00d3fc..2ff8b29 100644
--- a/drivers/media/media-device.c
+++ b/drivers/media/media-device.c
@@ -348,8 +348,10 @@ void media_device_request_complete(struct media_device 
*mdev,
 */
list_del(>list);
list_del(>fh_list);
-   media_device_request_queue_event(
-   mdev, req, media_device_fh(filp));
+   /* If the user asked for an event, let's queue one. */
+   if (req->flags & MEDIA_REQ_FL_COMPLETE_EVENT)
+   media_device_request_queue_event(
+   mdev, req, media_device_fh(filp));
req->filp = NULL;
}
 
@@ -367,8 +369,8 @@ EXPORT_SYMBOL_GPL(media_device_request_complete);
 
 static int media_device_request_queue_apply(
struct media_device *mdev, struct media_device_request *req,
-   int (*fn)(struct media_device *mdev,
- struct media_device_request *req), bool queue)
+   u32 req_flags, int (*fn)(struct media_device *mdev,
+struct media_device_request *req), bool queue)
 {
char *str = queue ? "queue" : "apply";
unsigned long flags;
@@ -385,6 +387,7 @@ static int media_device_request_queue_apply(
str, req->id, request_state(req->state));
} else {
req->state = MEDIA_DEVICE_REQUEST_STATE_QUEUED;
+   req->flags = req_flags;
}
spin_unlock_irqrestore(>req_lock, flags);
 
@@ -432,13 +435,13 @@ static long media_device_request_cmd(struct media_device 
*mdev,
break;
 
case MEDIA_REQ_CMD_APPLY:
-   ret = media_device_request_queue_apply(mdev, req,
+   ret = media_device_request_queue_apply(mdev, req, cmd->flags,
   mdev->ops->req_apply,
   false);
break;
 
case MEDIA_REQ_CMD_QUEUE:
-   ret = media_device_request_queue_apply(mdev, req,
+   ret = media_device_request_queue_apply(mdev, req, cmd->flags,
   mdev->ops->req_queue,
   true);
break;
@@ -1015,13 +1018,18 @@ out_free:
return ret;
 }
 
+static const unsigned short media_request_cmd_sizes[] = {
+   sizeof(struct media_request_cmd_0),
+   0
+};
+
 static const struct media_ioctl_info ioctl_info[] = {
MEDIA_IOC(DEVICE_INFO, media_device_get_info, MEDIA_IOC_FL_GRAPH_MUTEX),
MEDIA_IOC(ENUM_ENTITIES, media_device_enum_entities, 
MEDIA_IOC_FL_GRAPH_MUTEX),
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),
+   MEDIA_IOC_SZ(REQUEST_CMD, media_device_request_cmd, 0, 
media_request_cmd_sizes),
MEDIA_IOC(DQEVENT, media_device_dqevent, 0),
 };
 
@@ -1070,7 +1078,7 @@ static const struct media_ioctl_info compat_ioctl_info[] 
= {
MEDIA_IOC_ARG(ENUM_LINKS32, media_device_enum_links, 
MEDIA_IOC_FL_GRAPH_MUTEX, from_user_enum_links32, copy_arg_to_user_nop),
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),
+   MEDIA_IOC_SZ(REQUEST_CMD, media_device_request_cmd, 0, 
media_request_cmd_sizes),
MEDIA_IOC(DQEVENT, media_device_dqevent, 0),
 };
 
diff --git a/include/media/media-device.h b/include/media/media-device.h
index 21b3deb..15d496c 100644
--- a/include/media/media-device.h
+++ b/include/media/media-device.h
@@ -291,6 +291,7 @@ struct media_kevent {
  * @state: The state of the request, MEDIA_DEVICE_REQUEST_STATE_*,
  *access to state serialised by mdev->req_lock
  * @data: Per-entity data list
+ * @flags: Request specific flags, MEDIA_REQ_FL_*
  */
 struct media_device_request {
u32 id;
@@ -302,6 +303,7 @@ struct media_device_request {
struct list_head fh_list;
enum media_device_request_state state;
struct list_head data;
+   u32 flags;
 };
 
 /**
diff --git 

[RFC v2 12/21] vb2: Add allow_requests flag

2016-05-24 Thread Sakari Ailus
From: Hans Verkuil 

The driver has to set allow_requests explicitly in order to allow
queuing or preparing buffers for a specific request ID.

Signed-off-by: Hans Verkuil 
---
 drivers/media/v4l2-core/videobuf2-v4l2.c | 5 +
 include/media/videobuf2-core.h   | 2 ++
 2 files changed, 7 insertions(+)

diff --git a/drivers/media/v4l2-core/videobuf2-v4l2.c 
b/drivers/media/v4l2-core/videobuf2-v4l2.c
index 0721258..bb135fc 100644
--- a/drivers/media/v4l2-core/videobuf2-v4l2.c
+++ b/drivers/media/v4l2-core/videobuf2-v4l2.c
@@ -174,6 +174,11 @@ static int vb2_queue_or_prepare_buf(struct vb2_queue *q, 
struct v4l2_buffer *b,
return -EINVAL;
}
 
+   if (!q->allow_requests && b->request) {
+   dprintk(1, "%s: unsupported request ID\n", opname);
+   return -EINVAL;
+   }
+
return __verify_planes_array(q->bufs[b->index], b);
 }
 
diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h
index 8a0f55b..41dab63 100644
--- a/include/media/videobuf2-core.h
+++ b/include/media/videobuf2-core.h
@@ -400,6 +400,7 @@ struct vb2_buf_ops {
  * @fileio_read_once:  report EOF after reading the first buffer
  * @fileio_write_immediately:  queue buffer after each write() call
  * @allow_zero_bytesused:  allow bytesused == 0 to be passed to the driver
+ * @allow_requests:allow request != 0 to be passed to the driver
  * @lock:  pointer to a mutex that protects the vb2_queue struct. The
  * driver can set this to a mutex to let the v4l2 core serialize
  * the queuing ioctls. If the driver wants to handle locking
@@ -463,6 +464,7 @@ struct vb2_queue {
unsignedfileio_read_once:1;
unsignedfileio_write_immediately:1;
unsignedallow_zero_bytesused:1;
+   unsignedallow_requests:1;
 
struct mutex*lock;
void*owner;
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC v2 07/21] videodev2.h: Add request field to v4l2_buffer

2016-05-24 Thread Sakari Ailus
From: Hans Verkuil 

When queuing buffers allow for passing the request ID that
should be associated with this buffer. Split the u32 reserved2 field
into two u16 fields, one for request, one with the old reserved2 name.

Signed-off-by: Hans Verkuil 

Use full 32 bits for the request ID.

Signed-off-by: Sakari Ailus 
---
 drivers/media/usb/cpia2/cpia2_v4l.c   | 1 +
 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(+), 7 deletions(-)

diff --git a/drivers/media/usb/cpia2/cpia2_v4l.c 
b/drivers/media/usb/cpia2/cpia2_v4l.c
index 9caea83..01c596a 100644
--- a/drivers/media/usb/cpia2/cpia2_v4l.c
+++ b/drivers/media/usb/cpia2/cpia2_v4l.c
@@ -952,6 +952,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->request = 0;
buf->reserved2 = 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 bacecbd..3a74114 100644
--- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
+++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
@@ -348,7 +348,7 @@ struct v4l2_buffer32 {
__s32   fd;
} m;
__u32   length;
-   __u32   reserved2;
+   __u32   request;
__u32   reserved;
 };
 
@@ -417,7 +417,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))
@@ -509,7 +510,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 6bf5a3e..bf15580 100644
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
@@ -443,13 +443,13 @@ static void v4l_print_buffer(const void *arg, bool 
write_only)
int i;
 
pr_cont("%02ld:%02d:%02d.%08ld index=%d, type=%s, "
-   "flags=0x%08x, field=%s, sequence=%d, memory=%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 91f5521..0721258 100644
--- a/drivers/media/v4l2-core/videobuf2-v4l2.c
+++ b/drivers/media/v4l2-core/videobuf2-v4l2.c
@@ -199,7 +199,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) {
@@ -317,6 +317,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 3cc836f..b1ee91c 100644
--- a/include/media/videobuf2-v4l2.h
+++ b/include/media/videobuf2-v4l2.h

[RFC v2 02/21] media: Add media device request state

2016-05-24 Thread Sakari Ailus
Signed-off-by: Sakari Ailus 
---
 drivers/media/media-device.c | 9 +
 include/media/media-device.h | 8 
 2 files changed, 17 insertions(+)

diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c
index 85b13db..7781c49 100644
--- a/drivers/media/media-device.c
+++ b/drivers/media/media-device.c
@@ -38,6 +38,14 @@
 
 #ifdef CONFIG_MEDIA_CONTROLLER
 
+static char *__request_state[] = {
+   "IDLE",
+   "QUEUED",
+};
+
+#define request_state(i)   \
+   ((i) < ARRAY_SIZE(__request_state) ? __request_state[i] : "UNKNOWN")
+
 struct media_device_fh {
struct media_devnode_fh fh;
struct list_head requests;
@@ -140,6 +148,7 @@ static int media_device_request_alloc(struct media_device 
*mdev,
req->mdev = mdev;
req->id = id;
req->filp = filp;
+   req->state = MEDIA_DEVICE_REQUEST_STATE_IDLE;
kref_init(>kref);
 
spin_lock_irqsave(>req_lock, flags);
diff --git a/include/media/media-device.h b/include/media/media-device.h
index 39442ae..893e10b 100644
--- a/include/media/media-device.h
+++ b/include/media/media-device.h
@@ -265,6 +265,11 @@
 struct device;
 struct media_device;
 
+enum media_device_request_state {
+   MEDIA_DEVICE_REQUEST_STATE_IDLE,
+   MEDIA_DEVICE_REQUEST_STATE_QUEUED,
+};
+
 /**
  * struct media_device_request - Media device request
  * @id: Request ID
@@ -272,6 +277,8 @@ struct media_device;
  * @kref: Reference count
  * @list: List entry in the media device requests list
  * @fh_list: List entry in the media file handle requests list
+ * @state: The state of the request, MEDIA_DEVICE_REQUEST_STATE_*,
+ *access to state serialised by mdev->req_lock
  */
 struct media_device_request {
u32 id;
@@ -280,6 +287,7 @@ struct media_device_request {
struct kref kref;
struct list_head list;
struct list_head fh_list;
+   enum media_device_request_state state;
 };
 
 /**
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC v2 11/21] v4l: subdev: Support the request API in format and selection operations

2016-05-24 Thread Sakari Ailus
From: Laurent Pinchart 

Store the formats and selection rectangles in per-entity request data.
This minimizes changes to drivers by reusing the v4l2_subdev_pad_config
infrastructure.

Signed-off-by: Laurent Pinchart 

Replace three if's for testing the same variable by a switch.

Signed-off-by: Sakari Ailus 
---
 drivers/media/v4l2-core/v4l2-subdev.c | 225 +-
 include/media/v4l2-subdev.h   |  11 ++
 2 files changed, 180 insertions(+), 56 deletions(-)

diff --git a/drivers/media/v4l2-core/v4l2-subdev.c 
b/drivers/media/v4l2-core/v4l2-subdev.c
index 224ea60..b8e91a6 100644
--- a/drivers/media/v4l2-core/v4l2-subdev.c
+++ b/drivers/media/v4l2-core/v4l2-subdev.c
@@ -128,39 +128,182 @@ static int subdev_close(struct file *file)
 }
 
 #if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)
-static int check_format(struct v4l2_subdev *sd,
-   struct v4l2_subdev_format *format)
+static void subdev_request_data_release(struct media_entity_request_data *data)
 {
-   if (format->which != V4L2_SUBDEV_FORMAT_TRY &&
-   format->which != V4L2_SUBDEV_FORMAT_ACTIVE)
-   return -EINVAL;
+   struct v4l2_subdev_request_data *sddata =
+   to_v4l2_subdev_request_data(data);
 
-   if (format->pad >= sd->entity.num_pads)
-   return -EINVAL;
+   kfree(sddata->pad);
+   kfree(sddata);
+}
 
-   return 0;
+static struct v4l2_subdev_pad_config *
+subdev_request_pad_config(struct v4l2_subdev *sd,
+ struct media_device_request *req)
+{
+   struct media_entity_request_data *data;
+   struct v4l2_subdev_request_data *sddata;
+
+   data = media_device_request_get_entity_data(req, >entity);
+   if (data) {
+   sddata = to_v4l2_subdev_request_data(data);
+   return sddata->pad;
+   }
+
+   sddata = kzalloc(sizeof(*sddata), GFP_KERNEL);
+   if (!sddata)
+   return ERR_PTR(-ENOMEM);
+
+   sddata->data.release = subdev_request_data_release;
+
+   sddata->pad = v4l2_subdev_alloc_pad_config(sd);
+   if (sddata->pad == NULL) {
+   kfree(sddata);
+   return ERR_PTR(-ENOMEM);
+   }
+
+   media_device_request_set_entity_data(req, >entity, >data);
+
+   return sddata->pad;
 }
 
-static int check_crop(struct v4l2_subdev *sd, struct v4l2_subdev_crop *crop)
+static int subdev_prepare_pad_config(struct v4l2_subdev *sd,
+struct v4l2_subdev_fh *fh,
+enum v4l2_subdev_format_whence which,
+unsigned int pad, unsigned int req_id,
+struct media_device_request **_req,
+struct v4l2_subdev_pad_config **_cfg)
 {
-   if (crop->which != V4L2_SUBDEV_FORMAT_TRY &&
-   crop->which != V4L2_SUBDEV_FORMAT_ACTIVE)
+   struct v4l2_subdev_pad_config *cfg;
+   struct media_device_request *req;
+
+   if (pad >= sd->entity.num_pads)
return -EINVAL;
 
-   if (crop->pad >= sd->entity.num_pads)
+   switch (which) {
+   case V4L2_SUBDEV_FORMAT_ACTIVE:
+   *_req = NULL;
+   *_cfg = NULL;
+   return 0;
+   case V4L2_SUBDEV_FORMAT_TRY:
+   *_req = NULL;
+   *_cfg = fh->pad;
+   return 0;
+   case V4L2_SUBDEV_FORMAT_REQUEST:
+   if (!sd->v4l2_dev->mdev)
+   return -EINVAL;
+
+   req = media_device_request_find(sd->v4l2_dev->mdev, req_id);
+   if (!req)
+   return -EINVAL;
+
+   cfg = subdev_request_pad_config(sd, req);
+   if (IS_ERR(cfg)) {
+   media_device_request_put(req);
+   return PTR_ERR(cfg);
+   }
+
+   *_req = req;
+   *_cfg = cfg;
+
+   return 0;
+   default:
return -EINVAL;
+   }
 
-   return 0;
 }
 
-static int check_selection(struct v4l2_subdev *sd,
-  struct v4l2_subdev_selection *sel)
+static int subdev_get_format(struct v4l2_subdev *sd,
+struct v4l2_subdev_fh *fh,
+struct v4l2_subdev_format *format)
+{
+   struct v4l2_subdev_pad_config *cfg;
+   struct media_device_request *req;
+   int ret;
+
+   ret = subdev_prepare_pad_config(sd, fh, format->which, format->pad,
+   format->request, , );
+   if (ret < 0)
+   return ret;
+
+   ret = v4l2_subdev_call(sd, pad, get_fmt, cfg, format);
+
+   if (req)
+   media_device_request_put(req);
+
+   return ret;
+}
+
+static int subdev_set_format(struct v4l2_subdev *sd,
+  

[RFC v2 10/21] v4l: Support the request API in format operations

2016-05-24 Thread Sakari Ailus
From: Laurent Pinchart 

Store the formats in per-entity request data. The get and set format
operations are completely handled by the V4L2 core with help of the try
format driver operation.

Signed-off-by: Laurent Pinchart 
---
 drivers/media/v4l2-core/v4l2-ioctl.c | 121 +++
 include/media/v4l2-dev.h |  13 
 2 files changed, 134 insertions(+)

diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c 
b/drivers/media/v4l2-core/v4l2-ioctl.c
index bf15580..533fac6 100644
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
@@ -1355,6 +1355,119 @@ static int v4l_enum_fmt(const struct v4l2_ioctl_ops 
*ops,
return ret;
 }
 
+#if defined(CONFIG_MEDIA_CONTROLLER)
+static void vdev_request_data_release(struct media_entity_request_data *data)
+{
+   struct video_device_request_data *vdata =
+   to_video_device_request_data(data);
+
+   kfree(vdata);
+}
+
+static int vdev_request_format(struct video_device *vdev, unsigned int req_id,
+  struct media_device_request **_req,
+  struct v4l2_pix_format_mplane **_fmt)
+{
+   struct media_entity_request_data *data;
+   struct video_device_request_data *vdata;
+   struct media_device_request *req;
+
+   if (!vdev->v4l2_dev || !vdev->v4l2_dev->mdev)
+   return -EINVAL;
+
+   req = media_device_request_find(vdev->v4l2_dev->mdev, req_id);
+   if (!req)
+   return -EINVAL;
+
+   *_req = req;
+
+   data = media_device_request_get_entity_data(req, >entity);
+   if (data) {
+   vdata = to_video_device_request_data(data);
+   *_fmt = >format;
+   return 0;
+   }
+
+   vdata = kzalloc(sizeof(*vdata), GFP_KERNEL);
+   if (!vdata) {
+   media_device_request_put(req);
+   return -ENOMEM;
+   }
+
+   vdata->data.release = vdev_request_data_release;
+
+   media_device_request_set_entity_data(req, >entity, >data);
+
+   *_fmt = >format;
+   return 0;
+}
+
+static int v4l_g_req_mplane_fmt(const struct v4l2_ioctl_ops *ops,
+   struct file *file, void *fh,
+   struct v4l2_format *fmt)
+{
+   struct video_device *vdev = video_devdata(file);
+   struct v4l2_pix_format_mplane *format;
+   struct media_device_request *req;
+   int ret;
+
+   ret = vdev_request_format(vdev, fmt->fmt.pix_mp.request,
+ , );
+   if (ret < 0)
+   return ret;
+
+   fmt->fmt.pix_mp = *format;
+   media_device_request_put(req);
+   return 0;
+}
+
+static int v4l_s_req_mplane_fmt(const struct v4l2_ioctl_ops *ops,
+   struct file *file, void *fh,
+   struct v4l2_format *fmt)
+{
+   int (*try_op)(struct file *file, void *fh, struct v4l2_format *fmt);
+   struct video_device *vdev = video_devdata(file);
+   struct v4l2_pix_format_mplane *format;
+   struct media_device_request *req;
+   int ret;
+
+   if (fmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
+   try_op = ops->vidioc_try_fmt_vid_cap_mplane;
+   else
+   try_op = ops->vidioc_try_fmt_vid_out_mplane;
+
+   if (unlikely(!try_op))
+   return -ENOSYS;
+
+   ret = try_op(file, fh, fmt);
+   if (ret < 0)
+   return ret;
+
+   ret = vdev_request_format(vdev, fmt->fmt.pix_mp.request,
+ , );
+   if (ret < 0)
+   return ret;
+
+   *format = fmt->fmt.pix_mp;
+   media_device_request_put(req);
+   return 0;
+}
+#else
+static int v4l_g_req_mplane_fmt(const struct v4l2_ioctl_ops *ops,
+   struct file *file, void *fh,
+   struct v4l2_format *fmt)
+{
+   return -ENOSYS;
+}
+
+static int v4l_s_req_mplane_fmt(const struct v4l2_ioctl_ops *ops,
+   struct file *file, void *fh,
+   struct v4l2_format *fmt)
+{
+   return -ENOSYS;
+}
+#endif
+
 static int v4l_g_fmt(const struct v4l2_ioctl_ops *ops,
struct file *file, void *fh, void *arg)
 {
@@ -1402,6 +1515,8 @@ static int v4l_g_fmt(const struct v4l2_ioctl_ops *ops,
case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
if (unlikely(!is_rx || !is_vid || 
!ops->vidioc_g_fmt_vid_cap_mplane))
break;
+   if (p->fmt.pix_mp.request)
+   return v4l_g_req_mplane_fmt(ops, file, fh, p);
return ops->vidioc_g_fmt_vid_cap_mplane(file, fh, arg);
case V4L2_BUF_TYPE_VIDEO_OVERLAY:
if (unlikely(!is_rx || !is_vid || 
!ops->vidioc_g_fmt_vid_overlay))
@@ -1426,6 +1541,8 @@ 

[RFC v2 08/21] videodev2.h: Add request field to v4l2_pix_format_mplane

2016-05-24 Thread Sakari Ailus
From: Laurent Pinchart 

Let userspace specify a request ID when getting or setting formats. The
support is limited to the multi-planar API at the moment, extending it
to the single-planar API is possible if needed.

>From a userspace point of view the API change is also minimized and
doesn't require any new ioctl.

Signed-off-by: Laurent Pinchart 
---
 include/uapi/linux/videodev2.h | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
index ac28299..6260d0e 100644
--- a/include/uapi/linux/videodev2.h
+++ b/include/uapi/linux/videodev2.h
@@ -1972,6 +1972,7 @@ struct v4l2_plane_pix_format {
  * @ycbcr_enc: enum v4l2_ycbcr_encoding, Y'CbCr encoding
  * @quantization:  enum v4l2_quantization, colorspace quantization
  * @xfer_func: enum v4l2_xfer_func, colorspace transfer function
+ * @request:   request ID
  */
 struct v4l2_pix_format_mplane {
__u32   width;
@@ -1986,7 +1987,8 @@ struct v4l2_pix_format_mplane {
__u8ycbcr_enc;
__u8quantization;
__u8xfer_func;
-   __u8reserved[7];
+   __u8reserved[3];
+   __u32   request;
 } __attribute__ ((packed));
 
 /**
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC v2 20/21] DocBook: media: Document media events (MEDIA_IOC_DQEVENT IOCTL)

2016-05-24 Thread Sakari Ailus
Add DocBook documentation for media events.

Signed-off-by: Sakari Ailus 
---
 .../DocBook/media/v4l/media-controller.xml |   1 +
 .../DocBook/media/v4l/media-ioc-dqevent.xml| 156 +
 2 files changed, 157 insertions(+)
 create mode 100644 Documentation/DocBook/media/v4l/media-ioc-dqevent.xml

diff --git a/Documentation/DocBook/media/v4l/media-controller.xml 
b/Documentation/DocBook/media/v4l/media-controller.xml
index 2a5a5d0..aa78fcb 100644
--- a/Documentation/DocBook/media/v4l/media-controller.xml
+++ b/Documentation/DocBook/media/v4l/media-controller.xml
@@ -98,6 +98,7 @@
   
   
   
+  
   
   
   
diff --git a/Documentation/DocBook/media/v4l/media-ioc-dqevent.xml 
b/Documentation/DocBook/media/v4l/media-ioc-dqevent.xml
new file mode 100644
index 000..8cf0462
--- /dev/null
+++ b/Documentation/DocBook/media/v4l/media-ioc-dqevent.xml
@@ -0,0 +1,156 @@
+
+  
+ioctl MEDIA_IOC_DQEVENT
+
+  
+
+  
+MEDIA_IOC_DQEVENT
+Dequeue a media event
+  
+
+  
+
+  
+   int ioctl
+   int fd
+   int request
+   struct media_event *argp
+  
+
+  
+
+  
+Arguments
+
+
+  
+   fd
+   
+ File descriptor returned by
+ open().
+   
+  
+  
+   request
+   
+ MEDIA_IOC_DQEVENT
+   
+  
+  
+   argp
+   
+ 
+   
+  
+
+  
+
+  
+Description
+
+Dequeue a media event from a media device. Both non-blocking
+and blocking access is supported. poll(2)
+IOCTL may be used with poll event type
+POLLPRI to learn about dequeueable
+events.
+
+Media events are specific to file handle: they are delivered
+to and dequeued from each file handle separately.
+
+
+  struct media_event
+  
+
+   
+ 
+   __u32
+   type
+   
+   Type of the media event. Set by the driver. See
+for available media
+   event types.
+ 
+ 
+   __u32
+   sequence
+   
+   Event sequence number. The sequence number is file
+   handle specific and counts from zero until it wraps around
+   after reaching 32^2-1.
+ 
+ 
+   __u32
+   reserved[4]
+   Reserved for future extensions. Applications and
+   drivers must set this to zero.
+ 
+ 
+   union
+   
+   
+   Anonymous union for event type specific data.
+ 
+ 
+   
+   struct _event_request_complete;
+   req_complete
+   Event data for
+   MEDIA_EVENT_REQUEST_COMPLETE event.
+   
+ 
+   
+  
+
+
+
+  Media event types
+  
+   
+   
+ 
+   MEDIA_EVENT_REQUEST_COMPLETE
+   1
+   A request has been completed. This media event type
+   has  associated with it. The
+yes
+   event is only queued to the file handle from which the
+   event was queued.
+   
+ 
+   
+  
+
+
+
+  struct 
media_event_request_complete
+  
+
+   
+ 
+   __u32
+   id
+   Request ID. The identifier of the request which has
+   been completed.
+ 
+   
+  
+
+
+  
+
+  
+
+
+
+  
+   ENOENT
+   
+ No events are available for dequeueing. This is returned
+ only when non-blocking I/O is used.
+ 
+   
+  
+
+  
+
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC v2 19/21] DocBook: media: Document the V4L2 subdev request API

2016-05-24 Thread Sakari Ailus
From: Laurent Pinchart 

The V4L2 subdev request API consists in extensions to existing V4L2
subdev ioctls. Document it.

Signed-off-by: Laurent Pinchart 
---
 .../DocBook/media/v4l/vidioc-subdev-g-fmt.xml  | 27 +++---
 .../media/v4l/vidioc-subdev-g-selection.xml| 24 +++
 2 files changed, 44 insertions(+), 7 deletions(-)

diff --git a/Documentation/DocBook/media/v4l/vidioc-subdev-g-fmt.xml 
b/Documentation/DocBook/media/v4l/vidioc-subdev-g-fmt.xml
index 781089c..5cf6d89 100644
--- a/Documentation/DocBook/media/v4l/vidioc-subdev-g-fmt.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-subdev-g-fmt.xml
@@ -91,6 +91,13 @@
 low-pass noise filter might crop pixels at the frame boundaries, modifying
 its output frame size.
 
+Applications can get and set formats stored in a request by setting
+the which field to
+V4L2_SUBDEV_FORMAT_REQUEST and the
+request to the request ID. See
+ for more information about the request
+API.
+
 Drivers must not return an error solely because the requested format
 doesn't match the device capabilities. They must instead modify the format
 to match what the hardware can provide. The modified format should be as
@@ -119,7 +126,15 @@
  
  
__u32
-   reserved[8]
+   request
+   Request ID, only valid when the 
which
+   field is set to V4L2_SUBDEV_FORMAT_REQUEST.
+   Applications and drivers must set the field to zero in all other
+   cases.
+ 
+ 
+   __u32
+   reserved[7]
Reserved for future extensions. Applications and drivers must
set the array to zero.
  
@@ -142,6 +157,11 @@
1
Active formats, applied to the hardware.
  
+ 
+   V4L2_SUBDEV_FORMAT_REQUEST
+   2
+   Request formats, used with the requests API.
+ 

   
 
@@ -165,8 +185,9 @@
EINVAL

  The  pad
- references a non-existing pad, or the which
- field references a non-existing format.
+ references a non-existing pad, the which
+ field references a non-existing format or the request ID references
+ a nonexistant request.

   
 
diff --git a/Documentation/DocBook/media/v4l/vidioc-subdev-g-selection.xml 
b/Documentation/DocBook/media/v4l/vidioc-subdev-g-selection.xml
index faac955..c0fbfbe 100644
--- a/Documentation/DocBook/media/v4l/vidioc-subdev-g-selection.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-subdev-g-selection.xml
@@ -94,6 +94,13 @@
 handle. Two applications querying the same sub-device would thus not
 interfere with each other.
 
+Applications can get and set selection rectangles stored in a request
+by setting the which field to
+V4L2_SUBDEV_FORMAT_REQUEST and the
+request to the request ID. See
+ for more information about the request
+API.
+
 Drivers must not return an error solely because the requested
 selection rectangle doesn't match the device capabilities. They must 
instead
 modify the rectangle to match what the hardware can provide. The modified
@@ -128,7 +135,7 @@
  
__u32
which
-   Active or try selection, from
+   Selection to be modified, from
.
  
  
@@ -155,7 +162,15 @@
  
  
__u32
-   reserved[8]
+   request
+   Request ID, only valid when the 
which
+   field is set to V4L2_SUBDEV_FORMAT_REQUEST.
+   Applications and drivers must set the field to zero in all other
+   cases.
+ 
+ 
+   __u32
+   reserved[7]
Reserved for future extensions. Applications and drivers must
set the array to zero.
  
@@ -187,8 +202,9 @@
  The 
  pad references a non-existing
  pad, the which field references a
- non-existing format, or the selection target is not
- supported on the given subdev pad.
+ non-existing format, the selection target is not supported on
+ the given subdev pad or the request ID references a nonexistant
+ request.

   
 
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC v2 21/21] DocBook: media: Document request flags

2016-05-24 Thread Sakari Ailus
Signed-off-by: Sakari Ailus 
---
 .../DocBook/media/v4l/media-ioc-request-cmd.xml| 24 ++
 1 file changed, 24 insertions(+)

diff --git a/Documentation/DocBook/media/v4l/media-ioc-request-cmd.xml 
b/Documentation/DocBook/media/v4l/media-ioc-request-cmd.xml
index 4f4acea..14c0068 100644
--- a/Documentation/DocBook/media/v4l/media-ioc-request-cmd.xml
+++ b/Documentation/DocBook/media/v4l/media-ioc-request-cmd.xml
@@ -132,6 +132,13 @@
MEDIA_REQ_CMD_ALLOC and by the application
for all other commands.
  
+ 
+   __u32
+   flags
+   Flags related to a request. See  for the list of
+   flags.
+ 

   
 
@@ -161,6 +168,23 @@

   
 
+
+
+  Media request flags
+  
+
+
+   
+ 
+   MEDIA_REQ_FL_COMPLETE_EVENT
+   Queue and event to the file handle on request
+   completion. This flag is relevant for
+   MEDIA_REQ_CMD_APPLY and
+   MEDIA_REQ_CMD_QUEUE commands.
+ 
+   
+  
+
   
 
   
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC v2 16/21] DocBook: media: Document the media request API

2016-05-24 Thread Sakari Ailus
From: Laurent Pinchart 

The media request API is made of a new ioctl to implement request
management. Document it.

Signed-off-by: Laurent Pinchart 

Strip off the reserved fields.

Signed-off-by: Sakari Ailus 
---
 .../DocBook/media/v4l/media-controller.xml |   1 +
 .../DocBook/media/v4l/media-ioc-request-cmd.xml| 188 +
 2 files changed, 189 insertions(+)
 create mode 100644 Documentation/DocBook/media/v4l/media-ioc-request-cmd.xml

diff --git a/Documentation/DocBook/media/v4l/media-controller.xml 
b/Documentation/DocBook/media/v4l/media-controller.xml
index 5f2fc07..2a5a5d0 100644
--- a/Documentation/DocBook/media/v4l/media-controller.xml
+++ b/Documentation/DocBook/media/v4l/media-controller.xml
@@ -101,5 +101,6 @@
   
   
   
+  
   
 
diff --git a/Documentation/DocBook/media/v4l/media-ioc-request-cmd.xml 
b/Documentation/DocBook/media/v4l/media-ioc-request-cmd.xml
new file mode 100644
index 000..4f4acea
--- /dev/null
+++ b/Documentation/DocBook/media/v4l/media-ioc-request-cmd.xml
@@ -0,0 +1,188 @@
+
+  
+ioctl MEDIA_IOC_REQUEST_CMD
+
+  
+
+  
+MEDIA_IOC_REQUEST_CMD
+Manage media device requests
+  
+
+  
+
+  
+   int ioctl
+   int fd
+   int request
+   struct media_request_cmd 
*argp
+  
+
+  
+
+  
+Arguments
+
+
+  
+   fd
+   
+ File descriptor returned by
+ open().
+   
+  
+  
+   request
+   
+ MEDIA_IOC_REQUEST_CMD
+   
+  
+  
+   argp
+   
+ 
+   
+  
+
+  
+
+  
+Description
+
+The MEDIA_IOC_REQUEST_CMD ioctl allow applications to manage media
+device requests. A request is an object that can group media device
+configuration parameters, including subsystem-specific parameters, in order
+to apply all the parameters atomically. Applications are responsible for
+allocating and deleting requests, filling them with configuration 
parameters
+and (synchronously) applying or (asynchronously) queuing them.
+
+Request operations are performed by calling the MEDIA_IOC_REQUEST_CMD
+ioctl with a pointer to a  with the
+cmd set to the appropriate command.
+ lists the commands supported by
+the ioctl.
+
+The  request field
+contains the ID of the request on which the command operates. For the
+MEDIA_REQ_CMD_ALLOC command the field is set to zero
+by applications and filled by the driver. For all other commands the field
+is set by applications and left untouched by the driver.
+
+To allocate a new request applications use the
+MEDIA_REQ_CMD_ALLOC. The driver will allocate a new
+request and return its ID in the request field.
+
+
+Requests are reference-counted. A newly allocate request is 
referenced
+by the media device file handled on which it has been created, and can be
+later referenced by subsystem-specific operations using the request ID.
+Requests will thus be automatically deleted when they're not longer used
+after the media device file handle is closed.
+
+If a request isn't needed applications can delete it using the
+MEDIA_REQ_CMD_DELETE command. The driver will drop the
+reference to the request stored in the media device file handle. The 
request
+will not be usable through the MEDIA_IOC_REQUEST_CMD ioctl anymore, but 
will
+only be deleted when the last reference is released. If no other reference
+exists when the delete command is invoked the request will be deleted
+immediately.
+
+After creating a request applications should fill it with
+configuration parameters. This is performed through subsystem-specific
+request APIs outside the scope of the media controller API. See the
+appropriate subsystem APIs for more information, including how they 
interact
+with the MEDIA_IOC_REQUEST_CMD ioctl.
+
+Once a request contains all the desired configuration parameters it
+can be applied synchronously or queued asynchronously. To apply a request
+applications use the MEDIA_REQ_CMD_APPLY command. The
+driver will apply all configuration parameters stored in the request to the
+device atomically. The ioctl will return once all parameters have been
+applied, but it should be noted that they might not have fully taken effect
+yet.
+
+To queue a request applications use the
+MEDIA_REQ_CMD_QUEUE command. The driver will queue the
+request for processing and return immediately. The request will then be
+processed and applied after all previously queued requests.
+
+Once a request has been queued applications are not allowed to modify
+its configuration parameters until the request has been fully processed.
+Any attempt to do so will result in the related subsystem API returning
+an error. 

[RFC v2 05/21] media: Add media_device_request_complete() to mark requests complete

2016-05-24 Thread Sakari Ailus
Once the request has been queued and later on completed, a driver will
mark the request complete by calling media_device_request_complete().

Signed-off-by: Sakari Ailus 
---
 drivers/media/media-device.c | 49 
 include/media/media-device.h |  3 +++
 2 files changed, 52 insertions(+)

diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c
index a89d046..16fcc20 100644
--- a/drivers/media/media-device.c
+++ b/drivers/media/media-device.c
@@ -42,6 +42,7 @@ static char *__request_state[] = {
"IDLE",
"QUEUED",
"DELETED",
+   "COMPLETED",
 };
 
 #define request_state(i)   \
@@ -203,6 +204,54 @@ static int media_device_request_delete(struct media_device 
*mdev,
return 0;
 }
 
+void media_device_request_complete(struct media_device *mdev,
+  struct media_device_request *req)
+{
+   struct file *filp;
+   unsigned long flags;
+
+   spin_lock_irqsave(>req_lock, flags);
+
+   if (req->state == MEDIA_DEVICE_REQUEST_STATE_IDLE) {
+   dev_dbg(mdev->dev,
+   "request: not completing an idle request %u\n",
+   req->id);
+   spin_unlock_irqrestore(>req_lock, flags);
+   return;
+   }
+
+   if (WARN_ON(req->state != MEDIA_DEVICE_REQUEST_STATE_QUEUED)) {
+   dev_dbg(mdev->dev, "request: can't delete %u, state %s\n",
+   req->id, request_state(req->state));
+   spin_unlock_irqrestore(>req_lock, flags);
+   return;
+   }
+
+   req->state = MEDIA_DEVICE_REQUEST_STATE_COMPLETE;
+   filp = req->filp;
+   if (filp) {
+   /*
+* If the file handle is still around we remove if
+* from the lists here. Otherwise it has been removed
+* when the file handle closed.
+*/
+   list_del(>list);
+   list_del(>fh_list);
+   req->filp = NULL;
+   }
+
+   spin_unlock_irqrestore(>req_lock, flags);
+
+   /*
+* The driver holds a reference to a request if the filp
+* pointer is non-NULL: the file handle associated to the
+* request may have been released by now, i.e. filp is NULL.
+*/
+   if (filp)
+   media_device_request_put(req);
+}
+EXPORT_SYMBOL_GPL(media_device_request_complete);
+
 static int media_device_request_queue_apply(
struct media_device *mdev, struct media_device_request *req,
int (*fn)(struct media_device *mdev,
diff --git a/include/media/media-device.h b/include/media/media-device.h
index df4afeb..acb7181 100644
--- a/include/media/media-device.h
+++ b/include/media/media-device.h
@@ -269,6 +269,7 @@ enum media_device_request_state {
MEDIA_DEVICE_REQUEST_STATE_IDLE,
MEDIA_DEVICE_REQUEST_STATE_QUEUED,
MEDIA_DEVICE_REQUEST_STATE_DELETED,
+   MEDIA_DEVICE_REQUEST_STATE_COMPLETE,
 };
 
 /**
@@ -765,5 +766,7 @@ struct media_device_request *
 media_device_request_find(struct media_device *mdev, u16 reqid);
 void media_device_request_get(struct media_device_request *req);
 void media_device_request_put(struct media_device_request *req);
+void media_device_request_complete(struct media_device *mdev,
+  struct media_device_request *req);
 
 #endif
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC v2 18/21] DocBook: media: Document the subdev selection API

2016-05-24 Thread Sakari Ailus
From: Laurent Pinchart 

Now that the subdev crop API is considered obsolete, the selection API
that replaces it deserves a full documentation instead of referring to
the crop API documentation.

Signed-off-by: Laurent Pinchart 
---
 .../media/v4l/vidioc-subdev-g-selection.xml| 37 ++
 1 file changed, 37 insertions(+)

diff --git a/Documentation/DocBook/media/v4l/vidioc-subdev-g-selection.xml 
b/Documentation/DocBook/media/v4l/vidioc-subdev-g-selection.xml
index 8346b2e..faac955 100644
--- a/Documentation/DocBook/media/v4l/vidioc-subdev-g-selection.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-subdev-g-selection.xml
@@ -63,6 +63,43 @@
 more information on how each selection target affects the image
 processing pipeline inside the subdevice.
 
+To retrieve a current selection rectangle applications set the
+pad field of a  to the
+desired pad number as reported by the media API, the
+which field to
+V4L2_SUBDEV_FORMAT_ACTIVE and the
+target to the target selection rectangle. They
+then call the VIDIOC_SUBDEV_G_SELECTION ioctl with a
+pointer to this structure. The driver fills the members of the
+r field or returns  if the input
+arguments are invalid, or if selection is not supported on the given pad.
+
+
+To change a current selection rectangle applications set the
+pad, which and
+target fields and all members of the
+r field. They then call the
+VIDIOC_SUBDEV_S_SELECTION ioctl with a pointer to this
+structure. The driver verifies the requested selection rectangle, adjusts 
it
+based on the hardware capabilities and configures the device. Upon return
+the  contains the current selection rectangle as
+would be returned by a VIDIOC_SUBDEV_G_SELECTION call.
+
+
+Applications can query the device capabilities by setting the
+which to
+V4L2_SUBDEV_FORMAT_TRY. When set, 'try' selection
+rectangles are not applied to the device by the driver, but are mangled
+exactly as active selection rectangles and stored in the sub-device file
+handle. Two applications querying the same sub-device would thus not
+interfere with each other.
+
+Drivers must not return an error solely because the requested
+selection rectangle doesn't match the device capabilities. They must 
instead
+modify the rectangle to match what the hardware can provide. The modified
+selection rectangle should be as close as possible to the original request.
+
+
 
   Types of selection targets
 
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC v2 0/21] Media request API

2016-05-24 Thread Sakari Ailus
Hi all,

This is a second version of the RFC set on my request API work. It
includes patches from myself as well as from Hans and Laurent.

The current set can be found here as well:



I keep updating it as I work with the patches. The set depends on two
other sets available discretely in the media-device-fh and
media-ioctl-rework branches. Both sets have been posted to linux-media:

   
   

There's a large number of changes in these patches, mostly fixes linked
list handling and media request object reference management (read: there
were a ton of bugs). Since v1, I've also dropped patch "vb2: Add helper
function to check for request buffers" as I saw no use for it. The
previous set can be found here:



I'm still posting this as an RFC since I believe there are matters to be
resolved until the patches are mergeable.

My own use case for this is a little bit more limited than for some
others, i.e. I only need to bind video buffers to requests. That is
currently functional with these patches. Applying requests has not been
tested nor I have use for the functionality right now.

My open questions and to-do items I'm aware of: 

- Global ID space vs. file handles. Should requests be referred to by 
  global IDs or file handles specific to a process? V4L2 uses IDs but V4L2
  devices (other than m2m) can meaningfully be used only by a single
  program (or co-operative programs) at a time whereas the media device
  could conceivably be accessed and used for different purposes by  
  multiple programs at the same time as the resources accessible through  
  the media device are numerous and often independent of each other. A 
  badly behaving application could disturb other applications using the
  same media device even if no resource conflict exist by accessing the
  same request IDs than other applications. 
  
- Request completion and deletion. Should completed requests be deleted
  automatically, or should the request return to an "empty" state after
  completion? Applications typically have to create a new request right
  after a completion of an earlier one, and sparing one additional IOCTL  
  call would be nice. (In current implementation the requests are deleted 
  in completion, but this would be a trivial change.)

- Video buffers vs. requests. In the current implementation, I'm using 
  VIDIOC_QBUF() from user space to associate buffers with requests. This  
  is convenient in drivers since the only extra steps to support requests 
  (vs. operation without requests) is to find the request and not really  
  queueing the buffer yet. What's noteworthy as well that the VB2 buffer  
  is in correct state after this when the request is queued.  
  
- Subsystem framework specific request information. The requests are about
  the media device, and struct media_device_request is free of e.g. V4L2  
  related information. Adding a pointer to V4L2 related data would make it
  easier to add request handling related functionality to the V4L2  
  framework.  
  
- MEDIA_IOC_REQUEST_CMD + (ALLOC/DELETE/QUEUE/APPLY) vs.
  MEDIA_IOC_REQUEST_(ALLOC/DELETE/QUEUE/APPLY). Should we continue to have
  a single IOCTL on the media device for requests, or should each
  operation on a request have a distinct IOCTL? The current implementation
  has a single IOCTL.  
  
- VB2 queues are quite self-sufficient at the moment. Starting start in a 
  queue requires at least one queued buffer whereas a stream containing
  multiple queues using requests could start e.g. by having a single
  buffer in a request for three streaming queues. The functionality would 
  need to be relaxed to properly support requests.
  
- Limit number of allocated requests and dequeueable events to prevent 
  unintentional or intentional system memory exhaustion.

- Video buffer handling is currently done in a driver I'm working on. Much
  of this should be moved to the framework.

- Queueing requests vs. video buffer queue state. This is a real pain
  point. Queueing a request to hardware requires serialisation with video
  buffer queue state changes, i.e. stop_stream and start_stream video
  buffer queue callbacks for every queue which is a part of the pipeline.
  That is, for streaming devices.

  The problem comes from the fact that for queueing the request all the
  queues of the pipeline need to be in the streaming state and all the
  buffers bound to the request need to be in VB2_BUF_STATE_QUEUED as well.
  Let's see if this could be moved to the framework, 

[RFC v2 04/21] media: Only requests in IDLE state may be deleted

2016-05-24 Thread Sakari Ailus
Prevent deleting queued requests. Also mark deleted requests as such by
adding a new state for them.

Signed-off-by: Sakari Ailus 
---
 drivers/media/media-device.c | 21 +
 include/media/media-device.h |  1 +
 2 files changed, 18 insertions(+), 4 deletions(-)

diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c
index 247587b..a89d046 100644
--- a/drivers/media/media-device.c
+++ b/drivers/media/media-device.c
@@ -41,6 +41,7 @@
 static char *__request_state[] = {
"IDLE",
"QUEUED",
+   "DELETED",
 };
 
 #define request_state(i)   \
@@ -168,12 +169,22 @@ out_ida_simple_remove:
return ret;
 }
 
-static void media_device_request_delete(struct media_device *mdev,
-   struct media_device_request *req)
+static int media_device_request_delete(struct media_device *mdev,
+  struct media_device_request *req)
 {
unsigned long flags;
 
spin_lock_irqsave(>req_lock, flags);
+
+   if (req->state != MEDIA_DEVICE_REQUEST_STATE_IDLE) {
+   spin_unlock_irqrestore(>req_lock, flags);
+   dev_dbg(mdev->dev, "request: can't delete %u, state %s\n",
+   req->id, request_state(req->state));
+   return -EINVAL;
+   }
+
+   req->state = MEDIA_DEVICE_REQUEST_STATE_DELETED;
+
if (req->filp) {
/*
 * If the file handle is gone by now the
@@ -184,9 +195,12 @@ static void media_device_request_delete(struct 
media_device *mdev,
list_del(>fh_list);
req->filp = NULL;
}
+
spin_unlock_irqrestore(>req_lock, flags);
 
media_device_request_put(req);
+
+   return 0;
 }
 
 static int media_device_request_queue_apply(
@@ -252,8 +266,7 @@ static long media_device_request_cmd(struct media_device 
*mdev,
break;
 
case MEDIA_REQ_CMD_DELETE:
-   media_device_request_delete(mdev, req);
-   ret = 0;
+   ret = media_device_request_delete(mdev, req);
break;
 
case MEDIA_REQ_CMD_APPLY:
diff --git a/include/media/media-device.h b/include/media/media-device.h
index 893e10b..df4afeb 100644
--- a/include/media/media-device.h
+++ b/include/media/media-device.h
@@ -268,6 +268,7 @@ struct media_device;
 enum media_device_request_state {
MEDIA_DEVICE_REQUEST_STATE_IDLE,
MEDIA_DEVICE_REQUEST_STATE_QUEUED,
+   MEDIA_DEVICE_REQUEST_STATE_DELETED,
 };
 
 /**
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH/RFC v2 1/4] v4l: Add metadata buffer type and format

2016-05-24 Thread Sakari Ailus
Hi Hans,

On Tue, May 24, 2016 at 05:36:42PM +0200, Hans Verkuil wrote:
> On 05/24/2016 05:28 PM, Sakari Ailus wrote:
> > Hi Hans,
> > 
> >> Should it be mentioned here that changing the video format might change
> >> the buffersize? In case the buffersize is always a multiple of the width?
> > 
> > Isn't that the case in general, as with pixel formats? buffersize could also
> > be something else than a multiple of width (there's no width for metadata
> > formats) due to e.g. padding required by hardware.
> 
> Well, I don't think it is obvious that the metadata buffersize depends on the
> video width. Perhaps developers who are experienced with CSI know this, but
> if you know little or nothing about CSI, then it can be unexpected (hey, that
> was the case for me!).
> 
> I think it doesn't hurt to mention this relation.

Ah, I think I misunderstood you first.

Typically the metadata width is the same as the image data width, that's
true. And it's how the hardware works. This is still visible in the media
bus format and the solution belongs rather to how multiple streams over a
single link are supported.

It's just that setting the image media bus format affects the metadata media
bus format. I guess that could be mentioned albeit it's hardware specific,
on some sensors metadata width is independent of the image width. Even then
this is not where I'd put it. I'd get back to the topic when documenting how
the API for multiple streams over a single link works.

-- 
Kind regards,

Sakari Ailus
e-mail: sakari.ai...@iki.fi XMPP: sai...@retiisi.org.uk
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/2] drm/exynos: g2d: Add support for old S5Pv210 type

2016-05-24 Thread Tobias Jakobi
Hello Krzysztof,


Krzysztof Kozlowski wrote:
> On 05/24/2016 03:49 PM, Tobias Jakobi wrote:
>> Hello Krzysztof,
>>
>> are you sure that these are the only differences. Because AFAIK there
>> are quite a few more:
>> - DMA submission of commands
>> - blend mode / rounding
>> - solid fill
>> - YCrCb support
>> - and probably more
>>
>> One would need to add least split the command list parser into a v3 and
>> v41 version to accomodate for the differences. In fact userspace/libdrm
>> would need to know which hw type it currently uses, but you currently
>> always return 4.1 in the corresponding ioctl.
> 
> Eh, so probably my patch does not cover fully the support for v3 G2D. I
> looked mostly at the differences between v3 and v4 in the s5p-g2d driver
> itself. However you are right that this might be not sufficient because
> exynos-g2d moved forward and is different than s5p-g2d.
> 
>> Krzysztof Kozlowski wrote:
>>> The non-DRM s5p-g2d driver supports two versions of G2D: v3.0 on
>>> S5Pv210 and v4.x on Exynos 4x12 (or newer). The driver for 3.0 device
>>> version is doing two things differently:
>>> 1. Before starting the render process, it invalidates caches (pattern,
>>>source buffer and mask buffer). Cache control is not present on v4.x
>>>device.
>>> 2. Scalling is done through StretchEn command (in BITBLT_COMMAND_REG
>>>register) instead of SRC_SCALE_CTRL_REG as in v4.x. However the
>>>exynos_drm_g2d driver does not implement the scalling so this
>>>difference can be eliminated.
>> Huh? Where did you get this from? Scaling works with the DRM driver.
> 
> I was looking for the usage of scaling reg (as there is no scaling
> command). How the scaling is implemented then?
Like you said above the drivers work completly different. The DRM one
receives a command list that is constructed by userspace (libdrm
mostly), copies it to a contiguous buffer and passes the memory address
of that buffer to the engine which then works on it. Of course
everything is slightly more complex.

You don't see any reference to scaling in the driver because the scaling
regs don't need any kind of specific validation.

If you want to know how the command list is constructed, the best way is
to look into libdrm. The Exynos specific tests actually cover scaling.


With best wishes,
Tobias


> Thanks for feedback!
> 
> Best regards,
> Krzysztof
> 

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[GIT PULL] mem2mem fixes

2016-05-24 Thread Kamil Debski
The following changes since commit aff093d4bbca91f543e24cde2135f393b8130f4b:

  [media] exynos-gsc: avoid build warning without CONFIG_OF (2016-05-09
18:38:33 -0300)

are available in the git repository at:

  git://linuxtv.org/kdebski/media_tree_2.git fixes-20160524

for you to fetch changes up to 8295280677afd409c32839e47b49de2f20ee459a:

  s5p-mfc: fix a typo in s5p_mfc_dec (2016-05-24 16:41:43 +0200)


Javier Martinez Canillas (4):
  s5p-mfc: Don't try to put pm->clock if lookup failed
  s5p-mfc: Set device name for reserved memory region devs
  s5p-mfc: Add release callback for memory region devs
  s5p-mfc: Fix race between s5p_mfc_probe() and s5p_mfc_open()

ayaka (4):
  s5p-mfc: don't close instance after free OUTPUT buffers
  s5p-mfc: Add handling of buffer freeing reqbufs request
  s5p-mfc: remove unnecessary check in try_fmt
  s5p-mfc: fix a typo in s5p_mfc_dec

 drivers/media/platform/s5p-mfc/s5p_mfc.c | 50
++--
 drivers/media/platform/s5p-mfc/s5p_mfc_dec.c |  3 +-
 drivers/media/platform/s5p-mfc/s5p_mfc_enc.c | 12 ++-
 drivers/media/platform/s5p-mfc/s5p_mfc_pm.c  |  1 +
 4 files changed, 37 insertions(+), 29 deletions(-)

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH/RFC v2 1/4] v4l: Add metadata buffer type and format

2016-05-24 Thread Hans Verkuil
On 05/24/2016 05:28 PM, Sakari Ailus wrote:
> Hi Hans,
> 
>> Should it be mentioned here that changing the video format might change
>> the buffersize? In case the buffersize is always a multiple of the width?
> 
> Isn't that the case in general, as with pixel formats? buffersize could also
> be something else than a multiple of width (there's no width for metadata
> formats) due to e.g. padding required by hardware.

Well, I don't think it is obvious that the metadata buffersize depends on the
video width. Perhaps developers who are experienced with CSI know this, but
if you know little or nothing about CSI, then it can be unexpected (hey, that
was the case for me!).

I think it doesn't hurt to mention this relation.

Regards,

Hans
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH/RFC v2 1/4] v4l: Add metadata buffer type and format

2016-05-24 Thread Sakari Ailus
Hi Hans,

On Mon, May 23, 2016 at 12:09:16PM +0200, Hans Verkuil wrote:
> On 05/12/2016 02:18 AM, Laurent Pinchart wrote:
> > The metadata buffer type is used to transfer metadata between userspace
> > and kernelspace through a V4L2 buffers queue. It comes with a new
> > metadata capture capability and format description.
> 
> Thanks for the patch! I have some comments/suggestions below:
> 
> > 
> > Signed-off-by: Laurent Pinchart 
> > ---
> >  Documentation/DocBook/media/v4l/dev-meta.xml  | 93 
> > +++
> >  Documentation/DocBook/media/v4l/v4l2.xml  |  1 +
> >  drivers/media/v4l2-core/v4l2-compat-ioctl32.c | 19 ++
> >  drivers/media/v4l2-core/v4l2-dev.c| 16 +++--
> >  drivers/media/v4l2-core/v4l2-ioctl.c  | 34 ++
> >  drivers/media/v4l2-core/videobuf2-v4l2.c  |  3 +
> >  include/media/v4l2-ioctl.h|  8 +++
> >  include/uapi/linux/videodev2.h| 14 
> >  8 files changed, 182 insertions(+), 6 deletions(-)
> >  create mode 100644 Documentation/DocBook/media/v4l/dev-meta.xml
> > 
> > diff --git a/Documentation/DocBook/media/v4l/dev-meta.xml 
> > b/Documentation/DocBook/media/v4l/dev-meta.xml
> > new file mode 100644
> > index ..9b5b1fba2007
> > --- /dev/null
> > +++ b/Documentation/DocBook/media/v4l/dev-meta.xml
> > @@ -0,0 +1,93 @@
> > +  Metadata Interface
> > +
> > +  
> > +Experimental
> > +This is an  experimental 
> 
> No space before/after 'experimental'. It will look ugly in the docbook (I 
> tried
> it :-) ).
> 
> > +interface and may change in the future.
> > +  
> > +
> > +  
> > +Metadata refers to any non-image data that supplements video frames with
> > +additional information. This may include statistics computed over the image
> > +or frame capture parameters supplied by the image source. This interface is
> > +intended for transfer of metadata to userspace and control of that 
> > operation.
> 
> I think it can also be in the other direction. I'm thinking of metadata needed
> by codecs. I'm not sure if it should be mentioned that this is not supported 
> at
> the moment and that the ML should be contacted for more info if someone wants 
> this.

Good point.

> 
> > +  
> > +
> > +  
> > +The metadata interface is implemented on video capture devices. The device 
> > can
> 
> s/on/for/?
> 
> > +be dedicated to metadata or can implement both video and metadata capture 
> > as
> > +specified in its reported capabilities.
> > +  
> > +
> > +  
> > +Querying Capabilities
> > +
> > +
> > +Devices supporting the metadata interface set the
> > +V4L2_CAP_META_CAPTURE flag in the
> > +capabilities field of 
> > +returned by the  ioctl. That flag means the device can 
> > capture
> > +metadata to memory.
> > +
> 
> I know this is a copy and paste from the other interface descriptions, but it
> is rather outdated. I would write this instead:
> 
>  
> Device nodes supporting the metadata interface set the
> V4L2_CAP_META_CAPTURE flag in the
> device_caps field of 
> returned by the  ioctl. That flag means the device node can 
> capture
> metadata to memory.
>  
> 
> Any driver using this will be recent and always have a valid device_caps field
> (which, as you know, didn't exist in old kernels).
> 
> I find the capabilities field fairly useless in most cases due to the fact 
> that
> it contains the capabilities of all device nodes created by the device driver.
> 
> > +
> > +At least one of the read/write or streaming I/O methods must be supported.
> > +
> > +  
> > +
> > +  
> > +Data Format Negotiation
> > +
> > +
> > +The metadata device uses the format ioctls to
> > +select the capture format. The metadata buffer content format is bound to 
> > that
> > +selectable format. In addition to the basic
> > +format ioctls, the  ioctl
> > +must be supported as well.
> > +
> > +
> > +
> > +To use the format ioctls applications set the
> > +type field of a  to
> > +V4L2_BUF_TYPE_META_CAPTURE and use the 
> > 
> > +meta member of the 
> > fmt
> > +union as needed per the desired operation.
> > +Currently there are two fields, dataformat and
> > +buffersize, of struct  that 
> > are
> > +used. Content of the dataformat is the V4L2 
> > FourCC
> > +code of the data format. The buffersize field 
> > is the
> > +maximum buffer size in bytes required for data transfer, set by the driver 
> > in
> > +order to inform applications.
> 
> Should it be mentioned here that changing the video format might change
> the buffersize? In case the buffersize is always a multiple of the width?

Isn't that the case in general, as with pixel formats? buffersize could also
be something else than a multiple of width (there's no width for metadata
formats) due to e.g. padding required by hardware.

-- 
Kind regards,

Sakari Ailus
e-mail: sakari.ai...@iki.fi XMPP: sai...@retiisi.org.uk
--
To unsubscribe from this list: send the line 

Re: [PATCH for 4.7] v4l2-ioctl: fix stupid mistake in cropcap condition

2016-05-24 Thread Sakari Ailus
On Mon, May 23, 2016 at 01:45:44PM +0200, Hans Verkuil wrote:
> Fix duplicate tests in condition. The second test for vidioc_cropcap
> should have tested for vidioc_g_selection instead.
> 
> Signed-off-by: Hans Verkuil 
> Reported-by: David Binderman 

Acked-by: Sakari Ailus 

-- 
Sakari Ailus
e-mail: sakari.ai...@iki.fi XMPP: sai...@retiisi.org.uk
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v1 0/3] Add V4L2_PIX_FMT_VP9

2016-05-24 Thread Wu-Cheng Li
This patch series add V4L2_PIX_FMT_VP9 and the documentation.

Wu-Cheng Li (3):
  videodev2.h: add V4L2_PIX_FMT_VP9 format.
  v4l2-ioctl: add VP9 format description.
  V4L: add VP9 format documentation

 Documentation/DocBook/media/v4l/pixfmt.xml | 5 +
 drivers/media/v4l2-core/v4l2-ioctl.c   | 1 +
 include/uapi/linux/videodev2.h | 1 +
 3 files changed, 7 insertions(+)

-- 
2.8.0.rc3.226.g39d4020

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v1 1/3] videodev2.h: add V4L2_PIX_FMT_VP9 format.

2016-05-24 Thread Wu-Cheng Li
This adds VP9 video coding format, a successor to VP8.

Signed-off-by: Wu-Cheng Li 
---
 include/uapi/linux/videodev2.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
index 8f95191..a95f940 100644
--- a/include/uapi/linux/videodev2.h
+++ b/include/uapi/linux/videodev2.h
@@ -594,6 +594,7 @@ struct v4l2_pix_format {
 #define V4L2_PIX_FMT_VC1_ANNEX_G v4l2_fourcc('V', 'C', '1', 'G') /* SMPTE 421M 
Annex G compliant stream */
 #define V4L2_PIX_FMT_VC1_ANNEX_L v4l2_fourcc('V', 'C', '1', 'L') /* SMPTE 421M 
Annex L compliant stream */
 #define V4L2_PIX_FMT_VP8  v4l2_fourcc('V', 'P', '8', '0') /* VP8 */
+#define V4L2_PIX_FMT_VP9  v4l2_fourcc('V', 'P', '9', '0') /* VP9 */
 
 /*  Vendor-specific formats   */
 #define V4L2_PIX_FMT_CPIA1v4l2_fourcc('C', 'P', 'I', 'A') /* cpia1 YUV */
-- 
2.8.0.rc3.226.g39d4020

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v1 3/3] V4L: add VP9 format documentation

2016-05-24 Thread Wu-Cheng Li
Add documentation for V4L2_PIX_FMT_VP9.

Signed-off-by: Wu-Cheng Li 
---
 Documentation/DocBook/media/v4l/pixfmt.xml | 5 +
 1 file changed, 5 insertions(+)

diff --git a/Documentation/DocBook/media/v4l/pixfmt.xml 
b/Documentation/DocBook/media/v4l/pixfmt.xml
index 5a08aee..ab915c3 100644
--- a/Documentation/DocBook/media/v4l/pixfmt.xml
+++ b/Documentation/DocBook/media/v4l/pixfmt.xml
@@ -1735,6 +1735,11 @@ extended control 
V4L2_CID_MPEG_STREAM_TYPE, see
'VP80'
VP8 video elementary stream.
  
+ 
+   V4L2_PIX_FMT_VP9
+   'VP90'
+   VP9 video elementary stream.
+ 

   
 
-- 
2.8.0.rc3.226.g39d4020

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v1 2/3] v4l2-ioctl: add VP9 format description.

2016-05-24 Thread Wu-Cheng Li
VP9 is a video coding format and a successor to VP8.

Signed-off-by: Wu-Cheng Li 
---
 drivers/media/v4l2-core/v4l2-ioctl.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c 
b/drivers/media/v4l2-core/v4l2-ioctl.c
index 28e5be2..8f3e631 100644
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
@@ -1264,6 +1264,7 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt)
case V4L2_PIX_FMT_VC1_ANNEX_G:  descr = "VC-1 (SMPTE 412M Annex 
G)"; break;
case V4L2_PIX_FMT_VC1_ANNEX_L:  descr = "VC-1 (SMPTE 412M Annex 
L)"; break;
case V4L2_PIX_FMT_VP8:  descr = "VP8"; break;
+   case V4L2_PIX_FMT_VP9:  descr = "VP9"; break;
case V4L2_PIX_FMT_CPIA1:descr = "GSPCA CPiA YUV"; break;
case V4L2_PIX_FMT_WNVA: descr = "WNVA"; break;
case V4L2_PIX_FMT_SN9C10X:  descr = "GSPCA SN9C10X"; break;
-- 
2.8.0.rc3.226.g39d4020

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2] [media] adv7604: Add support for hardware reset

2016-05-24 Thread Dragos Bogdan
The part can be reset by a low pulse on the RESET pin (i.e. a hardware
reset) with a minimum width of 5 ms. It is recommended to wait 5 ms
after the low pulse before an I2C write is performed to the part.
For safety reasons, the delays will be between 5 and 10 ms.

The RESET pin can be tied high, so the GPIO is optional.

Signed-off-by: Dragos Bogdan 
---
Changes since v1:
 - Replace mdelay() with usleep_range();
 - Limit the comments to 75 characters per line.

 drivers/media/i2c/adv7604.c | 22 ++
 1 file changed, 22 insertions(+)

diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c
index 41a1bfc..73c79bb 100644
--- a/drivers/media/i2c/adv7604.c
+++ b/drivers/media/i2c/adv7604.c
@@ -164,6 +164,7 @@ struct adv76xx_state {
struct adv76xx_platform_data pdata;
 
struct gpio_desc *hpd_gpio[4];
+   struct gpio_desc *reset_gpio;
 
struct v4l2_subdev sd;
struct media_pad pads[ADV76XX_PAD_MAX];
@@ -2996,6 +2997,21 @@ static int configure_regmaps(struct adv76xx_state *state)
return 0;
 }
 
+static int adv76xx_reset(struct adv76xx_state *state)
+{
+   if (state->reset_gpio) {
+   /* ADV76XX can be reset by a low reset pulse of minimum 5 ms. */
+   gpiod_set_value_cansleep(state->reset_gpio, 0);
+   usleep_range(5000, 1);
+   gpiod_set_value_cansleep(state->reset_gpio, 1);
+   /* It is recommended to wait 5 ms after the low pulse before */
+   /* an I2C write is performed to the ADV76XX. */
+   usleep_range(5000, 1);
+   }
+
+   return 0;
+}
+
 static int adv76xx_probe(struct i2c_client *client,
 const struct i2c_device_id *id)
 {
@@ -3059,6 +3075,12 @@ static int adv76xx_probe(struct i2c_client *client,
if (state->hpd_gpio[i])
v4l_info(client, "Handling HPD %u GPIO\n", i);
}
+   state->reset_gpio = devm_gpiod_get_optional(>dev, "reset",
+   GPIOD_OUT_HIGH);
+   if (IS_ERR(state->reset_gpio))
+   return PTR_ERR(state->reset_gpio);
+
+   adv76xx_reset(state);
 
state->timings = cea640x480;
state->format = adv76xx_format_info(state, MEDIA_BUS_FMT_YUYV8_2X8);
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/2] drm/exynos: g2d: Add support for old S5Pv210 type

2016-05-24 Thread Krzysztof Kozlowski
On 05/24/2016 03:49 PM, Tobias Jakobi wrote:
> Hello Krzysztof,
> 
> are you sure that these are the only differences. Because AFAIK there
> are quite a few more:
> - DMA submission of commands
> - blend mode / rounding
> - solid fill
> - YCrCb support
> - and probably more
> 
> One would need to add least split the command list parser into a v3 and
> v41 version to accomodate for the differences. In fact userspace/libdrm
> would need to know which hw type it currently uses, but you currently
> always return 4.1 in the corresponding ioctl.

Eh, so probably my patch does not cover fully the support for v3 G2D. I
looked mostly at the differences between v3 and v4 in the s5p-g2d driver
itself. However you are right that this might be not sufficient because
exynos-g2d moved forward and is different than s5p-g2d.

> Krzysztof Kozlowski wrote:
>> The non-DRM s5p-g2d driver supports two versions of G2D: v3.0 on
>> S5Pv210 and v4.x on Exynos 4x12 (or newer). The driver for 3.0 device
>> version is doing two things differently:
>> 1. Before starting the render process, it invalidates caches (pattern,
>>source buffer and mask buffer). Cache control is not present on v4.x
>>device.
>> 2. Scalling is done through StretchEn command (in BITBLT_COMMAND_REG
>>register) instead of SRC_SCALE_CTRL_REG as in v4.x. However the
>>exynos_drm_g2d driver does not implement the scalling so this
>>difference can be eliminated.
> Huh? Where did you get this from? Scaling works with the DRM driver.

I was looking for the usage of scaling reg (as there is no scaling
command). How the scaling is implemented then?

Thanks for feedback!

Best regards,
Krzysztof

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/2] drm/exynos: g2d: Add support for old S5Pv210 type

2016-05-24 Thread Tobias Jakobi
Hello Krzysztof,

are you sure that these are the only differences. Because AFAIK there
are quite a few more:
- DMA submission of commands
- blend mode / rounding
- solid fill
- YCrCb support
- and probably more

One would need to add least split the command list parser into a v3 and
v41 version to accomodate for the differences. In fact userspace/libdrm
would need to know which hw type it currently uses, but you currently
always return 4.1 in the corresponding ioctl.


Krzysztof Kozlowski wrote:
> The non-DRM s5p-g2d driver supports two versions of G2D: v3.0 on
> S5Pv210 and v4.x on Exynos 4x12 (or newer). The driver for 3.0 device
> version is doing two things differently:
> 1. Before starting the render process, it invalidates caches (pattern,
>source buffer and mask buffer). Cache control is not present on v4.x
>device.
> 2. Scalling is done through StretchEn command (in BITBLT_COMMAND_REG
>register) instead of SRC_SCALE_CTRL_REG as in v4.x. However the
>exynos_drm_g2d driver does not implement the scalling so this
>difference can be eliminated.
Huh? Where did you get this from? Scaling works with the DRM driver.


With best wishes,
Tobias


> After adding support for v3.0 to exynos_drm_g2d driver, the old driver
> can be removed.
> 
> Cc: Kyungmin Park 
> Cc: Kamil Debski 
> Signed-off-by: Krzysztof Kozlowski 
> ---
>  drivers/gpu/drm/exynos/exynos_drm_g2d.c | 37 
> +++--
>  drivers/gpu/drm/exynos/exynos_drm_g2d.h |  7 +++
>  2 files changed, 42 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c 
> b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
> index 493552368295..44d8b28e9d98 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c
> +++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
> @@ -19,6 +19,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  
>  #include 
>  #include 
> @@ -38,6 +39,7 @@
>  #define G2D_SOFT_RESET   0x
>  #define G2D_INTEN0x0004
>  #define G2D_INTC_PEND0x000C
> +#define G2D_CACHECTL 0x0018 /* S5PV210 specific */
>  #define G2D_DMA_SFR_BASE_ADDR0x0080
>  #define G2D_DMA_COMMAND  0x0084
>  #define G2D_DMA_STATUS   0x008C
> @@ -78,6 +80,11 @@
>  #define G2D_INTP_GCMD_FIN(1 << 1)
>  #define G2D_INTP_SCMD_FIN(1 << 0)
>  
> +/* G2D_CACHECTL, S5PV210 specific */
> +#define G2D_CACHECTL_PATCACHE(BIT(2))
> +#define G2D_CACHECTL_SRCBUFFER   (BIT(1))
> +#define G2D_CACHECTL_MASKBUFFER  (BIT(0))
> +
>  /* G2D_DMA_COMMAND */
>  #define G2D_DMA_HALT (1 << 2)
>  #define G2D_DMA_CONTINUE (1 << 1)
> @@ -245,6 +252,7 @@ struct g2d_data {
>  
>   unsigned long   current_pool;
>   unsigned long   max_pool;
> + enum exynos_drm_g2d_typetype;
>  };
>  
>  static int g2d_init_cmdlist(struct g2d_data *g2d)
> @@ -1125,6 +1133,13 @@ int exynos_g2d_set_cmdlist_ioctl(struct drm_device 
> *drm_dev, void *data,
>   cmdlist->data[cmdlist->last++] = G2D_SRC_BASE_ADDR;
>   cmdlist->data[cmdlist->last++] = 0;
>  
> + if (g2d->type == EXYNOS_DRM_G2D_TYPE_3X) {
> + cmdlist->data[cmdlist->last++] = G2D_CACHECTL;
> + cmdlist->data[cmdlist->last++] = G2D_CACHECTL_PATCACHE |
> +  G2D_CACHECTL_SRCBUFFER |
> +  G2D_CACHECTL_MASKBUFFER;
> + }
> +
>   /*
>* 'LIST_HOLD' command should be set to the DMA_HOLD_CMD_REG
>* and GCF bit should be set to INTEN register if user wants
> @@ -1369,10 +1384,20 @@ static int g2d_probe(struct platform_device *pdev)
>   struct exynos_drm_subdrv *subdrv;
>   int ret;
>  
> + /* Sanity check, we can be instatiated only from DT */
> + if (!dev->of_node)
> + return -EINVAL;
> +
>   g2d = devm_kzalloc(dev, sizeof(*g2d), GFP_KERNEL);
>   if (!g2d)
>   return -ENOMEM;
>  
> + g2d->type = (enum exynos_drm_g2d_type)of_device_get_match_data(dev);
> + if (g2d->type == EXYNOS_DRM_G2D_TYPE_UNKNOWN) {
> + dev_err(dev, "failed to get type of device\n");
> + return -EINVAL;
> + }
> +
>   g2d->runqueue_slab = kmem_cache_create("g2d_runqueue_slab",
>   sizeof(struct g2d_runqueue_node), 0, 0, NULL);
>   if (!g2d->runqueue_slab)
> @@ -1535,8 +1560,16 @@ static const struct dev_pm_ops g2d_pm_ops = {
>  };
>  
>  static const struct of_device_id exynos_g2d_match[] = {
> - { .compatible = "samsung,exynos5250-g2d" },
> - { .compatible = "samsung,exynos4212-g2d" },
> + {
> + .compatible = "samsung,exynos5250-g2d",
> + .data = (void *)EXYNOS_DRM_G2D_TYPE_4X,
> + }, {
> +

[PATCH v4 1/7] of: reserved_mem: add support for using more than one region for given device

2016-05-24 Thread Marek Szyprowski
This patch allows device drivers to initialize more than one reserved
memory region assigned to given device. When driver needs to use more
than one reserved memory region, it should allocate child devices and
initialize regions by index for each of its child devices.

Signed-off-by: Marek Szyprowski 
---
 drivers/of/of_reserved_mem.c| 85 +++--
 include/linux/of_reserved_mem.h | 25 ++--
 2 files changed, 86 insertions(+), 24 deletions(-)

diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
index ed01c01..04e4fe5 100644
--- a/drivers/of/of_reserved_mem.c
+++ b/drivers/of/of_reserved_mem.c
@@ -21,6 +21,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #define MAX_RESERVED_REGIONS   16
 static struct reserved_mem reserved_mem[MAX_RESERVED_REGIONS];
@@ -289,53 +290,95 @@ static inline struct reserved_mem *__find_rmem(struct 
device_node *node)
return NULL;
 }
 
+struct rmem_assigned_device {
+   struct device *dev;
+   struct reserved_mem *rmem;
+   struct list_head list;
+};
+
+static LIST_HEAD(of_rmem_assigned_device_list);
+static DEFINE_MUTEX(of_rmem_assigned_device_mutex);
+
 /**
- * of_reserved_mem_device_init() - assign reserved memory region to given 
device
+ * of_reserved_mem_device_init_by_idx() - assign reserved memory region to
+ *   given device
+ * @dev:   Pointer to the device to configure
+ * @np:Pointer to the device_node with 'reserved-memory' 
property
+ * @idx:   Index of selected region
  *
- * This function assign memory region pointed by "memory-region" device tree
- * property to the given device.
+ * This function assigns respective DMA-mapping operations based on reserved
+ * memory region specified by 'memory-region' property in @np node to the @dev
+ * device. When driver needs to use more than one reserved memory region, it
+ * should allocate child devices and initialize regions by name for each of
+ * child device.
+ *
+ * Returns error code or zero on success.
  */
-int of_reserved_mem_device_init(struct device *dev)
+int of_reserved_mem_device_init_by_idx(struct device *dev,
+  struct device_node *np, int idx)
 {
+   struct rmem_assigned_device *rd;
+   struct device_node *target;
struct reserved_mem *rmem;
-   struct device_node *np;
int ret;
 
-   np = of_parse_phandle(dev->of_node, "memory-region", 0);
-   if (!np)
-   return -ENODEV;
+   if (!np || !dev)
+   return -EINVAL;
+
+   target = of_parse_phandle(np, "memory-region", idx);
+   if (!target)
+   return -EINVAL;
 
-   rmem = __find_rmem(np);
-   of_node_put(np);
+   rmem = __find_rmem(target);
+   of_node_put(target);
 
if (!rmem || !rmem->ops || !rmem->ops->device_init)
return -EINVAL;
 
+   rd = kmalloc(sizeof(struct rmem_assigned_device), GFP_KERNEL);
+   if (!rd)
+   return -ENOMEM;
+
ret = rmem->ops->device_init(rmem, dev);
-   if (ret == 0)
+   if (ret == 0) {
+   rd->dev = dev;
+   rd->rmem = rmem;
+
+   mutex_lock(_rmem_assigned_device_mutex);
+   list_add(>list, _rmem_assigned_device_list);
+   mutex_unlock(_rmem_assigned_device_mutex);
+
dev_info(dev, "assigned reserved memory node %s\n", rmem->name);
+   } else {
+   kfree(rd);
+   }
 
return ret;
 }
-EXPORT_SYMBOL_GPL(of_reserved_mem_device_init);
+EXPORT_SYMBOL_GPL(of_reserved_mem_device_init_by_idx);
 
 /**
  * of_reserved_mem_device_release() - release reserved memory device structures
+ * @dev:   Pointer to the device to deconfigure
  *
  * This function releases structures allocated for memory region handling for
  * the given device.
  */
 void of_reserved_mem_device_release(struct device *dev)
 {
-   struct reserved_mem *rmem;
-   struct device_node *np;
-
-   np = of_parse_phandle(dev->of_node, "memory-region", 0);
-   if (!np)
-   return;
-
-   rmem = __find_rmem(np);
-   of_node_put(np);
+   struct rmem_assigned_device *rd;
+   struct reserved_mem *rmem = NULL;
+
+   mutex_lock(_rmem_assigned_device_mutex);
+   list_for_each_entry(rd, _rmem_assigned_device_list, list) {
+   if (rd->dev == dev) {
+   rmem = rd->rmem;
+   list_del(>list);
+   kfree(rd);
+   break;
+   }
+   }
+   mutex_unlock(_rmem_assigned_device_mutex);
 
if (!rmem || !rmem->ops || !rmem->ops->device_release)
return;
diff --git a/include/linux/of_reserved_mem.h b/include/linux/of_reserved_mem.h
index ad2f670..1779cda 100644
--- a/include/linux/of_reserved_mem.h
+++ b/include/linux/of_reserved_mem.h
@@ -1,7 +1,8 @@
 

[PATCH v4 3/7] media: s5p-mfc: replace custom reserved memory handling code with generic one

2016-05-24 Thread Marek Szyprowski
This patch removes custom code for initialization and handling of
reserved memory regions in s5p-mfc driver and replaces it with generic
reserved memory regions api.

s5p-mfc driver now handles two reserved memory regions defined by
generic reserved memory bindings. Support for non-dt platform has been
removed, because all supported platforms have been already converted to
device tree.

Signed-off-by: Marek Szyprowski 
---
 drivers/media/platform/s5p-mfc/s5p_mfc.c | 138 ++-
 1 file changed, 63 insertions(+), 75 deletions(-)

diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c 
b/drivers/media/platform/s5p-mfc/s5p_mfc.c
index d1d9d388..fff5f43 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c
@@ -22,6 +22,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include "s5p_mfc_common.h"
 #include "s5p_mfc_ctrl.h"
@@ -1043,66 +1044,71 @@ static const struct v4l2_file_operations s5p_mfc_fops = 
{
.mmap = s5p_mfc_mmap,
 };
 
-static int match_child(struct device *dev, void *data)
-{
-   if (!dev_name(dev))
-   return 0;
-   return !strcmp(dev_name(dev), (char *)data);
-}
-
+/* DMA memory related helper functions */
 static void s5p_mfc_memdev_release(struct device *dev)
 {
-   dma_release_declared_memory(dev);
+   of_reserved_mem_device_release(dev);
 }
 
-static void *mfc_get_drv_data(struct platform_device *pdev);
-
-static int s5p_mfc_alloc_memdevs(struct s5p_mfc_dev *dev)
+static struct device *s5p_mfc_alloc_memdev(struct device *dev,
+  const char *name, unsigned int idx)
 {
-   unsigned int mem_info[2] = { };
+   struct device *child;
+   int ret;
 
-   dev->mem_dev_l = devm_kzalloc(>plat_dev->dev,
-   sizeof(struct device), GFP_KERNEL);
-   if (!dev->mem_dev_l) {
-   mfc_err("Not enough memory\n");
-   return -ENOMEM;
+   child = devm_kzalloc(dev, sizeof(struct device), GFP_KERNEL);
+   if (!child)
+   return NULL;
+
+   device_initialize(child);
+   dev_set_name(child, "%s:%s", dev_name(dev), name);
+   child->parent = dev;
+   child->bus = dev->bus;
+   child->coherent_dma_mask = dev->coherent_dma_mask;
+   child->dma_mask = dev->dma_mask;
+   child->release = s5p_mfc_memdev_release;
+
+   if (device_add(child) == 0) {
+   ret = of_reserved_mem_device_init_by_idx(child, dev->of_node,
+idx);
+   if (ret == 0)
+   return child;
}
 
-   dev_set_name(dev->mem_dev_l, "%s", "s5p-mfc-l");
-   dev->mem_dev_l->release = s5p_mfc_memdev_release;
-   device_initialize(dev->mem_dev_l);
-   of_property_read_u32_array(dev->plat_dev->dev.of_node,
-   "samsung,mfc-l", mem_info, 2);
-   if (dma_declare_coherent_memory(dev->mem_dev_l, mem_info[0],
-   mem_info[0], mem_info[1],
-   DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE) == 0) {
-   mfc_err("Failed to declare coherent memory for\n"
-   "MFC device\n");
-   return -ENOMEM;
-   }
+   put_device(child);
+   return NULL;
+}
 
-   dev->mem_dev_r = devm_kzalloc(>plat_dev->dev,
-   sizeof(struct device), GFP_KERNEL);
-   if (!dev->mem_dev_r) {
-   mfc_err("Not enough memory\n");
-   return -ENOMEM;
-   }
+static int s5p_mfc_configure_dma_memory(struct s5p_mfc_dev *mfc_dev)
+{
+   struct device *dev = _dev->plat_dev->dev;
 
-   dev_set_name(dev->mem_dev_r, "%s", "s5p-mfc-r");
-   dev->mem_dev_r->release = s5p_mfc_memdev_release;
-   device_initialize(dev->mem_dev_r);
-   of_property_read_u32_array(dev->plat_dev->dev.of_node,
-   "samsung,mfc-r", mem_info, 2);
-   if (dma_declare_coherent_memory(dev->mem_dev_r, mem_info[0],
-   mem_info[0], mem_info[1],
-   DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE) == 0) {
-   pr_err("Failed to declare coherent memory for\n"
-   "MFC device\n");
-   return -ENOMEM;
+   /*
+* Create and initialize virtual devices for accessing
+* reserved memory regions.
+*/
+   mfc_dev->mem_dev_l = s5p_mfc_alloc_memdev(dev, "left",
+ MFC_BANK1_ALLOC_CTX);
+   if (!mfc_dev->mem_dev_l)
+   return -ENODEV;
+   mfc_dev->mem_dev_r = s5p_mfc_alloc_memdev(dev, "right",
+ MFC_BANK2_ALLOC_CTX);
+   if (!mfc_dev->mem_dev_r) {
+   device_unregister(mfc_dev->mem_dev_l);
+   return -ENODEV;
}
+
return 0;
 }
 
+static void 

[PATCH v4 5/7] ARM: Exynos: remove code for MFC custom reserved memory handling

2016-05-24 Thread Marek Szyprowski
Once MFC driver has been converted to generic reserved memory bindings,
there is no need for custom memory reservation code.

Signed-off-by: Marek Szyprowski 
---
 arch/arm/mach-exynos/Makefile  |  2 -
 arch/arm/mach-exynos/exynos.c  | 19 
 arch/arm/mach-exynos/mfc.h | 16 ---
 arch/arm/mach-exynos/s5p-dev-mfc.c | 93 --
 4 files changed, 130 deletions(-)
 delete mode 100644 arch/arm/mach-exynos/mfc.h
 delete mode 100644 arch/arm/mach-exynos/s5p-dev-mfc.c

diff --git a/arch/arm/mach-exynos/Makefile b/arch/arm/mach-exynos/Makefile
index 34d29df..b91b382 100644
--- a/arch/arm/mach-exynos/Makefile
+++ b/arch/arm/mach-exynos/Makefile
@@ -23,5 +23,3 @@ AFLAGS_sleep.o
:=-Wa,-march=armv7-a$(plus_sec)
 
 obj-$(CONFIG_EXYNOS5420_MCPM)  += mcpm-exynos.o
 CFLAGS_mcpm-exynos.o   += -march=armv7-a
-
-obj-$(CONFIG_S5P_DEV_MFC)  += s5p-dev-mfc.o
diff --git a/arch/arm/mach-exynos/exynos.c b/arch/arm/mach-exynos/exynos.c
index 52ccf24..a8620c6 100644
--- a/arch/arm/mach-exynos/exynos.c
+++ b/arch/arm/mach-exynos/exynos.c
@@ -27,7 +27,6 @@
 #include 
 
 #include "common.h"
-#include "mfc.h"
 
 static struct map_desc exynos4_iodesc[] __initdata = {
{
@@ -237,23 +236,6 @@ static char const *const exynos_dt_compat[] __initconst = {
NULL
 };
 
-static void __init exynos_reserve(void)
-{
-#ifdef CONFIG_S5P_DEV_MFC
-   int i;
-   char *mfc_mem[] = {
-   "samsung,mfc-v5",
-   "samsung,mfc-v6",
-   "samsung,mfc-v7",
-   "samsung,mfc-v8",
-   };
-
-   for (i = 0; i < ARRAY_SIZE(mfc_mem); i++)
-   if (of_scan_flat_dt(s5p_fdt_alloc_mfc_mem, mfc_mem[i]))
-   break;
-#endif
-}
-
 static void __init exynos_dt_fixup(void)
 {
/*
@@ -275,6 +257,5 @@ DT_MACHINE_START(EXYNOS_DT, "SAMSUNG EXYNOS (Flattened 
Device Tree)")
.init_machine   = exynos_dt_machine_init,
.init_late  = exynos_init_late,
.dt_compat  = exynos_dt_compat,
-   .reserve= exynos_reserve,
.dt_fixup   = exynos_dt_fixup,
 MACHINE_END
diff --git a/arch/arm/mach-exynos/mfc.h b/arch/arm/mach-exynos/mfc.h
deleted file mode 100644
index dec93cd..000
--- a/arch/arm/mach-exynos/mfc.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * Copyright (C) 2013 Samsung Electronics Co.Ltd
- *
- * This program is free software; you can redistribute  it and/or modify it
- * under  the terms of  the GNU General  Public License as published by the
- * Free Software Foundation;  either version 2 of the  License, or (at your
- * option) any later version.
- */
-
-#ifndef __MACH_EXYNOS_MFC_H
-#define __MACH_EXYNOS_MFC_H __FILE__
-
-int __init s5p_fdt_alloc_mfc_mem(unsigned long node, const char *uname,
-   int depth, void *data);
-
-#endif /* __MACH_EXYNOS_MFC_H */
diff --git a/arch/arm/mach-exynos/s5p-dev-mfc.c 
b/arch/arm/mach-exynos/s5p-dev-mfc.c
deleted file mode 100644
index 8ef1f3e..000
--- a/arch/arm/mach-exynos/s5p-dev-mfc.c
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2010-2011 Samsung Electronics Co.Ltd
- *
- * Base S5P MFC resource and device definitions
- *
- * 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.
- */
-
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-
-static struct platform_device s5p_device_mfc_l;
-static struct platform_device s5p_device_mfc_r;
-
-struct s5p_mfc_dt_meminfo {
-   unsigned long   loff;
-   unsigned long   lsize;
-   unsigned long   roff;
-   unsigned long   rsize;
-   char*compatible;
-};
-
-struct s5p_mfc_reserved_mem {
-   phys_addr_t base;
-   unsigned long   size;
-   struct device   *dev;
-};
-
-static struct s5p_mfc_reserved_mem s5p_mfc_mem[2] __initdata;
-
-
-static void __init s5p_mfc_reserve_mem(phys_addr_t rbase, unsigned int rsize,
-   phys_addr_t lbase, unsigned int lsize)
-{
-   int i;
-
-   s5p_mfc_mem[0].dev = _device_mfc_r.dev;
-   s5p_mfc_mem[0].base = rbase;
-   s5p_mfc_mem[0].size = rsize;
-
-   s5p_mfc_mem[1].dev = _device_mfc_l.dev;
-   s5p_mfc_mem[1].base = lbase;
-   s5p_mfc_mem[1].size = lsize;
-
-   for (i = 0; i < ARRAY_SIZE(s5p_mfc_mem); i++) {
-   struct s5p_mfc_reserved_mem *area = _mfc_mem[i];
-   if (memblock_remove(area->base, area->size)) {
-   printk(KERN_ERR "Failed to reserve memory for MFC 
device (%ld bytes at 0x%08lx)\n",
-  area->size, (unsigned long) area->base);
-   area->base = 0;
-   }
-   }
-}
-
-int __init s5p_fdt_alloc_mfc_mem(unsigned long node, const char *uname,
-   int depth, void 

[PATCH v4 2/7] media: s5p-mfc: use generic reserved memory bindings

2016-05-24 Thread Marek Szyprowski
Use generic reserved memory bindings and mark old, custom properties
as obsoleted.

Signed-off-by: Marek Szyprowski 
---
 .../devicetree/bindings/media/s5p-mfc.txt  | 39 +-
 1 file changed, 31 insertions(+), 8 deletions(-)

diff --git a/Documentation/devicetree/bindings/media/s5p-mfc.txt 
b/Documentation/devicetree/bindings/media/s5p-mfc.txt
index 2d5787e..92c94f5 100644
--- a/Documentation/devicetree/bindings/media/s5p-mfc.txt
+++ b/Documentation/devicetree/bindings/media/s5p-mfc.txt
@@ -21,15 +21,18 @@ Required properties:
   - clock-names : from common clock binding: must contain "mfc",
  corresponding to entry in the clocks property.
 
-  - samsung,mfc-r : Base address of the first memory bank used by MFC
-   for DMA contiguous memory allocation and its size.
-
-  - samsung,mfc-l : Base address of the second memory bank used by MFC
-   for DMA contiguous memory allocation and its size.
-
 Optional properties:
   - power-domains : power-domain property defined with a phandle
   to respective power domain.
+  - memory-region : from reserved memory binding: phandles to two reserved
+   memory regions, first is for "left" mfc memory bus interfaces,
+   second if for the "right" mfc memory bus, used when no SYSMMU
+   support is available
+
+Obsolete properties:
+  - samsung,mfc-r, samsung,mfc-l : support removed, please use memory-region
+   property instead
+
 
 Example:
 SoC specific DT entry:
@@ -43,9 +46,29 @@ mfc: codec@1340 {
clock-names = "mfc";
 };
 
+Reserved memory specific DT entry for given board (see reserved memory binding
+for more information):
+
+reserved-memory {
+   #address-cells = <1>;
+   #size-cells = <1>;
+   ranges;
+
+   mfc_left: region@5100 {
+   compatible = "shared-dma-pool";
+   no-map;
+   reg = <0x5100 0x80>;
+   };
+
+   mfc_right: region@4300 {
+   compatible = "shared-dma-pool";
+   no-map;
+   reg = <0x4300 0x80>;
+   };
+};
+
 Board specific DT entry:
 
 codec@1340 {
-   samsung,mfc-r = <0x4300 0x80>;
-   samsung,mfc-l = <0x5100 0x80>;
+   memory-region = <_left>, <_right>;
 };
-- 
1.9.2

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 6/7] ARM: dts: exynos: convert MFC device to generic reserved memory bindings

2016-05-24 Thread Marek Szyprowski
This patch replaces custom properties for defining reserved memory
regions with generic reserved memory bindings for MFC video codec
device.

Signed-off-by: Marek Szyprowski 
---
 arch/arm/boot/dts/exynos-mfc-reserved-memory.dtsi  | 27 ++
 arch/arm/boot/dts/exynos4210-origen.dts|  4 ++--
 arch/arm/boot/dts/exynos4210-smdkv310.dts  |  4 ++--
 arch/arm/boot/dts/exynos4412-origen.dts|  4 ++--
 arch/arm/boot/dts/exynos4412-smdk4412.dts  |  4 ++--
 arch/arm/boot/dts/exynos5250-arndale.dts   |  4 ++--
 arch/arm/boot/dts/exynos5250-smdk5250.dts  |  4 ++--
 arch/arm/boot/dts/exynos5250-spring.dts|  4 ++--
 arch/arm/boot/dts/exynos5420-arndale-octa.dts  |  4 ++--
 arch/arm/boot/dts/exynos5420-peach-pit.dts |  4 ++--
 arch/arm/boot/dts/exynos5420-smdk5420.dts  |  4 ++--
 arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi |  4 ++--
 arch/arm/boot/dts/exynos5800-peach-pi.dts  |  4 ++--
 13 files changed, 51 insertions(+), 24 deletions(-)
 create mode 100644 arch/arm/boot/dts/exynos-mfc-reserved-memory.dtsi

diff --git a/arch/arm/boot/dts/exynos-mfc-reserved-memory.dtsi 
b/arch/arm/boot/dts/exynos-mfc-reserved-memory.dtsi
new file mode 100644
index 000..e7445c9
--- /dev/null
+++ b/arch/arm/boot/dts/exynos-mfc-reserved-memory.dtsi
@@ -0,0 +1,27 @@
+/*
+ * Samsung's Exynos SoC MFC (Video Codec) reserved memory common definition.
+ *
+ * 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.
+ */
+
+/ {
+   reserved-memory {
+   #address-cells = <1>;
+   #size-cells = <1>;
+   ranges;
+
+   mfc_left: region@5100 {
+   compatible = "shared-dma-pool";
+   no-map;
+   reg = <0x5100 0x80>;
+   };
+
+   mfc_right: region@4300 {
+   compatible = "shared-dma-pool";
+   no-map;
+   reg = <0x4300 0x80>;
+   };
+   };
+};
diff --git a/arch/arm/boot/dts/exynos4210-origen.dts 
b/arch/arm/boot/dts/exynos4210-origen.dts
index ad7394c..f5e4eb2 100644
--- a/arch/arm/boot/dts/exynos4210-origen.dts
+++ b/arch/arm/boot/dts/exynos4210-origen.dts
@@ -18,6 +18,7 @@
 #include "exynos4210.dtsi"
 #include 
 #include 
+#include "exynos-mfc-reserved-memory.dtsi"
 
 / {
model = "Insignal Origen evaluation board based on Exynos4210";
@@ -288,8 +289,7 @@
 };
 
  {
-   samsung,mfc-r = <0x4300 0x80>;
-   samsung,mfc-l = <0x5100 0x80>;
+   memory-region = <_left>, <_right>;
status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/exynos4210-smdkv310.dts 
b/arch/arm/boot/dts/exynos4210-smdkv310.dts
index 94ca7d3..de917f0 100644
--- a/arch/arm/boot/dts/exynos4210-smdkv310.dts
+++ b/arch/arm/boot/dts/exynos4210-smdkv310.dts
@@ -17,6 +17,7 @@
 /dts-v1/;
 #include "exynos4210.dtsi"
 #include 
+#include "exynos-mfc-reserved-memory.dtsi"
 
 / {
model = "Samsung smdkv310 evaluation board based on Exynos4210";
@@ -133,8 +134,7 @@
 };
 
  {
-   samsung,mfc-r = <0x4300 0x80>;
-   samsung,mfc-l = <0x5100 0x80>;
+   memory-region = <_left>, <_right>;
status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/exynos4412-origen.dts 
b/arch/arm/boot/dts/exynos4412-origen.dts
index 8bca699..cd363d7 100644
--- a/arch/arm/boot/dts/exynos4412-origen.dts
+++ b/arch/arm/boot/dts/exynos4412-origen.dts
@@ -16,6 +16,7 @@
 #include "exynos4412.dtsi"
 #include 
 #include 
+#include "exynos-mfc-reserved-memory.dtsi"
 
 / {
model = "Insignal Origen evaluation board based on Exynos4412";
@@ -466,8 +467,7 @@
 };
 
  {
-   samsung,mfc-r = <0x4300 0x80>;
-   samsung,mfc-l = <0x5100 0x80>;
+   memory-region = <_left>, <_right>;
status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/exynos4412-smdk4412.dts 
b/arch/arm/boot/dts/exynos4412-smdk4412.dts
index a51069f..9b6d561 100644
--- a/arch/arm/boot/dts/exynos4412-smdk4412.dts
+++ b/arch/arm/boot/dts/exynos4412-smdk4412.dts
@@ -14,6 +14,7 @@
 
 /dts-v1/;
 #include "exynos4412.dtsi"
+#include "exynos-mfc-reserved-memory.dtsi"
 
 / {
model = "Samsung SMDK evaluation board based on Exynos4412";
@@ -112,8 +113,7 @@
 };
 
  {
-   samsung,mfc-r = <0x4300 0x80>;
-   samsung,mfc-l = <0x5100 0x80>;
+   memory-region = <_left>, <_right>;
status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/exynos5250-arndale.dts 
b/arch/arm/boot/dts/exynos5250-arndale.dts
index 85dad29..39940f4 100644
--- a/arch/arm/boot/dts/exynos5250-arndale.dts
+++ b/arch/arm/boot/dts/exynos5250-arndale.dts
@@ -14,6 +14,7 @@
 #include 
 #include 
 #include "exynos5250.dtsi"
+#include 

[PATCH v4 7/7] ARM: dts: exynos4412-odroid*: enable MFC device

2016-05-24 Thread Marek Szyprowski
Enable support for Multimedia Codec (MFC) device for all Exynos4412-based
Odroid boards.

Signed-off-by: Marek Szyprowski 
---
 arch/arm/boot/dts/exynos4412-odroid-common.dtsi | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi 
b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi
index ec7619a..276ac9a 100644
--- a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi
+++ b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi
@@ -13,6 +13,7 @@
 #include "exynos4412.dtsi"
 #include "exynos4412-ppmu-common.dtsi"
 #include 
+#include "exynos-mfc-reserved-memory.dtsi"
 
 / {
chosen {
@@ -499,6 +500,11 @@
clock-names = "iis", "i2s_opclk0", "i2s_opclk1";
 };
 
+ {
+   memory-region = <_left>, <_right>;
+   status = "okay";
+};
+
  {
status = "okay";
 };
-- 
1.9.2

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 0/7] Exynos: MFC driver: reserved memory cleanup and IOMMU support

2016-05-24 Thread Marek Szyprowski
Hello,

This is another version of the patchset, which performs cleanup of
custom code for reserved memory handling in s5p-mfc codec driver. The
first part is removal of custom, driver specific code for intializing
and handling of reserved memory. Instead, a generic code for reserved
memory regions is used. Then, the driver is extended with IOMMU support.
The additional code is needed because of specific requirements of MFC
device firmware (see patch 3 for more details). When no IOMMU is
available, the code fallbacks to use generic reserved memory regions.

After applying this patchset, MFC device works correctly either when
IOMMU is either enabled or disabled (assuming that board provides
required reserved memory regions).

Patches have been tested on top of linux-next from 20160524 with some
additional patches:
- "[PATCH 0/3] [media] s5p-mfc: Fixes for issues when module is removed":
  https://lkml.org/lkml/2016/5/3/782
- "[PATCH v5 0/2] vb2-dma-contig: configure DMA max segment size properly":
  https://www.mail-archive.com/linux-media@vger.kernel.org/msg97625.html

I've prepared a git branch with all needed patches:
https://git.linaro.org/people/marek.szyprowski/linux-srpol.git 
v4.6-next20160524-mfc

I would prefer to merge patches 1-4 via media tree and patches 5-7 via
Samsung SoC tree (there are no compile-time dependencies between those
two sets). Patches have been tested on Odroid U3 (Exynos 4412 based) and
Odroid XU3 (Exynos 5422 based) boards.

Best regards
Marek Szyprowski
Samsung R Institute Poland


Changelog:
v4:
- moved videobuf2-dma-contig/dma max segment size patches to separate thread:
  https://www.mail-archive.com/linux-media@vger.kernel.org/msg97625.html
- removed 'named' support for reserved memory regions, now regions are selected
 by index (requested by Rob Herring in v3)
- splitted 'ARM: Exynos: convert MFC device to generic reserved memory bindings'
  patch into 3 separate changes (bindings, dts, code removal), rewrote commit
  messages to better describe the changes
- rebased onto latest linux-next kernel tree

v3: 
http://comments.gmane.org/gmane.linux.drivers.video-input-infrastructure/97316
- fixed issues pointed by Laurent Pinchart:
  - added documentation to memory-region-names property,
  - changed devm_kzalloc to kzalloc in vb2_dma_contig_set_max_seg_size() to
avoid access to freed memory after reloading driver module
- unified odroid mfc reserved memory configuration with other Exynos4 boards

v2: http://thread.gmane.org/gmane.linux.drivers.video-input-infrastructure/97025
- reworked of_reserved_mem_init* functions on request from Rob Herring,
  added separate index and name based selection of reserved region
- adapted for of_reserved_mem_init* related changes

v1: https://www.mail-archive.com/linux-media@vger.kernel.org/msg94100.html
- initial version of another approach for this problem, rewrote driver code
  for new reserved memory bindings, which finally have been merged some
  time ago

v0: 
http://lists.infradead.org/pipermail/linux-arm-kernel/2013-August/189259.html
- old patchset solving the same problem, abandoned due to other tasks
  and long time of merging reserved memory bindings and support code for
  it

Patch summary:


Marek Szyprowski (7):
  of: reserved_mem: add support for using more than one region for given
device
  media: s5p-mfc: use generic reserved memory bindings
  media: s5p-mfc: replace custom reserved memory handling code with
generic one
  media: s5p-mfc: add iommu support
  ARM: Exynos: remove code for MFC custom reserved memory handling
  ARM: dts: exynos: convert MFC device to generic reserved memory
bindings
  ARM: dts: exynos4412-odroid*: enable MFC device

 .../devicetree/bindings/media/s5p-mfc.txt  |  39 +++--
 arch/arm/boot/dts/exynos-mfc-reserved-memory.dtsi  |  27 
 arch/arm/boot/dts/exynos4210-origen.dts|   4 +-
 arch/arm/boot/dts/exynos4210-smdkv310.dts  |   4 +-
 arch/arm/boot/dts/exynos4412-odroid-common.dtsi|   6 +
 arch/arm/boot/dts/exynos4412-origen.dts|   4 +-
 arch/arm/boot/dts/exynos4412-smdk4412.dts  |   4 +-
 arch/arm/boot/dts/exynos5250-arndale.dts   |   4 +-
 arch/arm/boot/dts/exynos5250-smdk5250.dts  |   4 +-
 arch/arm/boot/dts/exynos5250-spring.dts|   4 +-
 arch/arm/boot/dts/exynos5420-arndale-octa.dts  |   4 +-
 arch/arm/boot/dts/exynos5420-peach-pit.dts |   4 +-
 arch/arm/boot/dts/exynos5420-smdk5420.dts  |   4 +-
 arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi |   4 +-
 arch/arm/boot/dts/exynos5800-peach-pi.dts  |   4 +-
 arch/arm/mach-exynos/Makefile  |   2 -
 arch/arm/mach-exynos/exynos.c  |  19 ---
 arch/arm/mach-exynos/mfc.h |  16 ---
 arch/arm/mach-exynos/s5p-dev-mfc.c |  93 
 drivers/media/platform/s5p-mfc/s5p_mfc.c   | 158 +++--
 drivers/me

[PATCH v4 4/7] media: s5p-mfc: add iommu support

2016-05-24 Thread Marek Szyprowski
This patch adds support for IOMMU to s5p-mfc device driver. MFC firmware
is limited and it cannot use the default configuration. If IOMMU is
available, the patch disables the default DMA address space
configuration and creates a new address space of size limited to 256M
and base address set to 0x2000.

For now the same address space is shared by both 'left' and 'right'
memory channels, because the DMA/IOMMU frameworks do not support
configuring them separately. This is not optimal, but besides limiting
total address space available has no other drawbacks (MFC firmware
supports 256M of address space per each channel).

Signed-off-by: Marek Szyprowski 
---
 drivers/media/platform/s5p-mfc/s5p_mfc.c   | 24 
 drivers/media/platform/s5p-mfc/s5p_mfc_iommu.h | 79 ++
 2 files changed, 103 insertions(+)
 create mode 100644 drivers/media/platform/s5p-mfc/s5p_mfc_iommu.h

diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c 
b/drivers/media/platform/s5p-mfc/s5p_mfc.c
index fff5f43..6ee620e 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c
@@ -30,6 +30,7 @@
 #include "s5p_mfc_dec.h"
 #include "s5p_mfc_enc.h"
 #include "s5p_mfc_intr.h"
+#include "s5p_mfc_iommu.h"
 #include "s5p_mfc_opr.h"
 #include "s5p_mfc_cmd.h"
 #include "s5p_mfc_pm.h"
@@ -1084,6 +1085,22 @@ static int s5p_mfc_configure_dma_memory(struct 
s5p_mfc_dev *mfc_dev)
struct device *dev = _dev->plat_dev->dev;
 
/*
+* When IOMMU is available, we cannot use the default configuration,
+* because of MFC firmware requirements: address space limited to
+* 256M and non-zero default start address.
+* This is still simplified, not optimal configuration, but for now
+* IOMMU core doesn't allow to configure device's IOMMUs channel
+* separately.
+*/
+   if (exynos_is_iommu_available(dev)) {
+   int ret = exynos_configure_iommu(dev, S5P_MFC_IOMMU_DMA_BASE,
+S5P_MFC_IOMMU_DMA_SIZE);
+   if (ret == 0)
+   mfc_dev->mem_dev_l = mfc_dev->mem_dev_r = dev;
+   return ret;
+   }
+
+   /*
 * Create and initialize virtual devices for accessing
 * reserved memory regions.
 */
@@ -1103,6 +1120,13 @@ static int s5p_mfc_configure_dma_memory(struct 
s5p_mfc_dev *mfc_dev)
 
 static void s5p_mfc_unconfigure_dma_memory(struct s5p_mfc_dev *mfc_dev)
 {
+   struct device *dev = _dev->plat_dev->dev;
+
+   if (exynos_is_iommu_available(dev)) {
+   exynos_unconfigure_iommu(dev);
+   return;
+   }
+
device_unregister(mfc_dev->mem_dev_l);
device_unregister(mfc_dev->mem_dev_r);
 }
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_iommu.h 
b/drivers/media/platform/s5p-mfc/s5p_mfc_iommu.h
new file mode 100644
index 000..5d1d1c2
--- /dev/null
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_iommu.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2015 Samsung Electronics Co.Ltd
+ * Authors: Marek Szyprowski 
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#ifndef S5P_MFC_IOMMU_H_
+#define S5P_MFC_IOMMU_H_
+
+#define S5P_MFC_IOMMU_DMA_BASE 0x2000lu
+#define S5P_MFC_IOMMU_DMA_SIZE SZ_256M
+
+#ifdef CONFIG_EXYNOS_IOMMU
+
+#include 
+
+static inline bool exynos_is_iommu_available(struct device *dev)
+{
+   return dev->archdata.iommu != NULL;
+}
+
+static inline void exynos_unconfigure_iommu(struct device *dev)
+{
+   struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev);
+
+   arm_iommu_detach_device(dev);
+   arm_iommu_release_mapping(mapping);
+}
+
+static inline int exynos_configure_iommu(struct device *dev,
+unsigned int base, unsigned int size)
+{
+   struct dma_iommu_mapping *mapping = NULL;
+   int ret;
+
+   /* Disable the default mapping created by device core */
+   if (to_dma_iommu_mapping(dev))
+   exynos_unconfigure_iommu(dev);
+
+   mapping = arm_iommu_create_mapping(dev->bus, base, size);
+   if (IS_ERR(mapping)) {
+   pr_warn("Failed to create IOMMU mapping for device %s\n",
+   dev_name(dev));
+   return PTR_ERR(mapping);
+   }
+
+   ret = arm_iommu_attach_device(dev, mapping);
+   if (ret) {
+   pr_warn("Failed to attached device %s to IOMMU_mapping\n",
+   dev_name(dev));
+   arm_iommu_release_mapping(mapping);
+   return ret;
+   }
+
+   return 0;
+}
+
+#else
+
+static inline bool exynos_is_iommu_available(struct device *dev)
+{
+   

[PATCH 1/2] drm/exynos: g2d: Add support for old S5Pv210 type

2016-05-24 Thread Krzysztof Kozlowski
The non-DRM s5p-g2d driver supports two versions of G2D: v3.0 on
S5Pv210 and v4.x on Exynos 4x12 (or newer). The driver for 3.0 device
version is doing two things differently:
1. Before starting the render process, it invalidates caches (pattern,
   source buffer and mask buffer). Cache control is not present on v4.x
   device.
2. Scalling is done through StretchEn command (in BITBLT_COMMAND_REG
   register) instead of SRC_SCALE_CTRL_REG as in v4.x. However the
   exynos_drm_g2d driver does not implement the scalling so this
   difference can be eliminated.

After adding support for v3.0 to exynos_drm_g2d driver, the old driver
can be removed.

Cc: Kyungmin Park 
Cc: Kamil Debski 
Signed-off-by: Krzysztof Kozlowski 
---
 drivers/gpu/drm/exynos/exynos_drm_g2d.c | 37 +++--
 drivers/gpu/drm/exynos/exynos_drm_g2d.h |  7 +++
 2 files changed, 42 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c 
b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
index 493552368295..44d8b28e9d98 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
@@ -19,6 +19,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -38,6 +39,7 @@
 #define G2D_SOFT_RESET 0x
 #define G2D_INTEN  0x0004
 #define G2D_INTC_PEND  0x000C
+#define G2D_CACHECTL   0x0018 /* S5PV210 specific */
 #define G2D_DMA_SFR_BASE_ADDR  0x0080
 #define G2D_DMA_COMMAND0x0084
 #define G2D_DMA_STATUS 0x008C
@@ -78,6 +80,11 @@
 #define G2D_INTP_GCMD_FIN  (1 << 1)
 #define G2D_INTP_SCMD_FIN  (1 << 0)
 
+/* G2D_CACHECTL, S5PV210 specific */
+#define G2D_CACHECTL_PATCACHE  (BIT(2))
+#define G2D_CACHECTL_SRCBUFFER (BIT(1))
+#define G2D_CACHECTL_MASKBUFFER(BIT(0))
+
 /* G2D_DMA_COMMAND */
 #define G2D_DMA_HALT   (1 << 2)
 #define G2D_DMA_CONTINUE   (1 << 1)
@@ -245,6 +252,7 @@ struct g2d_data {
 
unsigned long   current_pool;
unsigned long   max_pool;
+   enum exynos_drm_g2d_typetype;
 };
 
 static int g2d_init_cmdlist(struct g2d_data *g2d)
@@ -1125,6 +1133,13 @@ int exynos_g2d_set_cmdlist_ioctl(struct drm_device 
*drm_dev, void *data,
cmdlist->data[cmdlist->last++] = G2D_SRC_BASE_ADDR;
cmdlist->data[cmdlist->last++] = 0;
 
+   if (g2d->type == EXYNOS_DRM_G2D_TYPE_3X) {
+   cmdlist->data[cmdlist->last++] = G2D_CACHECTL;
+   cmdlist->data[cmdlist->last++] = G2D_CACHECTL_PATCACHE |
+G2D_CACHECTL_SRCBUFFER |
+G2D_CACHECTL_MASKBUFFER;
+   }
+
/*
 * 'LIST_HOLD' command should be set to the DMA_HOLD_CMD_REG
 * and GCF bit should be set to INTEN register if user wants
@@ -1369,10 +1384,20 @@ static int g2d_probe(struct platform_device *pdev)
struct exynos_drm_subdrv *subdrv;
int ret;
 
+   /* Sanity check, we can be instatiated only from DT */
+   if (!dev->of_node)
+   return -EINVAL;
+
g2d = devm_kzalloc(dev, sizeof(*g2d), GFP_KERNEL);
if (!g2d)
return -ENOMEM;
 
+   g2d->type = (enum exynos_drm_g2d_type)of_device_get_match_data(dev);
+   if (g2d->type == EXYNOS_DRM_G2D_TYPE_UNKNOWN) {
+   dev_err(dev, "failed to get type of device\n");
+   return -EINVAL;
+   }
+
g2d->runqueue_slab = kmem_cache_create("g2d_runqueue_slab",
sizeof(struct g2d_runqueue_node), 0, 0, NULL);
if (!g2d->runqueue_slab)
@@ -1535,8 +1560,16 @@ static const struct dev_pm_ops g2d_pm_ops = {
 };
 
 static const struct of_device_id exynos_g2d_match[] = {
-   { .compatible = "samsung,exynos5250-g2d" },
-   { .compatible = "samsung,exynos4212-g2d" },
+   {
+   .compatible = "samsung,exynos5250-g2d",
+   .data = (void *)EXYNOS_DRM_G2D_TYPE_4X,
+   }, {
+   .compatible = "samsung,exynos4212-g2d",
+   .data = (void *)EXYNOS_DRM_G2D_TYPE_4X,
+   }, {
+   .compatible = "samsung,s5pv210-g2d",
+   .data = (void *)EXYNOS_DRM_G2D_TYPE_3X,
+   },
{},
 };
 MODULE_DEVICE_TABLE(of, exynos_g2d_match);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.h 
b/drivers/gpu/drm/exynos/exynos_drm_g2d.h
index 1a9c7ca8c15b..84ec8aff6f0a 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_g2d.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.h
@@ -7,6 +7,13 @@
  * published by the Free Software Foundationr
  */
 
+enum exynos_drm_g2d_type {
+   EXYNOS_DRM_G2D_TYPE_UNKNOWN,
+
+   EXYNOS_DRM_G2D_TYPE_3X,
+   EXYNOS_DRM_G2D_TYPE_4X,
+};
+
 #ifdef CONFIG_DRM_EXYNOS_G2D
 extern 

[PATCH 2/2] [media] s5p-g2d: Replace old driver with DRM version

2016-05-24 Thread Krzysztof Kozlowski
Remove the old non-DRM driver because it is now entirely supported by
exynos_drm_g2d driver.

Cc: Kyungmin Park 
Cc: Kamil Debski 
Signed-off-by: Krzysztof Kozlowski 
---
 MAINTAINERS   |   8 -
 drivers/gpu/drm/exynos/Kconfig|   1 -
 drivers/media/platform/Kconfig|  12 -
 drivers/media/platform/Makefile   |   1 -
 drivers/media/platform/s5p-g2d/Makefile   |   3 -
 drivers/media/platform/s5p-g2d/g2d-hw.c   | 117 -
 drivers/media/platform/s5p-g2d/g2d-regs.h | 122 -
 drivers/media/platform/s5p-g2d/g2d.c  | 800 --
 drivers/media/platform/s5p-g2d/g2d.h  |  91 
 9 files changed, 1155 deletions(-)
 delete mode 100644 drivers/media/platform/s5p-g2d/Makefile
 delete mode 100644 drivers/media/platform/s5p-g2d/g2d-hw.c
 delete mode 100644 drivers/media/platform/s5p-g2d/g2d-regs.h
 delete mode 100644 drivers/media/platform/s5p-g2d/g2d.c
 delete mode 100644 drivers/media/platform/s5p-g2d/g2d.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 243c0811a4d8..01763419c6a1 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1616,14 +1616,6 @@ L:   linux-arm-ker...@lists.infradead.org (moderated 
for non-subscribers)
 S: Maintained
 F: arch/arm/mach-s5pv210/
 
-ARM/SAMSUNG S5P SERIES 2D GRAPHICS ACCELERATION (G2D) SUPPORT
-M: Kyungmin Park 
-M: Kamil Debski 
-L: linux-arm-ker...@lists.infradead.org
-L: linux-media@vger.kernel.org
-S: Maintained
-F: drivers/media/platform/s5p-g2d/
-
 ARM/SAMSUNG S5P SERIES Multi Format Codec (MFC) SUPPORT
 M: Kyungmin Park 
 M: Kamil Debski 
diff --git a/drivers/gpu/drm/exynos/Kconfig b/drivers/gpu/drm/exynos/Kconfig
index d814b3048ee5..b0eb20ba1b28 100644
--- a/drivers/gpu/drm/exynos/Kconfig
+++ b/drivers/gpu/drm/exynos/Kconfig
@@ -95,7 +95,6 @@ comment "Sub-drivers"
 
 config DRM_EXYNOS_G2D
bool "G2D"
-   depends on VIDEO_SAMSUNG_S5P_G2D=n
select FRAME_VECTOR
help
  Choose this option if you want to use Exynos G2D for DRM.
diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
index 84e041c0a70e..171005c53d62 100644
--- a/drivers/media/platform/Kconfig
+++ b/drivers/media/platform/Kconfig
@@ -161,18 +161,6 @@ config VIDEO_MEM2MEM_DEINTERLACE
help
Generic deinterlacing V4L2 driver.
 
-config VIDEO_SAMSUNG_S5P_G2D
-   tristate "Samsung S5P and EXYNOS4 G2D 2d graphics accelerator driver"
-   depends on VIDEO_DEV && VIDEO_V4L2
-   depends on ARCH_S5PV210 || ARCH_EXYNOS || COMPILE_TEST
-   depends on HAS_DMA
-   select VIDEOBUF2_DMA_CONTIG
-   select V4L2_MEM2MEM_DEV
-   default n
-   ---help---
- This is a v4l2 driver for Samsung S5P and EXYNOS4 G2D
- 2d graphics accelerator.
-
 config VIDEO_SAMSUNG_S5P_JPEG
tristate "Samsung S5P/Exynos3250/Exynos4 JPEG codec driver"
depends on VIDEO_DEV && VIDEO_V4L2
diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile
index bbb7bd1eb268..ad5e26a0bd17 100644
--- a/drivers/media/platform/Makefile
+++ b/drivers/media/platform/Makefile
@@ -32,7 +32,6 @@ obj-$(CONFIG_VIDEO_SAMSUNG_S5P_JPEG)  += s5p-jpeg/
 obj-$(CONFIG_VIDEO_SAMSUNG_S5P_MFC)+= s5p-mfc/
 obj-$(CONFIG_VIDEO_SAMSUNG_S5P_TV) += s5p-tv/
 
-obj-$(CONFIG_VIDEO_SAMSUNG_S5P_G2D)+= s5p-g2d/
 obj-$(CONFIG_VIDEO_SAMSUNG_EXYNOS_GSC) += exynos-gsc/
 
 obj-$(CONFIG_VIDEO_STI_BDISP)  += sti/bdisp/
diff --git a/drivers/media/platform/s5p-g2d/Makefile 
b/drivers/media/platform/s5p-g2d/Makefile
deleted file mode 100644
index 2c48c416a804..
--- a/drivers/media/platform/s5p-g2d/Makefile
+++ /dev/null
@@ -1,3 +0,0 @@
-s5p-g2d-objs := g2d.o g2d-hw.o
-
-obj-$(CONFIG_VIDEO_SAMSUNG_S5P_G2D)+= s5p-g2d.o
diff --git a/drivers/media/platform/s5p-g2d/g2d-hw.c 
b/drivers/media/platform/s5p-g2d/g2d-hw.c
deleted file mode 100644
index e87bd93811d4..
--- a/drivers/media/platform/s5p-g2d/g2d-hw.c
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Samsung S5P G2D - 2D Graphics Accelerator Driver
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd.
- * Kamil Debski, 
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version
- */
-
-#include 
-
-#include "g2d.h"
-#include "g2d-regs.h"
-
-#define w(x, a)writel((x), d->regs + (a))
-#define r(a)   readl(d->regs + (a))
-
-/* g2d_reset clears all g2d registers */
-void g2d_reset(struct g2d_dev *d)
-{
-   w(1, SOFT_RESET_REG);
-}
-
-void g2d_set_src_size(struct g2d_dev *d, struct g2d_frame *f)
-{
-   u32 n;
-
-   w(0, SRC_SELECT_REG);
-   

[v4l-utils PATCH 0/2] Prepare for mediatext library, cleanups

2016-05-24 Thread Sakari Ailus
Hi,

These two patches prepare for the mediatext library and clean up
libmediactl interface a little.

-- 
Kind regards,
Sakari

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[v4l-utils PATCH 2/2] mediactl: Separate entity and pad parsing

2016-05-24 Thread Sakari Ailus
Sometimes it's useful to be able to parse the entity independent of the pad.
Separate entity parsing into media_parse_entity().

Signed-off-by: Sakari Ailus 
---
 utils/media-ctl/libmediactl.c | 28 
 utils/media-ctl/mediactl.h| 14 ++
 2 files changed, 38 insertions(+), 4 deletions(-)

diff --git a/utils/media-ctl/libmediactl.c b/utils/media-ctl/libmediactl.c
index 78caa7c..14b17e6 100644
--- a/utils/media-ctl/libmediactl.c
+++ b/utils/media-ctl/libmediactl.c
@@ -781,10 +781,10 @@ int media_device_add_entity(struct media_device *media,
return 0;
 }
 
-struct media_pad *media_parse_pad(struct media_device *media,
- const char *p, char **endp)
+struct media_entity *media_parse_entity(struct media_device *media,
+   const char *p, char **endp)
 {
-   unsigned int entity_id, pad;
+   unsigned int entity_id;
struct media_entity *entity;
char *end;
 
@@ -827,7 +827,27 @@ struct media_pad *media_parse_pad(struct media_device 
*media,
return NULL;
}
}
-   for (; isspace(*end); ++end);
+   for (p = end; isspace(*p); ++p);
+
+   *endp = (char *)p;
+
+   return entity;
+}
+
+struct media_pad *media_parse_pad(struct media_device *media,
+ const char *p, char **endp)
+{
+   unsigned int pad;
+   struct media_entity *entity;
+   char *end;
+
+   if (endp == NULL)
+   endp = 
+
+   entity = media_parse_entity(media, p, );
+   if (!entity)
+   return NULL;
+   *endp = end;
 
if (*end != ':') {
media_dbg(media, "Expected ':'\n", *end);
diff --git a/utils/media-ctl/mediactl.h b/utils/media-ctl/mediactl.h
index b5a92f5..af36051 100644
--- a/utils/media-ctl/mediactl.h
+++ b/utils/media-ctl/mediactl.h
@@ -367,6 +367,20 @@ int media_setup_link(struct media_device *media,
 int media_reset_links(struct media_device *media);
 
 /**
+ * @brief Parse string to an entity on the media device.
+ * @param media - media device.
+ * @param p - input string
+ * @param endp - pointer to string where parsing ended
+ *
+ * Parse NULL terminated string describing an entity and return its
+ * struct media_entity instance.
+ *
+ * @return Pointer to struct media_entity on success, NULL on failure.
+ */
+struct media_entity *media_parse_entity(struct media_device *media,
+   const char *p, char **endp);
+
+/**
  * @brief Parse string to a pad on the media device.
  * @param media - media device.
  * @param p - input string
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[v4l-utils PATCH 1/2] libmediactl: Drop length argument from media_get_entity_by_name()

2016-05-24 Thread Sakari Ailus
Recently it was decided that the API dealing with string operations would
be better to just receive a nul-terminated string rather than a string the
length of which is defined. This change was implemented for
v4l2_subdev_string_to_pixelcode() and v4l2_subdev_string_to_field()
functions by patch "v4l: libv4l2subdev: Drop length argument from string
conversion functions" (commit id
341f4343e6190a7ceb546f7c74fa67e1cc9ae79f).

Do the same change for media_get_entity_by_name() in libmediactl. No other
functions using length argument for strings remain in libmediactl.

Signed-off-by: Sakari Ailus 
---
 utils/media-ctl/libmediactl.c | 19 +--
 utils/media-ctl/media-ctl.c   |  3 +--
 utils/media-ctl/mediactl.h|  3 +--
 3 files changed, 11 insertions(+), 14 deletions(-)

diff --git a/utils/media-ctl/libmediactl.c b/utils/media-ctl/libmediactl.c
index 89ac11c..78caa7c 100644
--- a/utils/media-ctl/libmediactl.c
+++ b/utils/media-ctl/libmediactl.c
@@ -66,21 +66,14 @@ struct media_pad *media_entity_remote_source(struct 
media_pad *pad)
 }
 
 struct media_entity *media_get_entity_by_name(struct media_device *media,
- const char *name, size_t length)
+ const char *name)
 {
unsigned int i;
 
-   /* A match is impossible if the entity name is longer than the maximum
-* size we can get from the kernel.
-*/
-   if (length >= FIELD_SIZEOF(struct media_entity_desc, name))
-   return NULL;
-
for (i = 0; i < media->entities_count; ++i) {
struct media_entity *entity = >entities[i];
 
-   if (strncmp(entity->info.name, name, length) == 0 &&
-   entity->info.name[length] == '\0')
+   if (strcmp(entity->info.name, name) == 0)
return entity;
}
 
@@ -804,6 +797,8 @@ struct media_pad *media_parse_pad(struct media_device 
*media,
for (; isspace(*p); ++p);
 
if (*p == '"' || *p == '\'') {
+   char *name;
+
for (end = (char *)p + 1; *end && *end != '"' && *end != '\''; 
++end);
if (*end != '"' && *end != '\'') {
media_dbg(media, "missing matching '\"'\n");
@@ -811,7 +806,11 @@ struct media_pad *media_parse_pad(struct media_device 
*media,
return NULL;
}
 
-   entity = media_get_entity_by_name(media, p + 1, end - p - 1);
+   name = strndup(p + 1, end - p - 1);
+   if (!name)
+   return NULL;
+   entity = media_get_entity_by_name(media, name);
+   free(name);
if (entity == NULL) {
media_dbg(media, "no such entity \"%.*s\"\n", end - p - 
1, p + 1);
*endp = (char *)p + 1;
diff --git a/utils/media-ctl/media-ctl.c b/utils/media-ctl/media-ctl.c
index f45ca43..2f049c6 100644
--- a/utils/media-ctl/media-ctl.c
+++ b/utils/media-ctl/media-ctl.c
@@ -559,8 +559,7 @@ int main(int argc, char **argv)
if (media_opts.entity) {
struct media_entity *entity;
 
-   entity = media_get_entity_by_name(media, media_opts.entity,
- strlen(media_opts.entity));
+   entity = media_get_entity_by_name(media, media_opts.entity);
if (entity == NULL) {
printf("Entity '%s' not found\n", media_opts.entity);
goto out;
diff --git a/utils/media-ctl/mediactl.h b/utils/media-ctl/mediactl.h
index 77ac182..b5a92f5 100644
--- a/utils/media-ctl/mediactl.h
+++ b/utils/media-ctl/mediactl.h
@@ -245,14 +245,13 @@ static inline unsigned int media_entity_type(struct 
media_entity *entity)
  * @brief Find an entity by its name.
  * @param media - media device.
  * @param name - entity name.
- * @param length - size of @a name.
  *
  * Search for an entity with a name equal to @a name.
  *
  * @return A pointer to the entity if found, or NULL otherwise.
  */
 struct media_entity *media_get_entity_by_name(struct media_device *media,
-   const char *name, size_t length);
+   const char *name);
 
 /**
  * @brief Find an entity by its ID.
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] [media] adv7604: Add support for hardware reset

2016-05-24 Thread Laurent Pinchart
Hi Dragos,

On Tuesday 24 May 2016 12:13:22 Dragos Bogdan wrote:
> The part can be reset by a low pulse on the RESET pin (i.e. a hardware
> reset) with a minimum width of 5 ms. It is recommended to wait 5 ms after
> the low pulse before an I2C write is performed to the part. For safety
> reasons, the delays will be 10 ms.
> The RESET pin can be tied high, so the GPIO is optional.
> 
> Signed-off-by: Dragos Bogdan 
> ---
>  drivers/media/i2c/adv7604.c | 22 ++
>  1 file changed, 22 insertions(+)
> 
> diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c
> index 41a1bfc..fac0ff1 100644
> --- a/drivers/media/i2c/adv7604.c
> +++ b/drivers/media/i2c/adv7604.c
> @@ -164,6 +164,7 @@ struct adv76xx_state {
>   struct adv76xx_platform_data pdata;
> 
>   struct gpio_desc *hpd_gpio[4];
> + struct gpio_desc *reset_gpio;
> 
>   struct v4l2_subdev sd;
>   struct media_pad pads[ADV76XX_PAD_MAX];
> @@ -2996,6 +2997,21 @@ static int configure_regmaps(struct adv76xx_state
> *state) return 0;
>  }
> 
> +static int adv76xx_reset(struct adv76xx_state *state)
> +{
> + if (state->reset_gpio) {
> + /* ADV76XX can be reset by a low reset pulse of minimum 5 ms. */
> + gpiod_set_value_cansleep(state->reset_gpio, 0);
> + mdelay(10);

A busy loop of 10ms is very long, please use usleep_range() instead. As the 
minimum is 5ms and you're fine with 10ms, you can use usleep_range(5000, 
1).

> + gpiod_set_value_cansleep(state->reset_gpio, 1);
> + /* It is recommended to wait 5 ms after the low pulse before */
> + /* an I2C write is performed to the ADV76XX. */
> + mdelay(10);

Ditto.

> + }
> +
> + return 0;
> +}
> +
>  static int adv76xx_probe(struct i2c_client *client,
>const struct i2c_device_id *id)
>  {
> @@ -3059,6 +3075,12 @@ static int adv76xx_probe(struct i2c_client *client,
>   if (state->hpd_gpio[i])
>   v4l_info(client, "Handling HPD %u GPIO\n", i);
>   }
> + state->reset_gpio = devm_gpiod_get_optional(>dev, "reset",
> + GPIOD_OUT_HIGH);
> + if (IS_ERR(state->reset_gpio))
> + return PTR_ERR(state->reset_gpio);
> +
> + adv76xx_reset(state);
> 
>   state->timings = cea640x480;
>   state->format = adv76xx_format_info(state, MEDIA_BUS_FMT_YUYV8_2X8);

-- 
Regards,

Laurent Pinchart

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] adv7604: Don't ignore pad number in subdev DV timings pad operations

2016-05-24 Thread Hans Verkuil
On 05/24/16 14:09, Laurent Pinchart wrote:
> The dv_timings_cap() and enum_dv_timings() pad operations take a pad
> number as an input argument and return the DV timings capabilities and
> list of supported DV timings for that pad.
> 
> Commit bd3e275f3ec0 ("[media] media: i2c: adv7604: Use v4l2-dv-timings
> helpers") broke this as it started ignoring the pad number, always
> returning the information associated with the currently selected input.
> Fix it.
> 
> Fixes: bd3e275f3ec0 ("[media] media: i2c: adv7604: Use v4l2-dv-timings 
> helpers")
> Signed-off-by: Laurent Pinchart 

Acked-by: Hans Verkuil 

I should have caught this :-(

Regards,

Hans

> ---
>  drivers/media/i2c/adv7604.c | 46 
> ++---
>  1 file changed, 35 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c
> index beb2841ceae5..3f1ab4986cfc 100644
> --- a/drivers/media/i2c/adv7604.c
> +++ b/drivers/media/i2c/adv7604.c
> @@ -779,11 +779,31 @@ static const struct v4l2_dv_timings_cap 
> adv76xx_timings_cap_digital = {
>   V4L2_DV_BT_CAP_CUSTOM)
>  };
>  
> -static inline const struct v4l2_dv_timings_cap *
> -adv76xx_get_dv_timings_cap(struct v4l2_subdev *sd)
> +/*
> + * Return the DV timings capabilities for the requested sink pad. As a 
> special
> + * case, pad value -1 returns the capabilities for the currently selected 
> input.
> + */
> +static const struct v4l2_dv_timings_cap *
> +adv76xx_get_dv_timings_cap(struct v4l2_subdev *sd, int pad)
>  {
> - return is_digital_input(sd) ? _timings_cap_digital :
> -   _timings_cap_analog;
> + if (pad == -1) {
> + struct adv76xx_state *state = to_state(sd);
> +
> + pad = state->selected_input;
> + }
> +
> + switch (pad) {
> + case ADV76XX_PAD_HDMI_PORT_A:
> + case ADV7604_PAD_HDMI_PORT_B:
> + case ADV7604_PAD_HDMI_PORT_C:
> + case ADV7604_PAD_HDMI_PORT_D:
> + return _timings_cap_digital;
> +
> + case ADV7604_PAD_VGA_RGB:
> + case ADV7604_PAD_VGA_COMP:
> + default:
> + return _timings_cap_analog;
> + }
>  }
>  
>  
> @@ -1329,7 +1349,7 @@ static int stdi2dv_timings(struct v4l2_subdev *sd,
>   const struct v4l2_bt_timings *bt = 
> _dv_timings_presets[i].bt;
>  
>   if (!v4l2_valid_dv_timings(_dv_timings_presets[i],
> -adv76xx_get_dv_timings_cap(sd),
> +adv76xx_get_dv_timings_cap(sd, -1),
>  adv76xx_check_dv_timings, NULL))
>   continue;
>   if (vtotal(bt) != stdi->lcf + 1)
> @@ -1430,18 +1450,22 @@ static int adv76xx_enum_dv_timings(struct v4l2_subdev 
> *sd,
>   return -EINVAL;
>  
>   return v4l2_enum_dv_timings_cap(timings,
> - adv76xx_get_dv_timings_cap(sd), adv76xx_check_dv_timings, NULL);
> + adv76xx_get_dv_timings_cap(sd, timings->pad),
> + adv76xx_check_dv_timings, NULL);
>  }
>  
>  static int adv76xx_dv_timings_cap(struct v4l2_subdev *sd,
>   struct v4l2_dv_timings_cap *cap)
>  {
>   struct adv76xx_state *state = to_state(sd);
> + unsigned int pad = cap->pad;
>  
>   if (cap->pad >= state->source_pad)
>   return -EINVAL;
>  
> - *cap = *adv76xx_get_dv_timings_cap(sd);
> + *cap = *adv76xx_get_dv_timings_cap(sd, pad);
> + cap->pad = pad;
> +
>   return 0;
>  }
>  
> @@ -1450,9 +1474,9 @@ static int adv76xx_dv_timings_cap(struct v4l2_subdev 
> *sd,
>  static void adv76xx_fill_optional_dv_timings_fields(struct v4l2_subdev *sd,
>   struct v4l2_dv_timings *timings)
>  {
> - v4l2_find_dv_timings_cap(timings, adv76xx_get_dv_timings_cap(sd),
> - is_digital_input(sd) ? 25 : 100,
> - adv76xx_check_dv_timings, NULL);
> + v4l2_find_dv_timings_cap(timings, adv76xx_get_dv_timings_cap(sd, -1),
> +  is_digital_input(sd) ? 25 : 100,
> +  adv76xx_check_dv_timings, NULL);
>  }
>  
>  static unsigned int adv7604_read_hdmi_pixelclock(struct v4l2_subdev *sd)
> @@ -1620,7 +1644,7 @@ static int adv76xx_s_dv_timings(struct v4l2_subdev *sd,
>  
>   bt = >bt;
>  
> - if (!v4l2_valid_dv_timings(timings, adv76xx_get_dv_timings_cap(sd),
> + if (!v4l2_valid_dv_timings(timings, adv76xx_get_dv_timings_cap(sd, -1),
>  adv76xx_check_dv_timings, NULL))
>   return -ERANGE;
>  
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] adv7604: Don't ignore pad number in subdev DV timings pad operations

2016-05-24 Thread Laurent Pinchart
The dv_timings_cap() and enum_dv_timings() pad operations take a pad
number as an input argument and return the DV timings capabilities and
list of supported DV timings for that pad.

Commit bd3e275f3ec0 ("[media] media: i2c: adv7604: Use v4l2-dv-timings
helpers") broke this as it started ignoring the pad number, always
returning the information associated with the currently selected input.
Fix it.

Fixes: bd3e275f3ec0 ("[media] media: i2c: adv7604: Use v4l2-dv-timings helpers")
Signed-off-by: Laurent Pinchart 
---
 drivers/media/i2c/adv7604.c | 46 ++---
 1 file changed, 35 insertions(+), 11 deletions(-)

diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c
index beb2841ceae5..3f1ab4986cfc 100644
--- a/drivers/media/i2c/adv7604.c
+++ b/drivers/media/i2c/adv7604.c
@@ -779,11 +779,31 @@ static const struct v4l2_dv_timings_cap 
adv76xx_timings_cap_digital = {
V4L2_DV_BT_CAP_CUSTOM)
 };
 
-static inline const struct v4l2_dv_timings_cap *
-adv76xx_get_dv_timings_cap(struct v4l2_subdev *sd)
+/*
+ * Return the DV timings capabilities for the requested sink pad. As a special
+ * case, pad value -1 returns the capabilities for the currently selected 
input.
+ */
+static const struct v4l2_dv_timings_cap *
+adv76xx_get_dv_timings_cap(struct v4l2_subdev *sd, int pad)
 {
-   return is_digital_input(sd) ? _timings_cap_digital :
- _timings_cap_analog;
+   if (pad == -1) {
+   struct adv76xx_state *state = to_state(sd);
+
+   pad = state->selected_input;
+   }
+
+   switch (pad) {
+   case ADV76XX_PAD_HDMI_PORT_A:
+   case ADV7604_PAD_HDMI_PORT_B:
+   case ADV7604_PAD_HDMI_PORT_C:
+   case ADV7604_PAD_HDMI_PORT_D:
+   return _timings_cap_digital;
+
+   case ADV7604_PAD_VGA_RGB:
+   case ADV7604_PAD_VGA_COMP:
+   default:
+   return _timings_cap_analog;
+   }
 }
 
 
@@ -1329,7 +1349,7 @@ static int stdi2dv_timings(struct v4l2_subdev *sd,
const struct v4l2_bt_timings *bt = 
_dv_timings_presets[i].bt;
 
if (!v4l2_valid_dv_timings(_dv_timings_presets[i],
-  adv76xx_get_dv_timings_cap(sd),
+  adv76xx_get_dv_timings_cap(sd, -1),
   adv76xx_check_dv_timings, NULL))
continue;
if (vtotal(bt) != stdi->lcf + 1)
@@ -1430,18 +1450,22 @@ static int adv76xx_enum_dv_timings(struct v4l2_subdev 
*sd,
return -EINVAL;
 
return v4l2_enum_dv_timings_cap(timings,
-   adv76xx_get_dv_timings_cap(sd), adv76xx_check_dv_timings, NULL);
+   adv76xx_get_dv_timings_cap(sd, timings->pad),
+   adv76xx_check_dv_timings, NULL);
 }
 
 static int adv76xx_dv_timings_cap(struct v4l2_subdev *sd,
struct v4l2_dv_timings_cap *cap)
 {
struct adv76xx_state *state = to_state(sd);
+   unsigned int pad = cap->pad;
 
if (cap->pad >= state->source_pad)
return -EINVAL;
 
-   *cap = *adv76xx_get_dv_timings_cap(sd);
+   *cap = *adv76xx_get_dv_timings_cap(sd, pad);
+   cap->pad = pad;
+
return 0;
 }
 
@@ -1450,9 +1474,9 @@ static int adv76xx_dv_timings_cap(struct v4l2_subdev *sd,
 static void adv76xx_fill_optional_dv_timings_fields(struct v4l2_subdev *sd,
struct v4l2_dv_timings *timings)
 {
-   v4l2_find_dv_timings_cap(timings, adv76xx_get_dv_timings_cap(sd),
-   is_digital_input(sd) ? 25 : 100,
-   adv76xx_check_dv_timings, NULL);
+   v4l2_find_dv_timings_cap(timings, adv76xx_get_dv_timings_cap(sd, -1),
+is_digital_input(sd) ? 25 : 100,
+adv76xx_check_dv_timings, NULL);
 }
 
 static unsigned int adv7604_read_hdmi_pixelclock(struct v4l2_subdev *sd)
@@ -1620,7 +1644,7 @@ static int adv76xx_s_dv_timings(struct v4l2_subdev *sd,
 
bt = >bt;
 
-   if (!v4l2_valid_dv_timings(timings, adv76xx_get_dv_timings_cap(sd),
+   if (!v4l2_valid_dv_timings(timings, adv76xx_get_dv_timings_cap(sd, -1),
   adv76xx_check_dv_timings, NULL))
return -ERANGE;
 
-- 
Regards,

Laurent Pinchart

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] [media]: Driver for Toshiba et8ek8 5MP sensor

2016-05-24 Thread Pavel Machek
Hi!

> The sensor is found in Nokia N900 main camera
> 
> Signed-off-by: Ivaylo Dimitrov 

> +/*
> + * A buffered write method that puts the wanted register write
> + * commands in a message list and passes the list to the i2c framework
> + */
> +static int et8ek8_i2c_buffered_write_regs(struct i2c_client *client,
> +   const struct et8ek8_reg *wnext,
> +   int cnt)
> +{
> + /* FIXME: check how big cnt is */
> + struct i2c_msg msg[cnt];
> + unsigned char data[cnt][6];

Uff, no, variable length arrays in the kernel. No, I don't think that
should be done. Rather allocate maximum length here and then check its
> cnt?

> +/*
> + * Write a list of registers to i2c device.
> + *
> + * The list of registers is terminated by ET8EK8_REG_TERM.
> + * Returns zero if successful, or non-zero otherwise.
> + */
> +static int et8ek8_i2c_write_regs(struct i2c_client *client,
> +  const struct et8ek8_reg reglist[])
> +{
> + int r, cnt = 0;
> + const struct et8ek8_reg *next, *wnext;
> +
> + if (!client->adapter)
> + return -ENODEV;
> +
> + if (reglist == NULL)

(!reglist) ? :-). Actually, you can keep your preffered style there,
but maybe ammount of if (something that can not happen) return
... should be reduced. Noone should ever call this without valid
reglist or client->adapter, right?

> + return -EINVAL;
> +
> + /* Initialize list pointers to the start of the list */
> + next = wnext = reglist;
> +
> + do {
> + /*
> +  * We have to go through the list to figure out how
> +  * many regular writes we have in a row
> +  */
> + while (next->type != ET8EK8_REG_TERM
> +&& next->type != ET8EK8_REG_DELAY) {
> + /*
> +  * Here we check that the actual length fields
> +  * are valid
> +  */
> + if (next->type != ET8EK8_REG_8BIT
> + &&  next->type != ET8EK8_REG_16BIT) {

Extra space after &&

> + dev_err(>dev,
> + "Invalid value on entry %d 0x%x\n",
> + cnt, next->type);
> + return -EINVAL;
> + }

And maybe this could be just BUG_ON(). 

> +static struct et8ek8_reglist *et8ek8_reglist_find_mode_fmt(
> + struct et8ek8_meta_reglist *meta,
> + struct v4l2_mbus_framefmt *fmt)
> +{
> + struct et8ek8_reglist **list = et8ek8_reglist_first(meta);
> + struct et8ek8_reglist *best_match = NULL;
> + struct et8ek8_reglist *best_other = NULL;
> + struct v4l2_mbus_framefmt format;
> + unsigned int max_dist_match = (unsigned int)-1;
> + unsigned int max_dist_other = (unsigned int)-1;
> +
> + /* Find the mode with the closest image size. The distance between
> +  * image sizes is the size in pixels of the non-overlapping regions

You may want to run checkpatch. I guess it will complain. I doubt it
matters much :-).

> + while (meta->reglist[nlists].ptr != NULL)
> + nlists++;

...!= NULL) can be removed. ... here and in other places.

> +
> + rval = et8ek8_i2c_write_reg(client, ET8EK8_REG_8BIT, 0x111B,
> + tp_mode << 4);
> + if (rval)
> + goto out;
> +
> + rval = et8ek8_i2c_write_reg(client, ET8EK8_REG_8BIT, 0x1121,
> + cbh_mode << 7);
> + if (rval)
> + goto out;
> +
> + rval = et8ek8_i2c_write_reg(client, ET8EK8_REG_8BIT, 0x1124,
> + cbv_mode << 7);
> + if (rval)
> + goto out;
> +
> + rval = et8ek8_i2c_write_reg(client, ET8EK8_REG_8BIT, 0x112C, din_sw);
> + if (rval)
> + goto out;
> +
> + rval = et8ek8_i2c_write_reg(client, ET8EK8_REG_8BIT, 0x1420, r1420);
> + if (rval)
> + goto out;
> +
> +out:
> + return rval;
> +}

Goto out when all out does is return is a bit of overkill.

> +static int et8ek8_get_ctrl(struct v4l2_ctrl *ctrl)
> +{
> + struct et8ek8_sensor *sensor =
> + container_of(ctrl->handler, struct et8ek8_sensor, ctrl_handler);
> + const struct et8ek8_mode *mode = >current_reglist->mode;
> +
> + switch (ctrl->id) {
> + case ET8EK8_CID_USER_FRAME_WIDTH:
> + ctrl->cur.val = mode->width;
> + break;
> + case ET8EK8_CID_USER_FRAME_HEIGHT:
> + ctrl->cur.val = mode->height;
> + break;
> + case ET8EK8_CID_USER_VISIBLE_WIDTH:
> + ctrl->cur.val = mode->window_width;
> + break;
> + case ET8EK8_CID_USER_VISIBLE_HEIGHT:
> + ctrl->cur.val = mode->window_height;
> + break;
> + case ET8EK8_CID_USER_SENSITIVITY:
> + 

Re: [PATCH 0/3] [media] s5p-mfc: Fixes for issues when module is removed

2016-05-24 Thread Marek Szyprowski

Hello,


On 2016-05-03 22:27, Javier Martinez Canillas wrote:

Hello,

This patch series fixes some issues that I noticed when trying to remove
the s5p-mfc driver when built as a module.

Some of these issues will be fixed once Marek's patches to convert the
custom memory region reservation code is replaced by a generic one that
supports named memory region reservation [0]. But the fixes are trivial
so we can fix the current code until his rework patch lands.


For the whole series:

Tested-by: Marek Szyprowski 

Please queue it as fixes to v4.7-rcX.



[0]: https://patchwork.linuxtv.org/patch/32287/

Best regards,
Javier


Javier Martinez Canillas (3):
   [media] s5p-mfc: Set device name for reserved memory region devs
   [media] s5p-mfc: Add release callback for memory region devs
   [media] s5p-mfc: Fix race between s5p_mfc_probe() and s5p_mfc_open()

  drivers/media/platform/s5p-mfc/s5p_mfc.c | 50 
  1 file changed, 32 insertions(+), 18 deletions(-)



Best regards
--
Marek Szyprowski, PhD
Samsung R Institute Poland

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RESEND PATCH] [media] s5p-mfc: don't close instance after free OUTPUT buffers

2016-05-24 Thread Marek Szyprowski

Hello,


On 2016-05-07 00:11, Javier Martinez Canillas wrote:

From: ayaka 

User-space applications can use the VIDIOC_REQBUFS ioctl to determine if a
memory mapped, user pointer or DMABUF based I/O is supported by the driver.

So a set of VIDIOC_REQBUFS ioctl calls will be made with count 0 and then
the real VIDIOC_REQBUFS call with count == n. But for count 0, the driver
not only frees the buffer but also closes the MFC instance and s5p_mfc_ctx
state is set to MFCINST_FREE.

The VIDIOC_REQBUFS handler for the output device checks if the s5p_mfc_ctx
state is set to MFCINST_INIT (which happens on an VIDIOC_S_FMT) and fails
otherwise. So after a VIDIOC_REQBUFS(n), future VIDIOC_REQBUFS(n) calls
will fails unless a VIDIOC_S_FMT ioctl calls happens before the reqbufs.

But applications may first set the format and then attempt to determine
the I/O methods supported by the driver (for example Gstramer does it) so
the state won't be set to MFCINST_INIT again and VIDIOC_REQBUFS will fail.

To avoid this issue, only free the buffers on VIDIOC_REQBUFS(0) but don't
close the MFC instance to allow future VIDIOC_REQBUFS(n) calls to succeed.

Signed-off-by: ayaka 
[javier: Rewrote changelog to explain the problem more detailed]
Signed-off-by: Javier Martinez Canillas 


Tested-by: Marek Szyprowski 



---
Hello,

This is a resend of a patch posted by Ayaka some time ago [0].
Without $SUBJECT, trying to decode a video using Gstramer fails
on an Exynos5422 Odroid XU4 board with following error message:

$ gst-launch-1.0 filesrc location=test.mov ! qtdemux ! h264parse ! 
v4l2video0dec ! videoconvert ! autovideosink

Setting pipeline to PAUSED ...
Pipeline is PREROLLING ...
[ 3947.114756] vidioc_reqbufs:576: Only V4L2_MEMORY_MAP is supported
[ 3947.114771] vidioc_reqbufs:576: Only V4L2_MEMORY_MAP is supported
[ 3947.114903] reqbufs_output:484: Reqbufs called in an invalid state
[ 3947.114913] reqbufs_output:510: Failed allocating buffers for OUTPUT queue
ERROR: from element /GstPipeline:pipeline0/v4l2video0dec:v4l2video0dec0: Failed 
to allocate required memory.
Additional debug info:
gstv4l2videodec.c(575): gst_v4l2_video_dec_handle_frame (): 
/GstPipeline:pipeline0/v4l2video0dec:v4l2video0dec0:
Buffer pool activation failed
ERROR: pipeline doesn't want to preroll.
Setting pipeline to NULL ...
Freeing pipeline ...

[0]: https://patchwork.linuxtv.org/patch/32794/

Best regards,
Javier

  drivers/media/platform/s5p-mfc/s5p_mfc_dec.c | 1 -
  1 file changed, 1 deletion(-)

diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c 
b/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c
index f2d6376ce618..8b9467de2d6a 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c
@@ -474,7 +474,6 @@ static int reqbufs_output(struct s5p_mfc_dev *dev, struct 
s5p_mfc_ctx *ctx,
ret = vb2_reqbufs(>vq_src, reqbufs);
if (ret)
goto out;
-   s5p_mfc_close_mfc_inst(dev, ctx);
ctx->src_bufs_cnt = 0;
ctx->output_state = QUEUE_FREE;
} else if (ctx->output_state == QUEUE_FREE) {


Best regards
--
Marek Szyprowski, PhD
Samsung R Institute Poland

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC PATCH 04/24] smiapp-pll: Take existing divisor into account in minimum divisor check

2016-05-24 Thread Pavel Machek
On Mon 2016-04-25 00:08:04, Ivaylo Dimitrov wrote:
> From: Sakari Ailus 
> 
> Required added multiplier (and divisor) calculation did not take into
> account the existing divisor when checking the values against the minimum
> divisor. Do just that.
> 
> Signed-off-by: Sakari Ailus 

Acked-by: Pavel Machek 

-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) 
http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] [media] adv7604: Add support for hardware reset

2016-05-24 Thread Dragos Bogdan
The part can be reset by a low pulse on the RESET pin (i.e. a hardware reset) 
with a minimum width of 5 ms. It is recommended to wait 5 ms after the low 
pulse before an I2C write is performed to the part.
For safety reasons, the delays will be 10 ms.
The RESET pin can be tied high, so the GPIO is optional.

Signed-off-by: Dragos Bogdan 
---
 drivers/media/i2c/adv7604.c | 22 ++
 1 file changed, 22 insertions(+)

diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c
index 41a1bfc..fac0ff1 100644
--- a/drivers/media/i2c/adv7604.c
+++ b/drivers/media/i2c/adv7604.c
@@ -164,6 +164,7 @@ struct adv76xx_state {
struct adv76xx_platform_data pdata;
 
struct gpio_desc *hpd_gpio[4];
+   struct gpio_desc *reset_gpio;
 
struct v4l2_subdev sd;
struct media_pad pads[ADV76XX_PAD_MAX];
@@ -2996,6 +2997,21 @@ static int configure_regmaps(struct adv76xx_state *state)
return 0;
 }
 
+static int adv76xx_reset(struct adv76xx_state *state)
+{
+   if (state->reset_gpio) {
+   /* ADV76XX can be reset by a low reset pulse of minimum 5 ms. */
+   gpiod_set_value_cansleep(state->reset_gpio, 0);
+   mdelay(10);
+   gpiod_set_value_cansleep(state->reset_gpio, 1);
+   /* It is recommended to wait 5 ms after the low pulse before */
+   /* an I2C write is performed to the ADV76XX. */
+   mdelay(10);
+   }
+
+   return 0;
+}
+
 static int adv76xx_probe(struct i2c_client *client,
 const struct i2c_device_id *id)
 {
@@ -3059,6 +3075,12 @@ static int adv76xx_probe(struct i2c_client *client,
if (state->hpd_gpio[i])
v4l_info(client, "Handling HPD %u GPIO\n", i);
}
+   state->reset_gpio = devm_gpiod_get_optional(>dev, "reset",
+   GPIOD_OUT_HIGH);
+   if (IS_ERR(state->reset_gpio))
+   return PTR_ERR(state->reset_gpio);
+
+   adv76xx_reset(state);
 
state->timings = cea640x480;
state->format = adv76xx_format_info(state, MEDIA_BUS_FMT_YUYV8_2X8);
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv4] support for AD5820 camera auto-focus coil

2016-05-24 Thread Pavel Machek
This adds support for AD5820 autofocus coil, found for example in
Nokia N900 smartphone.

Signed-off-by: Pavel Machek 

---
v2: simple cleanups, fix error paths, simplify probe
v3: more cleanups, remove printk, add include
v4: remove header file.

diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
index 993dc50..77313a1 100644
--- a/drivers/media/i2c/Kconfig
+++ b/drivers/media/i2c/Kconfig
@@ -279,6 +279,13 @@ config VIDEO_ML86V7667
  To compile this driver as a module, choose M here: the
  module will be called ml86v7667.
 
+config VIDEO_AD5820
+   tristate "AD5820 lens voice coil support"
+   depends on I2C && VIDEO_V4L2 && MEDIA_CONTROLLER
+   ---help---
+ This is a driver for the AD5820 camera lens voice coil.
+ It is used for example in Nokia N900 (RX-51).
+
 config VIDEO_SAA7110
tristate "Philips SAA7110 video decoder"
depends on VIDEO_V4L2 && I2C
diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile
index 94f2c99..34434ae 100644
--- a/drivers/media/i2c/Makefile
+++ b/drivers/media/i2c/Makefile
@@ -19,6 +20,7 @@ obj-$(CONFIG_VIDEO_SAA717X) += saa717x.o
 obj-$(CONFIG_VIDEO_SAA7127) += saa7127.o
 obj-$(CONFIG_VIDEO_SAA7185) += saa7185.o
 obj-$(CONFIG_VIDEO_SAA6752HS) += saa6752hs.o
+obj-$(CONFIG_VIDEO_AD5820)  += ad5820.o
 obj-$(CONFIG_VIDEO_ADV7170) += adv7170.o
 obj-$(CONFIG_VIDEO_ADV7175) += adv7175.o
 obj-$(CONFIG_VIDEO_ADV7180) += adv7180.o
diff --git a/drivers/media/i2c/ad5820.c b/drivers/media/i2c/ad5820.c
new file mode 100644
index 000..f956bd3
--- /dev/null
+++ b/drivers/media/i2c/ad5820.c
@@ -0,0 +1,438 @@
+/*
+ * drivers/media/i2c/ad5820.c
+ *
+ * AD5820 DAC driver for camera voice coil focus.
+ *
+ * Copyright (C) 2008 Nokia Corporation
+ * Copyright (C) 2007 Texas Instruments
+ * Copyright (C) 2016 Pavel Machek 
+ *
+ * Contact: Tuukka Toivonen
+ *  Sakari Ailus
+ *
+ * Based on af_d88.c by Texas Instruments.
+ *
+ * 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 
+
+#define AD5820_NAME"ad5820"
+
+/* Register definitions */
+#define AD5820_POWER_DOWN  (1 << 15)
+#define AD5820_DAC_SHIFT   4
+#define AD5820_RAMP_MODE_LINEAR(0 << 3)
+#define AD5820_RAMP_MODE_64_16 (1 << 3)
+
+#define CODE_TO_RAMP_US(s) ((s) == 0 ? 0 : (1 << ((s) - 1)) * 50)
+#define RAMP_US_TO_CODE(c) fls(((c) + ((c)>>1)) / 50)
+
+#define to_ad5820_device(sd)   container_of(sd, struct ad5820_device, subdev)
+
+struct ad5820_device {
+   struct v4l2_subdev subdev;
+   struct ad5820_platform_data *platform_data;
+   struct regulator *vana;
+
+   struct v4l2_ctrl_handler ctrls;
+   u32 focus_absolute;
+   u32 focus_ramp_time;
+   u32 focus_ramp_mode;
+
+   struct mutex power_lock;
+   int power_count;
+
+   int standby : 1;
+};
+
+/**
+ * @brief I2C write using i2c_transfer().
+ * @param coil - the driver data structure
+ * @param data - register value to be written
+ * @returns nonnegative on success, negative if failed
+ */
+static int ad5820_write(struct ad5820_device *coil, u16 data)
+{
+   struct i2c_client *client = v4l2_get_subdevdata(>subdev);
+   struct i2c_msg msg;
+   int r;
+
+   if (!client->adapter)
+   return -ENODEV;
+
+   data = cpu_to_be16(data);
+   msg.addr  = client->addr;
+   msg.flags = 0;
+   msg.len   = 2;
+   msg.buf   = (u8 *)
+
+   r = i2c_transfer(client->adapter, , 1);
+   if (r < 0) {
+   dev_err(>dev, "write failed, error %d\n", r);
+   return r;
+   }
+
+   return 0;
+}
+
+/*
+ * Calculate status word and write it to the device based on current
+ * values of V4L2 controls. It is assumed that the stored V4L2 control
+ * values are properly limited and rounded.
+ */
+static int ad5820_update_hw(struct ad5820_device *coil)
+{
+   u16 status;
+
+   status = RAMP_US_TO_CODE(coil->focus_ramp_time);
+   status |= coil->focus_ramp_mode
+   ? AD5820_RAMP_MODE_64_16 : AD5820_RAMP_MODE_LINEAR;
+   status |= coil->focus_absolute << AD5820_DAC_SHIFT;
+
+   if (coil->standby)
+   status |= AD5820_POWER_DOWN;
+
+   return ad5820_write(coil, status);
+}
+
+/*
+ * Power handling
+ */
+static int ad5820_power_off(struct ad5820_device *coil, int standby)
+{
+   int ret = 0;
+
+   /*
+* Go to standby first as real power off my be denied by the 

Re: [PATCH] [media] adv7604: Add support for hardware reset

2016-05-24 Thread Lars-Peter Clausen
On 05/24/2016 11:13 AM, Dragos Bogdan wrote:
> The part can be reset by a low pulse on the RESET pin (i.e. a hardware reset) 
> with a minimum width of 5 ms. It is recommended to wait 5 ms after the low 
> pulse before an I2C write is performed to the part.
> For safety reasons, the delays will be 10 ms.
> The RESET pin can be tied high, so the GPIO is optional.
> 
> Signed-off-by: Dragos Bogdan 

Patch looks OK. One comment about the commit message, usually this should be
line-wrapped at around 75 characters.

Reviewed-by: Lars-Peter Clausen 

Thanks.
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCHv3] support for AD5820 camera auto-focus coil

2016-05-24 Thread Ivaylo Dimitrov



On 24.05.2016 12:04, Pavel Machek wrote:

Hi!


+static int ad5820_registered(struct v4l2_subdev *subdev)
+{
+   struct ad5820_device *coil = to_ad5820_device(subdev);
+   struct i2c_client *client = v4l2_get_subdevdata(subdev);
+
+   coil->vana = regulator_get(>dev, "VANA");


devm_regulator_get()?


I'd rather avoid devm_ here. Driver is simple enough to allow it.



Now thinking about it, what would happen here if regulator_get() returns 
-EPROBE_DEFER? Wouldn't it be better to move regulator_get to the 
probe() function, something like:


static int ad5820_probe(struct i2c_client *client,
const struct i2c_device_id *devid)
{
struct ad5820_device *coil;
int ret = 0;

coil = devm_kzalloc(sizeof(*coil), GFP_KERNEL);
if (coil == NULL)
return -ENOMEM;

coil->vana = devm_regulator_get(>dev, NULL);
if (IS_ERR(coil->vana)) {
ret = PTR_ERR(coil->vana);
if (ret != -EPROBE_DEFER)
dev_err(>dev, "could not get regulator for 
vana\n");
return ret;
}

mutex_init(>power_lock);
...

with the appropriate changes to remove() because of the devm API usage.


+#define AD5820_RAMP_MODE_LINEAR(0 << 3)
+#define AD5820_RAMP_MODE_64_16 (1 << 3)
+
+struct ad5820_platform_data {
+   int (*set_xshutdown)(struct v4l2_subdev *subdev, int set);
+};
+
+#define to_ad5820_device(sd)   container_of(sd, struct ad5820_device, subdev)
+
+struct ad5820_device {
+   struct v4l2_subdev subdev;
+   struct ad5820_platform_data *platform_data;
+   struct regulator *vana;
+
+   struct v4l2_ctrl_handler ctrls;
+   u32 focus_absolute;
+   u32 focus_ramp_time;
+   u32 focus_ramp_mode;
+
+   struct mutex power_lock;
+   int power_count;
+
+   int standby : 1;
+};
+


The same for struct ad5820_device, is it really part of the public API?


Let me check what can be done with it.
Pavel


--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC PATCH 04/24] smiapp-pll: Take existing divisor into account in minimum divisor check

2016-05-24 Thread Pali Rohár
On Sunday 01 May 2016 13:45:24 Sakari Ailus wrote:
> Hi Ivaylo,
> 
> On Mon, Apr 25, 2016 at 12:08:04AM +0300, Ivaylo Dimitrov wrote:
> > From: Sakari Ailus 
> > 
> > Required added multiplier (and divisor) calculation did not take into
> > account the existing divisor when checking the values against the minimum
> > divisor. Do just that.
> > 
> > Signed-off-by: Sakari Ailus 
> > ---
> >  drivers/media/i2c/smiapp-pll.c | 3 ++-
> >  1 file changed, 2 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/media/i2c/smiapp-pll.c b/drivers/media/i2c/smiapp-pll.c
> > index e3348db..5ad1edb 100644
> > --- a/drivers/media/i2c/smiapp-pll.c
> > +++ b/drivers/media/i2c/smiapp-pll.c
> > @@ -227,7 +227,8 @@ static int __smiapp_pll_calculate(
> >  
> > more_mul_factor = lcm(div, pll->pre_pll_clk_div) / div;
> > dev_dbg(dev, "more_mul_factor: %u\n", more_mul_factor);
> > -   more_mul_factor = lcm(more_mul_factor, op_limits->min_sys_clk_div);
> > +   more_mul_factor = lcm(more_mul_factor,
> > + DIV_ROUND_UP(op_limits->min_sys_clk_div, div));
> > dev_dbg(dev, "more_mul_factor: min_op_sys_clk_div: %d\n",
> > more_mul_factor);
> > i = roundup(more_mul_min, more_mul_factor);
> 
> I remember writing the patch, but I don't remember what for, or whether it
> was really needed. Does the secondary sensor work without this one?

Hi! You sent me this patch more then 3 years ago. Look at our private
email discussion, e.g. email with Message-Id <201303281524.10538@pali>
and subject "Re: Nokia N900 - smiapp driver" which was sent years ago
Thu, 28 Mar 2013 15:24:10 +0100.

-- 
Pali Rohár
pali.ro...@gmail.com
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCHv3] support for AD5820 camera auto-focus coil

2016-05-24 Thread Pavel Machek
Hi!

> >+static int ad5820_registered(struct v4l2_subdev *subdev)
> >+{
> >+struct ad5820_device *coil = to_ad5820_device(subdev);
> >+struct i2c_client *client = v4l2_get_subdevdata(subdev);
> >+
> >+coil->vana = regulator_get(>dev, "VANA");
> 
> devm_regulator_get()?

I'd rather avoid devm_ here. Driver is simple enough to allow it.

> >+#define AD5820_RAMP_MODE_LINEAR (0 << 3)
> >+#define AD5820_RAMP_MODE_64_16  (1 << 3)
> >+
> >+struct ad5820_platform_data {
> >+int (*set_xshutdown)(struct v4l2_subdev *subdev, int set);
> >+};
> >+
> >+#define to_ad5820_device(sd)container_of(sd, struct ad5820_device, 
> >subdev)
> >+
> >+struct ad5820_device {
> >+struct v4l2_subdev subdev;
> >+struct ad5820_platform_data *platform_data;
> >+struct regulator *vana;
> >+
> >+struct v4l2_ctrl_handler ctrls;
> >+u32 focus_absolute;
> >+u32 focus_ramp_time;
> >+u32 focus_ramp_mode;
> >+
> >+struct mutex power_lock;
> >+int power_count;
> >+
> >+int standby : 1;
> >+};
> >+
> 
> The same for struct ad5820_device, is it really part of the public API?

Let me check what can be done with it.
Pavel

-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) 
http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v5 2/2] media: set proper max seg size for devices on Exynos SoCs

2016-05-24 Thread Marek Szyprowski
All multimedia devices found on Exynos SoCs support only contiguous
buffers, so set DMA max segment size to DMA_BIT_MASK(32) to let memory
allocator to correctly create contiguous memory mappings.

Signed-off-by: Marek Szyprowski 
---
 drivers/media/platform/exynos-gsc/gsc-core.c  | 2 ++
 drivers/media/platform/exynos4-is/fimc-core.c | 2 ++
 drivers/media/platform/exynos4-is/fimc-is.c   | 2 ++
 drivers/media/platform/exynos4-is/fimc-lite.c | 2 ++
 drivers/media/platform/s5p-g2d/g2d.c  | 2 ++
 drivers/media/platform/s5p-jpeg/jpeg-core.c   | 2 ++
 drivers/media/platform/s5p-mfc/s5p_mfc.c  | 4 
 drivers/media/platform/s5p-tv/mixer_video.c   | 2 ++
 8 files changed, 18 insertions(+)

diff --git a/drivers/media/platform/exynos-gsc/gsc-core.c 
b/drivers/media/platform/exynos-gsc/gsc-core.c
index c049736..c9d2009 100644
--- a/drivers/media/platform/exynos-gsc/gsc-core.c
+++ b/drivers/media/platform/exynos-gsc/gsc-core.c
@@ -1124,6 +1124,7 @@ static int gsc_probe(struct platform_device *pdev)
goto err_m2m;
 
/* Initialize continious memory allocator */
+   vb2_dma_contig_set_max_seg_size(dev, DMA_BIT_MASK(32));
gsc->alloc_ctx = vb2_dma_contig_init_ctx(dev);
if (IS_ERR(gsc->alloc_ctx)) {
ret = PTR_ERR(gsc->alloc_ctx);
@@ -1153,6 +1154,7 @@ static int gsc_remove(struct platform_device *pdev)
v4l2_device_unregister(>v4l2_dev);
 
vb2_dma_contig_cleanup_ctx(gsc->alloc_ctx);
+   vb2_dma_contig_clear_max_seg_size(>dev);
pm_runtime_disable(>dev);
gsc_clk_put(gsc);
 
diff --git a/drivers/media/platform/exynos4-is/fimc-core.c 
b/drivers/media/platform/exynos4-is/fimc-core.c
index b1c1cea..368f44f 100644
--- a/drivers/media/platform/exynos4-is/fimc-core.c
+++ b/drivers/media/platform/exynos4-is/fimc-core.c
@@ -1019,6 +1019,7 @@ static int fimc_probe(struct platform_device *pdev)
}
 
/* Initialize contiguous memory allocator */
+   vb2_dma_contig_set_max_seg_size(dev, DMA_BIT_MASK(32));
fimc->alloc_ctx = vb2_dma_contig_init_ctx(dev);
if (IS_ERR(fimc->alloc_ctx)) {
ret = PTR_ERR(fimc->alloc_ctx);
@@ -1124,6 +1125,7 @@ static int fimc_remove(struct platform_device *pdev)
 
fimc_unregister_capture_subdev(fimc);
vb2_dma_contig_cleanup_ctx(fimc->alloc_ctx);
+   vb2_dma_contig_clear_max_seg_size(>dev);
 
clk_disable(fimc->clock[CLK_BUS]);
fimc_clk_put(fimc);
diff --git a/drivers/media/platform/exynos4-is/fimc-is.c 
b/drivers/media/platform/exynos4-is/fimc-is.c
index 979c388..bd98b56 100644
--- a/drivers/media/platform/exynos4-is/fimc-is.c
+++ b/drivers/media/platform/exynos4-is/fimc-is.c
@@ -847,6 +847,7 @@ static int fimc_is_probe(struct platform_device *pdev)
if (ret < 0)
goto err_pm;
 
+   vb2_dma_contig_set_max_seg_size(dev, DMA_BIT_MASK(32));
is->alloc_ctx = vb2_dma_contig_init_ctx(dev);
if (IS_ERR(is->alloc_ctx)) {
ret = PTR_ERR(is->alloc_ctx);
@@ -940,6 +941,7 @@ static int fimc_is_remove(struct platform_device *pdev)
free_irq(is->irq, is);
fimc_is_unregister_subdevs(is);
vb2_dma_contig_cleanup_ctx(is->alloc_ctx);
+   vb2_dma_contig_clear_max_seg_size(dev);
fimc_is_put_clocks(is);
fimc_is_debugfs_remove(is);
release_firmware(is->fw.f_w);
diff --git a/drivers/media/platform/exynos4-is/fimc-lite.c 
b/drivers/media/platform/exynos4-is/fimc-lite.c
index dc1b929..27cb620 100644
--- a/drivers/media/platform/exynos4-is/fimc-lite.c
+++ b/drivers/media/platform/exynos4-is/fimc-lite.c
@@ -1551,6 +1551,7 @@ static int fimc_lite_probe(struct platform_device *pdev)
goto err_sd;
}
 
+   vb2_dma_contig_set_max_seg_size(dev, DMA_BIT_MASK(32));
fimc->alloc_ctx = vb2_dma_contig_init_ctx(dev);
if (IS_ERR(fimc->alloc_ctx)) {
ret = PTR_ERR(fimc->alloc_ctx);
@@ -1652,6 +1653,7 @@ static int fimc_lite_remove(struct platform_device *pdev)
pm_runtime_set_suspended(dev);
fimc_lite_unregister_capture_subdev(fimc);
vb2_dma_contig_cleanup_ctx(fimc->alloc_ctx);
+   vb2_dma_contig_clear_max_seg_size(dev);
fimc_lite_clk_put(fimc);
 
dev_info(dev, "Driver unloaded\n");
diff --git a/drivers/media/platform/s5p-g2d/g2d.c 
b/drivers/media/platform/s5p-g2d/g2d.c
index 612d1ea..d3e3469 100644
--- a/drivers/media/platform/s5p-g2d/g2d.c
+++ b/drivers/media/platform/s5p-g2d/g2d.c
@@ -681,6 +681,7 @@ static int g2d_probe(struct platform_device *pdev)
goto put_clk_gate;
}
 
+   vb2_dma_contig_set_max_seg_size(>dev, DMA_BIT_MASK(32));
dev->alloc_ctx = vb2_dma_contig_init_ctx(>dev);
if (IS_ERR(dev->alloc_ctx)) {
ret = PTR_ERR(dev->alloc_ctx);
@@ -757,6 +758,7 @@ static int g2d_remove(struct platform_device *pdev)
video_unregister_device(dev->vfd);

[PATCH v5 0/2] vb2-dma-contig: configure DMA max segment size properly

2016-05-24 Thread Marek Szyprowski
Hello,

This patch is a follow-up of my previous attempts to let Exynos
multimedia devices to work properly with shared buffers when IOMMU is
enabled:
1. https://www.mail-archive.com/linux-media@vger.kernel.org/msg96946.html
2. http://thread.gmane.org/gmane.linux.drivers.video-input-infrastructure/97316
3. https://patchwork.linuxtv.org/patch/30870/
4. http://www.spinics.net/lists/linux-media/msg100353.html

After another discussion (4th link above) I agree with Mauro that
changing dma_parms should be done from device drivers not the
videobuf2-dc module. Now drivers releases dma_parms structure (allocated
by vb2_dc_set_max_seg_size()), which in theory might be allocated by
other function than vb2_dc_set_max_seg_size(). This is however not a big
issue, because no such case exist in mainline kernel (there is no
generic bus code for platform devices, which allocates dma_parms
structure).

Here is some more backgroud why this is done in videobuf2-dc not in the
respective generic bus code:
http://lists.infradead.org/pipermail/linux-arm-kernel/2014-November/305913.html

Best regards,
Marek Szyprowski

changelog:
v5:
- got back to the v1-style version on Mauro request
- added function to clear dma_parms and release allocated structure

v4: http://www.spinics.net/lists/linux-media/msg100182.html
- rebased onto media master tree
- call vb2_dc_set_max_seg_size after allocating vb2 buf object

v3: http://www.spinics.net/lists/linux-media/msg100125.html
- added FIXME note about possible memory leak

v2: http://www.spinics.net/lists/linux-media/msg100011.html
- fixes typos and other language issues in the comments

v1: http://article.gmane.org/gmane.linux.kernel.samsung-soc/53690

Marek Szyprowski (2):
  media: vb2-dma-contig: add helper for setting dma max seg size
  media: set proper max seg size for devices on Exynos SoCs

 drivers/media/platform/exynos-gsc/gsc-core.c   |  2 +
 drivers/media/platform/exynos4-is/fimc-core.c  |  2 +
 drivers/media/platform/exynos4-is/fimc-is.c|  2 +
 drivers/media/platform/exynos4-is/fimc-lite.c  |  2 +
 drivers/media/platform/s5p-g2d/g2d.c   |  2 +
 drivers/media/platform/s5p-jpeg/jpeg-core.c|  2 +
 drivers/media/platform/s5p-mfc/s5p_mfc.c   |  4 ++
 drivers/media/platform/s5p-tv/mixer_video.c|  2 +
 drivers/media/v4l2-core/videobuf2-dma-contig.c | 53 ++
 include/media/videobuf2-dma-contig.h   |  2 +
 10 files changed, 73 insertions(+)

-- 
1.9.2

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v5 1/2] media: vb2-dma-contig: add helper for setting dma max seg size

2016-05-24 Thread Marek Szyprowski
Add a helper function for device drivers to set DMA's max_seg_size.
Setting it to largest possible value lets DMA-mapping API always create
contiguous mappings in DMA address space. This is essential for all
devices, which use dma-contig videobuf2 memory allocator and shared
buffers.

Till now, the only case when vb2-dma-contig really 'worked' was a case
where userspace provided USERPTR buffer, which was in fact mmaped
contiguous buffer from the other v4l2/drm device. Also DMABUF made of
contiguous buffer worked only when its exporter did not split it into
several chunks in the scatter-list. Any other buffer failed, regardless
of the arch/platform used and the presence of the IOMMU of the device bus.

This patch provides interface to fix this issue.

Signed-off-by: Marek Szyprowski 
---
 drivers/media/v4l2-core/videobuf2-dma-contig.c | 53 ++
 include/media/videobuf2-dma-contig.h   |  2 +
 2 files changed, 55 insertions(+)

diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c 
b/drivers/media/v4l2-core/videobuf2-dma-contig.c
index 5361197..e3e47ac 100644
--- a/drivers/media/v4l2-core/videobuf2-dma-contig.c
+++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c
@@ -753,6 +753,59 @@ void vb2_dma_contig_cleanup_ctx(void *alloc_ctx)
 }
 EXPORT_SYMBOL_GPL(vb2_dma_contig_cleanup_ctx);
 
+/**
+ * vb2_dma_contig_set_max_seg_size() - configure DMA max segment size
+ * @dev:   device for configuring DMA parameters
+ * @size:  size of DMA max segment size to set
+ *
+ * To allow mapping the scatter-list into a single chunk in the DMA
+ * address space, the device is required to have the DMA max segment
+ * size parameter set to a value larger than the buffer size. Otherwise,
+ * the DMA-mapping subsystem will split the mapping into max segment
+ * size chunks. This function sets the DMA max segment size
+ * parameter to let DMA-mapping map a buffer as a single chunk in DMA
+ * address space.
+ * This code assumes that the DMA-mapping subsystem will merge all
+ * scatterlist segments if this is really possible (for example when
+ * an IOMMU is available and enabled).
+ * Ideally, this parameter should be set by the generic bus code, but it
+ * is left with the default 64KiB value due to historical litmiations in
+ * other subsystems (like limited USB host drivers) and there no good
+ * place to set it to the proper value.
+ * This function should be called from the drivers, which are known to
+ * operate on platforms with IOMMU and provide access to shared buffers
+ * (either USERPTR or DMABUF). This should be done before initializing
+ * videobuf2 queue.
+ */
+int vb2_dma_contig_set_max_seg_size(struct device *dev, unsigned int size)
+{
+   if (!dev->dma_parms) {
+   dev->dma_parms = kzalloc(sizeof(dev->dma_parms), GFP_KERNEL);
+   if (!dev->dma_parms)
+   return -ENOMEM;
+   }
+   if (dma_get_max_seg_size(dev) < size)
+   return dma_set_max_seg_size(dev, size);
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(vb2_dma_contig_set_max_seg_size);
+
+/*
+ * vb2_dma_contig_clear_max_seg_size() - release resources for DMA parameters
+ * @dev:   device for configuring DMA parameters
+ *
+ * This function releases resources allocated to configure DMA parameters
+ * (see vb2_dma_contig_set_max_seg_size() function). It should be called from
+ * device drivers on driver remove.
+ */
+void vb2_dma_contig_clear_max_seg_size(struct device *dev)
+{
+   kfree(dev->dma_parms);
+   dev->dma_parms = NULL;
+}
+EXPORT_SYMBOL_GPL(vb2_dma_contig_clear_max_seg_size);
+
 MODULE_DESCRIPTION("DMA-contig memory handling routines for videobuf2");
 MODULE_AUTHOR("Pawel Osciak ");
 MODULE_LICENSE("GPL");
diff --git a/include/media/videobuf2-dma-contig.h 
b/include/media/videobuf2-dma-contig.h
index 2087c9a..f7dc840 100644
--- a/include/media/videobuf2-dma-contig.h
+++ b/include/media/videobuf2-dma-contig.h
@@ -35,6 +35,8 @@ static inline void *vb2_dma_contig_init_ctx(struct device 
*dev)
 }
 
 void vb2_dma_contig_cleanup_ctx(void *alloc_ctx);
+int vb2_dma_contig_set_max_seg_size(struct device *dev, unsigned int size);
+void vb2_dma_contig_clear_max_seg_size(struct device *dev);
 
 extern const struct vb2_mem_ops vb2_dma_contig_memops;
 
-- 
1.9.2

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html