Re: [RFCv4 09/21] v4l2: add request API support

2018-02-19 Thread Philippe Ombredanne
On Tue, Feb 20, 2018 at 5:44 AM, Alexandre Courbot
 wrote:
> Add a v4l2 request entity data structure that takes care of storing the
> request-related state of a V4L2 device ; in this case, its controls.
>
> Signed-off-by: Alexandre Courbot 



> --- /dev/null
> +++ b/drivers/media/v4l2-core/v4l2-request.c
> @@ -0,0 +1,178 @@
> +/*
> + * Media requests support for V4L2
> + *
> + * Copyright (C) 2018, The Chromium OS Authors.  All rights reserved.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + */

Do you mind using SPDX tags per [1] rather that this fine but long
legalese. (Here and in the whole patch series)

[1] 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/process/license-rules.rst
-- 
Cordially
Philippe Ombredanne


[PATCH v2] Staging: bcm2048: Fix function argument alignment in radio-bcm2048.c.

2018-02-19 Thread Quytelda Kahja
Fix a coding style problem.

Signed-off-by: Quytelda Kahja 
---
This is the patch without the unnecessary fixes for line length.

 drivers/staging/media/bcm2048/radio-bcm2048.c | 22 +++---
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/drivers/staging/media/bcm2048/radio-bcm2048.c 
b/drivers/staging/media/bcm2048/radio-bcm2048.c
index 06d1920150da..f38a4f2acdde 100644
--- a/drivers/staging/media/bcm2048/radio-bcm2048.c
+++ b/drivers/staging/media/bcm2048/radio-bcm2048.c
@@ -1864,7 +1864,7 @@ static int bcm2048_probe(struct bcm2048_device *bdev)
goto unlock;
 
err = bcm2048_set_fm_search_rssi_threshold(bdev,
-   BCM2048_DEFAULT_RSSI_THRESHOLD);
+  
BCM2048_DEFAULT_RSSI_THRESHOLD);
if (err < 0)
goto unlock;
 
@@ -1942,9 +1942,9 @@ static irqreturn_t bcm2048_handler(int irq, void *dev)
  */
 #define property_write(prop, type, mask, check)
\
 static ssize_t bcm2048_##prop##_write(struct device *dev,  \
-   struct device_attribute *attr,  \
-   const char *buf,\
-   size_t count)   \
+ struct device_attribute *attr,\
+ const char *buf,  \
+ size_t count) \
 {  \
struct bcm2048_device *bdev = dev_get_drvdata(dev); \
type value; \
@@ -1966,8 +1966,8 @@ static ssize_t bcm2048_##prop##_write(struct device *dev, 
\
 
 #define property_read(prop, mask)  \
 static ssize_t bcm2048_##prop##_read(struct device *dev,   \
-   struct device_attribute *attr,  \
-   char *buf)  \
+struct device_attribute *attr, \
+char *buf) \
 {  \
struct bcm2048_device *bdev = dev_get_drvdata(dev); \
int value;  \
@@ -1985,8 +1985,8 @@ static ssize_t bcm2048_##prop##_read(struct device *dev,  
\
 
 #define property_signed_read(prop, size, mask) \
 static ssize_t bcm2048_##prop##_read(struct device *dev,   \
-   struct device_attribute *attr,  \
-   char *buf)  \
+struct device_attribute *attr, \
+char *buf) \
 {  \
struct bcm2048_device *bdev = dev_get_drvdata(dev); \
size value; \
@@ -2005,8 +2005,8 @@ property_read(prop, mask) 
\
 
 #define property_str_read(prop, size)  \
 static ssize_t bcm2048_##prop##_read(struct device *dev,   \
-   struct device_attribute *attr,  \
-   char *buf)  \
+struct device_attribute *attr, \
+char *buf) \
 {  \
struct bcm2048_device *bdev = dev_get_drvdata(dev); \
int count;  \
@@ -2175,7 +2175,7 @@ static int bcm2048_fops_release(struct file *file)
 }
 
 static __poll_t bcm2048_fops_poll(struct file *file,
- struct poll_table_struct *pts)
+ struct poll_table_struct *pts)
 {
struct bcm2048_device *bdev = video_drvdata(file);
__poll_t retval = 0;
-- 
2.16.2



Hello Beautiful

2018-02-19 Thread Jack
Good day dear, i hope this mail meets you well? my name is Jack, from the U.S. 
I know this may seem inappropriate so i ask for your forgiveness but i wish to 
get to know you better, if I may be so bold. I consider myself an easy-going 
man, adventurous, honest and fun loving person but I am currently looking for a 
relationship in which I will feel loved. I promise to answer any question that 
you may want to ask me...all i need is just your attention and the chance to 
know you more.

Please tell me more about yourself, if you do not mind. Hope to hear back from 
you soon.

Jack.


[RFC PATCH] media: i2c: ov772x: ov772x_frame_intervals[] can be static

2018-02-19 Thread kbuild test robot

Fixes: 42b7d5be5f1f ("media: i2c: ov772x: Support frame interval handling")
Signed-off-by: Fengguang Wu 
---
 ov772x.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/i2c/ov772x.c b/drivers/media/i2c/ov772x.c
index eba71d97..0d8ce2a 100644
--- a/drivers/media/i2c/ov772x.c
+++ b/drivers/media/i2c/ov772x.c
@@ -532,7 +532,7 @@ static const struct ov772x_win_size ov772x_win_sizes[] = {
 /*
  * frame rate settings lists
  */
-unsigned int ov772x_frame_intervals[] = { 5, 10, 15, 20, 30, 60 };
+static unsigned int ov772x_frame_intervals[] = { 5, 10, 15, 20, 30, 60 };
 #define OV772X_N_FRAME_INTERVALS ARRAY_SIZE(ov772x_frame_intervals)
 
 /*


Re: [PATCH v9 07/11] media: i2c: ov772x: Support frame interval handling

2018-02-19 Thread kbuild test robot
Hi Jacopo,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on linuxtv-media/master]
[also build test WARNING on v4.16-rc2 next-20180220]
[if your patch is applied to the wrong git tree, please drop us a note to help 
improve the system]

url:
https://github.com/0day-ci/linux/commits/Jacopo-Mondi/Renesas-Capture-Engine-Unit-CEU-V4L2-driver/20180220-101027
base:   git://linuxtv.org/media_tree.git master
reproduce:
# apt-get install sparse
make ARCH=x86_64 allmodconfig
make C=1 CF=-D__CHECK_ENDIAN__


sparse warnings: (new ones prefixed by >>)

>> drivers/media/i2c/ov772x.c:386:3: sparse: symbol 'ov772x_pll' was not 
>> declared. Should it be
>> drivers/media/i2c/ov772x.c:535:14: sparse: symbol 'ov772x_frame_intervals' 
>> was not declared. Should it be
   drivers/media/i2c/ov772x.c: In function 'ov772x_set_frame_rate.isra.2':
   drivers/media/i2c/ov772x.c:643:7: warning: 'fsize' may be used uninitialized 
in this function
pclk = fps COPYING CREDITS Documentation Kbuild Kconfig LICENSES 
MAINTAINERS Makefile README arch block certs crypto drivers firmware fs include 
init ipc kernel lib mm net samples scripts security sound tools usr virt fsize;
~^

Please review and possibly fold the followup patch.

---
0-DAY kernel test infrastructureOpen Source Technology Center
https://lists.01.org/pipermail/kbuild-all   Intel Corporation


[RFCv4 00/21] Request API

2018-02-19 Thread Alexandre Courbot
(resending with correct word-wrap - sorry for the inconvenience)

Hi everyone,

And thanks for all the feedback on the previous version! I have tried to address
as much as possible, which results in (another) almost rewrite. But I think the
behavior and structure are converging to something satisfying and usable.

Besides the buffer queuing behavior that has been fixed, some of the big design
changes undertaken are that the media controller framework is not a requirement
anymore (although it can still be used in exactly the same way as before), and
that ioctls related to requests are now performed directly on the request FD.

As discussed with Sakari, the fact that request entities were in fact media
entities was a bit limiting, so I created a request_entity type that can be
embedded into any structure we want to control with requests. This is what
allows drivers to support requests without the media controller: simple V4L2
drivers can use the V4L2 implementation that allows to control a single video
device (as opposed to the whole pipeline under a media controller). Media
controllers can still, of course, use a more complex implementation and control
their whole pipeline, but bringing that complexity to simple drivers seemed
overreached to me.

Independently of the request implementation, request entities can store their
own data, in a way that makes sense regarding their type (that would be
v4l2_request_entity_data for V4L2 devices, but can be another data type for
media controllers topology).

The entity data lookup is also performed on these request_entities, working
effectively like the data store Sakari proposed, but retaining a base type for
data lookup.

Patches are organized as follows:

Patch 1 provides the base request support, not tied to either media or v4l2.

Patches 2 to 8 are the control rework done by Hans, with an extra workaround for
a bug discovered while working on vivid (see commit message for details).

Patch 9 adds request support to V4L2 in the form of entity data for v4l2 devices
to be used in requests, and a request manager capable of producing simple
requests for video devices. Maybe this should be split into different files, but
since the code is not that big I have kept it under the same file.

Patches 10 to 13 add request support to vb2-core and vb2-v4l2.

Patches 14 and 15 add support for the request_fd field in G/S/TRY_EXT_CTRLS
ioctls.

Patch 16 allows requests to be allocated from a supporting V4L2 video device
node.

Patches 17 and 19 add request support to mem2mem and vim2m. Patch 18 documents
usage of requests with V4L2 devices.

Patch 20 adds support to the vivid capture device.

Finally, 21 is a WIP patch implementing request support for media controller
nodes. Requests allocated that way are of a different, broader nature than V4L2
requests, and will be able to control any device managed by the controller. To
allow this, request_entity is embedded into media_entity, so that media entities
can be upcasted as in the previous version.

Phew! That was quite long, sorry about that. As usual, simple programs
demonstrating requests on vim2m and vivid are available:

https://gist.github.com/Gnurou/34c35f1f8e278dad454b51578d239a42
https://gist.github.com/Gnurou/5052e6ab41e7c55164b75d2970bc5a04

If things are starting to look ok, I would like to move on to the next step and
implement support in v4l2-ctl. Maybe also start submitting an actual codec
driver once the control work is completed. And of course, it may be good time to
think about how pipeline configuration would work. The current design should
make this question orthogonal to getting support in for simple V4L2 devices.

Looking forward to your feedback!

Changes since RFC v3:
* Buffer queuing is now performed as soon as the request is queued, allowing
drivers to see them early.
* Request refcounting is done using the file * structure instead of a kref
* Requests can now be used independently of a media controller, to avoid having
to pull it for simple codec drivers. For such drivers, the device node can
allocate requests that are exclusive to this device only. Media controller nodes
can still allocate requests that control their topology as well as the devices
under them.
* Consequently, media_request is now its own module since it can be used
independently of media.ko.
* SUBMIT/REINIT request ioctls are now performed on the request FD instead of
the media device. This means that device/media controller node's business with
requests is limited to allocating them.
* Got rid of request IDs.
* Only allow one buffer to be queued to each queue of request entities.
* The request FD that produced a CAPTURE buffer is not returned to user-space
anymore.
* Added requests support for the Vivid video capture device.
* Let drivers decide individually whether their entities should be per file
handle or global to the device, solving the question we had about this in
previous RFCs. Vim2m provides an example of per-context entities, 

[RFCv4 02/21] v4l2-ctrls: v4l2_ctrl_add_handler: add from_other_dev

2018-02-19 Thread Alexandre Courbot
From: Hans Verkuil 

Add a 'bool from_other_dev' argument: set to true if the two
handlers refer to different devices (e.g. it is true when
inheriting controls from a subdev into a main v4l2 bridge
driver).

This will be used later when implementing support for the
request API since we need to skip such controls.

TODO: check drivers/staging/media/imx/imx-media-fim.c change.

Signed-off-by: Hans Verkuil 
Signed-off-by: Alexandre Courbot 
---
 drivers/media/dvb-frontends/rtl2832_sdr.c |  5 +-
 drivers/media/pci/bt8xx/bttv-driver.c |  2 +-
 drivers/media/pci/cx23885/cx23885-417.c   |  2 +-
 drivers/media/pci/cx88/cx88-blackbird.c   |  2 +-
 drivers/media/pci/cx88/cx88-video.c   |  2 +-
 drivers/media/pci/saa7134/saa7134-empress.c   |  4 +-
 drivers/media/pci/saa7134/saa7134-video.c |  2 +-
 .../media/platform/exynos4-is/fimc-capture.c  |  2 +-
 drivers/media/platform/rcar-vin/rcar-v4l2.c   |  3 +-
 drivers/media/platform/rcar_drif.c|  2 +-
 .../media/platform/soc_camera/soc_camera.c|  3 +-
 drivers/media/platform/vivid/vivid-ctrls.c| 46 +--
 drivers/media/usb/cx231xx/cx231xx-417.c   |  2 +-
 drivers/media/usb/cx231xx/cx231xx-video.c |  4 +-
 drivers/media/usb/msi2500/msi2500.c   |  2 +-
 drivers/media/usb/tm6000/tm6000-video.c   |  2 +-
 drivers/media/v4l2-core/v4l2-ctrls.c  | 11 +++--
 drivers/media/v4l2-core/v4l2-device.c |  3 +-
 drivers/staging/media/imx/imx-media-dev.c |  2 +-
 drivers/staging/media/imx/imx-media-fim.c |  2 +-
 include/media/v4l2-ctrls.h|  4 +-
 21 files changed, 58 insertions(+), 49 deletions(-)

diff --git a/drivers/media/dvb-frontends/rtl2832_sdr.c 
b/drivers/media/dvb-frontends/rtl2832_sdr.c
index c6e78d870ccd..6064d28224e8 100644
--- a/drivers/media/dvb-frontends/rtl2832_sdr.c
+++ b/drivers/media/dvb-frontends/rtl2832_sdr.c
@@ -1394,7 +1394,8 @@ static int rtl2832_sdr_probe(struct platform_device *pdev)
case RTL2832_SDR_TUNER_E4000:
v4l2_ctrl_handler_init(>hdl, 9);
if (subdev)
-   v4l2_ctrl_add_handler(>hdl, subdev->ctrl_handler, 
NULL);
+   v4l2_ctrl_add_handler(>hdl, subdev->ctrl_handler,
+ NULL, true);
break;
case RTL2832_SDR_TUNER_R820T:
case RTL2832_SDR_TUNER_R828D:
@@ -1423,7 +1424,7 @@ static int rtl2832_sdr_probe(struct platform_device *pdev)
v4l2_ctrl_handler_init(>hdl, 2);
if (subdev)
v4l2_ctrl_add_handler(>hdl, subdev->ctrl_handler,
- NULL);
+ NULL, true);
break;
default:
v4l2_ctrl_handler_init(>hdl, 0);
diff --git a/drivers/media/pci/bt8xx/bttv-driver.c 
b/drivers/media/pci/bt8xx/bttv-driver.c
index f697698fe38d..cdcb36d8c5c3 100644
--- a/drivers/media/pci/bt8xx/bttv-driver.c
+++ b/drivers/media/pci/bt8xx/bttv-driver.c
@@ -4211,7 +4211,7 @@ static int bttv_probe(struct pci_dev *dev, const struct 
pci_device_id *pci_id)
/* register video4linux + input */
if (!bttv_tvcards[btv->c.type].no_video) {
v4l2_ctrl_add_handler(>radio_ctrl_handler, hdl,
-   v4l2_ctrl_radio_filter);
+   v4l2_ctrl_radio_filter, false);
if (btv->radio_ctrl_handler.error) {
result = btv->radio_ctrl_handler.error;
goto fail2;
diff --git a/drivers/media/pci/cx23885/cx23885-417.c 
b/drivers/media/pci/cx23885/cx23885-417.c
index a71f3c7569ce..762823871c78 100644
--- a/drivers/media/pci/cx23885/cx23885-417.c
+++ b/drivers/media/pci/cx23885/cx23885-417.c
@@ -1527,7 +1527,7 @@ int cx23885_417_register(struct cx23885_dev *dev)
dev->cxhdl.priv = dev;
dev->cxhdl.func = cx23885_api_func;
cx2341x_handler_set_50hz(>cxhdl, tsport->height == 576);
-   v4l2_ctrl_add_handler(>ctrl_handler, >cxhdl.hdl, NULL);
+   v4l2_ctrl_add_handler(>ctrl_handler, >cxhdl.hdl, NULL, false);
 
/* Allocate and initialize V4L video device */
dev->v4l_device = cx23885_video_dev_alloc(tsport,
diff --git a/drivers/media/pci/cx88/cx88-blackbird.c 
b/drivers/media/pci/cx88/cx88-blackbird.c
index 0e0952e60795..39f69d89a663 100644
--- a/drivers/media/pci/cx88/cx88-blackbird.c
+++ b/drivers/media/pci/cx88/cx88-blackbird.c
@@ -1183,7 +1183,7 @@ static int cx8802_blackbird_probe(struct cx8802_driver 
*drv)
err = cx2341x_handler_init(>cxhdl, 36);
if (err)
goto fail_core;
-   v4l2_ctrl_add_handler(>cxhdl.hdl, >video_hdl, NULL);
+   v4l2_ctrl_add_handler(>cxhdl.hdl, >video_hdl, NULL, false);
 
/* blackbird stuff */
pr_info("cx23416 based mpeg encoder (blackbird 

[RFCv4 00/21] Request API

2018-02-19 Thread Alexandre Courbot
Hi everyone,

And thanks for all the feedback on the previous version! I have tried to 
address as much as possible, which results in (another) almost rewrite. But I 
think the behavior and structure are converging to something satisfying and 
usable.

Besides the buffer queuing behavior that has been fixed, some of the big design 
changes undertaken are that the media controller framework is not a requirement 
anymore (although it can still be used in exactly the same way as before), and 
that ioctls related to requests are now performed directly on the request FD.

As discussed with Sakari, the fact that request entities were in fact media 
entities was a bit limiting, so I created a request_entity type that can be 
embedded into any structure we want to control with requests. This is what 
allows drivers to support requests without the media controller: simple V4L2 
drivers can use the V4L2 implementation that allows to control a single video 
device (as opposed to the whole pipeline under a media controller). Media 
controllers can still, of course, use a more complex implementation and control 
their whole pipeline, but bringing that complexity to simple drivers seemed 
overreached to me.

Independently of the request implementation, request entities can store their 
own data, in a way that makes sense regarding their type (that would be 
v4l2_request_entity_data for V4L2 devices, but can be another data type for 
media controllers topology).

The entity data lookup is also performed on these request_entities, working 
effectively like the data store Sakari proposed, but retaining a base type for 
data lookup.

Patches are organized as follows:

Patch 1 provides the base request support, not tied to either media or v4l2.

Patches 2 to 8 are the control rework done by Hans, with an extra workaround 
for a bug discovered while working on vivid (see commit message for details).

Patch 9 adds request support to V4L2 in the form of entity data for v4l2 
devices to be used in requests, and a request manager capable of producing 
simple requests for video devices. Maybe this should be split into different 
files, but since the code is not that big I have kept it under the same file.

Patches 10 to 13 add request support to vb2-core and vb2-v4l2.

Patches 14 and 15 add support for the request_fd field in G/S/TRY_EXT_CTRLS 
ioctls.

Patch 16 allows requests to be allocated from a supporting V4L2 video device 
node.

Patches 17 and 19 add request support to mem2mem and vim2m. Patch 18 documents 
usage of requests with V4L2 devices.

Patch 20 adds support to the vivid capture device.

Finally, 21 is a WIP patch implementing request support for media controller 
nodes. Requests allocated that way are of a different, broader nature than V4L2 
requests, and will be able to control any device managed by the controller. To 
allow this, request_entity is embedded into media_entity, so that media 
entities can be upcasted as in the previous version.

Phew! That was quite long, sorry about that. As usual, simple programs 
demonstrating requests on vim2m and vivid are available:

https://gist.github.com/Gnurou/34c35f1f8e278dad454b51578d239a42
https://gist.github.com/Gnurou/5052e6ab41e7c55164b75d2970bc5a04

If things are starting to look ok, I would like to move on to the next step and 
implement support in v4l2-ctl. Maybe also start submitting an actual codec 
driver once the control work is completed. And of course, it may be good time 
to think about how pipeline configuration would work. The current design should 
make this question orthogonal to getting support in for simple V4L2 devices.

Looking forward to your feedback!

Changes since RFC v3:
* Buffer queuing is now performed as soon as the request is queued, allowing 
drivers to see them early.
* Request refcounting is done using the file * structure instead of a kref
* Requests can now be used independently of a media controller, to avoid having 
to pull it for simple codec drivers. For such drivers, the device node can 
allocate requests that are exclusive to this device only. Media controller 
nodes can still allocate requests that control their topology as well as the 
devices under them.
* Consequently, media_request is now its own module since it can be used 
independently of media.ko.
* SUBMIT/REINIT request ioctls are now performed on the request FD instead of 
the media device. This means that device/media controller node's business with 
requests is limited to allocating them.
* Got rid of request IDs.
* Only allow one buffer to be queued to each queue of request entities.
* The request FD that produced a CAPTURE buffer is not returned to user-space 
anymore.
* Added requests support for the Vivid video capture device.
* Let drivers decide individually whether their entities should be per file 
handle or global to the device, solving the question we had about this in 
previous RFCs. Vim2m provides an example of per-context entities, while vivid 
gives 

[RFCv4 03/21] v4l2-ctrls: prepare internal structs for request API

2018-02-19 Thread Alexandre Courbot
From: Hans Verkuil 

Add a refcount and is_request bool to struct v4l2_ctrl_handler:
this is used to refcount a handler that represents a request.

Add a p_req field to struct v4l2_ctrl_ref that will store the
request value.

Signed-off-by: Hans Verkuil 
Signed-off-by: Alexandre Courbot 
---
 drivers/media/v4l2-core/v4l2-ctrls.c | 1 +
 include/media/v4l2-ctrls.h   | 4 
 2 files changed, 5 insertions(+)

diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c 
b/drivers/media/v4l2-core/v4l2-ctrls.c
index 5c705f5dde9b..eac70598635d 100644
--- a/drivers/media/v4l2-core/v4l2-ctrls.c
+++ b/drivers/media/v4l2-core/v4l2-ctrls.c
@@ -1761,6 +1761,7 @@ int v4l2_ctrl_handler_init_class(struct v4l2_ctrl_handler 
*hdl,
  sizeof(hdl->buckets[0]),
  GFP_KERNEL | __GFP_ZERO);
hdl->error = hdl->buckets ? 0 : -ENOMEM;
+   hdl->is_request = false;
return hdl->error;
 }
 EXPORT_SYMBOL(v4l2_ctrl_handler_init_class);
diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h
index 96f5c63c12d0..bcabbf8a44b5 100644
--- a/include/media/v4l2-ctrls.h
+++ b/include/media/v4l2-ctrls.h
@@ -18,6 +18,7 @@
 #define _V4L2_CTRLS_H
 
 #include 
+#include 
 #include 
 #include 
 
@@ -257,6 +258,7 @@ struct v4l2_ctrl_ref {
struct v4l2_ctrl_ref *next;
struct v4l2_ctrl *ctrl;
struct v4l2_ctrl_helper *helper;
+   union v4l2_ctrl_ptr p_req;
bool from_other_dev;
 };
 
@@ -292,7 +294,9 @@ struct v4l2_ctrl_handler {
v4l2_ctrl_notify_fnc notify;
void *notify_priv;
u16 nr_of_buckets;
+   bool is_request;
int error;
+   struct kref ref;
 };
 
 /**
-- 
2.16.1.291.g4437f3f132-goog



[RFCv4 04/21] v4l2-ctrls: add core request API

2018-02-19 Thread Alexandre Courbot
From: Hans Verkuil 

Add the four core request functions:

v4l2_ctrl_request_init() initializes a new (empty) request.
v4l2_ctrl_request_clone() resets a request based on another request
(or clears it if that request is NULL).
v4l2_ctrl_request_get(): increase refcount
v4l2_ctrl_request_put(): decrease refcount and delete if it reaches 0.

Signed-off-by: Hans Verkuil 
[acour...@chromium.org: turn v4l2_ctrl_request_alloc into init function]
Signed-off-by: Alexandre Courbot 
---
 drivers/media/v4l2-core/v4l2-ctrls.c | 106 ++-
 include/media/v4l2-ctrls.h   |   7 ++
 2 files changed, 110 insertions(+), 3 deletions(-)

diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c 
b/drivers/media/v4l2-core/v4l2-ctrls.c
index eac70598635d..784879816c24 100644
--- a/drivers/media/v4l2-core/v4l2-ctrls.c
+++ b/drivers/media/v4l2-core/v4l2-ctrls.c
@@ -1878,6 +1878,7 @@ EXPORT_SYMBOL(v4l2_ctrl_find);
 /* Allocate a new v4l2_ctrl_ref and hook it into the handler. */
 static int handler_new_ref(struct v4l2_ctrl_handler *hdl,
   struct v4l2_ctrl *ctrl,
+  struct v4l2_ctrl_ref **ctrl_ref,
   bool from_other_dev)
 {
struct v4l2_ctrl_ref *ref;
@@ -1885,6 +1886,10 @@ static int handler_new_ref(struct v4l2_ctrl_handler *hdl,
u32 id = ctrl->id;
u32 class_ctrl = V4L2_CTRL_ID2WHICH(id) | 1;
int bucket = id % hdl->nr_of_buckets;   /* which bucket to use */
+   unsigned int sz_extra = 0;
+
+   if (ctrl_ref)
+   *ctrl_ref = NULL;
 
/*
 * Automatically add the control class if it is not yet present and
@@ -1898,11 +1903,16 @@ static int handler_new_ref(struct v4l2_ctrl_handler 
*hdl,
if (hdl->error)
return hdl->error;
 
-   new_ref = kzalloc(sizeof(*new_ref), GFP_KERNEL);
+   if (hdl->is_request)
+   sz_extra = ctrl->elems * ctrl->elem_size;
+   new_ref = kzalloc(sizeof(*new_ref) + sz_extra, GFP_KERNEL);
if (!new_ref)
return handler_set_err(hdl, -ENOMEM);
new_ref->ctrl = ctrl;
new_ref->from_other_dev = from_other_dev;
+   if (sz_extra)
+   new_ref->p_req.p = _ref[1];
+
if (ctrl->handler == hdl) {
/* By default each control starts in a cluster of its own.
   new_ref->ctrl is basically a cluster array with one
@@ -1942,6 +1952,8 @@ static int handler_new_ref(struct v4l2_ctrl_handler *hdl,
/* Insert the control node in the hash */
new_ref->next = hdl->buckets[bucket];
hdl->buckets[bucket] = new_ref;
+   if (ctrl_ref)
+   *ctrl_ref = new_ref;
 
 unlock:
mutex_unlock(hdl->lock);
@@ -2083,7 +2095,7 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct 
v4l2_ctrl_handler *hdl,
ctrl->type_ops->init(ctrl, idx, ctrl->p_new);
}
 
-   if (handler_new_ref(hdl, ctrl, false)) {
+   if (handler_new_ref(hdl, ctrl, NULL, false)) {
kvfree(ctrl);
return NULL;
}
@@ -2276,7 +2288,7 @@ int v4l2_ctrl_add_handler(struct v4l2_ctrl_handler *hdl,
/* Filter any unwanted controls */
if (filter && !filter(ctrl))
continue;
-   ret = handler_new_ref(hdl, ctrl, from_other_dev);
+   ret = handler_new_ref(hdl, ctrl, NULL, from_other_dev);
if (ret)
break;
}
@@ -2685,6 +2697,94 @@ int v4l2_querymenu(struct v4l2_ctrl_handler *hdl, struct 
v4l2_querymenu *qm)
 }
 EXPORT_SYMBOL(v4l2_querymenu);
 
+int v4l2_ctrl_request_init(struct v4l2_ctrl_handler *hdl)
+{
+   int err;
+
+   err = v4l2_ctrl_handler_init(hdl, 0);
+   if (err)
+   return err;
+   hdl->is_request = true;
+   kref_init(>ref);
+
+   return 0;
+}
+EXPORT_SYMBOL(v4l2_ctrl_request_init);
+
+int v4l2_ctrl_request_clone(struct v4l2_ctrl_handler *hdl,
+   const struct v4l2_ctrl_handler *from,
+   bool (*filter)(const struct v4l2_ctrl *ctrl))
+{
+   struct v4l2_ctrl_ref *ref;
+   int err;
+
+   if (WARN_ON(!hdl || hdl == from))
+   return -EINVAL;
+
+   if (hdl->error)
+   return hdl->error;
+
+   WARN_ON(hdl->lock != >_lock);
+   v4l2_ctrl_handler_free(hdl);
+   err = v4l2_ctrl_handler_init(hdl, (from->nr_of_buckets - 1) * 8);
+   hdl->is_request = true;
+   if (err)
+   return err;
+   if (!from)
+   return 0;
+
+   mutex_lock(from->lock);
+   list_for_each_entry(ref, >ctrl_refs, node) {
+   struct v4l2_ctrl *ctrl = ref->ctrl;
+   struct v4l2_ctrl_ref *new_ref;
+
+   /* Skip refs inherited from other devices */
+   if (ref->from_other_dev)
+   continue;
+  

[RFCv4 06/21] v4l2-ctrls: support g/s_ext_ctrls for requests

2018-02-19 Thread Alexandre Courbot
From: Hans Verkuil 

The v4l2_g/s_ext_ctrls functions now support control handlers that
represent requests.

Signed-off-by: Hans Verkuil 
Signed-off-by: Alexandre Courbot 
---
 drivers/media/v4l2-core/v4l2-ctrls.c | 37 +---
 1 file changed, 33 insertions(+), 4 deletions(-)

diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c 
b/drivers/media/v4l2-core/v4l2-ctrls.c
index b3be022b219f..00c4488ca1da 100644
--- a/drivers/media/v4l2-core/v4l2-ctrls.c
+++ b/drivers/media/v4l2-core/v4l2-ctrls.c
@@ -1528,6 +1528,13 @@ static int new_to_user(struct v4l2_ext_control *c,
return ptr_to_user(c, ctrl, ctrl->p_new);
 }
 
+/* Helper function: copy the request value back to the caller */
+static int req_to_user(struct v4l2_ext_control *c,
+  struct v4l2_ctrl_ref *ref)
+{
+   return ptr_to_user(c, ref->ctrl, ref->p_req);
+}
+
 /* Helper function: copy the initial control value back to the caller */
 static int def_to_user(struct v4l2_ext_control *c, struct v4l2_ctrl *ctrl)
 {
@@ -1647,6 +1654,14 @@ static void cur_to_new(struct v4l2_ctrl *ctrl)
ptr_to_ptr(ctrl, ctrl->p_cur, ctrl->p_new);
 }
 
+/* Copy the new value to the request value */
+static void new_to_req(struct v4l2_ctrl_ref *ref)
+{
+   if (!ref)
+   return;
+   ptr_to_ptr(ref->ctrl, ref->ctrl->p_new, ref->p_req);
+}
+
 /* Return non-zero if one or more of the controls in the cluster has a new
value that differs from the current value. */
 static int cluster_changed(struct v4l2_ctrl *master)
@@ -2971,7 +2986,8 @@ int v4l2_g_ext_ctrls(struct v4l2_ctrl_handler *hdl, 
struct v4l2_ext_controls *cs
struct v4l2_ctrl *ctrl);
struct v4l2_ctrl *master;
 
-   ctrl_to_user = def_value ? def_to_user : cur_to_user;
+   ctrl_to_user = def_value ? def_to_user :
+  (hdl->is_request ? NULL : cur_to_user);
 
if (helpers[i].mref == NULL)
continue;
@@ -2997,8 +3013,12 @@ int v4l2_g_ext_ctrls(struct v4l2_ctrl_handler *hdl, 
struct v4l2_ext_controls *cs
u32 idx = i;
 
do {
-   ret = ctrl_to_user(cs->controls + idx,
-  helpers[idx].ref->ctrl);
+   if (ctrl_to_user)
+   ret = ctrl_to_user(cs->controls + idx,
+   helpers[idx].ref->ctrl);
+   else
+   ret = req_to_user(cs->controls + idx,
+   helpers[idx].ref);
idx = helpers[idx].next;
} while (!ret && idx);
}
@@ -3271,7 +3291,16 @@ static int try_set_ext_ctrls(struct v4l2_fh *fh, struct 
v4l2_ctrl_handler *hdl,
} while (!ret && idx);
 
if (!ret)
-   ret = try_or_set_cluster(fh, master, set, 0);
+   ret = try_or_set_cluster(fh, master,
+!hdl->is_request && set, 0);
+   if (!ret && hdl->is_request && set) {
+   for (j = 0; j < master->ncontrols; j++) {
+   struct v4l2_ctrl_ref *ref =
+   find_ref(hdl, master->cluster[j]->id);
+
+   new_to_req(ref);
+   }
+   }
 
/* Copy the new values back to userspace. */
if (!ret) {
-- 
2.16.1.291.g4437f3f132-goog



[RFCv4 07/21] v4l2-ctrls: add v4l2_ctrl_request_setup

2018-02-19 Thread Alexandre Courbot
From: Hans Verkuil 

Add a helper function that can set controls from a request.

Signed-off-by: Hans Verkuil 
Signed-off-by: Alexandre Courbot 
---
 drivers/media/v4l2-core/v4l2-ctrls.c | 71 
 include/media/v4l2-ctrls.h   |  2 +
 2 files changed, 73 insertions(+)

diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c 
b/drivers/media/v4l2-core/v4l2-ctrls.c
index 00c4488ca1da..166647817efb 100644
--- a/drivers/media/v4l2-core/v4l2-ctrls.c
+++ b/drivers/media/v4l2-core/v4l2-ctrls.c
@@ -1662,6 +1662,14 @@ static void new_to_req(struct v4l2_ctrl_ref *ref)
ptr_to_ptr(ref->ctrl, ref->ctrl->p_new, ref->p_req);
 }
 
+/* Copy the request value to the new value */
+static void req_to_new(struct v4l2_ctrl_ref *ref)
+{
+   if (!ref)
+   return;
+   ptr_to_ptr(ref->ctrl, ref->p_req, ref->ctrl->p_new);
+}
+
 /* Return non-zero if one or more of the controls in the cluster has a new
value that differs from the current value. */
 static int cluster_changed(struct v4l2_ctrl *master)
@@ -3427,6 +3435,69 @@ int __v4l2_ctrl_s_ctrl_string(struct v4l2_ctrl *ctrl, 
const char *s)
 }
 EXPORT_SYMBOL(__v4l2_ctrl_s_ctrl_string);
 
+void v4l2_ctrl_request_setup(struct v4l2_ctrl_handler *hdl)
+{
+   struct v4l2_ctrl_ref *ref;
+
+   if (!hdl)
+   return;
+
+   mutex_lock(hdl->lock);
+
+   list_for_each_entry(ref, >ctrl_refs, node)
+   ref->done = false;
+
+   list_for_each_entry(ref, >ctrl_refs, node) {
+   struct v4l2_ctrl *ctrl = ref->ctrl;
+   struct v4l2_ctrl *master = ctrl->cluster[0];
+   int i;
+
+   /* Skip if this control was already handled by a cluster. */
+   /* Skip button controls and read-only controls. */
+   if (ref->done || ctrl->type == V4L2_CTRL_TYPE_BUTTON ||
+   (ctrl->flags & V4L2_CTRL_FLAG_READ_ONLY))
+   continue;
+
+   v4l2_ctrl_lock(master);
+   for (i = 0; i < master->ncontrols; i++) {
+   if (master->cluster[i]) {
+   struct v4l2_ctrl_ref *r =
+   find_ref(hdl, master->cluster[i]->id);
+
+   req_to_new(r);
+   master->cluster[i]->is_new = 1;
+   r->done = true;
+   }
+   }
+   /*
+* For volatile autoclusters that are currently in auto mode
+* we need to discover if it will be set to manual mode.
+* If so, then we have to copy the current volatile values
+* first since those will become the new manual values (which
+* may be overwritten by explicit new values from this set
+* of controls).
+*/
+   if (master->is_auto && master->has_volatiles &&
+   !is_cur_manual(master)) {
+   s32 new_auto_val = *master->p_new.p_s32;
+
+   /*
+* If the new value == the manual value, then copy
+* the current volatile values.
+*/
+   if (new_auto_val == master->manual_mode_value)
+   update_from_auto_cluster(master);
+   }
+
+   try_or_set_cluster(NULL, master, true, 0);
+
+   v4l2_ctrl_unlock(master);
+   }
+
+   mutex_unlock(hdl->lock);
+}
+EXPORT_SYMBOL(v4l2_ctrl_request_setup);
+
 void v4l2_ctrl_notify(struct v4l2_ctrl *ctrl, v4l2_ctrl_notify_fnc notify, 
void *priv)
 {
if (ctrl == NULL)
diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h
index c51e1cacc09d..3a10fb3419e3 100644
--- a/include/media/v4l2-ctrls.h
+++ b/include/media/v4l2-ctrls.h
@@ -259,6 +259,7 @@ struct v4l2_ctrl_ref {
struct v4l2_ctrl *ctrl;
struct v4l2_ctrl_helper *helper;
union v4l2_ctrl_ptr p_req;
+   bool done;
bool from_other_dev;
 };
 
@@ -1056,6 +1057,7 @@ int v4l2_ctrl_request_init(struct v4l2_ctrl_handler *hdl);
 int v4l2_ctrl_request_clone(struct v4l2_ctrl_handler *hdl,
const struct v4l2_ctrl_handler *from,
bool (*filter)(const struct v4l2_ctrl *ctrl));
+void v4l2_ctrl_request_setup(struct v4l2_ctrl_handler *hdl);
 void v4l2_ctrl_request_get(struct v4l2_ctrl_handler *hdl);
 void v4l2_ctrl_request_put(struct v4l2_ctrl_handler *hdl);
 
-- 
2.16.1.291.g4437f3f132-goog



[RFCv4 05/21] v4l2-ctrls: use ref in helper instead of ctrl

2018-02-19 Thread Alexandre Courbot
From: Hans Verkuil 

The next patch needs the reference to a control instead of the
control itself, so change struct v4l2_ctrl_helper accordingly.

Signed-off-by: Hans Verkuil 
Signed-off-by: Alexandre Courbot 
---
 drivers/media/v4l2-core/v4l2-ctrls.c | 18 +-
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c 
b/drivers/media/v4l2-core/v4l2-ctrls.c
index 784879816c24..b3be022b219f 100644
--- a/drivers/media/v4l2-core/v4l2-ctrls.c
+++ b/drivers/media/v4l2-core/v4l2-ctrls.c
@@ -37,8 +37,8 @@
 struct v4l2_ctrl_helper {
/* Pointer to the control reference of the master control */
struct v4l2_ctrl_ref *mref;
-   /* The control corresponding to the v4l2_ext_control ID field. */
-   struct v4l2_ctrl *ctrl;
+   /* The control ref corresponding to the v4l2_ext_control ID field. */
+   struct v4l2_ctrl_ref *ref;
/* v4l2_ext_control index of the next control belonging to the
   same cluster, or 0 if there isn't any. */
u32 next;
@@ -2856,6 +2856,7 @@ static int prepare_ext_ctrls(struct v4l2_ctrl_handler 
*hdl,
ref = find_ref_lock(hdl, id);
if (ref == NULL)
return -EINVAL;
+   h->ref = ref;
ctrl = ref->ctrl;
if (ctrl->flags & V4L2_CTRL_FLAG_DISABLED)
return -EINVAL;
@@ -2878,7 +2879,6 @@ static int prepare_ext_ctrls(struct v4l2_ctrl_handler 
*hdl,
}
/* Store the ref to the master control of the cluster */
h->mref = ref;
-   h->ctrl = ctrl;
/* Initially set next to 0, meaning that there is no other
   control in this helper array belonging to the same
   cluster */
@@ -2963,7 +2963,7 @@ int v4l2_g_ext_ctrls(struct v4l2_ctrl_handler *hdl, 
struct v4l2_ext_controls *cs
cs->error_idx = cs->count;
 
for (i = 0; !ret && i < cs->count; i++)
-   if (helpers[i].ctrl->flags & V4L2_CTRL_FLAG_WRITE_ONLY)
+   if (helpers[i].ref->ctrl->flags & V4L2_CTRL_FLAG_WRITE_ONLY)
ret = -EACCES;
 
for (i = 0; !ret && i < cs->count; i++) {
@@ -2998,7 +2998,7 @@ int v4l2_g_ext_ctrls(struct v4l2_ctrl_handler *hdl, 
struct v4l2_ext_controls *cs
 
do {
ret = ctrl_to_user(cs->controls + idx,
-  helpers[idx].ctrl);
+  helpers[idx].ref->ctrl);
idx = helpers[idx].next;
} while (!ret && idx);
}
@@ -3137,7 +3137,7 @@ static int validate_ctrls(struct v4l2_ext_controls *cs,
 
cs->error_idx = cs->count;
for (i = 0; i < cs->count; i++) {
-   struct v4l2_ctrl *ctrl = helpers[i].ctrl;
+   struct v4l2_ctrl *ctrl = helpers[i].ref->ctrl;
union v4l2_ctrl_ptr p_new;
 
cs->error_idx = i;
@@ -3249,7 +3249,7 @@ static int try_set_ext_ctrls(struct v4l2_fh *fh, struct 
v4l2_ctrl_handler *hdl,
do {
/* Check if the auto control is part of the
   list, and remember the new value. */
-   if (helpers[tmp_idx].ctrl == master)
+   if (helpers[tmp_idx].ref->ctrl == master)
new_auto_val = 
cs->controls[tmp_idx].value;
tmp_idx = helpers[tmp_idx].next;
} while (tmp_idx);
@@ -3262,7 +3262,7 @@ static int try_set_ext_ctrls(struct v4l2_fh *fh, struct 
v4l2_ctrl_handler *hdl,
/* Copy the new caller-supplied control values.
   user_to_new() sets 'is_new' to 1. */
do {
-   struct v4l2_ctrl *ctrl = helpers[idx].ctrl;
+   struct v4l2_ctrl *ctrl = helpers[idx].ref->ctrl;
 
ret = user_to_new(cs->controls + idx, ctrl);
if (!ret && ctrl->is_ptr)
@@ -3278,7 +3278,7 @@ static int try_set_ext_ctrls(struct v4l2_fh *fh, struct 
v4l2_ctrl_handler *hdl,
idx = i;
do {
ret = new_to_user(cs->controls + idx,
-   helpers[idx].ctrl);
+   helpers[idx].ref->ctrl);
idx = helpers[idx].next;
} while (!ret && idx);
}
-- 
2.16.1.291.g4437f3f132-goog



[RFCv4 08/21] [WAR] v4l2-ctrls: do not clone non-standard controls

2018-02-19 Thread Alexandre Courbot
Only standard controls can be successfully cloned: handler_new_ref, used
by v4l2_ctrl_request_clone(), forcibly calls v4l2_ctrl_new_std() which
fails to find custom controls names, and we eventually hit the condition
that name == NULL in v4l2_ctrl_new().

This prevents us from using non-standard controls with requests, but
that is enough for testing purposes.

Signed-off-by: Alexandre Courbot 
---
 drivers/media/v4l2-core/v4l2-ctrls.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c 
b/drivers/media/v4l2-core/v4l2-ctrls.c
index 166647817efb..7a81aa5959c3 100644
--- a/drivers/media/v4l2-core/v4l2-ctrls.c
+++ b/drivers/media/v4l2-core/v4l2-ctrls.c
@@ -2772,6 +2772,11 @@ int v4l2_ctrl_request_clone(struct v4l2_ctrl_handler 
*hdl,
if (filter && !filter(ctrl))
continue;
err = handler_new_ref(hdl, ctrl, _ref, false);
+   if (err) {
+   printk("%s: handler_new_ref on control %x (%s) returned 
%d\n", __func__, ctrl->id, ctrl->name, err);
+   err = 0;
+   continue;
+   }
if (err)
break;
if (from->is_request)
-- 
2.16.1.291.g4437f3f132-goog



[RFCv4 11/21] media: v4l2_fh: add request entity field

2018-02-19 Thread Alexandre Courbot
Allow drivers to assign a request entity to v4l2_fh. This will be useful
for request-aware ioctls to find out which request entity to use.

Signed-off-by: Alexandre Courbot 
---
 include/media/v4l2-fh.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/include/media/v4l2-fh.h b/include/media/v4l2-fh.h
index ea73fef8bdc0..f54cb319dd64 100644
--- a/include/media/v4l2-fh.h
+++ b/include/media/v4l2-fh.h
@@ -28,6 +28,7 @@
 
 struct video_device;
 struct v4l2_ctrl_handler;
+struct media_request_entity;
 
 /**
  * struct v4l2_fh - Describes a V4L2 file handler
@@ -43,6 +44,7 @@ struct v4l2_ctrl_handler;
  * @navailable: number of available events at @available list
  * @sequence: event sequence number
  * @m2m_ctx: pointer to  v4l2_m2m_ctx
+ * @entity: the request entity this fh operates on behalf of
  */
 struct v4l2_fh {
struct list_headlist;
@@ -60,6 +62,7 @@ struct v4l2_fh {
 #if IS_ENABLED(CONFIG_V4L2_MEM2MEM_DEV)
struct v4l2_m2m_ctx *m2m_ctx;
 #endif
+   struct media_request_entity *entity;
 };
 
 /**
-- 
2.16.1.291.g4437f3f132-goog



[RFCv4 09/21] v4l2: add request API support

2018-02-19 Thread Alexandre Courbot
Add a v4l2 request entity data structure that takes care of storing the
request-related state of a V4L2 device ; in this case, its controls.

Signed-off-by: Alexandre Courbot 
---
 drivers/media/v4l2-core/Makefile   |   1 +
 drivers/media/v4l2-core/v4l2-request.c | 178 +
 include/media/v4l2-request.h   | 159 ++
 3 files changed, 338 insertions(+)
 create mode 100644 drivers/media/v4l2-core/v4l2-request.c
 create mode 100644 include/media/v4l2-request.h

diff --git a/drivers/media/v4l2-core/Makefile b/drivers/media/v4l2-core/Makefile
index 80de2cb9c476..13d0477535bd 100644
--- a/drivers/media/v4l2-core/Makefile
+++ b/drivers/media/v4l2-core/Makefile
@@ -16,6 +16,7 @@ ifeq ($(CONFIG_TRACEPOINTS),y)
   videodev-objs += vb2-trace.o v4l2-trace.o
 endif
 videodev-$(CONFIG_MEDIA_CONTROLLER) += v4l2-mc.o
+videodev-$(CONFIG_MEDIA_REQUEST_API) += v4l2-request.o
 
 obj-$(CONFIG_VIDEO_V4L2) += videodev.o
 obj-$(CONFIG_VIDEO_V4L2) += v4l2-common.o
diff --git a/drivers/media/v4l2-core/v4l2-request.c 
b/drivers/media/v4l2-core/v4l2-request.c
new file mode 100644
index ..e8ad10e2f525
--- /dev/null
+++ b/drivers/media/v4l2-core/v4l2-request.c
@@ -0,0 +1,178 @@
+/*
+ * Media requests support for V4L2
+ *
+ * Copyright (C) 2018, The Chromium OS Authors.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include 
+
+#include 
+#include 
+#include 
+
+void v4l2_request_entity_init(struct v4l2_request_entity *entity,
+ const struct media_request_entity_ops *ops,
+ struct video_device *vdev)
+{
+   media_request_entity_init(>base, 
MEDIA_REQUEST_ENTITY_TYPE_V4L2, ops);
+   entity->vdev = vdev;
+}
+EXPORT_SYMBOL_GPL(v4l2_request_entity_init);
+
+struct media_request_entity_data *
+v4l2_request_entity_data_alloc(struct media_request *req,
+  struct v4l2_ctrl_handler *hdl)
+{
+   struct v4l2_request_entity_data *data;
+   int ret;
+
+   data = kzalloc(sizeof(*data), GFP_KERNEL);
+   if (!data)
+   return ERR_PTR(-ENOMEM);
+
+   ret = v4l2_ctrl_request_init(>ctrls);
+   if (ret) {
+   kfree(data);
+   return ERR_PTR(ret);
+   }
+   ret = v4l2_ctrl_request_clone(>ctrls, hdl, NULL);
+   if (ret) {
+   kfree(data);
+   return ERR_PTR(ret);
+   }
+
+   INIT_LIST_HEAD(>queued_buffers);
+
+   return >base;
+}
+EXPORT_SYMBOL_GPL(v4l2_request_entity_data_alloc);
+
+void v4l2_request_entity_data_free(struct media_request_entity_data *_data)
+{
+   struct v4l2_request_entity_data *data;
+   struct v4l2_vb2_request_buffer *qb, *n;
+
+   data = to_v4l2_entity_data(_data);
+
+   list_for_each_entry_safe(qb, n, >queued_buffers, node) {
+   struct vb2_buffer *buf;
+   dev_warn(_data->request->mgr->dev,
+"entity data freed while buffer still queued!\n");
+
+   /* give buffer back to user-space */
+   buf = qb->queue->bufs[qb->v4l2_buf.index];
+   buf->state = qb->pre_req_state;
+   buf->request = NULL;
+
+   kfree(qb);
+   }
+
+   v4l2_ctrl_handler_free(>ctrls);
+   kfree(data);
+}
+EXPORT_SYMBOL_GPL(v4l2_request_entity_data_free);
+
+
+
+
+
+static struct media_request *v4l2_request_alloc(struct media_request_mgr *mgr)
+{
+   struct media_request *req;
+
+   req = kzalloc(sizeof(*req), GFP_KERNEL);
+   if (!req)
+   return ERR_PTR(-ENOMEM);
+
+   req->mgr = mgr;
+   req->state = MEDIA_REQUEST_STATE_IDLE;
+   INIT_LIST_HEAD(>data);
+   init_waitqueue_head(>complete_wait);
+   mutex_init(>lock);
+
+   mutex_lock(>mutex);
+   list_add_tail(>list, >requests);
+   mutex_unlock(>mutex);
+
+   return req;
+}
+
+static void v4l2_request_free(struct media_request *req)
+{
+   struct media_request_mgr *mgr = req->mgr;
+   struct media_request_entity_data *data, *next;
+
+   mutex_lock(>mutex);
+   list_del(>list);
+   mutex_unlock(>mutex);
+
+   list_for_each_entry_safe(data, next, >data, list) {
+   list_del(>list);
+   data->entity->ops->data_free(data);
+   }
+
+   kfree(req);
+}
+
+static bool v4l2_entity_valid(const struct media_request *req,
+ const struct media_request_entity *_entity)
+{
+   const struct v4l2_request_mgr *mgr;
+   const struct 

[RFCv4 10/21] videodev2.h: Add request_fd field to v4l2_buffer

2018-02-19 Thread Alexandre Courbot
From: Hans Verkuil 

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

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

diff --git a/drivers/media/common/videobuf2/videobuf2-v4l2.c 
b/drivers/media/common/videobuf2/videobuf2-v4l2.c
index 886a2d8d5c6c..6d4d184aa68e 100644
--- a/drivers/media/common/videobuf2/videobuf2-v4l2.c
+++ b/drivers/media/common/videobuf2/videobuf2-v4l2.c
@@ -203,7 +203,7 @@ static void __fill_v4l2_buffer(struct vb2_buffer *vb, void 
*pb)
b->timestamp = ns_to_timeval(vb->timestamp);
b->timecode = vbuf->timecode;
b->sequence = vbuf->sequence;
-   b->reserved2 = 0;
+   b->request_fd = 0;
b->reserved = 0;
 
if (q->is_multiplanar) {
diff --git a/drivers/media/usb/cpia2/cpia2_v4l.c 
b/drivers/media/usb/cpia2/cpia2_v4l.c
index 99f106b13280..af42ce3ceb48 100644
--- a/drivers/media/usb/cpia2/cpia2_v4l.c
+++ b/drivers/media/usb/cpia2/cpia2_v4l.c
@@ -948,7 +948,7 @@ static int cpia2_dqbuf(struct file *file, void *fh, struct 
v4l2_buffer *buf)
buf->sequence = cam->buffers[buf->index].seq;
buf->m.offset = cam->buffers[buf->index].data - cam->frame_buffer;
buf->length = cam->frame_size;
-   buf->reserved2 = 0;
+   buf->request_fd = 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 5198c9eeb348..32bf47489a2e 100644
--- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
+++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
@@ -386,7 +386,7 @@ struct v4l2_buffer32 {
__s32   fd;
} m;
__u32   length;
-   __u32   reserved2;
+   __s32   request_fd;
__u32   reserved;
 };
 
@@ -486,6 +486,7 @@ static int get_v4l2_buffer32(struct v4l2_buffer __user *kp,
 {
u32 type;
u32 length;
+   s32 request_fd;
enum v4l2_memory memory;
struct v4l2_plane32 __user *uplane32;
struct v4l2_plane __user *uplane;
@@ -500,7 +501,9 @@ static int get_v4l2_buffer32(struct v4l2_buffer __user *kp,
get_user(memory, >memory) ||
put_user(memory, >memory) ||
get_user(length, >length) ||
-   put_user(length, >length))
+   put_user(length, >length) ||
+   get_user(request_fd, >request_fd) ||
+   put_user(request_fd, >request_fd))
return -EFAULT;
 
if (V4L2_TYPE_IS_OUTPUT(type))
@@ -604,7 +607,7 @@ static int put_v4l2_buffer32(struct v4l2_buffer __user *kp,
assign_in_user(>timestamp.tv_usec, >timestamp.tv_usec) ||
copy_in_user(>timecode, >timecode, sizeof(kp->timecode)) ||
assign_in_user(>sequence, >sequence) ||
-   assign_in_user(>reserved2, >reserved2) ||
+   assign_in_user(>request_fd, >request_fd) ||
assign_in_user(>reserved, >reserved) ||
get_user(length, >length) ||
put_user(length, >length))
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c 
b/drivers/media/v4l2-core/v4l2-ioctl.c
index 260288ca4f55..7bfeaf233d5a 100644
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
@@ -437,13 +437,13 @@ static void v4l_print_buffer(const void *arg, bool 
write_only)
const struct v4l2_plane *plane;
int i;
 
-   pr_cont("%02ld:%02d:%02d.%08ld index=%d, type=%s, flags=0x%08x, 
field=%s, sequence=%d, memory=%s",
+   pr_cont("%02ld:%02d:%02d.%08ld index=%d, type=%s, request_fd=%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_fd,
p->flags, prt_names(p->field, v4l2_field_names),
p->sequence, prt_names(p->memory, v4l2_memory_names));
 
diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
index 982718965180..4fd46ae8fad5 100644
--- a/include/uapi/linux/videodev2.h
+++ b/include/uapi/linux/videodev2.h
@@ -909,6 +909,7 @@ struct v4l2_plane {
  * @length:size in 

[RFCv4 12/21] media: videobuf2: add support for requests

2018-02-19 Thread Alexandre Courbot
Make vb2 core aware of requests. Drivers can specify whether a given
queue accepts requests or not.

Signed-off-by: Alexandre Courbot 
---
 drivers/media/common/videobuf2/videobuf2-core.c | 3 +++
 include/media/videobuf2-core.h  | 4 
 2 files changed, 7 insertions(+)

diff --git a/drivers/media/common/videobuf2/videobuf2-core.c 
b/drivers/media/common/videobuf2/videobuf2-core.c
index debe35fc66b4..355fe7dc99d7 100644
--- a/drivers/media/common/videobuf2/videobuf2-core.c
+++ b/drivers/media/common/videobuf2/videobuf2-core.c
@@ -930,6 +930,9 @@ void vb2_buffer_done(struct vb2_buffer *vb, enum 
vb2_buffer_state state)
vb->state = state;
}
atomic_dec(>owned_by_drv_count);
+
+   vb->request = NULL;
+
spin_unlock_irqrestore(>done_lock, flags);
 
trace_vb2_buf_done(q, vb);
diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h
index 5b6c541e4e1b..6e9e814886e7 100644
--- a/include/media/videobuf2-core.h
+++ b/include/media/videobuf2-core.h
@@ -238,6 +238,7 @@ struct vb2_queue;
  * @num_planes:number of planes in the buffer
  * on an internal driver queue.
  * @timestamp: frame timestamp in ns.
+ * @request:   request the buffer belongs to, if any.
  */
 struct vb2_buffer {
struct vb2_queue*vb2_queue;
@@ -246,6 +247,7 @@ struct vb2_buffer {
unsigned intmemory;
unsigned intnum_planes;
u64 timestamp;
+   struct media_request*request;
 
/* private: internal use only
 *
@@ -446,6 +448,7 @@ struct vb2_buf_ops {
  * @quirk_poll_must_check_waiting_for_buffers: Return %EPOLLERR at poll when 
QBUF
  *  has not been called. This is a vb1 idiom that has been adopted
  *  also by vb2.
+ * @allow_requests:whether requests are supported on this queue.
  * @lock:  pointer to a mutex that protects the  vb2_queue. The
  * driver can set this to a mutex to let the v4l2 core serialize
  * the queuing ioctls. If the driver wants to handle locking
@@ -513,6 +516,7 @@ struct vb2_queue {
unsignedfileio_write_immediately:1;
unsignedallow_zero_bytesused:1;
unsigned   quirk_poll_must_check_waiting_for_buffers:1;
+   unsignedallow_requests:1;
 
struct mutex*lock;
void*owner;
-- 
2.16.1.291.g4437f3f132-goog



[RFCv4 17/21] media: mem2mem: support for requests

2018-02-19 Thread Alexandre Courbot
Add generic support for requests to the mem2mem framework. This just
requires calling vb2_qbuf_request() instead of vb2_qbuf() in
v4l2_m2m_qbuf().

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

diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c 
b/drivers/media/v4l2-core/v4l2-mem2mem.c
index c4f963d96a79..d9ae428651c4 100644
--- a/drivers/media/v4l2-core/v4l2-mem2mem.c
+++ b/drivers/media/v4l2-core/v4l2-mem2mem.c
@@ -388,11 +388,12 @@ EXPORT_SYMBOL_GPL(v4l2_m2m_querybuf);
 int v4l2_m2m_qbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
  struct v4l2_buffer *buf)
 {
+   struct v4l2_fh *fh = file->private_data;
struct vb2_queue *vq;
int ret;
 
vq = v4l2_m2m_get_vq(m2m_ctx, buf->type);
-   ret = vb2_qbuf(vq, buf);
+   ret = vb2_qbuf_request(vq, buf, fh->entity);
if (!ret)
v4l2_m2m_try_schedule(m2m_ctx);
 
-- 
2.16.1.291.g4437f3f132-goog



[RFCv4 13/21] media: videobuf2-v4l2: support for requests

2018-02-19 Thread Alexandre Courbot
Add a new vb2_qbuf_request() (a request-aware version of vb2_qbuf())
that request-aware drivers can call to queue a buffer into a request
instead of directly into the vb2 queue if relevent.

This function expects that drivers invoking it are using instances of
v4l2_request_entity and v4l2_request_entity_data to describe their
entity and entity data respectively.

Also add the vb2_request_submit() helper function which drivers can
invoke in order to queue all the buffers previously queued into a
request into the regular vb2 queue.

Signed-off-by: Alexandre Courbot 
---
 .../media/common/videobuf2/videobuf2-v4l2.c   | 129 +-
 include/media/videobuf2-v4l2.h|  59 
 2 files changed, 187 insertions(+), 1 deletion(-)

diff --git a/drivers/media/common/videobuf2/videobuf2-v4l2.c 
b/drivers/media/common/videobuf2/videobuf2-v4l2.c
index 6d4d184aa68e..0627c3339572 100644
--- a/drivers/media/common/videobuf2/videobuf2-v4l2.c
+++ b/drivers/media/common/videobuf2/videobuf2-v4l2.c
@@ -28,8 +28,11 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 
 #include 
+#include 
 
 static int debug;
 module_param(debug, int, 0644);
@@ -569,11 +572,131 @@ int vb2_qbuf(struct vb2_queue *q, struct v4l2_buffer *b)
return -EBUSY;
}
 
+   /* drivers supporting requests must call vb2_qbuf_request instead */
+   if (b->request_fd > 0) {
+   dprintk(1, "invalid call to vb2_qbuf with request_fd set\n");
+   return -EINVAL;
+   }
+
ret = vb2_queue_or_prepare_buf(q, b, "qbuf");
return ret ? ret : vb2_core_qbuf(q, b->index, b);
 }
 EXPORT_SYMBOL_GPL(vb2_qbuf);
 
+#if IS_ENABLED(CONFIG_MEDIA_REQUEST_API)
+int vb2_qbuf_request(struct vb2_queue *q, struct v4l2_buffer *b,
+struct media_request_entity *entity)
+{
+   struct v4l2_request_entity_data *data;
+   struct v4l2_vb2_request_buffer *qb;
+   struct media_request *req;
+   struct vb2_buffer *vb;
+   int ret = 0;
+
+   if (b->request_fd <= 0)
+   return vb2_qbuf(q, b);
+
+   if (!q->allow_requests)
+   return -EINVAL;
+
+   req = media_request_get_from_fd(b->request_fd);
+   if (!req)
+   return -EINVAL;
+
+   data = to_v4l2_entity_data(media_request_get_entity_data(req, entity));
+   if (IS_ERR(data)) {
+   ret = PTR_ERR(data);
+   goto out;
+   }
+
+   mutex_lock(>lock);
+
+   if (req->state != MEDIA_REQUEST_STATE_IDLE) {
+   ret = -EINVAL;
+   goto out;
+   }
+
+   ret = vb2_queue_or_prepare_buf(q, b, "qbuf");
+   if (ret)
+   goto out;
+
+   vb = q->bufs[b->index];
+   switch (vb->state) {
+   case VB2_BUF_STATE_DEQUEUED:
+   break;
+   case VB2_BUF_STATE_PREPARED:
+   break;
+   case VB2_BUF_STATE_PREPARING:
+   dprintk(1, "buffer still being prepared\n");
+   ret = -EINVAL;
+   goto out;
+   default:
+   dprintk(1, "invalid buffer state %d\n", vb->state);
+   ret = -EINVAL;
+   goto out;
+   }
+
+   /* do we already have a buffer for this request in the queue? */
+   list_for_each_entry(qb, >queued_buffers, node) {
+   if (qb->queue == q) {
+   ret = -EBUSY;
+   goto out;
+   }
+   }
+
+   qb = kzalloc(sizeof(*qb), GFP_KERNEL);
+   if (!qb) {
+   ret = -ENOMEM;
+   goto out;
+   }
+
+   /*
+* TODO should be prepare the buffer here if needed, to report errors
+* early?
+*/
+   qb->pre_req_state = vb->state;
+   qb->queue = q;
+   memcpy(>v4l2_buf, b, sizeof(*b));
+   vb->request = req;
+   vb->state = VB2_BUF_STATE_QUEUED;
+   list_add_tail(>node, >queued_buffers);
+
+out:
+   mutex_unlock(>lock);
+   media_request_put(req);
+
+   return ret;
+}
+EXPORT_SYMBOL_GPL(vb2_qbuf_request);
+
+int vb2_request_submit(struct v4l2_request_entity_data *data)
+{
+   struct v4l2_vb2_request_buffer *qb, *n;
+
+   /* v4l2 requests require at least one buffer to reach the device */
+   if (list_empty(>queued_buffers)) {
+   return -EINVAL;
+   }
+
+   list_for_each_entry_safe(qb, n, >queued_buffers, node) {
+   struct vb2_queue *q = qb->queue;
+   struct vb2_buffer *vb = q->bufs[qb->v4l2_buf.index];
+   int ret;
+
+   list_del(>node);
+   vb->state = qb->pre_req_state;
+   ret = vb2_core_qbuf(q, vb->index, >v4l2_buf);
+   kfree(qb);
+   if (ret)
+   return ret;
+   }
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(vb2_request_submit);
+
+#endif /* CONFIG_MEDIA_REQUEST_API */
+
 int vb2_dqbuf(struct vb2_queue *q, struct v4l2_buffer *b, bool 

[RFCv4 14/21] videodev2.h: add request_fd field to v4l2_ext_controls

2018-02-19 Thread Alexandre Courbot
Allow to specify a request to be used with the S_EXT_CTRLS and
G_EXT_CTRLS operations.

Signed-off-by: Alexandre Courbot 
---
 drivers/media/v4l2-core/v4l2-ioctl.c | 2 +-
 include/uapi/linux/videodev2.h   | 3 ++-
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c 
b/drivers/media/v4l2-core/v4l2-ioctl.c
index 7bfeaf233d5a..2f40ac0cdf6e 100644
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
@@ -870,7 +870,7 @@ static int check_ext_ctrls(struct v4l2_ext_controls *c, int 
allow_priv)
__u32 i;
 
/* zero the reserved fields */
-   c->reserved[0] = c->reserved[1] = 0;
+   c->reserved[0] = 0;
for (i = 0; i < c->count; i++)
c->controls[i].reserved2[0] = 0;
 
diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
index 4fd46ae8fad5..91cfe0cbd5c5 100644
--- a/include/uapi/linux/videodev2.h
+++ b/include/uapi/linux/videodev2.h
@@ -1592,7 +1592,8 @@ struct v4l2_ext_controls {
};
__u32 count;
__u32 error_idx;
-   __u32 reserved[2];
+   __s32 request_fd;
+   __u32 reserved[1];
struct v4l2_ext_control *controls;
 };
 
-- 
2.16.1.291.g4437f3f132-goog



[RFCv4 15/21] v4l2-ctrls: support requests in EXT_CTRLS ioctls

2018-02-19 Thread Alexandre Courbot
Read and use the request_fd field of struct v4l2_ext_controls to apply
VIDIOC_G_EXT_CTRLS or VIDIOC_S_EXT_CTRLS to a request when asked by
userspace.

Signed-off-by: Alexandre Courbot 
---
 drivers/media/platform/omap3isp/ispvideo.c |  2 +-
 drivers/media/v4l2-core/v4l2-ctrls.c   | 98 +-
 drivers/media/v4l2-core/v4l2-ioctl.c   |  6 +-
 drivers/media/v4l2-core/v4l2-subdev.c  |  2 +-
 include/media/v4l2-ctrls.h |  3 +-
 5 files changed, 102 insertions(+), 9 deletions(-)

diff --git a/drivers/media/platform/omap3isp/ispvideo.c 
b/drivers/media/platform/omap3isp/ispvideo.c
index a751c89a3ea8..3976cd9ac2f2 100644
--- a/drivers/media/platform/omap3isp/ispvideo.c
+++ b/drivers/media/platform/omap3isp/ispvideo.c
@@ -1028,7 +1028,7 @@ static int isp_video_check_external_subdevs(struct 
isp_video *video,
ctrls.count = 1;
ctrls.controls = 
 
-   ret = v4l2_g_ext_ctrls(pipe->external->ctrl_handler, );
+   ret = v4l2_g_ext_ctrls(NULL, pipe->external->ctrl_handler, );
if (ret < 0) {
dev_warn(isp->dev, "no pixel rate control in subdev %s\n",
 pipe->external->name);
diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c 
b/drivers/media/v4l2-core/v4l2-ctrls.c
index 7a81aa5959c3..d7b1aeb32470 100644
--- a/drivers/media/v4l2-core/v4l2-ctrls.c
+++ b/drivers/media/v4l2-core/v4l2-ctrls.c
@@ -27,6 +27,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #define has_op(master, op) \
(master->ops && master->ops->op)
@@ -2959,9 +2960,44 @@ static int class_check(struct v4l2_ctrl_handler *hdl, 
u32 which)
 }
 
 
+#if IS_ENABLED(CONFIG_MEDIA_REQUEST_API)
+static struct media_request *
+get_handler_for_request(struct v4l2_fh *fh, struct v4l2_ext_controls *cs,
+   struct v4l2_ctrl_handler **hdl)
+{
+   struct media_request *req;
+   struct v4l2_request_entity_data *data;
+
+   if (!fh || !fh->entity)
+   return ERR_PTR(-EINVAL);
+
+   req = media_request_get_from_fd(cs->request_fd);
+   if (!req)
+   return ERR_PTR(-EINVAL);
+
+   data = to_v4l2_entity_data(media_request_get_entity_data(req,
+fh->entity));
+   if (IS_ERR(data)) {
+   media_request_put(req);
+   return (void *)data;
+   }
+
+   *hdl = >ctrls;
+
+   return req;
+}
+#else
+static struct media_request *
+get_handler_for_request(struct v4l2_fh *fh, struct v4l2_ext_controls *cs,
+   struct v4l2_ctrl_handler **hdl)
+{
+   return ERR_PTR(-ENOTSUPP);
+}
+#endif
 
 /* Get extended controls. Allocates the helpers array if needed. */
-int v4l2_g_ext_ctrls(struct v4l2_ctrl_handler *hdl, struct v4l2_ext_controls 
*cs)
+int __v4l2_g_ext_ctrls(struct v4l2_ctrl_handler *hdl,
+  struct v4l2_ext_controls *cs)
 {
struct v4l2_ctrl_helper helper[4];
struct v4l2_ctrl_helper *helpers = helper;
@@ -3042,6 +3078,30 @@ int v4l2_g_ext_ctrls(struct v4l2_ctrl_handler *hdl, 
struct v4l2_ext_controls *cs
kvfree(helpers);
return ret;
 }
+
+int v4l2_g_ext_ctrls(struct v4l2_fh *fh, struct v4l2_ctrl_handler *hdl,
+struct v4l2_ext_controls *cs)
+{
+   struct media_request *req = NULL;
+   int ret;
+
+   if (cs->request_fd > 0) {
+   req = get_handler_for_request(fh, cs, );
+   if (IS_ERR(req))
+   return PTR_ERR(req);
+
+media_request_lock(req);
+   }
+
+   ret = __v4l2_g_ext_ctrls(hdl, cs);
+
+   if (req) {
+   media_request_unlock(req);
+   media_request_put(req);
+   }
+
+   return ret;
+}
 EXPORT_SYMBOL(v4l2_g_ext_ctrls);
 
 /* Helper function to get a single control */
@@ -3217,9 +3277,9 @@ static void update_from_auto_cluster(struct v4l2_ctrl 
*master)
 }
 
 /* Try or try-and-set controls */
-static int try_set_ext_ctrls(struct v4l2_fh *fh, struct v4l2_ctrl_handler *hdl,
-struct v4l2_ext_controls *cs,
-bool set)
+static int __try_set_ext_ctrls(struct v4l2_fh *fh,
+  struct v4l2_ctrl_handler *hdl,
+  struct v4l2_ext_controls *cs, bool set)
 {
struct v4l2_ctrl_helper helper[4];
struct v4l2_ctrl_helper *helpers = helper;
@@ -3332,6 +3392,36 @@ static int try_set_ext_ctrls(struct v4l2_fh *fh, struct 
v4l2_ctrl_handler *hdl,
return ret;
 }
 
+static int try_set_ext_ctrls(struct v4l2_fh *fh, struct v4l2_ctrl_handler *hdl,
+struct v4l2_ext_controls *cs, bool set)
+{
+   struct media_request *req = NULL;
+   int ret;
+
+   if (cs->request_fd > 0) {
+   req = get_handler_for_request(fh, cs, );
+   if (IS_ERR(req))
+   return PTR_ERR(req);
+
+   

[RFCv4 16/21] v4l2: video_device: support for creating requests

2018-02-19 Thread Alexandre Courbot
Add a new VIDIOC_NEW_REQUEST ioctl, which allows to instanciate requests
on devices that support the request API. Requests created that way can
only control the device they originate from, making them suitable for
simple devices, but not complex pipelines.

Signed-off-by: Alexandre Courbot 
---
 Documentation/ioctl/ioctl-number.txt |  1 +
 drivers/media/v4l2-core/v4l2-dev.c   |  2 ++
 drivers/media/v4l2-core/v4l2-ioctl.c | 25 +
 include/media/v4l2-dev.h |  2 ++
 include/uapi/linux/videodev2.h   |  3 +++
 5 files changed, 33 insertions(+)

diff --git a/Documentation/ioctl/ioctl-number.txt 
b/Documentation/ioctl/ioctl-number.txt
index 6501389d55b9..afdc9ed255b0 100644
--- a/Documentation/ioctl/ioctl-number.txt
+++ b/Documentation/ioctl/ioctl-number.txt
@@ -286,6 +286,7 @@ Code  Seq#(hex) Include FileComments

 'z'10-4F   drivers/s390/crypto/zcrypt_api.hconflict!
 '|'00-7F   linux/media.h
+'|'80-9F   linux/media-request.h
 0x80   00-1F   linux/fb.h
 0x89   00-06   arch/x86/include/asm/sockios.h
 0x89   0B-DF   linux/sockios.h
diff --git a/drivers/media/v4l2-core/v4l2-dev.c 
b/drivers/media/v4l2-core/v4l2-dev.c
index 0301fe426a43..062ebee5bffc 100644
--- a/drivers/media/v4l2-core/v4l2-dev.c
+++ b/drivers/media/v4l2-core/v4l2-dev.c
@@ -559,6 +559,8 @@ static void determine_valid_ioctls(struct video_device 
*vdev)
set_bit(_IOC_NR(VIDIOC_TRY_EXT_CTRLS), valid_ioctls);
if (vdev->ctrl_handler || ops->vidioc_querymenu)
set_bit(_IOC_NR(VIDIOC_QUERYMENU), valid_ioctls);
+   if (vdev->req_mgr)
+   set_bit(_IOC_NR(VIDIOC_NEW_REQUEST), valid_ioctls);
SET_VALID_IOCTL(ops, VIDIOC_G_FREQUENCY, vidioc_g_frequency);
SET_VALID_IOCTL(ops, VIDIOC_S_FREQUENCY, vidioc_s_frequency);
SET_VALID_IOCTL(ops, VIDIOC_LOG_STATUS, vidioc_log_status);
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c 
b/drivers/media/v4l2-core/v4l2-ioctl.c
index ab4968ea443f..a45fe078f8ae 100644
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
@@ -21,6 +21,7 @@
 
 #include 
 
+#include 
 #include 
 #include 
 #include 
@@ -842,6 +843,13 @@ static void v4l_print_freq_band(const void *arg, bool 
write_only)
p->rangehigh, p->modulation);
 }
 
+static void vidioc_print_new_request(const void *arg, bool write_only)
+{
+   const struct media_request_new *new = arg;
+
+   pr_cont("fd=0x%x\n", new->fd);
+}
+
 static void v4l_print_edid(const void *arg, bool write_only)
 {
const struct v4l2_edid *p = arg;
@@ -2486,6 +2494,22 @@ static int v4l_enum_freq_bands(const struct 
v4l2_ioctl_ops *ops,
return -ENOTTY;
 }
 
+static int vidioc_new_request(const struct v4l2_ioctl_ops *ops,
+ struct file *file, void *fh, void *arg)
+{
+#if IS_ENABLED(CONFIG_MEDIA_REQUEST_API)
+   struct media_request_new *new = arg;
+   struct video_device *vfd = video_devdata(file);
+
+   if (!vfd->req_mgr)
+   return -ENOTTY;
+
+   return media_request_ioctl_new(vfd->req_mgr, new);
+#else
+   return -ENOTTY;
+#endif
+}
+
 struct v4l2_ioctl_info {
unsigned int ioctl;
u32 flags;
@@ -2617,6 +2641,7 @@ static struct v4l2_ioctl_info v4l2_ioctls[] = {
IOCTL_INFO_FNC(VIDIOC_ENUM_FREQ_BANDS, v4l_enum_freq_bands, 
v4l_print_freq_band, 0),
IOCTL_INFO_FNC(VIDIOC_DBG_G_CHIP_INFO, v4l_dbg_g_chip_info, 
v4l_print_dbg_chip_info, INFO_FL_CLEAR(v4l2_dbg_chip_info, match)),
IOCTL_INFO_FNC(VIDIOC_QUERY_EXT_CTRL, v4l_query_ext_ctrl, 
v4l_print_query_ext_ctrl, INFO_FL_CTRL | INFO_FL_CLEAR(v4l2_query_ext_ctrl, 
id)),
+   IOCTL_INFO_FNC(VIDIOC_NEW_REQUEST, vidioc_new_request, 
vidioc_print_new_request, 0),
 };
 #define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
 
diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h
index 53f32022fabe..e6c4e10889bc 100644
--- a/include/media/v4l2-dev.h
+++ b/include/media/v4l2-dev.h
@@ -209,6 +209,7 @@ struct v4l2_file_operations {
  * @entity:  media_entity
  * @intf_devnode: pointer to  media_intf_devnode
  * @pipe:  media_pipeline
+ * @req_mgr: request manager to use if this device supports creating requests
  * @fops: pointer to  v4l2_file_operations for the video device
  * @device_caps: device capabilities as used in v4l2_capabilities
  * @dev:  device for the video device
@@ -251,6 +252,7 @@ struct video_device
struct media_intf_devnode *intf_devnode;
struct media_pipeline pipe;
 #endif
+   struct media_request_mgr *req_mgr;
const struct v4l2_file_operations *fops;
 
u32 device_caps;
diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
index 91cfe0cbd5c5..35706204e81d 100644
--- a/include/uapi/linux/videodev2.h
+++ b/include/uapi/linux/videodev2.h
@@ -63,6 +63,7 @@
 #include 
 #include 
 

[RFCv4 20/21] media: vivid: add request support for the video capture device

2018-02-19 Thread Alexandre Courbot
Allow to use requests with the video capture device.

Signed-off-by: Alexandre Courbot 
---
 drivers/media/platform/vivid/Kconfig  |  1 +
 drivers/media/platform/vivid/vivid-core.c | 63 ++-
 drivers/media/platform/vivid/vivid-core.h |  3 +
 .../media/platform/vivid/vivid-kthread-cap.c  | 17 +
 4 files changed, 83 insertions(+), 1 deletion(-)

diff --git a/drivers/media/platform/vivid/Kconfig 
b/drivers/media/platform/vivid/Kconfig
index 154de92dd809..a6494dabae95 100644
--- a/drivers/media/platform/vivid/Kconfig
+++ b/drivers/media/platform/vivid/Kconfig
@@ -7,6 +7,7 @@ config VIDEO_VIVID
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
+   select MEDIA_REQUEST_API
select VIDEOBUF2_VMALLOC
select VIDEOBUF2_DMA_CONTIG
select VIDEO_V4L2_TPG
diff --git a/drivers/media/platform/vivid/vivid-core.c 
b/drivers/media/platform/vivid/vivid-core.c
index 82ec216f2ad8..c1cf8e7ca2c9 100644
--- a/drivers/media/platform/vivid/vivid-core.c
+++ b/drivers/media/platform/vivid/vivid-core.c
@@ -23,6 +23,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "vivid-core.h"
 #include "vivid-vid-common.h"
@@ -486,6 +487,33 @@ static const struct v4l2_file_operations vivid_fops = {
.mmap   = vb2_fop_mmap,
 };
 
+static int vivid_cap_open(struct file *filp)
+{
+   struct vivid_dev *dev;
+   struct v4l2_fh *fh;
+   int ret;
+
+   ret = v4l2_fh_open(filp);
+   if (ret)
+   return ret;
+
+   dev = container_of(video_devdata(filp), struct vivid_dev, vid_cap_dev);
+   fh = filp->private_data;
+   fh->entity = >vid_cap_req_entity.base;
+
+   return ret;
+}
+
+static const struct v4l2_file_operations vivid_cap_fops = {
+   .owner  = THIS_MODULE,
+   .open   = vivid_cap_open,
+   .release= vivid_fop_release,
+   .read   = vb2_fop_read,
+   .write  = vb2_fop_write,
+   .poll   = vb2_fop_poll,
+   .unlocked_ioctl = video_ioctl2,
+   .mmap   = vb2_fop_mmap,
+};
 static const struct v4l2_file_operations vivid_radio_fops = {
.owner  = THIS_MODULE,
.open   = v4l2_fh_open,
@@ -607,6 +635,31 @@ static const struct v4l2_ioctl_ops vivid_ioctl_ops = {
.vidioc_unsubscribe_event   = v4l2_event_unsubscribe,
 };
 
+struct media_request_entity_data *
+vid_cap_entity_data_alloc(struct media_request *req,
+   struct media_request_entity *entity)
+{
+   struct vivid_dev *dev;
+
+   dev = container_of(entity, struct vivid_dev, vid_cap_req_entity.base);
+   return v4l2_request_entity_data_alloc(req, >ctrl_hdl_vid_cap);
+}
+
+static int vid_cap_request_submit(struct media_request *req,
+   struct media_request_entity_data *_data)
+{
+   struct v4l2_request_entity_data *data;
+
+   data = to_v4l2_entity_data(_data);
+   return vb2_request_submit(data);
+}
+
+static const struct media_request_entity_ops vivid_request_entity_ops = {
+   .data_alloc = vid_cap_entity_data_alloc,
+   .data_free  = v4l2_request_entity_data_free,
+   .submit = vid_cap_request_submit,
+};
+
 /* -
Initialization and module stuff
--*/
@@ -1057,6 +1110,7 @@ static int vivid_create_instance(struct platform_device 
*pdev, int inst)
q->mem_ops = vivid_mem_ops[allocator];
q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
q->min_buffers_needed = 2;
+   q->allow_requests = true;
q->lock = >mutex;
q->dev = dev->v4l2_dev.dev;
 
@@ -1158,13 +1212,19 @@ static int vivid_create_instance(struct platform_device 
*pdev, int inst)
vfd = >vid_cap_dev;
snprintf(vfd->name, sizeof(vfd->name),
 "vivid-%03d-vid-cap", inst);
-   vfd->fops = _fops;
+   vfd->fops = _cap_fops;
vfd->ioctl_ops = _ioctl_ops;
vfd->device_caps = dev->vid_cap_caps;
vfd->release = video_device_release_empty;
vfd->v4l2_dev = >v4l2_dev;
vfd->queue = >vb_vid_cap_q;
vfd->tvnorms = tvnorms_cap;
+   vfd->req_mgr = >vid_cap_req_mgr.base;
+   v4l2_request_mgr_init(>vid_cap_req_mgr, vfd,
+ _request_ops);
+   v4l2_request_entity_init(>vid_cap_req_entity,
+_request_entity_ops,
+vfd);
 
/*
 * Provide a mutex to v4l2 core. It will be used to protect
@@ -1448,6 +1508,7 @@ static int vivid_remove(struct platform_device *pdev)
  

[RFCv4 18/21] Documentation: v4l: document request API

2018-02-19 Thread Alexandre Courbot
Document the request API for V4L2 devices, and amend the documentation
of system calls influenced by it.

Signed-off-by: Alexandre Courbot 
---
 Documentation/media/uapi/v4l/buffer.rst   |   9 +-
 Documentation/media/uapi/v4l/common.rst   |   1 +
 Documentation/media/uapi/v4l/request-api.rst  | 199 ++
 Documentation/media/uapi/v4l/user-func.rst|   1 +
 .../media/uapi/v4l/vidioc-g-ext-ctrls.rst |  16 +-
 .../media/uapi/v4l/vidioc-new-request.rst |  64 ++
 Documentation/media/uapi/v4l/vidioc-qbuf.rst  |   7 +
 7 files changed, 293 insertions(+), 4 deletions(-)
 create mode 100644 Documentation/media/uapi/v4l/request-api.rst
 create mode 100644 Documentation/media/uapi/v4l/vidioc-new-request.rst

diff --git a/Documentation/media/uapi/v4l/buffer.rst 
b/Documentation/media/uapi/v4l/buffer.rst
index ae6ee73f151c..62caa8c9120d 100644
--- a/Documentation/media/uapi/v4l/buffer.rst
+++ b/Documentation/media/uapi/v4l/buffer.rst
@@ -301,10 +301,13 @@ struct v4l2_buffer
elements in the ``planes`` array. The driver will fill in the
actual number of valid elements in that array.
 * - __u32
-  - ``reserved2``
+  - ``request_fd``
   -
-  - A place holder for future extensions. Drivers and applications
-   must set this to 0.
+  - The file descriptor of the request to queue the buffer to. If 
specified,
+   the buffer will be queued to that request. If zero, the buffer will
+   be directly queued to the queue designated by the ``type`` field. This
+   is set by the user when calling :ref:`VIDIOC_QBUF` and ignored by other
+   ioctls.
 * - __u32
   - ``reserved``
   -
diff --git a/Documentation/media/uapi/v4l/common.rst 
b/Documentation/media/uapi/v4l/common.rst
index 13f2ed3fc5a6..a4aa0059d45a 100644
--- a/Documentation/media/uapi/v4l/common.rst
+++ b/Documentation/media/uapi/v4l/common.rst
@@ -44,3 +44,4 @@ applicable to all devices.
 crop
 selection-api
 streaming-par
+request-api
diff --git a/Documentation/media/uapi/v4l/request-api.rst 
b/Documentation/media/uapi/v4l/request-api.rst
new file mode 100644
index ..0c1f2896e197
--- /dev/null
+++ b/Documentation/media/uapi/v4l/request-api.rst
@@ -0,0 +1,199 @@
+.. -*- coding: utf-8; mode: rst -*-
+
+.. _media-request-api:
+
+Request API
+===
+
+The Request API has been designed to allow V4L2 to deal with requirements of
+modern devices (stateless codecs, MIPI cameras, ...) and APIs (Android Codec
+v2). One such requirement is the ability for devices belonging to the same
+pipeline to reconfigure and collaborate closely on a per-frame basis. Another 
is
+efficient support of stateless codecs, which need per-frame controls to be set
+asynchronously in order to be efficiently used.
+
+Supporting these features without the Request API is possible but terribly
+inefficient: user-space would have to flush all activity on the media pipeline,
+reconfigure it for the next frame, queue the buffers to be processed with that
+configuration, and wait until they are all available for dequeing before
+considering the next frame. This defeats the purpose of having buffer queues
+since in practice only one buffer would be queued at a time.
+
+The Request API allows a specific configuration of the pipeline (media
+controller topology + controls for each device) to be associated with specific
+buffers. The parameters are applied by each participating device as buffers
+associated to a request flow in. This allows user-space to schedule several
+tasks ("requests") with different parameters in advance, knowing that the
+parameters will be applied when needed to get the expected result. Controls
+values at the time of request completion are also available for reading.
+
+Usage
+=
+
+The Request API is used on top of standard media controller and V4L2 calls,
+which are augmented with an extra ``request_fd`` parameter. Request themselves
+are allocated from either a supporting V4L2 device node, or a supporting media
+controller node. The origin of requests determine their scope: requests
+allocated from a V4L2 device node can only act on that device, whereas requests
+allocated from a media controller node can control the whole pipeline of the
+controller.
+
+Request Allocation
+--
+
+User-space allocates requests using the ``VIDIOC_NEW_REQUEST`` (for V4L2 device
+requests) or ``MEDIA_IOC_NEW_REQUEST`` (for media controller requests) on an
+opened device or media node. This returns a file descriptor representing the
+request. Typically, several such requests will be allocated.
+
+Request Preparation
+---
+
+Standard V4L2 ioctls can then receive a request file descriptor to express the
+fact that the ioctl is part of said request, and is not to be applied
+immediately. V4L2 ioctls supporting this are :c:func:`VIDIOC_S_EXT_CTRLS` and
+:c:func:`VIDIOC_QBUF`. Controls set with a request parameter 

[RFCv4 21/21] [WIP] media: media-device: support for creating requests

2018-02-19 Thread Alexandre Courbot
Add a new MEDIA_IOC_NEW_REQUEST ioctl, which can be used to instantiate
a request suitable to control the media device topology as well as the
parameters and buffer flow of its entities.

This is still very early work, and mainly here to demonstrate that it is
still possible to bind requests to media entities.

Signed-off-by: Alexandre Courbot 
---
 drivers/media/media-device.c | 11 +++
 include/media/mc-request.h   | 33 +
 include/media/media-device.h |  1 +
 include/media/media-entity.h |  5 +
 include/uapi/linux/media.h   |  2 ++
 5 files changed, 52 insertions(+)
 create mode 100644 include/media/mc-request.h

diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c
index e79f72b8b858..2fb8b9c5ec85 100644
--- a/drivers/media/media-device.c
+++ b/drivers/media/media-device.c
@@ -32,6 +32,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #ifdef CONFIG_MEDIA_CONTROLLER
 
@@ -359,6 +360,15 @@ static long media_device_get_topology(struct media_device 
*mdev,
return ret;
 }
 
+static long media_device_new_request(struct media_device *mdev,
+struct media_request_new *new)
+{
+   if (!mdev->req_mgr)
+   return -ENOTTY;
+
+   return media_request_ioctl_new(mdev->req_mgr, new);
+}
+
 static long copy_arg_from_user(void *karg, void __user *uarg, unsigned int cmd)
 {
/* All media IOCTLs are _IOWR() */
@@ -407,6 +417,7 @@ static const struct media_ioctl_info ioctl_info[] = {
MEDIA_IOC(ENUM_LINKS, media_device_enum_links, 
MEDIA_IOC_FL_GRAPH_MUTEX),
MEDIA_IOC(SETUP_LINK, media_device_setup_link, 
MEDIA_IOC_FL_GRAPH_MUTEX),
MEDIA_IOC(G_TOPOLOGY, media_device_get_topology, 
MEDIA_IOC_FL_GRAPH_MUTEX),
+   MEDIA_IOC(NEW_REQUEST, media_device_new_request, 0),
 };
 
 static long media_device_ioctl(struct file *filp, unsigned int cmd,
diff --git a/include/media/mc-request.h b/include/media/mc-request.h
new file mode 100644
index ..c14d38a93019
--- /dev/null
+++ b/include/media/mc-request.h
@@ -0,0 +1,33 @@
+/*
+ * Media requests support for media controller
+ *
+ * Copyright (C) 2018, The Chromium OS Authors.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _MEDIA_MC_REQUEST_H
+#define _MEDIA_MC_REQUEST_H
+
+#include 
+#include 
+
+#if IS_ENABLED(CONFIG_MEDIA_REQUEST_API)
+
+struct mc_request_entity {
+   struct media_request_entity base;
+   struct media_entity *entity;
+};
+
+#else  /* CONFIG_MEDIA_REQUEST_API */
+
+#endif  /* CONFIG_MEDIA_REQUEST_API */
+
+#endif
diff --git a/include/media/media-device.h b/include/media/media-device.h
index bcc6ec434f1f..e931e8b9f60e 100644
--- a/include/media/media-device.h
+++ b/include/media/media-device.h
@@ -127,6 +127,7 @@ struct media_device {
/* dev->driver_data points to this struct. */
struct device *dev;
struct media_devnode *devnode;
+   struct media_request_mgr *req_mgr;
 
char model[32];
char driver_name[32];
diff --git a/include/media/media-entity.h b/include/media/media-entity.h
index a732af1dbba0..e3525d1ec386 100644
--- a/include/media/media-entity.h
+++ b/include/media/media-entity.h
@@ -26,6 +26,8 @@
 #include 
 #include 
 
+struct mc_request_entity;
+
 /* Enums used internally at the media controller to represent graphs */
 
 /**
@@ -243,6 +245,7 @@ enum media_entity_type {
  * re-used if entities are unregistered or registered again.
  * @pads:  Pads array with the size defined by @num_pads.
  * @links: List of data links.
+ * @req_entity:Pointer to the request entity representing this entity, 
if any
  * @ops:   Entity operations.
  * @stream_count: Stream count for the entity.
  * @use_count: Use count for the entity.
@@ -279,6 +282,8 @@ struct media_entity {
struct media_pad *pads;
struct list_head links;
 
+   struct mc_request_entity *req_entity;
+
const struct media_entity_operations *ops;
 
int stream_count;
diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h
index b9b9446095e9..eb0014c4eb40 100644
--- a/include/uapi/linux/media.h
+++ b/include/uapi/linux/media.h
@@ -30,6 +30,7 @@
 #include 
 #include 
 #include 
+#include 
 
 struct media_device_info {
char driver[16];
@@ -413,5 +414,6 @@ struct media_v2_topology {
 #define MEDIA_IOC_ENUM_LINKS   _IOWR('|', 0x02, struct 
media_links_enum)
 #define MEDIA_IOC_SETUP_LINK   _IOWR('|', 0x03, struct media_link_desc)
 #define 

[RFCv4 19/21] media: vim2m: add request support

2018-02-19 Thread Alexandre Courbot
Set the necessary ops for supporting requests in vim2m.

Signed-off-by: Alexandre Courbot 
---
 drivers/media/platform/Kconfig |  1 +
 drivers/media/platform/vim2m.c | 75 ++
 2 files changed, 76 insertions(+)

diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
index 614fbef08ddc..09be0b5f9afe 100644
--- a/drivers/media/platform/Kconfig
+++ b/drivers/media/platform/Kconfig
@@ -534,6 +534,7 @@ source "drivers/media/platform/vivid/Kconfig"
 config VIDEO_VIM2M
tristate "Virtual Memory-to-Memory Driver"
depends on VIDEO_DEV && VIDEO_V4L2
+   select MEDIA_REQUEST_API
select VIDEOBUF2_VMALLOC
select V4L2_MEM2MEM_DEV
default n
diff --git a/drivers/media/platform/vim2m.c b/drivers/media/platform/vim2m.c
index 065483e62db4..02793dd9a330 100644
--- a/drivers/media/platform/vim2m.c
+++ b/drivers/media/platform/vim2m.c
@@ -30,6 +30,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 
 MODULE_DESCRIPTION("Virtual device for mem2mem framework testing");
 MODULE_AUTHOR("Pawel Osciak, ");
@@ -148,6 +150,8 @@ struct vim2m_dev {
struct timer_list   timer;
 
struct v4l2_m2m_dev *m2m_dev;
+
+   struct v4l2_request_mgr req_mgr;
 };
 
 struct vim2m_ctx {
@@ -155,6 +159,7 @@ struct vim2m_ctx {
struct vim2m_dev*dev;
 
struct v4l2_ctrl_handler hdl;
+   struct v4l2_request_entity req_entity;
 
/* Processed buffers in this transaction */
u8  num_processed;
@@ -367,6 +372,24 @@ static void job_abort(void *priv)
ctx->aborting = 1;
 }
 
+static int apply_request_params(struct media_request *req,
+   struct vim2m_ctx *ctx)
+{
+   struct v4l2_request_entity_data *data;
+
+   if (!req)
+   return -EINVAL;
+
+   data = to_v4l2_entity_data(media_request_get_entity_data(req,
+   >req_entity.base));
+   if (WARN_ON(IS_ERR(data)))
+   return PTR_ERR(data);
+
+   v4l2_ctrl_request_setup(>ctrls);
+
+   return 0;
+}
+
 /* device_run() - prepares and starts the device
  *
  * This simulates all the immediate preparations required before starting
@@ -382,6 +405,19 @@ static void device_run(void *priv)
src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
 
+   WARN_ON(dst_buf->vb2_buf.request != NULL &&
+   dst_buf->vb2_buf.request != src_buf->vb2_buf.request);
+
+   /* Apply request if needed */
+   if (src_buf->vb2_buf.request) {
+   int ret = apply_request_params(src_buf->vb2_buf.request, ctx);
+   if (ret) {
+   dprintk(dev, "error applying request parameters: %d\n",
+   ret);
+   return;
+   }
+   }
+
device_process(ctx, src_buf, dst_buf);
 
/* Run a timer, which simulates a hardware irq  */
@@ -393,6 +429,7 @@ static void device_isr(struct timer_list *t)
struct vim2m_dev *vim2m_dev = from_timer(vim2m_dev, t, timer);
struct vim2m_ctx *curr_ctx;
struct vb2_v4l2_buffer *src_vb, *dst_vb;
+   struct media_request *req;
unsigned long flags;
 
curr_ctx = v4l2_m2m_get_curr_priv(vim2m_dev->m2m_dev);
@@ -404,6 +441,7 @@ static void device_isr(struct timer_list *t)
 
src_vb = v4l2_m2m_src_buf_remove(curr_ctx->fh.m2m_ctx);
dst_vb = v4l2_m2m_dst_buf_remove(curr_ctx->fh.m2m_ctx);
+   req = src_vb->vb2_buf.request;
 
curr_ctx->num_processed++;
 
@@ -411,6 +449,8 @@ static void device_isr(struct timer_list *t)
v4l2_m2m_buf_done(src_vb, VB2_BUF_STATE_DONE);
v4l2_m2m_buf_done(dst_vb, VB2_BUF_STATE_DONE);
spin_unlock_irqrestore(_dev->irqlock, flags);
+   if (req)
+   media_request_entity_complete(req, _ctx->req_entity.base);
 
if (curr_ctx->num_processed == curr_ctx->translen
|| curr_ctx->aborting) {
@@ -838,6 +878,7 @@ static int queue_init(void *priv, struct vb2_queue *src_vq, 
struct vb2_queue *ds
src_vq->mem_ops = _vmalloc_memops;
src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
src_vq->lock = >dev->dev_mutex;
+   src_vq->allow_requests = true;
 
ret = vb2_queue_init(src_vq);
if (ret)
@@ -851,6 +892,7 @@ static int queue_init(void *priv, struct vb2_queue *src_vq, 
struct vb2_queue *ds
dst_vq->mem_ops = _vmalloc_memops;
dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
dst_vq->lock = >dev->dev_mutex;
+   dst_vq->allow_requests = true;
 
return vb2_queue_init(dst_vq);
 }
@@ -877,6 +919,31 @@ static const struct v4l2_ctrl_config 
vim2m_ctrl_trans_num_bufs = {
.step = 1,
 };
 
+struct media_request_entity_data *
+vim2m_entity_data_alloc(struct 

cron job: media_tree daily build: ABI WARNING

2018-02-19 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:   Tue Feb 20 05:00:11 CET 2018
media-tree git hash:29422737017b866d4a51014cc7522fa3a99e8852
media_build git hash:   d144cfe4b3c37ece55ae27778c99765d4943c4fa
v4l-utils git hash: 4665ab1fbab1ddaa5696bc3f5865ec6fc83eaf84
gcc version:i686-linux-gcc (GCC) 7.3.0
sparse version: v0.5.0-3994-g45eb2282
smatch version: v0.5.0-3994-g45eb2282
host hardware:  x86_64
host os:4.14.0-3-amd64

linux-git-arm-at91: OK
linux-git-arm-davinci: OK
linux-git-arm-multi: OK
linux-git-arm-pxa: OK
linux-git-arm-stm32: OK
linux-git-arm64: 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: WARNINGS
linux-2.6.36.4-x86_64: WARNINGS
linux-2.6.37.6-i686: WARNINGS
linux-2.6.37.6-x86_64: WARNINGS
linux-2.6.38.8-i686: WARNINGS
linux-2.6.38.8-x86_64: WARNINGS
linux-2.6.39.4-i686: WARNINGS
linux-2.6.39.4-x86_64: WARNINGS
linux-3.0.60-i686: WARNINGS
linux-3.0.60-x86_64: WARNINGS
linux-3.1.10-i686: WARNINGS
linux-3.1.10-x86_64: WARNINGS
linux-3.2.98-i686: WARNINGS
linux-3.2.98-x86_64: WARNINGS
linux-3.3.8-i686: WARNINGS
linux-3.3.8-x86_64: WARNINGS
linux-3.4.27-i686: WARNINGS
linux-3.4.27-x86_64: WARNINGS
linux-3.5.7-i686: WARNINGS
linux-3.5.7-x86_64: WARNINGS
linux-3.6.11-i686: WARNINGS
linux-3.6.11-x86_64: WARNINGS
linux-3.7.4-i686: WARNINGS
linux-3.7.4-x86_64: WARNINGS
linux-3.8-i686: WARNINGS
linux-3.8-x86_64: WARNINGS
linux-3.9.2-i686: WARNINGS
linux-3.9.2-x86_64: WARNINGS
linux-3.10.1-i686: WARNINGS
linux-3.10.1-x86_64: WARNINGS
linux-3.11.1-i686: WARNINGS
linux-3.11.1-x86_64: WARNINGS
linux-3.12.67-i686: WARNINGS
linux-3.12.67-x86_64: WARNINGS
linux-3.13.11-i686: WARNINGS
linux-3.13.11-x86_64: WARNINGS
linux-3.14.9-i686: WARNINGS
linux-3.14.9-x86_64: WARNINGS
linux-3.15.2-i686: WARNINGS
linux-3.15.2-x86_64: WARNINGS
linux-3.16.53-i686: WARNINGS
linux-3.16.53-x86_64: WARNINGS
linux-3.17.8-i686: WARNINGS
linux-3.17.8-x86_64: WARNINGS
linux-3.18.93-i686: WARNINGS
linux-3.18.93-x86_64: WARNINGS
linux-3.19-i686: WARNINGS
linux-3.19-x86_64: WARNINGS
linux-4.0.9-i686: WARNINGS
linux-4.0.9-x86_64: WARNINGS
linux-4.1.49-i686: WARNINGS
linux-4.1.49-x86_64: WARNINGS
linux-4.2.8-i686: WARNINGS
linux-4.2.8-x86_64: WARNINGS
linux-4.3.6-i686: WARNINGS
linux-4.3.6-x86_64: WARNINGS
linux-4.4.115-i686: OK
linux-4.4.115-x86_64: OK
linux-4.5.7-i686: WARNINGS
linux-4.5.7-x86_64: WARNINGS
linux-4.6.7-i686: OK
linux-4.6.7-x86_64: WARNINGS
linux-4.7.5-i686: OK
linux-4.7.5-x86_64: WARNINGS
linux-4.8-i686: OK
linux-4.8-x86_64: WARNINGS
linux-4.9.80-i686: OK
linux-4.9.80-x86_64: OK
linux-4.10.14-i686: OK
linux-4.10.14-x86_64: WARNINGS
linux-4.11-i686: OK
linux-4.11-x86_64: WARNINGS
linux-4.12.1-i686: OK
linux-4.12.1-x86_64: WARNINGS
linux-4.13-i686: OK
linux-4.13-x86_64: OK
linux-4.14.17-i686: OK
linux-4.14.17-x86_64: OK
linux-4.15.2-i686: OK
linux-4.15.2-x86_64: OK
linux-4.16-rc1-i686: OK
linux-4.16-rc1-x86_64: OK
apps: WARNINGS
spec-git: OK
ABI WARNING: change for blackfin-bf561
sparse: WARNINGS
smatch: OK

Detailed results are available here:

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

Full logs are available here:

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

The Media Infrastructure API from this daily build is here:

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


[RFCv4 01/21] media: add request API core and UAPI

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

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

Signed-off-by: Alexandre Courbot 
---
 drivers/media/Kconfig  |   3 +
 drivers/media/Makefile |   6 +
 drivers/media/media-request.c  | 341 
 include/media/media-request.h  | 349 +
 include/uapi/linux/media-request.h |  37 +++
 5 files changed, 736 insertions(+)
 create mode 100644 drivers/media/media-request.c
 create mode 100644 include/media/media-request.h
 create mode 100644 include/uapi/linux/media-request.h

diff --git a/drivers/media/Kconfig b/drivers/media/Kconfig
index 145e12bfb819..db30fc9547d2 100644
--- a/drivers/media/Kconfig
+++ b/drivers/media/Kconfig
@@ -130,6 +130,9 @@ config VIDEO_V4L2_SUBDEV_API
 
  This API is mostly used by camera interfaces in embedded platforms.
 
+config MEDIA_REQUEST_API
+   tristate
+
 source "drivers/media/v4l2-core/Kconfig"
 
 #
diff --git a/drivers/media/Makefile b/drivers/media/Makefile
index 594b462ddf0e..03c0a39ad344 100644
--- a/drivers/media/Makefile
+++ b/drivers/media/Makefile
@@ -5,6 +5,12 @@
 
 media-objs := media-device.o media-devnode.o media-entity.o
 
+#
+# Request API support comes as its own module since it can be used by
+# both media and video devices
+#
+obj-$(CONFIG_MEDIA_REQUEST_API) += media-request.o
+
 #
 # I2C drivers should come before other drivers, otherwise they'll fail
 # when compiled as builtin drivers
diff --git a/drivers/media/media-request.c b/drivers/media/media-request.c
new file mode 100644
index ..b88362028561
--- /dev/null
+++ b/drivers/media/media-request.c
@@ -0,0 +1,341 @@
+/*
+ * Request base implementation
+ *
+ * Copyright (C) 2018, The Chromium OS Authors.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+const struct file_operations request_fops;
+
+static const char * const media_request_states[] __maybe_unused = {
+   "IDLE",
+   "SUBMITTED",
+   "COMPLETED",
+   "INVALID",
+};
+
+struct media_request *media_request_get(struct media_request *req)
+{
+   get_file(req->file);
+   return req;
+}
+EXPORT_SYMBOL_GPL(media_request_get);
+
+struct media_request *media_request_get_from_fd(int fd)
+{
+   struct file *f;
+
+   f = fget(fd);
+   if (!f)
+   return NULL;
+
+   /* Not a request FD? */
+   if (f->f_op != _fops) {
+   fput(f);
+   return NULL;
+   }
+
+   return f->private_data;
+}
+EXPORT_SYMBOL_GPL(media_request_get_from_fd);
+
+void media_request_put(struct media_request *req)
+{
+   if (WARN_ON(req == NULL))
+   return;
+
+   fput(req->file);
+}
+EXPORT_SYMBOL_GPL(media_request_put);
+
+struct media_request_entity_data *
+media_request_get_entity_data(struct media_request *req,
+ struct media_request_entity *entity)
+{
+   struct media_request_entity_data *data;
+
+   /* First check that this entity is valid for this request at all */
+   if (!req->mgr->ops->entity_valid(req, entity))
+   return ERR_PTR(-EINVAL);
+
+   mutex_lock(>lock);
+
+   /* Lookup whether we already have entity data */
+   list_for_each_entry(data, >data, list) {
+   if (data->entity == entity)
+   goto out;
+   }
+
+   /* No entity data found, let's create it */
+   data = entity->ops->data_alloc(req, entity);
+   if (IS_ERR(data))
+   goto out;
+
+   data->entity = entity;
+   list_add_tail(>list, >data);
+
+out:
+   mutex_unlock(>lock);
+
+   return data;
+}
+EXPORT_SYMBOL_GPL(media_request_get_entity_data);
+
+static unsigned int media_request_poll(struct file *file, poll_table *wait)
+{
+   struct media_request *req = file->private_data;
+
+   poll_wait(file, >complete_wait, wait);
+
+   if (req->state == MEDIA_REQUEST_STATE_COMPLETED)
+   return POLLIN | POLLRDNORM;
+
+   return 0;
+}
+
+static int media_request_release(struct inode *inode, struct file *filp)
+{
+   struct media_request *req = filp->private_data;
+
+   if (req == NULL)
+   return 0;
+
+   

Re: [PATCH v9 07/11] media: i2c: ov772x: Support frame interval handling

2018-02-19 Thread kbuild test robot
Hi Jacopo,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on linuxtv-media/master]
[also build test WARNING on v4.16-rc2 next-20180220]
[if your patch is applied to the wrong git tree, please drop us a note to help 
improve the system]

url:
https://github.com/0day-ci/linux/commits/Jacopo-Mondi/Renesas-Capture-Engine-Unit-CEU-V4L2-driver/20180220-101027
base:   git://linuxtv.org/media_tree.git master
config: i386-allmodconfig (attached as .config)
compiler: gcc-7 (Debian 7.3.0-1) 7.3.0
reproduce:
# save the attached .config to linux build tree
make ARCH=i386 

Note: it may well be a FALSE warning. FWIW you are at least aware of it now.
http://gcc.gnu.org/wiki/Better_Uninitialized_Warnings

All warnings (new ones prefixed by >>):

   drivers/media/i2c/ov772x.c: In function 'ov772x_set_frame_rate.isra.2':
>> drivers/media/i2c/ov772x.c:643:7: warning: 'fsize' may be used uninitialized 
>> in this function [-Wmaybe-uninitialized]
 pclk = fps * fsize;
 ~^

vim +/fsize +643 drivers/media/i2c/ov772x.c

   604  
   605  static int ov772x_set_frame_rate(struct ov772x_priv *priv,
   606   struct v4l2_fract *tpf,
   607   const struct ov772x_color_format *cfmt,
   608   const struct ov772x_win_size *win)
   609  {
   610  struct i2c_client *client = v4l2_get_subdevdata(>subdev);
   611  unsigned long fin = clk_get_rate(priv->clk);
   612  unsigned int fps = tpf->numerator ?
   613 tpf->denominator / tpf->numerator :
   614 tpf->denominator;
   615  unsigned int best_diff;
   616  unsigned int fsize;
   617  unsigned int pclk;
   618  unsigned int diff;
   619  unsigned int idx;
   620  unsigned int i;
   621  u8 clkrc = 0;
   622  u8 com4 = 0;
   623  int ret;
   624  
   625  /* Approximate to the closest supported frame interval. */
   626  best_diff = ~0L;
   627  for (i = 0, idx = 0; i < OV772X_N_FRAME_INTERVALS; i++) {
   628  diff = abs(fps - ov772x_frame_intervals[i]);
   629  if (diff < best_diff) {
   630  idx = i;
   631  best_diff = diff;
   632  }
   633  }
   634  fps = ov772x_frame_intervals[idx];
   635  
   636  /* Use image size (with blankings) to calculate desired pixel 
clock. */
   637  if ((cfmt->com7 & OFMT_MASK) == OFMT_RGB ||
   638  (cfmt->com7 & OFMT_MASK) == OFMT_YUV)
   639  fsize = win->sizeimage * 2;
   640  else if ((cfmt->com7 & OFMT_MASK) == OFMT_BRAW)
   641  fsize = win->sizeimage;
   642  
 > 643  pclk = fps * fsize;
   644  
   645  /*
   646   * Pixel clock generation circuit is pretty simple:
   647   *
   648   * Fin -> [ / CLKRC_div] -> [ * PLL_mult] -> pclk
   649   *
   650   * Try to approximate the desired pixel clock testing all 
available
   651   * PLL multipliers (1x, 4x, 6x, 8x) and calculate corresponding
   652   * divisor with:
   653   *
   654   * div = PLL_mult * Fin / pclk
   655   *
   656   * and re-calculate the pixel clock using it:
   657   *
   658   * pclk = Fin * PLL_mult / CLKRC_div
   659   *
   660   * Choose the PLL_mult and CLKRC_div pair that gives a pixel 
clock
   661   * closer to the desired one.
   662   *
   663   * The desired pixel clock is calculated using a known frame 
size
   664   * (blanking included) and FPS.
   665   */
   666  best_diff = ~0L;
   667  for (i = 0; i < ARRAY_SIZE(ov772x_pll); i++) {
   668  unsigned int pll_mult = ov772x_pll[i].mult;
   669  unsigned int pll_out = pll_mult * fin;
   670  unsigned int t_pclk;
   671  unsigned int div;
   672  
   673  if (pll_out < pclk)
   674  continue;
   675  
   676  div = DIV_ROUND_CLOSEST(pll_out, pclk);
   677  t_pclk = DIV_ROUND_CLOSEST(fin * pll_mult, div);
   678  diff = abs(pclk - t_pclk);
   679  if (diff < best_diff) {
   680  best_diff = diff;
   681  clkrc = CLKRC_DIV(div);
   682  com4 = ov772x_pll[i].com4;
   683  }
   684  }
   685  
   686  ret = ov772x_write(client, COM4, com4 | COM4_RESERVED);
   687  if (ret < 0)
   688  return ret;
   689  
   690  ret = ov772x_write(client, CLKRC, clkrc | CLKRC_RESERVED);
   691  if (ret < 0)
   692   

Re: [PATCH v9 03/11] media: platform: Add Renesas CEU driver

2018-02-19 Thread kbuild test robot
Hi Jacopo,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on linuxtv-media/master]
[also build test ERROR on v4.16-rc2 next-20180220]
[if your patch is applied to the wrong git tree, please drop us a note to help 
improve the system]

url:
https://github.com/0day-ci/linux/commits/Jacopo-Mondi/Renesas-Capture-Engine-Unit-CEU-V4L2-driver/20180220-101027
base:   git://linuxtv.org/media_tree.git master
config: i386-allmodconfig (attached as .config)
compiler: gcc-7 (Debian 7.3.0-1) 7.3.0
reproduce:
# save the attached .config to linux build tree
make ARCH=i386 

All errors (new ones prefixed by >>):

   drivers/media/platform/renesas-ceu.c: In function 'ceu_g_parm':
>> drivers/media/platform/renesas-ceu.c:1177:9: error: implicit declaration of 
>> function 'v4l2_g_parm_cap'; did you mean 'v4l2_g_ctrl'? 
>> [-Werror=implicit-function-declaration]
 return v4l2_g_parm_cap(video_devdata(file), ceudev->sd->v4l2_sd, a);
^~~
v4l2_g_ctrl
   drivers/media/platform/renesas-ceu.c: In function 'ceu_s_parm':
>> drivers/media/platform/renesas-ceu.c:1184:9: error: implicit declaration of 
>> function 'v4l2_s_parm_cap'; did you mean 'v4l2_s_ctrl'? 
>> [-Werror=implicit-function-declaration]
 return v4l2_s_parm_cap(video_devdata(file), ceudev->sd->v4l2_sd, a);
^~~
v4l2_s_ctrl
   drivers/media/platform/renesas-ceu.c: In function 'ceu_start_streaming':
   drivers/media/platform/renesas-ceu.c:290:2: warning: 'cdwdr' may be used 
uninitialized in this function [-Wmaybe-uninitialized]
 iowrite32(data, priv->base + reg_offs);
 ^~
   drivers/media/platform/renesas-ceu.c:338:27: note: 'cdwdr' was declared here
 u32 camcr, cdocr, cfzsr, cdwdr, capwr;
  ^
   drivers/media/platform/renesas-ceu.c:290:2: warning: 'cfzsr' may be used 
uninitialized in this function [-Wmaybe-uninitialized]
 iowrite32(data, priv->base + reg_offs);
 ^~
   drivers/media/platform/renesas-ceu.c:338:20: note: 'cfzsr' was declared here
 u32 camcr, cdocr, cfzsr, cdwdr, capwr;
   ^
   drivers/media/platform/renesas-ceu.c:418:8: warning: 'camcr' may be used 
uninitialized in this function [-Wmaybe-uninitialized]
 camcr |= mbus_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW ? 1 << 0 : 0;
 ~~^~~
   drivers/media/platform/renesas-ceu.c:338:6: note: 'camcr' was declared here
 u32 camcr, cdocr, cfzsr, cdwdr, capwr;
 ^
   drivers/media/platform/renesas-ceu.c: In function 'ceu_probe':
   drivers/media/platform/renesas-ceu.c:1623:9: warning: 'ret' may be used 
uninitialized in this function [-Wmaybe-uninitialized]
 return ret;
^~~
   cc1: some warnings being treated as errors

vim +1177 drivers/media/platform/renesas-ceu.c

  1172  
  1173  static int ceu_g_parm(struct file *file, void *fh, struct 
v4l2_streamparm *a)
  1174  {
  1175  struct ceu_device *ceudev = video_drvdata(file);
  1176  
> 1177  return v4l2_g_parm_cap(video_devdata(file), 
> ceudev->sd->v4l2_sd, a);
  1178  }
  1179  
  1180  static int ceu_s_parm(struct file *file, void *fh, struct 
v4l2_streamparm *a)
  1181  {
  1182  struct ceu_device *ceudev = video_drvdata(file);
  1183  
> 1184  return v4l2_s_parm_cap(video_devdata(file), 
> ceudev->sd->v4l2_sd, a);
  1185  }
  1186  

---
0-DAY kernel test infrastructureOpen Source Technology Center
https://lists.01.org/pipermail/kbuild-all   Intel Corporation


.config.gz
Description: application/gzip


Re: [PATCH 8/8] [media] s5p-mfc: Use clk bulk API

2018-02-19 Thread kbuild test robot
Hi Maciej,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on linuxtv-media/master]
[also build test WARNING on v4.16-rc2 next-20180219]
[if your patch is applied to the wrong git tree, please drop us a note to help 
improve the system]

url:
https://github.com/0day-ci/linux/commits/Maciej-Purski/Use-clk-bulk-API-in-exynos5433-drivers/20180220-054431
base:   git://linuxtv.org/media_tree.git master
config: sparc64-allmodconfig (attached as .config)
compiler: sparc64-linux-gnu-gcc (Debian 7.2.0-11) 7.2.0
reproduce:
wget 
https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O 
~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
make.cross ARCH=sparc64 

All warnings (new ones prefixed by >>):

   drivers/media/platform/s5p-mfc/s5p_mfc_pm.c: In function 's5p_mfc_init_pm':
>> drivers/media/platform/s5p-mfc/s5p_mfc_pm.c:39:7: warning: passing argument 
>> 3 of 'devm_clk_bulk_alloc' discards 'const' qualifier from pointer target 
>> type [-Wdiscarded-qualifiers]
  pm->clk_names);
  ^~
   In file included from drivers/media/platform/s5p-mfc/s5p_mfc_pm.c:13:0:
   include/linux/clk.h:654:37: note: expected 'const char **' but argument is 
of type 'const char * const*'
static inline struct clk_bulk_data *devm_clk_bulk_alloc(struct device *dev,
^~~

vim +39 drivers/media/platform/s5p-mfc/s5p_mfc_pm.c

24  
25  int s5p_mfc_init_pm(struct s5p_mfc_dev *dev)
26  {
27  int ret;
28  
29  pm = >pm;
30  p_dev = dev;
31  
32  pm->num_clocks = dev->variant->num_clocks;
33  pm->clk_names = dev->variant->clk_names;
34  pm->device = >plat_dev->dev;
35  pm->clock_gate = NULL;
36  
37  /* clock control */
38  pm->clocks = devm_clk_bulk_alloc(pm->device, pm->num_clocks,
  > 39   pm->clk_names);
40  if (IS_ERR(pm->clocks))
41  return PTR_ERR(pm->clocks);
42  
43  ret = devm_clk_bulk_get(pm->device, pm->num_clocks, pm->clocks);
44  if (ret < 0)
45  return ret;
46  
47  if (dev->variant->use_clock_gating)
48  pm->clock_gate = pm->clocks[0].clk;
49  
50  pm_runtime_enable(pm->device);
51  atomic_set(_ref, 0);
52  return 0;
53  }
54  

---
0-DAY kernel test infrastructureOpen Source Technology Center
https://lists.01.org/pipermail/kbuild-all   Intel Corporation


.config.gz
Description: application/gzip


Re: [PATCH 4/8] drm/exynos/dsi: Use clk bulk API

2018-02-19 Thread kbuild test robot
Hi Maciej,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on linuxtv-media/master]
[also build test ERROR on v4.16-rc2 next-20180219]
[if your patch is applied to the wrong git tree, please drop us a note to help 
improve the system]

url:
https://github.com/0day-ci/linux/commits/Maciej-Purski/Use-clk-bulk-API-in-exynos5433-drivers/20180220-054431
base:   git://linuxtv.org/media_tree.git master
config: arm-multi_v7_defconfig (attached as .config)
compiler: arm-linux-gnueabi-gcc (Debian 7.2.0-11) 7.2.0
reproduce:
wget 
https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O 
~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
make.cross ARCH=arm 

All errors (new ones prefixed by >>):

   ERROR: "devm_clk_bulk_alloc" [drivers/media/platform/s5p-jpeg/s5p-jpeg.ko] 
undefined!
>> ERROR: "devm_clk_bulk_alloc" [drivers/gpu/drm/exynos/exynosdrm.ko] undefined!

---
0-DAY kernel test infrastructureOpen Source Technology Center
https://lists.01.org/pipermail/kbuild-all   Intel Corporation


.config.gz
Description: application/gzip


Re: [PATCH 2/8] media: s5p-jpeg: Use bulk clk API

2018-02-19 Thread kbuild test robot
Hi Maciej,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on linuxtv-media/master]
[also build test ERROR on v4.16-rc2 next-20180219]
[if your patch is applied to the wrong git tree, please drop us a note to help 
improve the system]

url:
https://github.com/0day-ci/linux/commits/Maciej-Purski/Use-clk-bulk-API-in-exynos5433-drivers/20180220-054431
base:   git://linuxtv.org/media_tree.git master
config: arm-multi_v7_defconfig (attached as .config)
compiler: arm-linux-gnueabi-gcc (Debian 7.2.0-11) 7.2.0
reproduce:
wget 
https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O 
~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
make.cross ARCH=arm 

All errors (new ones prefixed by >>):

>> ERROR: "devm_clk_bulk_alloc" [drivers/media/platform/s5p-jpeg/s5p-jpeg.ko] 
>> undefined!

---
0-DAY kernel test infrastructureOpen Source Technology Center
https://lists.01.org/pipermail/kbuild-all   Intel Corporation


.config.gz
Description: application/gzip


Re: [PATCH 7/8] [media] exynos-gsc: Use clk bulk API

2018-02-19 Thread kbuild test robot
Hi Maciej,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on linuxtv-media/master]
[also build test WARNING on v4.16-rc2 next-20180219]
[if your patch is applied to the wrong git tree, please drop us a note to help 
improve the system]

url:
https://github.com/0day-ci/linux/commits/Maciej-Purski/Use-clk-bulk-API-in-exynos5433-drivers/20180220-054431
base:   git://linuxtv.org/media_tree.git master
config: sparc64-allmodconfig (attached as .config)
compiler: sparc64-linux-gnu-gcc (Debian 7.2.0-11) 7.2.0
reproduce:
wget 
https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O 
~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
make.cross ARCH=sparc64 

All warnings (new ones prefixed by >>):

   drivers/media/platform/exynos-gsc/gsc-core.c: In function 'gsc_probe':
>> drivers/media/platform/exynos-gsc/gsc-core.c:1190:8: warning: passing 
>> argument 3 of 'devm_clk_bulk_alloc' discards 'const' qualifier from pointer 
>> target type [-Wdiscarded-qualifiers]
   drv_data->clk_names);
   ^~~~
   In file included from drivers/media/platform/exynos-gsc/gsc-core.c:25:0:
   include/linux/clk.h:654:37: note: expected 'const char **' but argument is 
of type 'const char * const*'
static inline struct clk_bulk_data *devm_clk_bulk_alloc(struct device *dev,
^~~

vim +1190 drivers/media/platform/exynos-gsc/gsc-core.c

  1144  
  1145  static int gsc_probe(struct platform_device *pdev)
  1146  {
  1147  struct gsc_dev *gsc;
  1148  struct resource *res;
  1149  struct device *dev = >dev;
  1150  const struct gsc_driverdata *drv_data = 
of_device_get_match_data(dev);
  1151  int ret;
  1152  
  1153  gsc = devm_kzalloc(dev, sizeof(struct gsc_dev), GFP_KERNEL);
  1154  if (!gsc)
  1155  return -ENOMEM;
  1156  
  1157  ret = of_alias_get_id(pdev->dev.of_node, "gsc");
  1158  if (ret < 0)
  1159  return ret;
  1160  
  1161  if (drv_data == _v_100_drvdata)
  1162  dev_info(dev, "compatible 'exynos5-gsc' is 
deprecated\n");
  1163  
  1164  gsc->id = ret;
  1165  if (gsc->id >= drv_data->num_entities) {
  1166  dev_err(dev, "Invalid platform device id: %d\n", 
gsc->id);
  1167  return -EINVAL;
  1168  }
  1169  
  1170  gsc->num_clocks = drv_data->num_clocks;
  1171  gsc->variant = drv_data->variant[gsc->id];
  1172  gsc->pdev = pdev;
  1173  
  1174  init_waitqueue_head(>irq_queue);
  1175  spin_lock_init(>slock);
  1176  mutex_init(>lock);
  1177  
  1178  res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  1179  gsc->regs = devm_ioremap_resource(dev, res);
  1180  if (IS_ERR(gsc->regs))
  1181  return PTR_ERR(gsc->regs);
  1182  
  1183  res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
  1184  if (!res) {
  1185  dev_err(dev, "failed to get IRQ resource\n");
  1186  return -ENXIO;
  1187  }
  1188  
  1189  gsc->clocks = devm_clk_bulk_alloc(dev, gsc->num_clocks,
> 1190drv_data->clk_names);
  1191  if (IS_ERR(gsc->clocks))
  1192  return PTR_ERR(gsc->clocks);
  1193  
  1194  ret = devm_clk_bulk_get(dev, gsc->num_clocks,
  1195  gsc->clocks);
  1196  if (ret)
  1197  return ret;
  1198  
  1199  ret = clk_bulk_prepare_enable(gsc->num_clocks, gsc->clocks);
  1200  if (ret)
  1201  return ret;
  1202  
  1203  ret = devm_request_irq(dev, res->start, gsc_irq_handler,
  1204  0, pdev->name, gsc);
  1205  if (ret) {
  1206  dev_err(dev, "failed to install irq (%d)\n", ret);
  1207  goto err_clk;
  1208  }
  1209  
  1210  ret = v4l2_device_register(dev, >v4l2_dev);
  1211  if (ret)
  1212  goto err_clk;
  1213  
  1214  ret = gsc_register_m2m_device(gsc);
  1215  if (ret)
  1216  goto err_v4l2;
  1217  
  1218  platform_set_drvdata(pdev, gsc);
  1219  
  1220  gsc_hw_set_sw_reset(gsc);
  1221  gsc_wait_reset(gsc);
  1222  
  1223  vb2_dma_contig_set_max_seg_size(dev, DMA_BIT_MASK(32));
  1224  
  1225  dev_dbg(dev, "gsc-%d registered successfully\n", gsc->id);
  1226  
  1227  pm_runtime_set_active(dev);
  1228  pm_runtime_enable(dev);

Re: [PATCH v2] videodev2.h: add helper to validate colorspace

2018-02-19 Thread Niklas Söderlund
Hi Hans,

Thanks for your feedback.

[snip]

> > >>> Can you then fix v4l2-compliance to stop testing colorspace 
> > >>> against 0xff
> > >>> ?
> > >> 
> > >> For now I can simply relax this test for subdevs with sources and sinks.
> > > 
> > > You also need to relax it for video nodes with MC drivers, as the DMA
> > > engines don't care about colorspaces.
> > 
> > Yes, they do. Many DMA engines can at least do RGB <-> YUV conversions, so
> > they should get the colorspace info from their source and pass it on to
> > userspace (after correcting for any conversions done by the DMA engine).
> 
> Not in the MC case. Video nodes there only model the DMA engine, and are thus 
> not aware of colorspaces. What MC drivers do is check at stream on time when 
> validating the pipeline that the colorspace set by userspace on the video 
> node 
> corresponds to the colorspace on the source pad of the connected subdev, but 
> that's only to ensure that userspace gets a coherent view of colorspace 
> across 
> the pipeline, not to program the hardware. There could be exceptions, but in 
> the general case, the video node implementation of an MC driver will accept 
> any colorspace and only validate it at stream on time, similarly to how it 
> does for the frame size format instance (and in the frame size case it will 
> usually enforce min/max limits when the DMA engine limits the frame size).

I'm afraid the issue described above by Laurent is what sparked me to 
write this commit to begin with. In my never ending VIN Gen3 patch-set I 
currency need to carry a patch [1] to implement a hack to make sure 
v4l2-compliance do not fail for the VIN Gen3 MC-centric use-case. This 
patch was an attempt to be able to validate the colorspace using the 
magic value 0xff.

I don't feel strongly for this patch in particular and I'm happy to drop 
it.  But I would like to receive some guidance on how to then properly 
be able to handle this problem for the MC-centric VIN driver use-case.  
One option is as you suggested to relax the test in v4l-compliance to 
not check colorspace, but commit [2] is not enough to resolve the issue 
for my MC use-case.

As Laurent stated above, the use-case is that the video device shall 
accept any colorspace set from user-space. This colorspace is then only 
used as stream on time to validate the MC pipeline. The VIN driver do 
not care about colorspace, but I care about not breaking v4l2-compliance 
as I find it's a very useful tool :-)

I'm basing the following on the latest v4l-utils master 
(4665ab1fbab1ddaa)  which contains commit [2]. The core issue is that if 
I do not have a patch like [1] the v4l2-compliance run fails for format 
ioctls:

Format ioctls (Input 0):
test VIDIOC_ENUM_FMT/FRAMESIZES/FRAMEINTERVALS: OK
test VIDIOC_G/S_PARM: OK (Not Supported)
test VIDIOC_G_FBUF: OK (Not Supported)
fail: v4l2-test-formats.cpp(330): !colorspace
fail: v4l2-test-formats.cpp(439): 
testColorspace(pix.pixelformat, pix.colorspace, pix.ycbcr_enc, pix.quantization)
test VIDIOC_G_FMT: FAIL
test VIDIOC_TRY_FMT: OK (Not Supported)
test VIDIOC_S_FMT: OK (Not Supported)
test VIDIOC_G_SLICED_VBI_CAP: OK (Not Supported)
test Cropping: OK (Not Supported)
test Composing: OK (Not Supported)
test Scaling: OK

Well that is OK as that fails when colorspace is V4L2_COLORSPACE_DEFAULT 
and that is not valid. If I instead of reverting [1] only test for 
V4L2_COLORSPACE_DEFAULT which would not require this patch to implement:

-   if (!pix->colorspace || pix->colorspace >= 0xff)
+   if (pix->colorspace == V4L2_COLORSPACE_DEFAULT)

I still fail for the format ioctls:

Format ioctls (Input 0):
test VIDIOC_ENUM_FMT/FRAMESIZES/FRAMEINTERVALS: OK
test VIDIOC_G/S_PARM: OK (Not Supported)
test VIDIOC_G_FBUF: OK (Not Supported)
test VIDIOC_G_FMT: OK
fail: v4l2-test-formats.cpp(336): colorspace >= 0xff
fail: v4l2-test-formats.cpp(439): 
testColorspace(pix.pixelformat, pix.colorspace, pix.ycbcr_enc, pix.quantization)
fail: v4l2-test-formats.cpp(753): Video Capture is valid, but 
TRY_FMT failed to return a format
test VIDIOC_TRY_FMT: FAIL
fail: v4l2-test-formats.cpp(336): colorspace >= 0xff
fail: v4l2-test-formats.cpp(439): 
testColorspace(pix.pixelformat, pix.colorspace, pix.ycbcr_enc, pix.quantization)
fail: v4l2-test-formats.cpp(1018): Video Capture is valid, but 
no S_FMT was implemented
test VIDIOC_S_FMT: FAIL
test VIDIOC_G_SLICED_VBI_CAP: OK (Not Supported)
test Cropping: OK (Not Supported)
test Composing: OK (Not Supported)
test Scaling: OK

But now I fail on that colorspace >= 0xff which was what the patch in my 
VIN Gen3 series tries to address but as Laurent points out and I agree 
is not a good idea as the 0xff is a magic number 

Re: [PATCH 2/2] media: Add a driver for the ov7251 camera sensor

2018-02-19 Thread Sakari Ailus
Hi Jacopo,

On Fri, Feb 16, 2018 at 11:05:00AM +0100, jacopo mondi wrote:
...
> > +   /* Update the power count. */
> > +   ov7251->power_count += on ? 1 : -1;
> > +   WARN_ON(ov7251->power_count < 0);
> 
> Is this 'reference counting' necessary? If you receive three
> s_power(1) you would need three s_power(0) to turn the sensor off.
> Is this better than a simple "if it's on, turn it off" and viceversa?

Some drivers did this as the drivers themselves controlled the power state
of the device through open / release callbacks.

> 
> Also, it should not happen that you receive multiple s_power(1) or
> s_power(0), but I may be wrong...

Agreed.

...

> > +static int ov7251_enum_frame_ival(struct v4l2_subdev *subdev,
> > + struct v4l2_subdev_pad_config *cfg,
> > + struct v4l2_subdev_frame_interval_enum *fie)
> > +{
> > +   int index = fie->index;
> > +   int i;
> > +
> > +   for (i = 0; i < ARRAY_SIZE(ov7251_mode_info_data); i++) {
> > +   if (fie->width != ov7251_mode_info_data[i].width ||
> > +   fie->height != ov7251_mode_info_data[i].height)
> > +   continue;
> 
> You only support 640x480 and you can return immediately
> if provided sizes do not match.
> 
> > +
> > +   if (index-- == 0) {
> > +   fie->interval = ov7251_mode_info_data[i].timeperframe;
> > +   return 0;
> > +   }
> > +   }
> > +
> > +   return -EINVAL;
> > +}
> > +
> > +static struct v4l2_mbus_framefmt *
> > +__ov7251_get_pad_format(struct ov7251 *ov7251,
> > +   struct v4l2_subdev_pad_config *cfg,
> > +   unsigned int pad,
> > +   enum v4l2_subdev_format_whence which)
> > +{
> > +   switch (which) {
> > +   case V4L2_SUBDEV_FORMAT_TRY:
> > +   return v4l2_subdev_get_try_format(>sd, cfg, pad);
> > +   case V4L2_SUBDEV_FORMAT_ACTIVE:
> > +   return >fmt;
> > +   default:
> > +   return NULL;
> > +   }
> > +}
> > +
> > +static int ov7251_get_format(struct v4l2_subdev *sd,
> > +struct v4l2_subdev_pad_config *cfg,
> > +struct v4l2_subdev_format *format)
> > +{
> > +   struct ov7251 *ov7251 = to_ov7251(sd);
> > +
> > +   format->format = *__ov7251_get_pad_format(ov7251, cfg, format->pad,
> > + format->which);
> > +   return 0;
> > +}
> > +
> > +static struct v4l2_rect *
> > +__ov7251_get_pad_crop(struct ov7251 *ov7251, struct v4l2_subdev_pad_config 
> > *cfg,
> > + unsigned int pad, enum v4l2_subdev_format_whence which)
> > +{
> > +   switch (which) {
> > +   case V4L2_SUBDEV_FORMAT_TRY:
> > +   return v4l2_subdev_get_try_crop(>sd, cfg, pad);
> > +   case V4L2_SUBDEV_FORMAT_ACTIVE:
> > +   return >crop;
> > +   default:
> > +   return NULL;
> > +   }
> > +}
> > +
> > +static const struct ov7251_mode_info *
> > +ov7251_find_mode_by_size(unsigned int width, unsigned int height)
> > +{
> > +   unsigned int max_dist_match = (unsigned int) -1;
> > +   int i, n = 0;
> > +
> > +   for (i = 0; i < ARRAY_SIZE(ov7251_mode_info_data); i++) {
> > +   unsigned int dist = min(width, ov7251_mode_info_data[i].width)
> > +   * min(height, ov7251_mode_info_data[i].height);
> > +
> > +   dist = ov7251_mode_info_data[i].width *
> > +   ov7251_mode_info_data[i].height +
> > +   width * height - 2 * dist;
> 
> I didn't get why you assign dist twice here..
> 
> > +
> > +   if (dist < max_dist_match) {
> > +   n = i;
> > +   max_dist_match = dist;
> > +   }
> > +   }
> > +
> > +   return _mode_info_data[n];
> > +}
> 
> I do not find that much value in this function, as being all
> ov7251_mode_info_data[] sizes equal you end up returning always the
> first one...

Could you check "[PATCH 1/5] v4l: common: Add a function to obtain best
size from a list" I've sent recently to the list? You could also make use
of that in frame interval enumeration if you change the driver's data
structures a little. Same for ov7251_find_mode_by_ival below.

> 
> > +
> > +#define TIMEPERFRAME_AVG_FPS(t)
> > \
> > +   (((t).denominator + ((t).numerator >> 1)) / (t).numerator)
> > +
> > +static const struct ov7251_mode_info *
> > +ov7251_find_mode_by_ival(struct ov7251 *ov7251, struct v4l2_fract 
> > *timeperframe)
> > +{
> > +   const struct ov7251_mode_info *mode = ov7251->current_mode;
> > +   int fps_req = TIMEPERFRAME_AVG_FPS(*timeperframe);
> > +   unsigned int max_dist_match = (unsigned int) -1;
> > +   int i, n = 0;
> > +
> > +   for (i = 0; i < ARRAY_SIZE(ov7251_mode_info_data); i++) {
> > +   unsigned int dist;
> > +   int fps_tmp;
> > +
> > +   if (mode->width != ov7251_mode_info_data[i].width ||
> > +   mode->height != 

[GIT PULL v2 for 4.17] Sensor and lens driver patches

2018-02-19 Thread Sakari Ailus
Hi Mauro,

Here's the first pile of sensor and lens driver patches for 4.17.

The most noteworthy parts are perhaps

- moving unmaintained imx074 and mt9t031 SoC camera drivers to staging in
  hope someone would start looking after them,

- add DT bindings and driver upport for the bindings for ov9650, ov7670,
  ov5695 and ov2685 sensors and

- JPEG support for ov5640.

The rest are related or random fixes.

since v1:

- Select V4L2_FWNODE for ov7670

Please pull.


The following changes since commit 29422737017b866d4a51014cc7522fa3a99e8852:

  media: rc: get start time just before calling driver tx (2018-02-14 14:17:21 
-0500)

are available in the git repository at:

  ssh://linuxtv.org/git/sailus/media_tree.git for-4.17-1

for you to fetch changes up to 4c2de036e83693d29e21b945f0ae9f6f697fa478:

  media: ov5640: fix framerate update (2018-02-19 13:02:13 +0200)


Akinobu Mita (3):
  media: MAINTAINERS: add entry for ov9650 driver
  media: ov9650: add device tree binding
  media: ov9650: support device tree probing

Chiranjeevi Rapolu (1):
  media: ov13858: Avoid possible null first frame

Gustavo A. R. Silva (2):
  ov13858: Use false for boolean value
  i2c: ov9650: fix potential integer overflow in __ov965x_set_frame_interval

Hans Verkuil (2):
  imx074: deprecate, move to staging
  mt9t031: deprecate, move to staging

Hugues Fruchet (5):
  media: ov5640: add JPEG support
  media: ov5640: add error trace in case of i2c read failure
  media: ov5640: various typo & style fixes
  media: ov5640: fix virtual_channel parameter permissions
  media: ov5640: fix framerate update

Jacopo Mondi (2):
  media: dt-bindings: Add OF properties to ov7670
  v4l2: i2c: ov7670: Implement OF mbus configuration

Sakari Ailus (1):
  ov2685: Assign ret in default case in s_ctrl callback

Shunqian Zheng (4):
  dt-bindings: media: Add bindings for OV5695
  media: ov5695: add support for OV5695 sensor
  dt-bindings: media: Add bindings for OV2685
  media: ov2685: add support for OV2685 sensor

 .../devicetree/bindings/media/i2c/ov2685.txt   |   41 +
 .../devicetree/bindings/media/i2c/ov5695.txt   |   41 +
 .../devicetree/bindings/media/i2c/ov7670.txt   |   16 +-
 .../devicetree/bindings/media/i2c/ov9650.txt   |   36 +
 MAINTAINERS|   24 +
 drivers/media/i2c/Kconfig  |   23 +
 drivers/media/i2c/Makefile |2 +
 drivers/media/i2c/ov13858.c|6 +-
 drivers/media/i2c/ov2685.c |  846 
 drivers/media/i2c/ov5640.c |   99 +-
 drivers/media/i2c/ov5695.c | 1399 
 drivers/media/i2c/ov7670.c |   98 +-
 drivers/media/i2c/ov9650.c |  134 +-
 drivers/media/i2c/soc_camera/Kconfig   |   12 -
 drivers/media/i2c/soc_camera/Makefile  |2 -
 drivers/staging/media/Kconfig  |4 +
 drivers/staging/media/Makefile |2 +
 drivers/staging/media/imx074/Kconfig   |5 +
 drivers/staging/media/imx074/Makefile  |1 +
 drivers/staging/media/imx074/TODO  |5 +
 .../soc_camera => staging/media/imx074}/imx074.c   |0
 drivers/staging/media/mt9t031/Kconfig  |   11 +
 drivers/staging/media/mt9t031/Makefile |1 +
 drivers/staging/media/mt9t031/TODO |5 +
 .../soc_camera => staging/media/mt9t031}/mt9t031.c |0
 25 files changed, 2718 insertions(+), 95 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/media/i2c/ov2685.txt
 create mode 100644 Documentation/devicetree/bindings/media/i2c/ov5695.txt
 create mode 100644 Documentation/devicetree/bindings/media/i2c/ov9650.txt
 create mode 100644 drivers/media/i2c/ov2685.c
 create mode 100644 drivers/media/i2c/ov5695.c
 create mode 100644 drivers/staging/media/imx074/Kconfig
 create mode 100644 drivers/staging/media/imx074/Makefile
 create mode 100644 drivers/staging/media/imx074/TODO
 rename drivers/{media/i2c/soc_camera => staging/media/imx074}/imx074.c (100%)
 create mode 100644 drivers/staging/media/mt9t031/Kconfig
 create mode 100644 drivers/staging/media/mt9t031/Makefile
 create mode 100644 drivers/staging/media/mt9t031/TODO
 rename drivers/{media/i2c/soc_camera => staging/media/mt9t031}/mt9t031.c (100%)

-- 
Kind regards,

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


Re: [PATCH v4 2/2] v4l2: i2c: ov7670: Implement OF mbus configuration

2018-02-19 Thread Sakari Ailus
On Wed, Jan 24, 2018 at 10:30:50AM +0100, Jacopo Mondi wrote:
> ov7670 driver supports two optional properties supplied through platform
> data, but currently does not support any standard video interface
> property.
> 
> Add support through OF parsing for 2 generic properties (vsync and hsync
> polarities) and for one custom property already supported through
> platform data to suppress pixel clock output during horizontal
> blanking.
> 
> While at there, check return value of register writes in set_fmt
> function and rationalize spacings.
> 
> Signal polarities and pixel clock blanking verified through scope and
> image capture.
> 
> Signed-off-by: Jacopo Mondi 

Hi Jacopo,

I'll add the following diff to the patch in order to fix the build error
without V4L2_FWNODE:

diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
index 535f85b73075..245387f7b65e 100644
--- a/drivers/media/i2c/Kconfig
+++ b/drivers/media/i2c/Kconfig
@@ -683,6 +683,7 @@ config VIDEO_OV7670
tristate "OmniVision OV7670 sensor support"
depends on I2C && VIDEO_V4L2
depends on MEDIA_CAMERA_SUPPORT
+   select V4L2_FWNODE
---help---
  This is a Video4Linux2 sensor-level driver for the OmniVision
  OV7670 VGA camera.  It currently only works with the M88ALP01

> ---
>  drivers/media/i2c/ov7670.c | 98 
> +++---
>  1 file changed, 84 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/media/i2c/ov7670.c b/drivers/media/i2c/ov7670.c
> index 61c472e..80c822c 100644
> --- a/drivers/media/i2c/ov7670.c
> +++ b/drivers/media/i2c/ov7670.c
> @@ -21,6 +21,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -242,6 +243,7 @@ struct ov7670_info {
>   struct clk *clk;
>   struct gpio_desc *resetb_gpio;
>   struct gpio_desc *pwdn_gpio;
> + unsigned int mbus_config;   /* Media bus configuration flags */
>   int min_width;  /* Filter out smaller sizes */
>   int min_height; /* Filter out smaller sizes */
>   int clock_speed;/* External clock speed (MHz) */
> @@ -1018,7 +1020,7 @@ static int ov7670_set_fmt(struct v4l2_subdev *sd,
>  #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
>   struct v4l2_mbus_framefmt *mbus_fmt;
>  #endif
> - unsigned char com7;
> + unsigned char com7, com10 = 0;
>   int ret;
>  
>   if (format->pad)
> @@ -1038,7 +1040,6 @@ static int ov7670_set_fmt(struct v4l2_subdev *sd,
>   }
>  
>   ret = ov7670_try_fmt_internal(sd, >format, , );
> -
>   if (ret)
>   return ret;
>   /*
> @@ -1049,16 +1050,41 @@ static int ov7670_set_fmt(struct v4l2_subdev *sd,
>*/
>   com7 = ovfmt->regs[0].value;
>   com7 |= wsize->com7_bit;
> - ov7670_write(sd, REG_COM7, com7);
> + ret = ov7670_write(sd, REG_COM7, com7);
> + if (ret)
> + return ret;
> +
> + /*
> +  * Configure the media bus through COM10 register
> +  */
> + if (info->mbus_config & V4L2_MBUS_VSYNC_ACTIVE_LOW)
> + com10 |= COM10_VS_NEG;
> + if (info->mbus_config & V4L2_MBUS_HSYNC_ACTIVE_LOW)
> + com10 |= COM10_HREF_REV;
> + if (info->pclk_hb_disable)
> + com10 |= COM10_PCLK_HB;
> + ret = ov7670_write(sd, REG_COM10, com10);
> + if (ret)
> + return ret;
> +
>   /*
>* Now write the rest of the array.  Also store start/stops
>*/
> - ov7670_write_array(sd, ovfmt->regs + 1);
> - ov7670_set_hw(sd, wsize->hstart, wsize->hstop, wsize->vstart,
> - wsize->vstop);
> - ret = 0;
> - if (wsize->regs)
> + ret = ov7670_write_array(sd, ovfmt->regs + 1);
> + if (ret)
> + return ret;
> +
> + ret = ov7670_set_hw(sd, wsize->hstart, wsize->hstop, wsize->vstart,
> + wsize->vstop);
> + if (ret)
> + return ret;
> +
> + if (wsize->regs) {
>   ret = ov7670_write_array(sd, wsize->regs);
> + if (ret)
> + return ret;
> + }
> +
>   info->fmt = ovfmt;
>  
>   /*
> @@ -1071,8 +1097,10 @@ static int ov7670_set_fmt(struct v4l2_subdev *sd,
>* to write it unconditionally, and that will make the frame
>* rate persistent too.
>*/
> - if (ret == 0)
> - ret = ov7670_write(sd, REG_CLKRC, info->clkrc);
> + ret = ov7670_write(sd, REG_CLKRC, info->clkrc);
> + if (ret)
> + return ret;
> +
>   return 0;
>  }
>  
> @@ -1698,6 +1726,45 @@ static int ov7670_init_gpio(struct i2c_client *client, 
> struct ov7670_info *info)
>   return 0;
>  }
>  
> +/*
> + * ov7670_parse_dt() - Parse device tree to collect mbus configuration
> + *   properties
> + */
> +static int ov7670_parse_dt(struct device *dev,
> +struct ov7670_info *info)
> +{
> + struct 

Problems with WinTV Hauppauge dualHD and LibreELEC 9 on Le Potato S905X box

2018-02-19 Thread Hauke

Dear all,

I am using a Libre Computer Le Potato SBC (see here: 
https://libre.computer/products/boards/aml-s905x-cc/) with LibreELEC 8 
Leia from adamg (community build). Included there is a driver for em28xx 
based DVB cards, which in the log refers to the email address I am 
sending this to - so here's my problem: I've a WinTV Hauppauge dualHD 
DVB-T/T2/C USB card, and I set it up under Raspberry Pi/xbian/tvheadend 
successfully, could scan DVB-C and DVB-T2 and watch TV - i.e. card works 
in principle (only one tuner, but that's OK at the moment). Now I 
attached the same card to the Libre Computer Le Potato, and have only 
partial success. From dmesg I see that even both tuners are recognized, 
but they do not show up as devices in /dev - there isn't even a /dev/dvb 
folder! dmesg looks very similar to Raspberry/xbian, with three notable 
exceptions: First, the i2c-bus is not added on Le Potato. Second, 
potentially as a result of the first, the firmware file 
dvb-demod-si2168-b40-01.fw 
, 
although present, is not loaded. Third: There's a warning that this is a 
downport of the driver, which is originally created for kernel v4, not 
v3. Hauppauge itself claims support only for v4. Of course as a result 
of all this tvheadend does not see any tuner. Still, it looks like I'm 
almost there - anyone can help me do the final step?


Here's the dmesg output (Le Potato):

[ 14.416196@3] em28xx 1-1.1:1.0: EEPROM ID = 26 00 01 00, EEPROM hash = 
0x16e6c5c8

[ 14.416208@3] em28xx 1-1.1:1.0: EEPROM info:
[ 14.416213@3] em28xx 1-1.1:1.0: microcode start address = 0x0004, boot 
configuration = 0x01

[ 14.422833@0] em28xx 1-1.1:1.0: AC97 audio (5 sample rates)
[ 14.422846@0] em28xx 1-1.1:1.0: 500mA max power
[ 14.422852@0] em28xx 1-1.1:1.0: Table at offset 0x27, strings=0x0e6a, 
0x1888, 0x087e
[ 14.423650@3] em28xx 1-1.1:1.0: Identified as Hauppauge WinTV-dualHD 
DVB (card=99)

[ 14.426389@3] tveeprom: Hauppauge model 204109, rev B3I6, serial# 13886631
[ 14.426398@3] tveeprom: tuner model is SiLabs Si2157 (idx 186, type 4)
[ 14.426403@3] tveeprom: TV standards PAL(B/G) NTSC(M) PAL(I) 
SECAM(L/L') PAL(D/D1/K) ATSC/DVB Digital (eeprom 0xfc)

[ 14.426407@3] tveeprom: audio processor is None (idx 0)
[ 14.426411@3] tveeprom: has no radio, has IR receiver, has no IR 
transmitter

[ 14.426422@3] em28xx 1-1.1:1.0: dvb set to isoc mode.
[ 14.426498@3] em28xx 1-1.1:1.0: chip ID is em28174
[ 14.826656@0] libphy: stmmac-0:08 - Link is Up - 100/Full
[ 15.626378@3] em28xx 1-1.1:1.0: EEPROM ID = 26 00 01 00, EEPROM hash = 
0x16e6c5c8

[ 15.626389@3] em28xx 1-1.1:1.0: EEPROM info:
[ 15.626395@3] em28xx 1-1.1:1.0: microcode start address = 0x0004, boot 
configuration = 0x01

[ 15.634435@3] em28xx 1-1.1:1.0: AC97 audio (5 sample rates)
[ 15.634450@3] em28xx 1-1.1:1.0: 500mA max power
[ 15.634457@3] em28xx 1-1.1:1.0: Table at offset 0x27, strings=0x0e6a, 
0x1888, 0x087e
[ 15.635644@3] em28xx 1-1.1:1.0: Identified as Hauppauge WinTV-dualHD 
DVB (card=99)

[ 15.642480@3] tveeprom: Hauppauge model 204109, rev B3I6, serial# 13886631
[ 15.642494@3] tveeprom: tuner model is SiLabs Si2157 (idx 186, type 4)
[ 15.642499@3] tveeprom: TV standards PAL(B/G) NTSC(M) PAL(I) 
SECAM(L/L') PAL(D/D1/K) ATSC/DVB Digital (eeprom 0xfc)

[ 15.642503@3] tveeprom: audio processor is None (idx 0)
[ 15.642507@3] tveeprom: has no radio, has IR receiver, has no IR 
transmitter

[ 15.642518@3] em28xx 1-1.1:1.0: dvb ts2 set to isoc mode.
[ 15.843930@3] usbcore: registered new interface driver em28xx
[ 15.847501@2] WARNING: You are using an experimental version of the 
media stack.
[ 15.847501@2] As the driver is backported to an older kernel, it 
doesn't offer

[ 15.847501@2] enough quality for its usage in production.
[ 15.847501@2] Use it with care.
[ 15.847501@2] Latest git patches (needed if you report a bug to 
linux-media@vger.kernel.org):
[ 15.847501@2] b32a2b42f76cdfd06b4b58a1ddf987ba329ae34e media: ddbridge: 
improve error handling logic on fe attach failures
[ 15.847501@2] 6738d3bbab999d7d9d77a185d62bd146d9a257f2 media: drivers: 
media: remove duplicate includes
[ 15.847501@2] 9ed785a926843ca5a954d3324082afa2b96f5824 media: platform: 
sti: Adopt SPDX identifier

[ 15.848721@2] em28xx 1-1.1:1.0: Binding DVB extension
[ 15.860406@2] em28xx 1-1.1:1.0: Binding DVB extension
[ 15.864730@3] em28xx: Registered (Em28xx dvb Extension) extension
[ 15.868624@0] em28xx 1-1.1:1.0: Registering input extension
[ 15.899572@0] Registered IR keymap rc-hauppauge
[ 15.899972@2] rc rc1: 1-1.1:1.0 IR as 
/devices/c900.dwc3/xhci-hcd.0.auto/usb1/1-1/1-1.1/1-1.1:1.0/rc/rc1
[ 15.900190@2] input: 1-1.1:1.0 IR as 
/devices/c900.dwc3/xhci-hcd.0.auto/usb1/1-1/1-1.1/1-1.1:1.0/rc/rc1/input3

[ 15.900445@2] em28xx 1-1.1:1.0: Input extension successfully initialized
[ 15.900459@2] em28xx 1-1.1:1.0: Remote control support is not available 
for this card.

[ 15.900463@2] em28xx: Registered 

Re: [RFC PATCH] Add core tuner_standby op, use where needed

2018-02-19 Thread Laurent Pinchart
Hi Hans,

Thank you for the patch.

On Monday, 19 February 2018 15:12:05 EET Hans Verkuil wrote:
> The v4l2_subdev core s_power op was used to two different things: power
> on/off sensors or video decoders/encoders and to put a tuner in standby
> (and only the tuner). There is no 'tuner wakeup' op, that's done
> automatically when the tuner is accessed.
> 
> The danger with calling (s_power, 0) to put a tuner into standby is that it
> is usually broadcast for all subdevs. So a video receiver subdev that also
> supports s_power will also be powered off, and since there is no
> corresponding (s_power, 1) they will never be powered on again.
> 
> In addition, this is specifically meant for tuners only since they draw the
> most current.
> 
> This patch adds a new core op called 'tuner_standby' and replaces all calls
> to (s_power, 0) by tuner_standby. This prevents confusion between the two
> uses of s_power. Note that there is no overlap: bridge drivers either just
> want to put the tuner into standby, or they deal with powering on/off
> sensors. Never both.
> 
> This also makes it easier to replace s_power for the remaining bridge
> drivers with some PM code later.
> 
> Whether we want something similar for tuners in the future is a separate
> topic. There is a lot of legacy code surrounding tuners, and I am very
> hesitant about making changes there.

While I don't request you to make changes, someone should. I assume the tuners 
are still maintained, aren't they ? :-)

> Signed-off-by: Hans Verkuil 
> ---

[snip]
 
>  static const struct v4l2_subdev_tuner_ops tuner_tuner_ops = {
> diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h
> index 980a86c08fce..b214da92a5c0 100644
> --- a/include/media/v4l2-subdev.h
> +++ b/include/media/v4l2-subdev.h
> @@ -184,6 +184,9 @@ struct v4l2_subdev_io_pin_config {
>   * @s_power: puts subdevice in power saving mode (on == 0) or normal
> operation *   mode (on == 1).
>   *
> + * @tuner_standby: puts the tuner in standby mode. It will be woken up
> + *   automatically the next time it is used.
> + *
>   * @interrupt_service_routine: Called by the bridge chip's interrupt
> service
>   *   handler, when an interrupt status has be raised due to this subdev,
>   *   so that this subdev can handle the details.  It may schedule work to be
> @@ -212,6 +215,7 @@ struct v4l2_subdev_core_ops {
>   int (*s_register)(struct v4l2_subdev *sd, const struct v4l2_dbg_register
> *reg); #endif
>   int (*s_power)(struct v4l2_subdev *sd, int on);
> + int (*tuner_standby)(struct v4l2_subdev *sd);

If it's a tuner operation, how about moving it to v4l2_subdev_tuner_ops ? That 
would at least make it clear that it shouldn't be used by other drivers (and I 
think we should also mention in the documentation that this is a legacy 
operation that shouldn't be used for any new purpose).

>   int (*interrupt_service_routine)(struct v4l2_subdev *sd,
>   u32 status, bool *handled);
>   int (*subscribe_event)(struct v4l2_subdev *sd, struct v4l2_fh *fh,

I'd prefer the bridge drivers to be fixed to use s_power in a balanced way, 
but I understand that it might be difficult to achieve in a timely fashion. 
I'm thus not against this patch, but I don't think it makes too much sense to 
merge it without a user, that is a patch series that works on removing 
s_power.

-- 
Regards,

Laurent Pinchart



Re: [PATCH v9 11/11] media: i2c: ov7670: Fully set mbus frame fmt

2018-02-19 Thread Laurent Pinchart
Hi Jacopo,

Thank you for the patch.

On Monday, 19 February 2018 18:59:44 EET Jacopo Mondi wrote:
> The sensor driver sets mbus format colorspace information and sizes,
> but not ycbcr encoding, quantization and xfer function. When supplied
> with an badly initialized mbus frame format structure, those fields
> need to be set explicitly not to leave them uninitialized. This is
> tested by v4l2-compliance, which supplies a mbus format description
> structure and checks for all fields to be properly set.
> 
> Without this commit, v4l2-compliance fails when testing formats with:
> fail: v4l2-test-formats.cpp(335): ycbcr_enc >= 0xff
> 
> Signed-off-by: Jacopo Mondi 
> ---
>  drivers/media/i2c/ov7670.c | 4 
>  1 file changed, 4 insertions(+)
> 
> diff --git a/drivers/media/i2c/ov7670.c b/drivers/media/i2c/ov7670.c
> index 25b26d4..61c472e 100644
> --- a/drivers/media/i2c/ov7670.c
> +++ b/drivers/media/i2c/ov7670.c
> @@ -996,6 +996,10 @@ static int ov7670_try_fmt_internal(struct v4l2_subdev
> *sd, fmt->height = wsize->height;
>   fmt->colorspace = ov7670_formats[index].colorspace;

On a side note, if I'm not mistaken the colorspace field is set to SRGB for 
all entries. Shouldn't you hardcode it here and remove the field ?

> + fmt->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
> + fmt->quantization = V4L2_QUANTIZATION_DEFAULT;
> + fmt->xfer_func = V4L2_XFER_FUNC_DEFAULT;

How about setting the values explicitly instead of relying on defaults ? That 
would be V4L2_YCBCR_ENC_601, V4L2_QUANTIZATION_LIM_RANGE and 
V4L2_XFER_FUNC_SRGB. And could you then check a captured frame to see if the 
sensor outputs limited or full range ?

>   info->format = *fmt;
> 
>   return 0;

-- 
Regards,

Laurent Pinchart



Re: Bug: Two device nodes created in /dev for a single UVC webcam

2018-02-19 Thread Laurent Pinchart
Hi Alexandre-Xavier,

On Monday, 19 February 2018 19:29:24 EET Alexandre-Xavier Labonté-Lamoureux 
wrote:
> Hi Kieran,
> 
> This is how I built the drivers:
> 
> $ git clone --depth=1 git://linuxtv.org/media_build.git
> $ cd media_build
> $ ./build --main-git
> 
> I then installed the newly built kernel modules:
> 
> $ sudo make install
> 
> Once the modules were updated, I restarted my computer to make sure
> every module got reloaded. I didn't make any changes to the code and I
> found the issues after trying each of those programs individually
> after I restarted my computer.
> 
> This was the latest commit when I cloned the repo:
> 
> commit d144cfe4b3c37ece55ae27778c99765d4943c4fa
> Author: Jasmin Jessich 
> Date:   Fri Feb 16 22:40:49 2018 +0100
> Re-generated v3.12_kfifo_in.patch
> 
> My version of VLC is 2.2.6. Here's a copy of the relevant data of
> VLC's log file in case it can help: https://paste.debian.net/1011025/
> In this case, I tried to open /dev/video0 first and /dev/video1 second.
> 
> I can also try with ffplay:
> $ ffplay /dev/video0
> 
> I get this: [video4linux2,v4l2 @ 0x7f216920]
> ioctl(VIDIOC_STREAMON): Message too long
> /dev/video0: Message too long
> 
> A new message appears in dmesg: uvcvideo: Failed to submit URB 0 (-90).

That's interesting, and possibly unrelated to the patch series that added 
metadata capture support. Would you be able to revert that patch series and 
see if the problem still occurs ? The four commits to be reverted are

088ead25524583e2200aa99111bea2f66a86545a
3bc85817d7982ed53fbc9b150b0205beff68ca5c
94c53e26dc74744cc4f9a8ddc593b7aef96ba764
31a96f4c872e8fb953c853630f69d5de6ec961c9

And if you could bisect the issue it would be even better :-)

Could you also send me the output of lsusb -v for your camera (you can 
restrict it to the camera with -d VID:PID), running as root if possible ?

> $ ffplay /dev/video1
> 
> I get this:
> [video4linux2,v4l2 @ 0x7f00ec000920] ioctl(VIDIOC_G_INPUT):
> Inappropriate ioctl for device
> /dev/video1: Inappropriate ioctl for device
> 
> Like Guennadi said, /dev/video1 is a metadata node, so I don't expect
> it to work. In the case of /dev/video0, I can't tell what could be
> wrong from the error message.

-- 
Regards,

Laurent Pinchart



next-20180219: camera problems on n900

2018-02-19 Thread Pavel Machek
Hi!

> > > > In v4.14, back camera on N900 works. On v4.15-rc1.. it works for few
> > > > seconds, but then I get repeated oopses.
> > > > 
> > > > On v4.15-rc0.5 (commit ed30b147e1f6e396e70a52dbb6c7d66befedd786),
> > > > camera does not start.
> > > > 
> > > > Any ideas what might be wrong there?
> > > 
> > > What kind of oopses do you get?
> > 
> > Hmm. bisect pointed to commit that can't be responsible Ideas
> > welcome.
> 
> Hi Pavel,
> 
> I tested N9 and capture appears to be working from the CSI-2 receiver
> (media tree master, i.e. v4.15-rc3 now).
> 
> Which pipeline did you use?

I tested next-20180219 and camera does not work there. It leads to
nasty oops. I tried to capture the oops with dmesg > file, and that
one oopsed, too. usb networking also has problems... fun.

Camera works ok in V4.16-rc1, but if I use the camera, next shutdown
will oops. I'll try to collect more data there, too.

Pavel
-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) 
http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html


signature.asc
Description: Digital signature


Re: [bug report] V4L/DVB (3420): Added iocls to configure VBI on tvp5150

2018-02-19 Thread Mauro Carvalho Chehab
Em Mon, 19 Feb 2018 17:27:52 +0300
Dan Carpenter  escreveu:

> [ This is obviously ancient code.  It's probably fine.  I've just been
>   going through all array overflow warnings recently.  - dan ]
> 
> Hello Mauro Carvalho Chehab,
> 
> The patch 12db56071b47: "V4L/DVB (3420): Added iocls to configure VBI
> on tvp5150" from Jan 23, 2006, leads to the following static checker
> warning:
> 
>   drivers/media/i2c/tvp5150.c:730 tvp5150_get_vbi()
>   error: buffer overflow 'regs' 5 <= 14
> 
> drivers/media/i2c/tvp5150.c
>699  static int tvp5150_get_vbi(struct v4l2_subdev *sd,
>700  const struct i2c_vbi_ram_value *regs, int 
> line)
>701  {
>702  struct tvp5150 *decoder = to_tvp5150(sd);
>703  v4l2_std_id std = decoder->norm;
>704  u8 reg;
>705  int pos, type = 0;
>706  int i, ret = 0;
>707  
>708  if (std == V4L2_STD_ALL) {
>709  dev_err(sd->dev, "VBI can't be configured without 
> knowing number of lines\n");
>710  return 0;
>711  } else if (std & V4L2_STD_625_50) {
>712  /* Don't follow NTSC Line number convension */
>713  line += 3;
>714  }
>715  
>716  if (line < 6 || line > 27)
>717  return 0;
>718  
>719  reg = ((line - 6) << 1) + TVP5150_LINE_MODE_INI;
>720  
>721  for (i = 0; i <= 1; i++) {
>722  ret = tvp5150_read(sd, reg + i);
>723  if (ret < 0) {
>724  dev_err(sd->dev, "%s: failed with error = 
> %d\n",
>725   __func__, ret);
>726  return 0;
>727  }
>728  pos = ret & 0x0f;
>729  if (pos < 0x0f)
> ^^
> Smatch thinks this implies pos can be 0-14.
> 
>730  type |= regs[pos].type.vbi_type;
> ^
> This array only has 5 elements.
> 
>731  }
>732  
>733  return type;
>734  }

Nice catch! This is indeed a bug. The fact is that no caller drivers
currently use the sliced VBI API. Due to that, in practice, this shouldn't
be causing any harm.

Yet, better to fix it. IMHO, the better fix would be a patch like the
one below.

Regards,

Thanks,
Mauro


Re: [PATCH v2] [media] Use common error handling code in 20 functions

2018-02-19 Thread Laurent Pinchart
Hello Markus,

On Monday, 19 February 2018 20:11:56 EET SF Markus Elfring wrote:
> From: Markus Elfring 
> Date: Mon, 19 Feb 2018 18:50:40 +0100
> 
> Adjust jump targets so that a bit of exception handling can be better
> reused at the end of these functions.
> 
> This issue was partly detected by using the Coccinelle software.
> 
> Signed-off-by: Markus Elfring 
> ---
> 
> v2:
> Hans Verkuil insisted on patch squashing. Thus several changes
> were recombined based on source files from Linux next-20180216.
> 
> The implementation of the function "tda8261_set_params" was improved
> after a notification by Christoph Böhmwalder on 2017-09-26.
> 
>  drivers/media/dvb-core/dmxdev.c| 16 
>  drivers/media/dvb-frontends/tda1004x.c | 20 ++
>  drivers/media/dvb-frontends/tda8261.c  | 19 ++
>  drivers/media/pci/bt8xx/dst.c  | 19 ++
>  drivers/media/pci/bt8xx/dst_ca.c   | 30 +++
>  drivers/media/pci/cx88/cx88-input.c| 17 +
>  drivers/media/platform/omap3isp/ispvideo.c | 29 +++
>  .../media/platform/qcom/camss-8x16/camss-csid.c| 20 +-
>  drivers/media/tuners/tuner-xc2028.c| 30 +++
>  drivers/media/usb/cpia2/cpia2_usb.c| 13 ---
>  drivers/media/usb/gspca/gspca.c| 17 +
>  drivers/media/usb/gspca/sn9c20x.c  | 17 +
>  drivers/media/usb/pvrusb2/pvrusb2-ioread.c | 10 +++--
>  drivers/media/usb/tm6000/tm6000-cards.c|  7 ++--
>  drivers/media/usb/tm6000/tm6000-dvb.c  | 11 --
>  drivers/media/usb/tm6000/tm6000-video.c| 13 ---
>  drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c  | 13 +++
>  drivers/media/usb/ttusb-dec/ttusb_dec.c| 43 +++
>  drivers/media/usb/uvc/uvc_v4l2.c   | 13 ---
>  19 files changed, 180 insertions(+), 177 deletions(-)

[snip]

> diff --git a/drivers/media/platform/omap3isp/ispvideo.c
> b/drivers/media/platform/omap3isp/ispvideo.c index
> a751c89a3ea8..2ddcac736402 100644
> --- a/drivers/media/platform/omap3isp/ispvideo.c
> +++ b/drivers/media/platform/omap3isp/ispvideo.c
> @@ -1315,14 +1315,12 @@ static int isp_video_open(struct file *file)
>   /* If this is the first user, initialise the pipeline. */
>   if (omap3isp_get(video->isp) == NULL) {
>   ret = -EBUSY;
> - goto done;
> + goto delete_fh;
>   }
> 
>   ret = v4l2_pipeline_pm_use(>video.entity, 1);
> - if (ret < 0) {
> - omap3isp_put(video->isp);
> - goto done;
> - }
> + if (ret < 0)
> + goto put_isp;
> 
>   queue = >queue;
>   queue->type = video->type;
> @@ -1335,10 +1333,8 @@ static int isp_video_open(struct file *file)
>   queue->dev = video->isp->dev;
> 
>   ret = vb2_queue_init(>queue);
> - if (ret < 0) {
> - omap3isp_put(video->isp);
> - goto done;
> - }
> + if (ret < 0)
> + goto put_isp;
> 
>   memset(>format, 0, sizeof(handle->format));
>   handle->format.type = video->type;
> @@ -1346,14 +1342,15 @@ static int isp_video_open(struct file *file)
> 
>   handle->video = video;
>   file->private_data = >vfh;
> + goto exit;

No need for a goto here, you can just return 0.

> 
> -done:
> - if (ret < 0) {
> - v4l2_fh_del(>vfh);
> - v4l2_fh_exit(>vfh);
> - kfree(handle);
> - }
> -
> +put_isp:
> + omap3isp_put(video->isp);
> +delete_fh:
> + v4l2_fh_del(>vfh);
> + v4l2_fh_exit(>vfh);
> + kfree(handle);

Please prefix the error labels with error_.

> +exit:
>   return ret;
>  }
> 

Otherwise the changes to omap3isp look OK to me.

[snip]

> diff --git a/drivers/media/usb/uvc/uvc_v4l2.c
> b/drivers/media/usb/uvc/uvc_v4l2.c index a13ad4e178be..f64c851adea2 100644
> --- a/drivers/media/usb/uvc/uvc_v4l2.c
> +++ b/drivers/media/usb/uvc/uvc_v4l2.c
> @@ -994,10 +994,8 @@ static int uvc_ioctl_g_ext_ctrls(struct file *file,
> void *fh, struct v4l2_queryctrl qc = { .id = ctrl->id };
> 
>   ret = uvc_query_v4l2_ctrl(chain, );
> - if (ret < 0) {
> - ctrls->error_idx = i;
> - return ret;
> - }
> + if (ret < 0)
> + goto set_index;
> 
>   ctrl->value = qc.default_value;
>   }
> @@ -1013,14 +1011,17 @@ static int uvc_ioctl_g_ext_ctrls(struct file *file,
> void *fh, ret = uvc_ctrl_get(chain, ctrl);
>   if (ret < 0) {
>   uvc_ctrl_rollback(handle);
> - ctrls->error_idx = i;
> - return ret;
> + goto 

Re: [PATCH 1/8] clk: Add clk_bulk_alloc functions

2018-02-19 Thread Emil Velikov
HI Maciej,

Just sharing a couple of fly-by ideas - please don't read too much into them.

On 19 February 2018 at 15:43, Maciej Purski  wrote:
> When a driver is going to use clk_bulk_get() function, it has to
> initialize an array of clk_bulk_data, by filling its id fields.
>
> Add a new function to the core, which dynamically allocates
> clk_bulk_data array and fills its id fields. Add clk_bulk_free()
> function, which frees the array allocated by clk_bulk_alloc() function.
> Add a managed version of clk_bulk_alloc().
>
Most places use a small fixed number of struct clk pointers.
Using devres + kalloc to allocate 1-4 pointers feels a bit strange.

Quick grep shows over 150 instances that could be updated to use the new API.
Adding a cocci script to simplify the transition would be a good idea.

> --- a/include/linux/clk.h
> +++ b/include/linux/clk.h
> @@ -15,6 +15,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>
The extra header declaration should not be needed. One should be able
to forward declare any undefined structs.

HTH
Emil


RE: i.MX53 using imx-media to capture analog video through ADV7180

2018-02-19 Thread Matthew Starr
On 02/16/2018 07:03 PM, Steve Longerbeam wrote:
> On 02/14/2018 07:44 AM, Fabio Estevam wrote:
> > [Adding Steve and Philipp in case they could provide some suggestions]
> >
> > On Wed, Feb 14, 2018 at 1:21 PM, Matthew Starr 
> wrote:
> >> I have successfully modified device tree files in the mainline 4.15.1 
> >> kernel
> to get a display product using the i.MX53 processor to initialize the 
> imx-media
> drivers.  I think up to this point they have only been tested on i.MX6
> processors.
> 
> Yes that's correct. I have not tested imx-media driver on any i.MX5 targets.
> There are likely issues with i.MX5 support.
> 
> >>I am using two ADV7180 analog capture chips, one per CSI port, on this
> display product.
> >>
> >> I have everything initialize successfully at boot, but I am unable to get 
> >> the
> media-ctl command to link the ADV7180 devices to the CSI ports.  I used the
> following website as guidance of how to setup the links between media
> devices:
> >> https://linuxtv.org/downloads/v4l-dvb-apis/v4l-drivers/imx.html
> >>
> >> When trying to link the ADV7180 chip to a CSI port, I use the following
> command and get the result below:
> >>
> >>  media-ctl -v -l "'adv7180 1-0021':0->'ipu1_csi0':0[1]"
> >>
> >>  No link between "adv7180 1-0021":0 and "ipu1_csi0":0
> >>  media_parse_setup_link: Unable to parse link
> >>  Unable to parse link: Invalid argument (22)
> >>
> >> How do I get the ADV7180 and CSI port on the i.MX53 processor to link?
> >>
> >> The difference for the i.MX53 compared to the i.MX6 processor is that
> there is only one IPU and no mipi support, so my device tree does not use
> any video-mux or mux devices.  Could this have something to do with why I
> can't link the ADV7180 to the CSI port?
> 
> It probably does. Clearly there was no media link defined from the adv7180
> to any of the CSI ports, which can also be seen from the media topology you
> printed below.
> 
> As long as the OF graph is correct, I don't see why this would have happened.
> Please send two things:
> 
> 1. Your patches to DT files
> 2. dmesg output.
> 
> There could be more issues with i.MX5 support in imx-media, but it should be
> figured out why the media links from adv7180 to the CSI ports were not
> established first.
> 
> 
> Steve
> 

Steve,

I figured out the linking issue with modifying the imx-media-of.c file in an 
attached patch (imx-media-of-support-imx53-sensor-links.patch). This change 
allowed the linking directly from the ADV7180 to the CSI port.

I also had to make some changes to the imx53.dtsi file to get the imx-capture 
driver to initially work and those changes are also in another attached patch 
(imx53-add-imx-capture-support.patch).  This included adding an alias for ipu0, 
adding the imx-capture-subsystem device, and creating CSI port endpoints.

Additionally I attached my device's shared .dtsi file (pm-041.dtsi) and .dts 
file (cl-711.dts).  In these files you can see I attached CSI0 to ADV7180_0 and 
CSI1 to ADV7180_1.  I am not sure if the imx53 can support two simultaneous 
parallel sensors on both CSI ports at the same time (although this is what I 
would really like), but at this time I would like to get at least one capture 
stream working to start with.

I attached the dmesg output as an attachment after applying my patches 
(dmesg.txt).

I am used to an old 2.6.35 Freescale kernel that supports imx53 video capture 
and I am not familiar with the updated V4L2 media linking and capture of the 
4.15 kernel.  I setup all the links with media-ctl commands and printed the 
topology in the media-ctl_imx53_adv7180.txt file that is attached 
(media-ctl_imx53_adv7180.txt).

I can't seem to get the capture to work, as I always get errors of some sort.  
There are never any errors in dmesg though so the drivers are not throwing 
errors.  Here is the output from gstreamer:
# gst-launch-1.0 -v v4l2src device=/dev/video7 ! autovideosink
Setting pipeline to PAUSED ...
Pipeline is live and does not need PREROLL ...
Setting pipeline to PLAYING ...
New clock: GstSystemClock
ERROR: from element /GstPipeline:pipeline0/GstV4l2Src:v4l2src0: Internal data 
stream error.
Additional debug info:
gstbasesrc.c(2939): gst_base_src_loop (): 
/GstPipeline:pipeline0/GstV4l2Src:v4l2src0:
streaming stopped, reason not-negotiated (-4)
Execution ended after 0:00:00.007445670
Setting pipeline to PAUSED ...
Setting pipeline to READY ...
Setting pipeline to NULL ...
Freeing pipeline ...

Any idea what could be wrong with the capture stream?

Regards,
Matt


imx53-add-imx-capture-support.patch
Description: imx53-add-imx-capture-support.patch


imx-media-of-support-imx53-sensor-links.patch
Description: imx-media-of-support-imx53-sensor-links.patch


pm-041.dtsi
Description: pm-041.dtsi


cl-711.dts
Description: cl-711.dts
# media-ctl -l "'adv7180 1-0020':0->'ipu1_csi0':0[1]"
# media-ctl -l "'ipu1_csi0':1->'ipu1_vdic':0[1]"
# media-ctl -l 

[PATCH v2] [media] Use common error handling code in 20 functions

2018-02-19 Thread SF Markus Elfring
From: Markus Elfring 
Date: Mon, 19 Feb 2018 18:50:40 +0100

Adjust jump targets so that a bit of exception handling can be better
reused at the end of these functions.

This issue was partly detected by using the Coccinelle software.

Signed-off-by: Markus Elfring 
---

v2:
Hans Verkuil insisted on patch squashing. Thus several changes
were recombined based on source files from Linux next-20180216.

The implementation of the function "tda8261_set_params" was improved
after a notification by Christoph Böhmwalder on 2017-09-26.

 drivers/media/dvb-core/dmxdev.c| 16 
 drivers/media/dvb-frontends/tda1004x.c | 20 ++
 drivers/media/dvb-frontends/tda8261.c  | 19 ++
 drivers/media/pci/bt8xx/dst.c  | 19 ++
 drivers/media/pci/bt8xx/dst_ca.c   | 30 +++
 drivers/media/pci/cx88/cx88-input.c| 17 +
 drivers/media/platform/omap3isp/ispvideo.c | 29 +++
 .../media/platform/qcom/camss-8x16/camss-csid.c| 20 +-
 drivers/media/tuners/tuner-xc2028.c| 30 +++
 drivers/media/usb/cpia2/cpia2_usb.c| 13 ---
 drivers/media/usb/gspca/gspca.c| 17 +
 drivers/media/usb/gspca/sn9c20x.c  | 17 +
 drivers/media/usb/pvrusb2/pvrusb2-ioread.c | 10 +++--
 drivers/media/usb/tm6000/tm6000-cards.c|  7 ++--
 drivers/media/usb/tm6000/tm6000-dvb.c  | 11 --
 drivers/media/usb/tm6000/tm6000-video.c| 13 ---
 drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c  | 13 +++
 drivers/media/usb/ttusb-dec/ttusb_dec.c| 43 --
 drivers/media/usb/uvc/uvc_v4l2.c   | 13 ---
 19 files changed, 180 insertions(+), 177 deletions(-)

diff --git a/drivers/media/dvb-core/dmxdev.c b/drivers/media/dvb-core/dmxdev.c
index 6d53af00190e..6a0411c91195 100644
--- a/drivers/media/dvb-core/dmxdev.c
+++ b/drivers/media/dvb-core/dmxdev.c
@@ -645,18 +645,18 @@ static int dvb_dmxdev_start_feed(struct dmxdev *dmxdev,
tsfeed->priv = filter;
 
ret = tsfeed->set(tsfeed, feed->pid, ts_type, ts_pes, timeout);
-   if (ret < 0) {
-   dmxdev->demux->release_ts_feed(dmxdev->demux, tsfeed);
-   return ret;
-   }
+   if (ret < 0)
+   goto release_feed;
 
ret = tsfeed->start_filtering(tsfeed);
-   if (ret < 0) {
-   dmxdev->demux->release_ts_feed(dmxdev->demux, tsfeed);
-   return ret;
-   }
+   if (ret < 0)
+   goto release_feed;
 
return 0;
+
+release_feed:
+   dmxdev->demux->release_ts_feed(dmxdev->demux, tsfeed);
+   return ret;
 }
 
 static int dvb_dmxdev_filter_start(struct dmxdev_filter *filter)
diff --git a/drivers/media/dvb-frontends/tda1004x.c 
b/drivers/media/dvb-frontends/tda1004x.c
index 58e3beff5adc..85ca111fc8c4 100644
--- a/drivers/media/dvb-frontends/tda1004x.c
+++ b/drivers/media/dvb-frontends/tda1004x.c
@@ -1299,20 +1299,22 @@ struct dvb_frontend* tda10045_attach(const struct 
tda1004x_config* config,
id = tda1004x_read_byte(state, TDA1004X_CHIPID);
if (id < 0) {
printk(KERN_ERR "tda10045: chip is not answering. Giving 
up.\n");
-   kfree(state);
-   return NULL;
+   goto free_state;
}
 
if (id != 0x25) {
printk(KERN_ERR "Invalid tda1004x ID = 0x%02x. Can't 
proceed\n", id);
-   kfree(state);
-   return NULL;
+   goto free_state;
}
 
/* create dvb_frontend */
memcpy(>frontend.ops, _ops, sizeof(struct 
dvb_frontend_ops));
state->frontend.demodulator_priv = state;
return >frontend;
+
+free_state:
+   kfree(state);
+   return NULL;
 }
 
 static const struct dvb_frontend_ops tda10046_ops = {
@@ -1369,19 +1371,21 @@ struct dvb_frontend* tda10046_attach(const struct 
tda1004x_config* config,
id = tda1004x_read_byte(state, TDA1004X_CHIPID);
if (id < 0) {
printk(KERN_ERR "tda10046: chip is not answering. Giving 
up.\n");
-   kfree(state);
-   return NULL;
+   goto free_state;
}
if (id != 0x46) {
printk(KERN_ERR "Invalid tda1004x ID = 0x%02x. Can't 
proceed\n", id);
-   kfree(state);
-   return NULL;
+   goto free_state;
}
 
/* create dvb_frontend */
memcpy(>frontend.ops, _ops, sizeof(struct 
dvb_frontend_ops));
state->frontend.demodulator_priv = state;
return >frontend;
+
+free_state:
+   kfree(state);
+   return NULL;
 }
 
 module_param(debug, int, 0644);
diff --git a/drivers/media/dvb-frontends/tda8261.c 
b/drivers/media/dvb-frontends/tda8261.c
index 

Re: Bug: Two device nodes created in /dev for a single UVC webcam

2018-02-19 Thread Alexandre-Xavier Labonté-Lamoureux
Hi Kieran,

This is how I built the drivers:

$ git clone --depth=1 git://linuxtv.org/media_build.git
$ cd media_build
$ ./build --main-git

I then installed the newly built kernel modules:

$ sudo make install

Once the modules were updated, I restarted my computer to make sure
every module got reloaded. I didn't make any changes to the code and I
found the issues after trying each of those programs individually
after I restarted my computer.

This was the latest commit when I cloned the repo:

commit d144cfe4b3c37ece55ae27778c99765d4943c4fa
Author: Jasmin Jessich 
Date:   Fri Feb 16 22:40:49 2018 +0100
Re-generated v3.12_kfifo_in.patch

My version of VLC is 2.2.6. Here's a copy of the relevant data of
VLC's log file in case it can help: https://paste.debian.net/1011025/
In this case, I tried to open /dev/video0 first and /dev/video1 second.

I can also try with ffplay:
$ ffplay /dev/video0

I get this: [video4linux2,v4l2 @ 0x7f216920]
ioctl(VIDIOC_STREAMON): Message too long
/dev/video0: Message too long

A new message appears in dmesg: uvcvideo: Failed to submit URB 0 (-90).

$ ffplay /dev/video1

I get this:
[video4linux2,v4l2 @ 0x7f00ec000920] ioctl(VIDIOC_G_INPUT):
Inappropriate ioctl for device
/dev/video1: Inappropriate ioctl for device

Like Guennadi said, /dev/video1 is a metadata node, so I don't expect
it to work. In the case of /dev/video0, I can't tell what could be
wrong from the error message.

Alexandre-Xavier

On Mon, Feb 19, 2018 at 8:52 AM, Kieran Bingham
 wrote:
> Hi Alexandre,
>
> Thankyou for your bug report,
>
> On 17/02/18 20:47, Alexandre-Xavier Labonté-Lamoureux wrote:
>> Hi,
>>
>> I'm running Linux 4.9.0-5-amd64 on Debian. I built the drivers from
>> the latest git and installed the modules.
>
> Could you please be specific here?
>
> Are you referring to linux-media/master branch or such? The latest from 
> Linus' tree?
>
> Please also detail the steps you have taken to reproduce this issue - and of
> course - if you have made any code changes to make the latest UVC module 
> compile
> against a v4.9 kernel...
>
> Building the latest git tree and installing as a module on a v4.9 kernel is
> quite a leap... I wouldn't have expected that to work.
>
> The code would have to be compiled against a v4.9 kernel directly, and I 
> didn't
> think compiling the UVC driver against older kernels worked.
>
> (at least it didn't work cleanly when I tried to compile v4.15 against a v4.14
> kernel last month)
>
>> Now, two device nodes are
>> created for my webcam. This is not normal as it has never happened to
>> me before. If I connect another webcam to my laptop, two more device
>> nodes will be created for this webcam. So two new device nodes are
>> created for a single webcam.
>
> I believe Guennadi's latest work for handling meta-data (in the latest 
> v4.16-rc1
> I think) will create two device nodes.
>
>
>> The name of my webcam appears twice in the device comobox in Guvcview
>> because of this. One of them will not work if I select it.
>
> It would be expected that only the device with video functions as a streaming
> camera device, while the other would not.
>
>
>> My webcam has completely stopped working with Cheese and VLC.
>
> This part is of particular concern however.
>
> Guennadi - Have you tested Cheese/VLC with your series?
>
> Are there any known issues that need looking at ?
>
>>> v4l2-ctl --list-devices
>> Laptop_Integrated_Webcam_E4HD:  (usb-:00:1a.0-1.5):
>> /dev/video0
>> /dev/video1
>>
>>> ls /dev/video*
>> /dev/video0  /dev/video1
>>
>> Have a nice day,
>> Alexandre-Xavier
>
> Regards
>
> Kieran Bingham
>
>


Re: [PATCH 2/2] media: Add a driver for the ov7251 camera sensor

2018-02-19 Thread Todor Tomov
Hi Jacopo,

On 16.02.2018 12:05, jacopo mondi wrote:
> Hi Todor,
> thanks for the patch.
> 
> Is the datsheet for this sensor public? I failed to find any reference
> to it online, am I wrong?

Thank you for the review!
The datasheet is not public.

> 
> On Thu, Feb 08, 2018 at 10:53:38AM +0200, Todor Tomov wrote:
>> The ov7251 sensor is a 1/7.5-Inch B VGA (640x480) CMOS Digital Image
>> Sensor from Omnivision.
>>
>> The driver supports the following modes:
>> - 640x480 30fps
>> - 640x480 60fps
>> - 640x480 90fps
>>
>> Output format is MIPI RAW 10.
>>
>> The driver supports configuration via user controls for:
>> - exposure and gain;
>> - horizontal and vertical flip;
>> - test pattern.
>>
>> Signed-off-by: Todor Tomov 
>> ---
>>  drivers/media/i2c/Kconfig  |   13 +
>>  drivers/media/i2c/Makefile |1 +
>>  drivers/media/i2c/ov7251.c | 1523 
>> 
>>  3 files changed, 1537 insertions(+)
>>  create mode 100644 drivers/media/i2c/ov7251.c
>>
>> diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
>> index 9f18cd2..bfa9aab 100644
>> --- a/drivers/media/i2c/Kconfig
>> +++ b/drivers/media/i2c/Kconfig
>> @@ -645,6 +645,19 @@ config VIDEO_OV5670
>>To compile this driver as a module, choose M here: the
>>module will be called ov5670.
>>
>> +config VIDEO_OV7251
>> +tristate "OmniVision OV7251 sensor support"
>> +depends on OF
>> +depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
>> +depends on MEDIA_CAMERA_SUPPORT
>> +select V4L2_FWNODE
>> +---help---
>> +  This is a Video4Linux2 sensor-level driver for the OmniVision
>> +  OV7251 camera.
>> +
>> +  To compile this driver as a module, choose M here: the
>> +  module will be called ov7251.
>> +
>>  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 c0f94cd..be6b3d3 100644
>> --- a/drivers/media/i2c/Makefile
>> +++ b/drivers/media/i2c/Makefile
>> @@ -66,6 +66,7 @@ obj-$(CONFIG_VIDEO_OV5645) += ov5645.o
>>  obj-$(CONFIG_VIDEO_OV5647) += ov5647.o
>>  obj-$(CONFIG_VIDEO_OV5670) += ov5670.o
>>  obj-$(CONFIG_VIDEO_OV6650) += ov6650.o
>> +obj-$(CONFIG_VIDEO_OV7251) += ov7251.o
>>  obj-$(CONFIG_VIDEO_OV7640) += ov7640.o
>>  obj-$(CONFIG_VIDEO_OV7670) += ov7670.o
>>  obj-$(CONFIG_VIDEO_OV7740) += ov7740.o
>> diff --git a/drivers/media/i2c/ov7251.c b/drivers/media/i2c/ov7251.c
>> new file mode 100644
>> index 000..f217177
>> --- /dev/null
>> +++ b/drivers/media/i2c/ov7251.c
>> @@ -0,0 +1,1523 @@
>> +/*
>> + * Driver for the OV7251 camera sensor.
>> + *
>> + * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
>> + * Copyright (c) 2017-2018, Linaro Ltd.
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License version 2 and
>> + * only 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.
>> + */
> 
> Please use SPDX identifiers instead of the license text
> 
> // SPDX-License-Identifier: GPL-2.0
> 

Ok.

>> +
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +
>> +#define OV7251_VOLTAGE_ANALOG   280
>> +#define OV7251_VOLTAGE_DIGITAL_CORE 150
>> +#define OV7251_VOLTAGE_DIGITAL_IO   180
>> +
>> +#define OV7251_SC_MODE_SELECT   0x0100
>> +#define OV7251_SC_MODE_SELECT_SW_STANDBY0x0
>> +#define OV7251_SC_MODE_SELECT_STREAMING 0x1
>> +
>> +#define OV7251_CHIP_ID_HIGH 0x300a
>> +#define OV7251_CHIP_ID_HIGH_BYTE0x77
>> +#define OV7251_CHIP_ID_LOW  0x300b
>> +#define OV7251_CHIP_ID_LOW_BYTE 0x50
>> +#define OV7251_SC_GP_IO_IN1 0x3029
>> +#define OV7251_AEC_EXPO_0   0x3500
>> +#define OV7251_AEC_EXPO_1   0x3501
>> +#define OV7251_AEC_EXPO_2   0x3502
>> +#define OV7251_AEC_AGC_ADJ_00x350a
>> +#define OV7251_AEC_AGC_ADJ_10x350b
>> +#define OV7251_TIMING_FORMAT1   0x3820
>> +#define OV7251_SENSOR_VFLIP BIT(2)
>> +#define OV7251_TIMING_FORMAT2   0x3821
>> +#define OV7251_SENSOR_MIRRORBIT(2)
>> +#define OV7251_PRE_ISP_00   0x5e00
>> +#define OV7251_TEST_PATTERN_BAR_ENABLE  BIT(7)
> 
> Are those tabs between the define and the macro name there by purpose?

Yes, but it will be better to 

[PATCH v9 00/11] Renesas Capture Engine Unit (CEU) V4L2 driver

2018-02-19 Thread Jacopo Mondi
Hello,
   finally I addressed Laurent's comment on ov772x frame rate handling, which
I almost forgot about :)

Also, Sergei reported that the ceu node name should be generic, so I changed it
to "ceu: camera@e821".

All patches but the trivial [11/11] one are now reviewed/acked. Hope this is
last iteration for CEU!

Series based on top of Hans':
[PATCHv2 0/9] media: replace g/s_parm by g/s_frame_interval
and makes use of newly introduced v4l2_g/s_parm_cap() functions from v4l2-common
in CEU's g/s_parm() callbacks.

A branch for testing is available at:
git://jmondi.org/linux ceu/media-tree-parm/v9
with few patches for Migo-R and GR-Peach applied on top of Hans' media-tree/parm
branch.

--
Copying from v7 cover letter:

The 2 new patches in the series:
[11/11] has been added to silence a v4l2-compliance error, and modifies
ov7670 driver to set all fields of 'struct v4l2_mbus_format' during set_format
operation, including ycbcr_enc, quantization and xfer_func. As the patch commit
reports, this suppresses the following v4l2-compliance error:
fail: v4l2-test-formats.cpp(335): ycbcr_enc >= 0xff
v8/v9: Did the same for ov772x

[7/11] has been required by Hans to add frame interval handling to ov772x
driver. As this is quite a big change I kept it in a separate patch to ease
review, it can eventually be squashed on [6/11] if accepted.
v8: Calculate PLL divider/multiplier in place of using static tables.
v9: Address Laurent's comment on frame rate handling patch

If for TW9910 video decoder the same is required (frame interval handling) I'm
in favour of moving that driver to staging as it was proposed for ov772x before
this series.

--
v4l2-compliance:

v4l2-compliance requires a fix to relax buffer type check on s/g_parm
(see Hans' "[PATCHv2 9/9] vidioc-g-parm.rst: also allow _MPLANE buffer types")
Issue is addressed by patch
"[PATCH] v4l2-compliance: Relax g/s_parm type check"
just sent to linux-media mailing list.

With that fixed, I have v4l2-compliance exhausting my tiny GR-Peach 6MB of
available system, and thus failing when allocating buffers to test "Buffer
IOCTLs":

renesas-ceu e821.camera: dma_alloc_coherent of size 307200 failed
Unable to request buffers: Cannot allocate memory (12).

Also, Hans, you asked me to run v4l2-compliance with the -f option, I cannot do
that on my tiny GR-Peach as with its limited available system memory it cannot
allocate the number of requested buffers for that test.
I won't stress here why I cannot do that on Migo-R, long story short: I need a
special compiler with DSP support to run anything but the little
initramfs I have received for SH7722. I've been able to tweak yavta to work and
test capture and frame rate handling with it, but v4l2-compliance is much more
complex and I don't think I'll be able run it on that platform.

I have verified capture still works properly in all supported image formats.
Below v4l2-compliance output, with 2 errors due to memory constraints on my
test platform. Hope this won't cause issues with ceu driver acceptance now
that we're so close to have it finalized :)

--
v4l2-compliance SHA   : 372109e86a4de045c642a808fc97b2e7ca5e6c93

Driver Info:
Driver name   : renesas-ceu
Card type : Renesas CEU
Bus info  : platform:renesas-ceu-e821.c
Driver version: 4.15.0
Capabilities  : 0x84201000
Video Capture Multiplanar
Streaming
Extended Pix Format
Device Capabilities
Device Caps   : 0x04201000
Video Capture Multiplanar
Streaming
Extended Pix Format

Compliance test for device /dev/video0 (not using libv4l2):

Required ioctls:
test VIDIOC_QUERYCAP: OK

Allow for multiple opens:
test second video open: OK
test VIDIOC_QUERYCAP: OK
test VIDIOC_G/S_PRIORITY: OK
test for unlimited opens: OK

Debug ioctls:
test VIDIOC_DBG_G/S_REGISTER: OK
test VIDIOC_LOG_STATUS: OK

Input ioctls:
test VIDIOC_G/S_TUNER/ENUM_FREQ_BANDS: OK (Not Supported)
test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
test VIDIOC_S_HW_FREQ_SEEK: OK (Not Supported)
test VIDIOC_ENUMAUDIO: OK (Not Supported)
test VIDIOC_G/S/ENUMINPUT: OK
test VIDIOC_G/S_AUDIO: OK (Not Supported)
Inputs: 1 Audio Inputs: 0 Tuners: 0

Output ioctls:
test VIDIOC_G/S_MODULATOR: OK (Not Supported)
test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
test VIDIOC_ENUMAUDOUT: OK (Not Supported)
test VIDIOC_G/S/ENUMOUTPUT: OK (Not Supported)
test VIDIOC_G/S_AUDOUT: OK (Not Supported)
Outputs: 0 Audio Outputs: 0 Modulators: 0

Input/Output configuration ioctls:
test 

[PATCH v9 02/11] include: media: Add Renesas CEU driver interface

2018-02-19 Thread Jacopo Mondi
Add renesas-ceu header file.

Do not remove the existing sh_mobile_ceu.h one as long as the original
driver does not go away.

Signed-off-by: Jacopo Mondi 
Reviewed-by: Laurent Pinchart 
Acked-by: Hans Verkuil 
---
 include/media/drv-intf/renesas-ceu.h | 26 ++
 1 file changed, 26 insertions(+)
 create mode 100644 include/media/drv-intf/renesas-ceu.h

diff --git a/include/media/drv-intf/renesas-ceu.h 
b/include/media/drv-intf/renesas-ceu.h
new file mode 100644
index 000..52841d1
--- /dev/null
+++ b/include/media/drv-intf/renesas-ceu.h
@@ -0,0 +1,26 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * renesas-ceu.h - Renesas CEU driver interface
+ *
+ * Copyright 2017-2018 Jacopo Mondi 
+ */
+
+#ifndef __MEDIA_DRV_INTF_RENESAS_CEU_H__
+#define __MEDIA_DRV_INTF_RENESAS_CEU_H__
+
+#define CEU_MAX_SUBDEVS2
+
+struct ceu_async_subdev {
+   unsigned long flags;
+   unsigned char bus_width;
+   unsigned char bus_shift;
+   unsigned int i2c_adapter_id;
+   unsigned int i2c_address;
+};
+
+struct ceu_platform_data {
+   unsigned int num_subdevs;
+   struct ceu_async_subdev subdevs[CEU_MAX_SUBDEVS];
+};
+
+#endif /* ___MEDIA_DRV_INTF_RENESAS_CEU_H__ */
-- 
2.7.4



[PATCH v9 01/11] dt-bindings: media: Add Renesas CEU bindings

2018-02-19 Thread Jacopo Mondi
Add bindings documentation for Renesas Capture Engine Unit (CEU).

Signed-off-by: Jacopo Mondi 
Reviewed-by: Rob Herring 
Reviewed-by: Laurent Pinchart 
Acked-by: Hans Verkuil 
---
 .../devicetree/bindings/media/renesas,ceu.txt  | 81 ++
 1 file changed, 81 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/media/renesas,ceu.txt

diff --git a/Documentation/devicetree/bindings/media/renesas,ceu.txt 
b/Documentation/devicetree/bindings/media/renesas,ceu.txt
new file mode 100644
index 000..3fc66df
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/renesas,ceu.txt
@@ -0,0 +1,81 @@
+Renesas Capture Engine Unit (CEU)
+--
+
+The Capture Engine Unit is the image capture interface found in the Renesas
+SH Mobile and RZ SoCs.
+
+The interface supports a single parallel input with data bus width of 8 or 16
+bits.
+
+Required properties:
+- compatible: Shall be "renesas,r7s72100-ceu" for CEU units found in RZ/A1H
+  and RZ/A1M SoCs.
+- reg: Registers address base and size.
+- interrupts: The interrupt specifier.
+
+The CEU supports a single parallel input and should contain a single 'port'
+subnode with a single 'endpoint'. Connection to input devices are modeled
+according to the video interfaces OF bindings specified in:
+Documentation/devicetree/bindings/media/video-interfaces.txt
+
+Optional endpoint properties applicable to parallel input bus described in
+the above mentioned "video-interfaces.txt" file are supported.
+
+- hsync-active: Active state of the HSYNC signal, 0/1 for LOW/HIGH 
respectively.
+  If property is not present, default is active high.
+- vsync-active: Active state of the VSYNC signal, 0/1 for LOW/HIGH 
respectively.
+  If property is not present, default is active high.
+
+Example:
+
+The example describes the connection between the Capture Engine Unit and an
+OV7670 image sensor connected to i2c1 interface.
+
+ceu: ceu@e821 {
+   reg = <0xe821 0x209c>;
+   compatible = "renesas,r7s72100-ceu";
+   interrupts = ;
+
+   pinctrl-names = "default";
+   pinctrl-0 = <_pins>;
+
+   status = "okay";
+
+   port {
+   ceu_in: endpoint {
+   remote-endpoint = <_out>;
+
+   hsync-active = <1>;
+   vsync-active = <0>;
+   };
+   };
+};
+
+i2c1: i2c@fcfee400 {
+   pinctrl-names = "default";
+   pinctrl-0 = <_pins>;
+
+   status = "okay";
+
+   clock-frequency = <10>;
+
+   ov7670: camera@21 {
+   compatible = "ovti,ov7670";
+   reg = <0x21>;
+
+   pinctrl-names = "default";
+   pinctrl-0 = <_pins>;
+
+   reset-gpios = < 11 GPIO_ACTIVE_LOW>;
+   powerdown-gpios = < 12 GPIO_ACTIVE_HIGH>;
+
+   port {
+   ov7670_out: endpoint {
+   remote-endpoint = <_in>;
+
+   hsync-active = <1>;
+   vsync-active = <0>;
+   };
+   };
+   };
+};
-- 
2.7.4



[PATCH v9 03/11] media: platform: Add Renesas CEU driver

2018-02-19 Thread Jacopo Mondi
Add driver for Renesas Capture Engine Unit (CEU).

The CEU interface supports capturing 'data' (YUV422) and 'images'
(NV[12|21|16|61]).

This driver aims to replace the soc_camera-based sh_mobile_ceu one.

Tested with ov7670 camera sensor, providing YUYV_2X8 data on Renesas RZ
platform GR-Peach.

Tested with ov7725 camera sensor on SH4 platform Migo-R.

Signed-off-by: Jacopo Mondi 
Reviewed-by: Laurent Pinchart 
---
 drivers/media/platform/Kconfig   |9 +
 drivers/media/platform/Makefile  |1 +
 drivers/media/platform/renesas-ceu.c | 1661 ++
 3 files changed, 1671 insertions(+)
 create mode 100644 drivers/media/platform/renesas-ceu.c

diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
index 614fbef..f9cc058 100644
--- a/drivers/media/platform/Kconfig
+++ b/drivers/media/platform/Kconfig
@@ -144,6 +144,15 @@ config VIDEO_STM32_DCMI
  To compile this driver as a module, choose M here: the module
  will be called stm32-dcmi.
 
+config VIDEO_RENESAS_CEU
+   tristate "Renesas Capture Engine Unit (CEU) driver"
+   depends on VIDEO_DEV && VIDEO_V4L2 && HAS_DMA
+   depends on ARCH_SHMOBILE || ARCH_R7S72100 || COMPILE_TEST
+   select VIDEOBUF2_DMA_CONTIG
+   select V4L2_FWNODE
+   ---help---
+ This is a v4l2 driver for the Renesas CEU Interface
+
 source "drivers/media/platform/soc_camera/Kconfig"
 source "drivers/media/platform/exynos4-is/Kconfig"
 source "drivers/media/platform/am437x/Kconfig"
diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile
index 7f30804..85e1121 100644
--- a/drivers/media/platform/Makefile
+++ b/drivers/media/platform/Makefile
@@ -62,6 +62,7 @@ obj-$(CONFIG_VIDEO_SH_VOU)+= sh_vou.o
 obj-$(CONFIG_SOC_CAMERA)   += soc_camera/
 
 obj-$(CONFIG_VIDEO_RCAR_DRIF)  += rcar_drif.o
+obj-$(CONFIG_VIDEO_RENESAS_CEU)+= renesas-ceu.o
 obj-$(CONFIG_VIDEO_RENESAS_FCP)+= rcar-fcp.o
 obj-$(CONFIG_VIDEO_RENESAS_FDP1)   += rcar_fdp1.o
 obj-$(CONFIG_VIDEO_RENESAS_JPU)+= rcar_jpu.o
diff --git a/drivers/media/platform/renesas-ceu.c 
b/drivers/media/platform/renesas-ceu.c
new file mode 100644
index 000..d0ac500
--- /dev/null
+++ b/drivers/media/platform/renesas-ceu.c
@@ -0,0 +1,1661 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * V4L2 Driver for Renesas Capture Engine Unit (CEU) interface
+ * Copyright (C) 2017-2018 Jacopo Mondi 
+ *
+ * Based on soc-camera driver "soc_camera/sh_mobile_ceu_camera.c"
+ * Copyright (C) 2008 Magnus Damm
+ *
+ * Based on V4L2 Driver for PXA camera host - "pxa_camera.c",
+ * Copyright (C) 2006, Sascha Hauer, Pengutronix
+ * Copyright (C) 2008, Guennadi Liakhovetski 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#define DRIVER_NAME"renesas-ceu"
+
+/* CEU registers offsets and masks. */
+#define CEU_CAPSR  0x00 /* Capture start register  */
+#define CEU_CAPCR  0x04 /* Capture control register*/
+#define CEU_CAMCR  0x08 /* Capture interface control register  */
+#define CEU_CAMOR  0x10 /* Capture interface offset register   */
+#define CEU_CAPWR  0x14 /* Capture interface width register*/
+#define CEU_CAIFR  0x18 /* Capture interface input format register */
+#define CEU_CRCNTR 0x28 /* CEU register control register   */
+#define CEU_CRCMPR 0x2c /* CEU register forcible control register  */
+#define CEU_CFLCR  0x30 /* Capture filter control register */
+#define CEU_CFSZR  0x34 /* Capture filter size clip register   */
+#define CEU_CDWDR  0x38 /* Capture destination width register  */
+#define CEU_CDAYR  0x3c /* Capture data address Y register */
+#define CEU_CDACR  0x40 /* Capture data address C register */
+#define CEU_CFWCR  0x5c /* Firewall operation control register */
+#define CEU_CDOCR  0x64 /* Capture data output control register*/
+#define CEU_CEIER  0x70 /* Capture event interrupt enable register */
+#define CEU_CETCR  0x74 /* Capture event flag clear register   */
+#define CEU_CSTSR  0x7c /* Capture status register */
+#define CEU_CSRTR  0x80 /* Capture software reset register */
+
+/* Data synchronous fetch mode. */
+#define CEU_CAMCR_JPEG BIT(4)
+
+/* Input components ordering: CEU_CAMCR.DTARY field. */
+#define CEU_CAMCR_DTARY_8_UYVY (0x00 << 8)
+#define CEU_CAMCR_DTARY_8_VYUY (0x01 << 8)
+#define 

[PATCH v9 04/11] ARM: dts: r7s72100: Add Capture Engine Unit (CEU)

2018-02-19 Thread Jacopo Mondi
Add Capture Engine Unit (CEU) node to device tree.

Signed-off-by: Jacopo Mondi 
Reviewed-by: Geert Uytterhoeven 
Reviewed-by: Laurent Pinchart 
Acked-by: Hans Verkuil 
---
 arch/arm/boot/dts/r7s72100.dtsi | 15 ---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/arch/arm/boot/dts/r7s72100.dtsi b/arch/arm/boot/dts/r7s72100.dtsi
index ab9645a..23e05ce 100644
--- a/arch/arm/boot/dts/r7s72100.dtsi
+++ b/arch/arm/boot/dts/r7s72100.dtsi
@@ -135,9 +135,9 @@
#clock-cells = <1>;
compatible = "renesas,r7s72100-mstp-clocks", 
"renesas,cpg-mstp-clocks";
reg = <0xfcfe042c 4>;
-   clocks = <_clk>;
-   clock-indices = ;
-   clock-output-names = "rtc";
+   clocks = <_clk>, <_clk>;
+   clock-indices = ;
+   clock-output-names = "ceu", "rtc";
};
 
mstp7_clks: mstp7_clks@fcfe0430 {
@@ -667,4 +667,13 @@
power-domains = <_clocks>;
status = "disabled";
};
+
+   ceu: camera@e821 {
+   reg = <0xe821 0x3000>;
+   compatible = "renesas,r7s72100-ceu";
+   interrupts = ;
+   clocks = <_clks R7S72100_CLK_CEU>;
+   power-domains = <_clocks>;
+   status = "disabled";
+   };
 };
-- 
2.7.4



[PATCH v9 06/11] media: i2c: ov772x: Remove soc_camera dependencies

2018-02-19 Thread Jacopo Mondi
Remove soc_camera framework dependencies from ov772x sensor driver.
- Handle clock and gpios
- Register async subdevice
- Remove soc_camera specific g/s_mbus_config operations
- Change image format colorspace from JPEG to SRGB as the two use the
  same colorspace information but JPEG makes assumptions on color
  components quantization that do not apply to the sensor
- Remove sizes crop from get_selection as driver can't scale
- Add kernel doc to driver interface header file
- Adjust build system

This commit does not remove the original soc_camera based driver as long
as other platforms depends on soc_camera-based CEU driver.

Signed-off-by: Jacopo Mondi 
Reviewed-by: Laurent Pinchart 
---
 drivers/media/i2c/Kconfig  |  11 +++
 drivers/media/i2c/Makefile |   1 +
 drivers/media/i2c/ov772x.c | 172 ++---
 include/media/i2c/ov772x.h |   6 +-
 4 files changed, 133 insertions(+), 57 deletions(-)

diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
index 9f18cd2..e71e968 100644
--- a/drivers/media/i2c/Kconfig
+++ b/drivers/media/i2c/Kconfig
@@ -645,6 +645,17 @@ config VIDEO_OV5670
  To compile this driver as a module, choose M here: the
  module will be called ov5670.
 
+config VIDEO_OV772X
+   tristate "OmniVision OV772x sensor support"
+   depends on I2C && VIDEO_V4L2
+   depends on MEDIA_CAMERA_SUPPORT
+   ---help---
+ This is a Video4Linux2 sensor-level driver for the OmniVision
+ OV772x camera.
+
+ To compile this driver as a module, choose M here: the
+ module will be called ov772x.
+
 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 c0f94cd..b0489a1 100644
--- a/drivers/media/i2c/Makefile
+++ b/drivers/media/i2c/Makefile
@@ -68,6 +68,7 @@ obj-$(CONFIG_VIDEO_OV5670) += ov5670.o
 obj-$(CONFIG_VIDEO_OV6650) += ov6650.o
 obj-$(CONFIG_VIDEO_OV7640) += ov7640.o
 obj-$(CONFIG_VIDEO_OV7670) += ov7670.o
+obj-$(CONFIG_VIDEO_OV772X) += ov772x.o
 obj-$(CONFIG_VIDEO_OV7740) += ov7740.o
 obj-$(CONFIG_VIDEO_OV9650) += ov9650.o
 obj-$(CONFIG_VIDEO_OV13858) += ov13858.o
diff --git a/drivers/media/i2c/ov772x.c b/drivers/media/i2c/ov772x.c
index 8063835..23106d7 100644
--- a/drivers/media/i2c/ov772x.c
+++ b/drivers/media/i2c/ov772x.c
@@ -1,6 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * ov772x Camera Driver
  *
+ * Copyright (C) 2017 Jacopo Mondi 
+ *
  * Copyright (C) 2008 Renesas Solutions Corp.
  * Kuninori Morimoto 
  *
@@ -9,27 +12,25 @@
  * Copyright 2006-7 Jonathan Corbet 
  * Copyright (C) 2008 Magnus Damm
  * Copyright (C) 2008, Guennadi Liakhovetski 
- *
- * 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 
-#include 
 #include 
-#include 
 #include 
 #include 
 
 #include 
-#include 
-#include 
+
 #include 
-#include 
+#include 
 #include 
+#include 
 
 /*
  * register offset
@@ -393,8 +394,10 @@ struct ov772x_win_size {
 struct ov772x_priv {
struct v4l2_subdevsubdev;
struct v4l2_ctrl_handler  hdl;
-   struct v4l2_clk  *clk;
+   struct clk   *clk;
struct ov772x_camera_info*info;
+   struct gpio_desc *pwdn_gpio;
+   struct gpio_desc *rstb_gpio;
const struct ov772x_color_format *cfmt;
const struct ov772x_win_size *win;
unsigned shortflag_vflip:1;
@@ -409,7 +412,7 @@ struct ov772x_priv {
 static const struct ov772x_color_format ov772x_cfmts[] = {
{
.code   = MEDIA_BUS_FMT_YUYV8_2X8,
-   .colorspace = V4L2_COLORSPACE_JPEG,
+   .colorspace = V4L2_COLORSPACE_SRGB,
.dsp3   = 0x0,
.dsp4   = DSP_OFMT_YUV,
.com3   = SWAP_YUV,
@@ -417,7 +420,7 @@ static const struct ov772x_color_format ov772x_cfmts[] = {
},
{
.code   = MEDIA_BUS_FMT_YVYU8_2X8,
-   .colorspace = V4L2_COLORSPACE_JPEG,
+   .colorspace = V4L2_COLORSPACE_SRGB,
.dsp3   = UV_ON,
.dsp4   = DSP_OFMT_YUV,
.com3   = SWAP_YUV,
@@ -425,7 +428,7 @@ static const struct ov772x_color_format ov772x_cfmts[] = {
},
{
.code   = MEDIA_BUS_FMT_UYVY8_2X8,
-   .colorspace = V4L2_COLORSPACE_JPEG,
+   .colorspace = 

[PATCH v9 07/11] media: i2c: ov772x: Support frame interval handling

2018-02-19 Thread Jacopo Mondi
Add support to ov772x driver for frame intervals handling and enumeration.
Tested with 10MHz and 24MHz input clock at VGA and QVGA resolutions for
10, 15 and 30 frame per second rates.

Signed-off-by: Jacopo Mondi 
Reviewed-by: Laurent Pinchart 
---
 drivers/media/i2c/ov772x.c | 212 +
 1 file changed, 195 insertions(+), 17 deletions(-)

diff --git a/drivers/media/i2c/ov772x.c b/drivers/media/i2c/ov772x.c
index 23106d7..eba71d9 100644
--- a/drivers/media/i2c/ov772x.c
+++ b/drivers/media/i2c/ov772x.c
@@ -250,6 +250,7 @@
 #define AEC_1p2 0x10   /*  01: 1/2  window */
 #define AEC_1p4 0x20   /*  10: 1/4  window */
 #define AEC_2p3 0x30   /*  11: Low 2/3 window */
+#define COM4_RESERVED   0x01   /* Reserved bit */

 /* COM5 */
 #define AFR_ON_OFF  0x80   /* Auto frame rate control ON/OFF selection */
@@ -267,6 +268,10 @@
/* AEC max step control */
 #define AEC_NO_LIMIT0x01   /*   0 : AEC incease step has limit */
/*   1 : No limit to AEC increase step */
+/* CLKRC */
+   /* Input clock divider register */
+#define CLKRC_RESERVED  0x80   /* Reserved bit */
+#define CLKRC_DIV(n)((n) - 1)

 /* COM7 */
/* SCCB Register Reset */
@@ -373,6 +378,19 @@
 #define VERSION(pid, ver) ((pid<<8)|(ver&0xFF))

 /*
+ * PLL multipliers
+ */
+struct {
+   unsigned int mult;
+   u8 com4;
+} ov772x_pll[] = {
+   { 1, PLL_BYPASS, },
+   { 4, PLL_4x, },
+   { 6, PLL_6x, },
+   { 8, PLL_8x, },
+};
+
+/*
  * struct
  */

@@ -388,6 +406,7 @@ struct ov772x_color_format {
 struct ov772x_win_size {
char *name;
unsigned char com7_bit;
+   unsigned int  sizeimage;
struct v4l2_rect  rect;
 };

@@ -404,6 +423,7 @@ struct ov772x_priv {
unsigned shortflag_hflip:1;
/* band_filter = COM8[5] ? 256 - BDBASE : 0 */
unsigned shortband_filter;
+   unsigned int  fps;
 };

 /*
@@ -487,27 +507,35 @@ static const struct ov772x_color_format ov772x_cfmts[] = {

 static const struct ov772x_win_size ov772x_win_sizes[] = {
{
-   .name = "VGA",
-   .com7_bit = SLCT_VGA,
+   .name   = "VGA",
+   .com7_bit   = SLCT_VGA,
+   .sizeimage  = 510 * 748,
.rect = {
-   .left = 140,
-   .top = 14,
-   .width = VGA_WIDTH,
-   .height = VGA_HEIGHT,
+   .left   = 140,
+   .top= 14,
+   .width  = VGA_WIDTH,
+   .height = VGA_HEIGHT,
},
}, {
-   .name = "QVGA",
-   .com7_bit = SLCT_QVGA,
+   .name   = "QVGA",
+   .com7_bit   = SLCT_QVGA,
+   .sizeimage  = 278 * 576,
.rect = {
-   .left = 252,
-   .top = 6,
-   .width = QVGA_WIDTH,
-   .height = QVGA_HEIGHT,
+   .left   = 252,
+   .top= 6,
+   .width  = QVGA_WIDTH,
+   .height = QVGA_HEIGHT,
},
},
 };

 /*
+ * frame rate settings lists
+ */
+unsigned int ov772x_frame_intervals[] = { 5, 10, 15, 20, 30, 60 };
+#define OV772X_N_FRAME_INTERVALS ARRAY_SIZE(ov772x_frame_intervals)
+
+/*
  * general function
  */

@@ -574,6 +602,126 @@ static int ov772x_s_stream(struct v4l2_subdev *sd, int 
enable)
return 0;
 }

+static int ov772x_set_frame_rate(struct ov772x_priv *priv,
+struct v4l2_fract *tpf,
+const struct ov772x_color_format *cfmt,
+const struct ov772x_win_size *win)
+{
+   struct i2c_client *client = v4l2_get_subdevdata(>subdev);
+   unsigned long fin = clk_get_rate(priv->clk);
+   unsigned int fps = tpf->numerator ?
+  tpf->denominator / tpf->numerator :
+  tpf->denominator;
+   unsigned int best_diff;
+   unsigned int fsize;
+   unsigned int pclk;
+   unsigned int diff;
+   unsigned int idx;
+   unsigned int i;
+   u8 clkrc = 0;
+   u8 com4 = 0;
+   int ret;
+
+   /* Approximate to the closest supported frame interval. */
+   best_diff = ~0L;
+   for (i = 0, idx = 0; i < OV772X_N_FRAME_INTERVALS; i++) {
+   diff = abs(fps - ov772x_frame_intervals[i]);
+   if (diff < best_diff) {
+   idx = i;
+   best_diff = diff;
+   }
+   }
+  

[PATCH v9 09/11] media: i2c: tw9910: Remove soc_camera dependencies

2018-02-19 Thread Jacopo Mondi
Remove soc_camera framework dependencies from tw9910 sensor driver.
- Handle clock and gpios
- Register async subdevice
- Remove soc_camera specific g/s_mbus_config operations
- Add kernel doc to driver interface header file
- Adjust build system

This commit does not remove the original soc_camera based driver as long
as other platforms depends on soc_camera-based CEU driver.

Signed-off-by: Jacopo Mondi 
Reviewed-by: Laurent Pinchart 
Acked-by: Hans Verkuil 
---
 drivers/media/i2c/Kconfig  |   9 +++
 drivers/media/i2c/Makefile |   1 +
 drivers/media/i2c/tw9910.c | 162 -
 include/media/i2c/tw9910.h |   9 +++
 4 files changed, 120 insertions(+), 61 deletions(-)

diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
index e71e968..0460613 100644
--- a/drivers/media/i2c/Kconfig
+++ b/drivers/media/i2c/Kconfig
@@ -423,6 +423,15 @@ config VIDEO_TW9906
  To compile this driver as a module, choose M here: the
  module will be called tw9906.
 
+config VIDEO_TW9910
+   tristate "Techwell TW9910 video decoder"
+   depends on VIDEO_V4L2 && I2C
+   ---help---
+ Support for Techwell TW9910 NTSC/PAL/SECAM video decoder.
+
+ To compile this driver as a module, choose M here: the
+ module will be called tw9910.
+
 config VIDEO_VPX3220
tristate "vpx3220a, vpx3216b & vpx3214c video decoders"
depends on VIDEO_V4L2 && I2C
diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile
index b0489a1..23c3ac6 100644
--- a/drivers/media/i2c/Makefile
+++ b/drivers/media/i2c/Makefile
@@ -48,6 +48,7 @@ obj-$(CONFIG_VIDEO_TVP7002) += tvp7002.o
 obj-$(CONFIG_VIDEO_TW2804) += tw2804.o
 obj-$(CONFIG_VIDEO_TW9903) += tw9903.o
 obj-$(CONFIG_VIDEO_TW9906) += tw9906.o
+obj-$(CONFIG_VIDEO_TW9910) += tw9910.o
 obj-$(CONFIG_VIDEO_CS3308) += cs3308.o
 obj-$(CONFIG_VIDEO_CS5345) += cs5345.o
 obj-$(CONFIG_VIDEO_CS53L32A) += cs53l32a.o
diff --git a/drivers/media/i2c/tw9910.c b/drivers/media/i2c/tw9910.c
index bdb5e0a..96792df 100644
--- a/drivers/media/i2c/tw9910.c
+++ b/drivers/media/i2c/tw9910.c
@@ -1,6 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * tw9910 Video Driver
  *
+ * Copyright (C) 2017 Jacopo Mondi 
+ *
  * Copyright (C) 2008 Renesas Solutions Corp.
  * Kuninori Morimoto 
  *
@@ -10,12 +13,10 @@
  * Copyright 2006-7 Jonathan Corbet 
  * Copyright (C) 2008 Magnus Damm
  * Copyright (C) 2008, Guennadi Liakhovetski 
- *
- * 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 
@@ -25,9 +26,7 @@
 #include 
 #include 
 
-#include 
 #include 
-#include 
 #include 
 
 #define GET_ID(val)  ((val & 0xF8) >> 3)
@@ -228,8 +227,10 @@ struct tw9910_scale_ctrl {
 
 struct tw9910_priv {
struct v4l2_subdev  subdev;
-   struct v4l2_clk *clk;
+   struct clk  *clk;
struct tw9910_video_info*info;
+   struct gpio_desc*pdn_gpio;
+   struct gpio_desc*rstb_gpio;
const struct tw9910_scale_ctrl  *scale;
v4l2_std_id norm;
u32 revision;
@@ -582,13 +583,66 @@ static int tw9910_s_register(struct v4l2_subdev *sd,
 }
 #endif
 
+static int tw9910_power_on(struct tw9910_priv *priv)
+{
+   struct i2c_client *client = v4l2_get_subdevdata(>subdev);
+   int ret;
+
+   if (priv->clk) {
+   ret = clk_prepare_enable(priv->clk);
+   if (ret)
+   return ret;
+   }
+
+   if (priv->pdn_gpio) {
+   gpiod_set_value(priv->pdn_gpio, 0);
+   usleep_range(500, 1000);
+   }
+
+   /*
+* FIXME: The reset signal is connected to a shared GPIO on some
+* platforms (namely the SuperH Migo-R). Until a framework becomes
+* available to handle this cleanly, request the GPIO temporarily
+* to avoid conflicts.
+*/
+   priv->rstb_gpio = gpiod_get_optional(>dev, "rstb",
+GPIOD_OUT_LOW);
+   if (IS_ERR(priv->rstb_gpio)) {
+   dev_info(>dev, "Unable to get GPIO \"rstb\"");
+   return PTR_ERR(priv->rstb_gpio);
+   }
+
+   if (priv->rstb_gpio) {
+   gpiod_set_value(priv->rstb_gpio, 1);
+   usleep_range(500, 1000);
+   gpiod_set_value(priv->rstb_gpio, 0);
+   usleep_range(500, 1000);
+
+   gpiod_put(priv->rstb_gpio);
+   }
+
+   return 0;
+}
+
+static int tw9910_power_off(struct tw9910_priv *priv)
+{
+   

[PATCH v9 10/11] arch: sh: migor: Use new renesas-ceu camera driver

2018-02-19 Thread Jacopo Mondi
Migo-R platform uses sh_mobile_ceu camera driver, which is now being
replaced by a proper V4L2 camera driver named 'renesas-ceu'.

Move Migo-R platform to use the v4l2 renesas-ceu camera driver
interface and get rid of soc_camera defined components used to register
sensor drivers and of platform specific enable/disable routines.

Register clock source and GPIOs for sensor drivers, so they can use
clock and gpio APIs.

Also, memory for CEU video buffers is now reserved with membocks APIs,
and need to be declared as dma_coherent during machine initialization to
remove that architecture specific part from CEU driver.

Signed-off-by: Jacopo Mondi 
Reviewed-by: Laurent Pinchart 
Acked-by: Hans Verkuil 
---
 arch/sh/boards/mach-migor/setup.c  | 225 +++--
 arch/sh/kernel/cpu/sh4a/clock-sh7722.c |   2 +-
 2 files changed, 101 insertions(+), 126 deletions(-)

diff --git a/arch/sh/boards/mach-migor/setup.c 
b/arch/sh/boards/mach-migor/setup.c
index 0bcbe58..271dfc2 100644
--- a/arch/sh/boards/mach-migor/setup.c
+++ b/arch/sh/boards/mach-migor/setup.c
@@ -1,17 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Renesas System Solutions Asia Pte. Ltd - Migo-R
  *
  * Copyright (C) 2008 Magnus Damm
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
  */
+#include 
 #include 
 #include 
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -23,10 +22,11 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
-#include 
+#include 
 #include 
 #include 
 #include 
@@ -45,6 +45,9 @@
  * 0x1800   8GB8   NAND Flash (K9K8G08U0A)
  */
 
+#define CEU_BUFFER_MEMORY_SIZE (4 << 20)
+static phys_addr_t ceu_dma_membase;
+
 static struct smc91x_platdata smc91x_info = {
.flags = SMC91X_USE_16BIT | SMC91X_NOWAIT,
 };
@@ -301,65 +304,24 @@ static struct platform_device migor_lcdc_device = {
},
 };
 
-static struct clk *camera_clk;
-static DEFINE_MUTEX(camera_lock);
-
-static void camera_power_on(int is_tw)
-{
-   mutex_lock(_lock);
-
-   /* Use 10 MHz VIO_CKO instead of 24 MHz to work
-* around signal quality issues on Panel Board V2.1.
-*/
-   camera_clk = clk_get(NULL, "video_clk");
-   clk_set_rate(camera_clk, 1000);
-   clk_enable(camera_clk); /* start VIO_CKO */
-
-   /* use VIO_RST to take camera out of reset */
-   mdelay(10);
-   if (is_tw) {
-   gpio_set_value(GPIO_PTT2, 0);
-   gpio_set_value(GPIO_PTT0, 0);
-   } else {
-   gpio_set_value(GPIO_PTT0, 1);
-   }
-   gpio_set_value(GPIO_PTT3, 0);
-   mdelay(10);
-   gpio_set_value(GPIO_PTT3, 1);
-   mdelay(10); /* wait to let chip come out of reset */
-}
-
-static void camera_power_off(void)
-{
-   clk_disable(camera_clk); /* stop VIO_CKO */
-   clk_put(camera_clk);
-
-   gpio_set_value(GPIO_PTT3, 0);
-   mutex_unlock(_lock);
-}
-
-static int ov7725_power(struct device *dev, int mode)
-{
-   if (mode)
-   camera_power_on(0);
-   else
-   camera_power_off();
-
-   return 0;
-}
-
-static int tw9910_power(struct device *dev, int mode)
-{
-   if (mode)
-   camera_power_on(1);
-   else
-   camera_power_off();
-
-   return 0;
-}
-
-static struct sh_mobile_ceu_info sh_mobile_ceu_info = {
-   .flags = SH_CEU_FLAG_USE_8BIT_BUS,
+static struct ceu_platform_data ceu_pdata = {
+   .num_subdevs= 2,
+   .subdevs = {
+   { /* [0] = ov772x */
+   .flags  = 0,
+   .bus_width  = 8,
+   .bus_shift  = 0,
+   .i2c_adapter_id = 0,
+   .i2c_address= 0x21,
+   },
+   { /* [1] = tw9910 */
+   .flags  = 0,
+   .bus_width  = 8,
+   .bus_shift  = 0,
+   .i2c_adapter_id = 0,
+   .i2c_address= 0x45,
+   },
+   },
 };
 
 static struct resource migor_ceu_resources[] = {
@@ -373,18 +335,32 @@ static struct resource migor_ceu_resources[] = {
.start  = evt2irq(0x880),
.flags  = IORESOURCE_IRQ,
},
-   [2] = {
-   /* place holder for contiguous memory */
-   },
 };
 
 static struct platform_device migor_ceu_device = {
-   .name   = "sh_mobile_ceu",
-   .id = 0, /* "ceu0" clock */
+   .name   = "renesas-ceu",
+   .id = 0, /* ceu.0 */
.num_resources  = ARRAY_SIZE(migor_ceu_resources),
.resource   = migor_ceu_resources,
.dev= {
-   

[PATCH v9 08/11] media: i2c: Copy tw9910 soc_camera sensor driver

2018-02-19 Thread Jacopo Mondi
Copy the soc_camera based driver in v4l2 sensor driver directory.
This commit just copies the original file without modifying it.
No modification to KConfig and Makefile as soc_camera framework
dependencies need to be removed first in next commit.

Signed-off-by: Jacopo Mondi 
Acked-by: Laurent Pinchart 
Acked-by: Hans Verkuil 
---
 drivers/media/i2c/tw9910.c | 999 +
 1 file changed, 999 insertions(+)
 create mode 100644 drivers/media/i2c/tw9910.c

diff --git a/drivers/media/i2c/tw9910.c b/drivers/media/i2c/tw9910.c
new file mode 100644
index 000..bdb5e0a
--- /dev/null
+++ b/drivers/media/i2c/tw9910.c
@@ -0,0 +1,999 @@
+/*
+ * tw9910 Video Driver
+ *
+ * Copyright (C) 2008 Renesas Solutions Corp.
+ * Kuninori Morimoto 
+ *
+ * Based on ov772x driver,
+ *
+ * Copyright (C) 2008 Kuninori Morimoto 
+ * Copyright 2006-7 Jonathan Corbet 
+ * Copyright (C) 2008 Magnus Damm
+ * Copyright (C) 2008, Guennadi Liakhovetski 
+ *
+ * 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 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+
+#define GET_ID(val)  ((val & 0xF8) >> 3)
+#define GET_REV(val) (val & 0x07)
+
+/*
+ * register offset
+ */
+#define ID 0x00 /* Product ID Code Register */
+#define STATUS10x01 /* Chip Status Register I */
+#define INFORM 0x02 /* Input Format */
+#define OPFORM 0x03 /* Output Format Control Register */
+#define DLYCTR 0x04 /* Hysteresis and HSYNC Delay Control */
+#define OUTCTR10x05 /* Output Control I */
+#define ACNTL1 0x06 /* Analog Control Register 1 */
+#define CROP_HI0x07 /* Cropping Register, High */
+#define VDELAY_LO  0x08 /* Vertical Delay Register, Low */
+#define VACTIVE_LO 0x09 /* Vertical Active Register, Low */
+#define HDELAY_LO  0x0A /* Horizontal Delay Register, Low */
+#define HACTIVE_LO 0x0B /* Horizontal Active Register, Low */
+#define CNTRL1 0x0C /* Control Register I */
+#define VSCALE_LO  0x0D /* Vertical Scaling Register, Low */
+#define SCALE_HI   0x0E /* Scaling Register, High */
+#define HSCALE_LO  0x0F /* Horizontal Scaling Register, Low */
+#define BRIGHT 0x10 /* BRIGHTNESS Control Register */
+#define CONTRAST   0x11 /* CONTRAST Control Register */
+#define SHARPNESS  0x12 /* SHARPNESS Control Register I */
+#define SAT_U  0x13 /* Chroma (U) Gain Register */
+#define SAT_V  0x14 /* Chroma (V) Gain Register */
+#define HUE0x15 /* Hue Control Register */
+#define CORING10x17
+#define CORING20x18 /* Coring and IF compensation */
+#define VBICNTL0x19 /* VBI Control Register */
+#define ACNTL2 0x1A /* Analog Control 2 */
+#define OUTCTR20x1B /* Output Control 2 */
+#define SDT0x1C /* Standard Selection */
+#define SDTR   0x1D /* Standard Recognition */
+#define TEST   0x1F /* Test Control Register */
+#define CLMPG  0x20 /* Clamping Gain */
+#define IAGC   0x21 /* Individual AGC Gain */
+#define AGCGAIN0x22 /* AGC Gain */
+#define PEAKWT 0x23 /* White Peak Threshold */
+#define CLMPL  0x24 /* Clamp level */
+#define SYNCT  0x25 /* Sync Amplitude */
+#define MISSCNT0x26 /* Sync Miss Count Register */
+#define PCLAMP 0x27 /* Clamp Position Register */
+#define VCNTL1 0x28 /* Vertical Control I */
+#define VCNTL2 0x29 /* Vertical Control II */
+#define CKILL  0x2A /* Color Killer Level Control */
+#define COMB   0x2B /* Comb Filter Control */
+#define LDLY   0x2C /* Luma Delay and H Filter Control */
+#define MISC1  0x2D /* Miscellaneous Control I */
+#define LOOP   0x2E /* LOOP Control Register */
+#define MISC2  0x2F /* Miscellaneous Control II */
+#define MVSN   0x30 /* Macrovision Detection */
+#define STATUS20x31 /* Chip STATUS II */
+#define HFREF  0x32 /* H monitor */
+#define CLMD   0x33 /* CLAMP MODE */
+#define IDCNTL 0x34 /* ID Detection Control */
+#define CLCNTL10x35 /* Clamp Control I */
+#define ANAPLLCTL  0x4C
+#define VBIMIN 0x4D
+#define HSLOWCTL   0x4E
+#define WSS3   0x4F
+#define FILLDATA   0x50
+#define SDID   0x51
+#define DID0x52
+#define WSS1   0x53
+#define WSS2   0x54
+#define VVBI   0x55
+#define LCTL6  0x56
+#define LCTL7  

[PATCH v9 11/11] media: i2c: ov7670: Fully set mbus frame fmt

2018-02-19 Thread Jacopo Mondi
The sensor driver sets mbus format colorspace information and sizes,
but not ycbcr encoding, quantization and xfer function. When supplied
with an badly initialized mbus frame format structure, those fields
need to be set explicitly not to leave them uninitialized. This is
tested by v4l2-compliance, which supplies a mbus format description
structure and checks for all fields to be properly set.

Without this commit, v4l2-compliance fails when testing formats with:
fail: v4l2-test-formats.cpp(335): ycbcr_enc >= 0xff

Signed-off-by: Jacopo Mondi 
---
 drivers/media/i2c/ov7670.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/media/i2c/ov7670.c b/drivers/media/i2c/ov7670.c
index 25b26d4..61c472e 100644
--- a/drivers/media/i2c/ov7670.c
+++ b/drivers/media/i2c/ov7670.c
@@ -996,6 +996,10 @@ static int ov7670_try_fmt_internal(struct v4l2_subdev *sd,
fmt->height = wsize->height;
fmt->colorspace = ov7670_formats[index].colorspace;
 
+   fmt->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
+   fmt->quantization = V4L2_QUANTIZATION_DEFAULT;
+   fmt->xfer_func = V4L2_XFER_FUNC_DEFAULT;
+
info->format = *fmt;
 
return 0;
-- 
2.7.4



[PATCH v9 05/11] media: i2c: Copy ov772x soc_camera sensor driver

2018-02-19 Thread Jacopo Mondi
Copy the soc_camera based driver in v4l2 sensor driver directory.
This commit just copies the original file without modifying it.
No modification to KConfig and Makefile as soc_camera framework
dependencies need to be removed first in next commit.

Signed-off-by: Jacopo Mondi 
Acked-by: Laurent Pinchart 
Acked-by: Hans Verkuil 
---
 drivers/media/i2c/ov772x.c | 1124 
 1 file changed, 1124 insertions(+)
 create mode 100644 drivers/media/i2c/ov772x.c

diff --git a/drivers/media/i2c/ov772x.c b/drivers/media/i2c/ov772x.c
new file mode 100644
index 000..8063835
--- /dev/null
+++ b/drivers/media/i2c/ov772x.c
@@ -0,0 +1,1124 @@
+/*
+ * ov772x Camera Driver
+ *
+ * Copyright (C) 2008 Renesas Solutions Corp.
+ * Kuninori Morimoto 
+ *
+ * Based on ov7670 and soc_camera_platform driver,
+ *
+ * Copyright 2006-7 Jonathan Corbet 
+ * Copyright (C) 2008 Magnus Damm
+ * Copyright (C) 2008, Guennadi Liakhovetski 
+ *
+ * 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 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/*
+ * register offset
+ */
+#define GAIN0x00 /* AGC - Gain control gain setting */
+#define BLUE0x01 /* AWB - Blue channel gain setting */
+#define RED 0x02 /* AWB - Red   channel gain setting */
+#define GREEN   0x03 /* AWB - Green channel gain setting */
+#define COM10x04 /* Common control 1 */
+#define BAVG0x05 /* U/B Average Level */
+#define GAVG0x06 /* Y/Gb Average Level */
+#define RAVG0x07 /* V/R Average Level */
+#define AECH0x08 /* Exposure Value - AEC MSBs */
+#define COM20x09 /* Common control 2 */
+#define PID 0x0A /* Product ID Number MSB */
+#define VER 0x0B /* Product ID Number LSB */
+#define COM30x0C /* Common control 3 */
+#define COM40x0D /* Common control 4 */
+#define COM50x0E /* Common control 5 */
+#define COM60x0F /* Common control 6 */
+#define AEC 0x10 /* Exposure Value */
+#define CLKRC   0x11 /* Internal clock */
+#define COM70x12 /* Common control 7 */
+#define COM80x13 /* Common control 8 */
+#define COM90x14 /* Common control 9 */
+#define COM10   0x15 /* Common control 10 */
+#define REG16   0x16 /* Register 16 */
+#define HSTART  0x17 /* Horizontal sensor size */
+#define HSIZE   0x18 /* Horizontal frame (HREF column) end high 8-bit */
+#define VSTART  0x19 /* Vertical frame (row) start high 8-bit */
+#define VSIZE   0x1A /* Vertical sensor size */
+#define PSHFT   0x1B /* Data format - pixel delay select */
+#define MIDH0x1C /* Manufacturer ID byte - high */
+#define MIDL0x1D /* Manufacturer ID byte - low  */
+#define LAEC0x1F /* Fine AEC value */
+#define COM11   0x20 /* Common control 11 */
+#define BDBASE  0x22 /* Banding filter Minimum AEC value */
+#define DBSTEP  0x23 /* Banding filter Maximum Setp */
+#define AEW 0x24 /* AGC/AEC - Stable operating region (upper limit) */
+#define AEB 0x25 /* AGC/AEC - Stable operating region (lower limit) */
+#define VPT 0x26 /* AGC/AEC Fast mode operating region */
+#define REG28   0x28 /* Register 28 */
+#define HOUTSIZE0x29 /* Horizontal data output size MSBs */
+#define EXHCH   0x2A /* Dummy pixel insert MSB */
+#define EXHCL   0x2B /* Dummy pixel insert LSB */
+#define VOUTSIZE0x2C /* Vertical data output size MSBs */
+#define ADVFL   0x2D /* LSB of insert dummy lines in Vertical direction */
+#define ADVFH   0x2E /* MSG of insert dummy lines in Vertical direction */
+#define YAVE0x2F /* Y/G Channel Average value */
+#define LUMHTH  0x30 /* Histogram AEC/AGC Luminance high level threshold */
+#define LUMLTH  0x31 /* Histogram AEC/AGC Luminance low  level threshold */
+#define HREF0x32 /* Image start and size control */
+#define DM_LNL  0x33 /* Dummy line low  8 bits */
+#define DM_LNH  0x34 /* Dummy line high 8 bits */
+#define ADOFF_B 0x35 /* AD offset compensation value for B  channel */
+#define ADOFF_R 0x36 /* AD offset compensation value for R  channel */
+#define ADOFF_GB0x37 /* AD offset compensation value for Gb channel */
+#define ADOFF_GR0x38 /* AD offset compensation value for Gr channel */
+#define OFF_B   0x39 /* Analog process B  channel offset value */
+#define OFF_R   0x3A /* Analog process R  channel offset value */
+#define OFF_GB  0x3B /* Analog process Gb channel offset value */
+#define OFF_GR  0x3C /* Analog process Gr 

Re: [PATCH] staging: imx-media-vdic: fix inconsistent IS_ERR and PTR_ERR

2018-02-19 Thread Gustavo A. R. Silva

Hi Philipp,

On 02/19/2018 08:23 AM, Philipp Zabel wrote:

Hi Gustavo,

On Wed, 2018-02-14 at 14:57 -0600, Gustavo A. R. Silva wrote:

Hi all,

I was just wondering about the status of this patch.


It is en route as commit dcd71a9292b1 ("staging: imx-media-vdic: fix
inconsistent IS_ERR and PTR_ERR") in Hans' for-v4.17a branch:
   git://linuxtv.org/hverkuil/media_tree.git for-v4.17a



Awesome.

Thanks for the info.
--
Gustavo


[PATCH] v4l2-compliance: Relax g/s_parm type check

2018-02-19 Thread Jacopo Mondi
Since commit

commit 2e564ee56978874ddd4a8d061d37be088f130fd9
Author: Hans Verkuil 
vidioc-g-parm.rst: also allow _MPLANE buffer types

V4L2 allows _MPLANE buffer types for capture/output on s/g_parm
operations.

Relax v4l2-compliance check to comply with this.

Signed-off-by: Jacopo Mondi 
---
 utils/v4l2-compliance/v4l2-test-formats.cpp | 17 ++---
 1 file changed, 14 insertions(+), 3 deletions(-)

diff --git a/utils/v4l2-compliance/v4l2-test-formats.cpp 
b/utils/v4l2-compliance/v4l2-test-formats.cpp
index b7a32fe..25c4da5 100644
--- a/utils/v4l2-compliance/v4l2-test-formats.cpp
+++ b/utils/v4l2-compliance/v4l2-test-formats.cpp
@@ -1235,9 +1235,20 @@ int testParm(struct node *node)
type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE &&
type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
return fail("G/S_PARM is only allowed for video 
capture/output\n");
-   if (!(node->g_caps() & buftype2cap[type]))
-   return fail("%s cap not set, but G/S_PARM 
worked\n",
-   buftype2s(type).c_str());
+
+   if (!((node->g_caps() & V4L2_BUF_TYPE_VIDEO_CAPTURE ||
+   node->g_caps() & 
V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)) &&
+   ((buftype2cap[type] == 
V4L2_BUF_TYPE_VIDEO_CAPTURE ||
+   buftype2cap[type] == 
V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)))
+   return fail("%s cap not set, 
but G/S_PARM worked\n",
+   
buftype2s(type).c_str());
+
+   if (!((node->g_caps() & V4L2_BUF_TYPE_VIDEO_OUTPUT ||
+   node->g_caps() & 
V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)) &&
+   ((buftype2cap[type] == 
V4L2_BUF_TYPE_VIDEO_OUTPUT ||
+   buftype2cap[type] == 
V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)))
+   return fail("%s cap not set, 
but G/S_PARM worked\n",
+   
buftype2s(type).c_str());
}
}

--
2.7.4



Re: [PATCH 1/8] clk: Add clk_bulk_alloc functions

2018-02-19 Thread Robin Murphy

Hi Maciej,

On 19/02/18 15:43, Maciej Purski wrote:

When a driver is going to use clk_bulk_get() function, it has to
initialize an array of clk_bulk_data, by filling its id fields.

Add a new function to the core, which dynamically allocates
clk_bulk_data array and fills its id fields. Add clk_bulk_free()
function, which frees the array allocated by clk_bulk_alloc() function.
Add a managed version of clk_bulk_alloc().


Seeing how every subsequent patch ends up with the roughly this same stanza:

x = devm_clk_bulk_alloc(dev, num, names);
if (IS_ERR(x)
return PTR_ERR(x);
ret = devm_clk_bulk_get(dev, x, num);

I wonder if it might be better to simply implement:

int devm_clk_bulk_alloc_get(dev, , num, names)

that does the whole lot in one go, and let drivers that want to do more 
fiddly things continue to open-code the allocation.


But perhaps that's an abstraction too far... I'm not all that familiar 
with the lie of the land here.



Signed-off-by: Maciej Purski 
---
  drivers/clk/clk-bulk.c   | 16 
  drivers/clk/clk-devres.c | 37 +---
  include/linux/clk.h  | 64 
  3 files changed, 113 insertions(+), 4 deletions(-)



[...]

@@ -598,6 +645,23 @@ struct clk *clk_get_sys(const char *dev_id, const char 
*con_id);
  
  #else /* !CONFIG_HAVE_CLK */
  
+static inline struct clk_bulk_data *clk_bulk_alloc(int num_clks,

+  const char **clk_ids)
+{
+   return NULL;


Either way, is it intentional not returning an ERR_PTR() value in this 
case? Since NULL will pass an IS_ERR() check, it seems a bit fragile for 
an allocation call to apparently succeed when the whole API is 
configured out (and I believe introducing new uses of IS_ERR_OR_NULL() 
is in general strongly discouraged.)


Robin.


+}
+
+static inline struct clk_bulk_data *devm_clk_bulk_alloc(struct device *dev,
+   int num_clks,
+   const char **clk_ids)
+{
+   return NULL;
+}
+
+static inline void clk_bulk_free(struct clk_bulk_data *clks)
+{
+}
+
  static inline struct clk *clk_get(struct device *dev, const char *id)
  {
return NULL;



Re: Bug: Two device nodes created in /dev for a single UVC webcam

2018-02-19 Thread Laurent Pinchart
Hello,

On Monday, 19 February 2018 15:58:40 EET Guennadi Liakhovetski wrote:
> On Mon, 19 Feb 2018, Kieran Bingham wrote:
> > On 17/02/18 20:47, Alexandre-Xavier Labonté-Lamoureux wrote:
> >> Hi,
> >> 
> >> I'm running Linux 4.9.0-5-amd64 on Debian. I built the drivers from
> >> the latest git and installed the modules.
> > 
> > Could you please be specific here?
> > 
> > Are you referring to linux-media/master branch or such? The latest from
> > Linus' tree?
> > 
> > Please also detail the steps you have taken to reproduce this issue - and
> > of course - if you have made any code changes to make the latest UVC
> > module compile against a v4.9 kernel...
> > 
> > Building the latest git tree and installing as a module on a v4.9 kernel
> > is quite a leap... I wouldn't have expected that to work.
> > 
> > The code would have to be compiled against a v4.9 kernel directly, and I
> > didn't think compiling the UVC driver against older kernels worked.
> > 
> > (at least it didn't work cleanly when I tried to compile v4.15 against a
> > v4.14 kernel last month)
> > 
> >> Now, two device nodes are created for my webcam. This is not normal as
> >> it has never happened to me before. If I connect another webcam to my
> >> laptop, two more device nodes will be created for this webcam. So two
> >> new device nodes are created for a single webcam.
> > 
> > I believe Guennadi's latest work for handling meta-data (in the latest
> > v4.16-rc1 I think) will create two device nodes.
> 
> That's correct. The lower index node (/dev/video0) is a video node, the
> higher videoo node (/dev/video1) is a metadata node.
> 
> > > The name of my webcam appears twice in the device comobox in Guvcview
> > > because of this. One of them will not work if I select it.
> > 
> > It would be expected that only the device with video functions as a
> > streaming camera device, while the other would not.
> 
> Exactly.
> 
> > > My webcam has completely stopped working with Cheese and VLC.
> > 
> > This part is of particular concern however.
> > 
> > Guennadi - Have you tested Cheese/VLC with your series?
> 
> Sure, with cheese you can specify which camera you need by using its
> --device= parameter. Eventually it's expected, that those programs will be
> updated to recognise metadata nodes and not attempt to use them.

I've tested VLC (2.2.8) and haven't noticed any issue. If a program is 
directed to the metadata video node and tries to capture video from it it will 
obviously fail. That being said, software that work today should continue 
working, otherwise it's a regression, and we'll have to handle that.

> > Are there any known issues that need looking at ?
> > 
> >>> v4l2-ctl --list-devices
> >> 
> >> Laptop_Integrated_Webcam_E4HD:  (usb-:00:1a.0-1.5):
> >> /dev/video0
> >> /dev/video1
> >>> 
> >>> ls /dev/video*
> >> 
> >> /dev/video0  /dev/video1

-- 
Regards,

Laurent Pinchart



[RESEND PATCH 0/2] DW9807 DT binding and driver patches

2018-02-19 Thread Andy Yeh
From: Alan Chiang 

Hi Sakari and Tomasz,

The two patches are the DT binding and driver for DW9807 VCM controller.

Alan Chiang (2):
  media: dw9807: Add dw9807 vcm driver
  media: dt-bindings: Add bindings for Dongwoon DW9807 voice coil

 .../bindings/media/i2c/dongwoon,dw9807.txt |   9 +
 MAINTAINERS|   7 +
 drivers/media/i2c/Kconfig  |  10 +
 drivers/media/i2c/Makefile |   1 +
 drivers/media/i2c/dw9807.c | 320 +
 5 files changed, 347 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/media/i2c/dongwoon,dw9807.txt
 create mode 100644 drivers/media/i2c/dw9807.c

-- 
2.7.4

>From 9de9f85bbd980fd873c38388cbfbd196ff84a84e Mon Sep 17 00:00:00 2001
From: Alan Chiang 
Date: Tue, 30 Jan 2018 00:28:48 +0800
Subject: [RESEND PATCH 1/2] media: dt-bindings: Add bindings for Dongwoon DW9807
 voice coil

Dongwoon DW9807 is a voice coil lens driver.

Also add a vendor prefix for Dongwoon for one did not exist previously.

Signed-off-by: Andy Yeh 
---
 Documentation/devicetree/bindings/media/i2c/dongwoon,dw9807.txt | 9 +
 1 file changed, 9 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/media/i2c/dongwoon,dw9807.txt

diff --git a/Documentation/devicetree/bindings/media/i2c/dongwoon,dw9807.txt 
b/Documentation/devicetree/bindings/media/i2c/dongwoon,dw9807.txt
new file mode 100644
index 000..0a1a860
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/i2c/dongwoon,dw9807.txt
@@ -0,0 +1,9 @@
+Dongwoon Anatech DW9807 voice coil lens driver
+
+DW9807 is a 10-bit DAC with current sink capability. It is intended for
+controlling voice coil lenses.
+
+Mandatory properties:
+
+- compatible: "dongwoon,dw9807"
+- reg: I2C slave address
-- 
2.7.4

>From 7d84b8eb85989fd55a07f132059a4c56d3131d11 Mon Sep 17 00:00:00 2001
From: Alan Chiang 
Date: Tue, 23 Jan 2018 00:12:25 +0800
Subject: [RESEND PATCH v5 2/2] media: dw9807: Add dw9807 vcm driver

DW9807 is a 10 bit DAC from Dongwoon, designed for linear
control of voice coil motor.

This driver creates a V4L2 subdevice and
provides control to set the desired focus.

Signed-off-by: Andy Yeh 
---
since v1:
- changed author.
since v2:
- addressed outstanding comments.
- enabled sequential write to update 2 registers in a single transaction.
since v3:
- addressed comments for v3.
- Remove redundant codes and declar some variables as constant variable.
- separate DT binding to another patch
since v4:
- Remove unnecessary typecast
- Put the temporary and loop variables in the end of the declaration

 MAINTAINERS|   7 +
 drivers/media/i2c/Kconfig  |  10 ++
 drivers/media/i2c/Makefile |   1 +
 drivers/media/i2c/dw9807.c | 320 +
 4 files changed, 338 insertions(+)
 create mode 100644 drivers/media/i2c/dw9807.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 845fc25..a339bb5 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4385,6 +4385,13 @@ T:   git git://linuxtv.org/media_tree.git
 S: Maintained
 F: drivers/media/i2c/dw9714.c
 
+DONGWOON DW9807 LENS VOICE COIL DRIVER
+M: Sakari Ailus 
+L: linux-media@vger.kernel.org
+T: git git://linuxtv.org/media_tree.git
+S: Maintained
+F: drivers/media/i2c/dw9807.c
+
 DOUBLETALK DRIVER
 M: "James R. Van Zandt" 
 L: blinux-l...@redhat.com
diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
index cb5d7ff..fd01842 100644
--- a/drivers/media/i2c/Kconfig
+++ b/drivers/media/i2c/Kconfig
@@ -325,6 +325,16 @@ config VIDEO_DW9714
  capability. This is designed for linear control of
  voice coil motors, controlled via I2C serial interface.
 
+config VIDEO_DW9807
+   tristate "DW9807 lens voice coil support"
+   depends on I2C && VIDEO_V4L2 && MEDIA_CONTROLLER
+   depends on VIDEO_V4L2_SUBDEV_API
+   ---help---
+ This is a driver for the DW9807 camera lens voice coil.
+ DW9807 is a 10 bit DAC with 100mA output current sink
+ capability. This is designed for linear control of
+ voice coil motors, controlled via I2C serial interface.
+
 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 548a9ef..1b62639 100644
--- a/drivers/media/i2c/Makefile
+++ b/drivers/media/i2c/Makefile
@@ -23,6 +23,7 @@ obj-$(CONFIG_VIDEO_SAA7185) += saa7185.o
 obj-$(CONFIG_VIDEO_SAA6752HS) += saa6752hs.o
 obj-$(CONFIG_VIDEO_AD5820)  += ad5820.o
 obj-$(CONFIG_VIDEO_DW9714)  += dw9714.o
+obj-$(CONFIG_VIDEO_DW9807)  += dw9807.o
 obj-$(CONFIG_VIDEO_ADV7170) += adv7170.o
 obj-$(CONFIG_VIDEO_ADV7175) += adv7175.o
 obj-$(CONFIG_VIDEO_ADV7180) += 

[PATCH 3/8] drm/exynos/decon: Use clk bulk API

2018-02-19 Thread Maciej Purski
Using bulk clk functions simplifies the driver's code. Use devm_clk_bulk
functions instead of iterating over an array of clks.

Signed-off-by: Maciej Purski 
---
 drivers/gpu/drm/exynos/exynos5433_drm_decon.c | 50 ---
 1 file changed, 15 insertions(+), 35 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c 
b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c
index 1c330f2..1760fcb 100644
--- a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c
+++ b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c
@@ -55,7 +55,7 @@ struct decon_context {
struct exynos_drm_plane_config  configs[WINDOWS_NR];
void __iomem*addr;
struct regmap   *sysreg;
-   struct clk  *clks[ARRAY_SIZE(decon_clks_name)];
+   struct clk_bulk_data*clks;
unsigned intirq;
unsigned intirq_vsync;
unsigned intirq_lcd_sys;
@@ -485,15 +485,13 @@ static irqreturn_t decon_te_irq_handler(int irq, void 
*dev_id)
 static void decon_clear_channels(struct exynos_drm_crtc *crtc)
 {
struct decon_context *ctx = crtc->ctx;
-   int win, i, ret;
+   int win, ret;
 
DRM_DEBUG_KMS("%s\n", __FILE__);
 
-   for (i = 0; i < ARRAY_SIZE(decon_clks_name); i++) {
-   ret = clk_prepare_enable(ctx->clks[i]);
-   if (ret < 0)
-   goto err;
-   }
+   ret = clk_bulk_prepare_enable(ARRAY_SIZE(decon_clks_name), ctx->clks);
+   if (ret < 0)
+   return;
 
decon_shadow_protect(ctx, true);
for (win = 0; win < WINDOWS_NR; win++)
@@ -504,10 +502,6 @@ static void decon_clear_channels(struct exynos_drm_crtc 
*crtc)
 
/* TODO: wait for possible vsync */
msleep(50);
-
-err:
-   while (--i >= 0)
-   clk_disable_unprepare(ctx->clks[i]);
 }
 
 static enum drm_mode_status decon_mode_valid(struct exynos_drm_crtc *crtc,
@@ -638,10 +632,8 @@ static irqreturn_t decon_irq_handler(int irq, void *dev_id)
 static int exynos5433_decon_suspend(struct device *dev)
 {
struct decon_context *ctx = dev_get_drvdata(dev);
-   int i = ARRAY_SIZE(decon_clks_name);
 
-   while (--i >= 0)
-   clk_disable_unprepare(ctx->clks[i]);
+   clk_bulk_disable_unprepare(ARRAY_SIZE(decon_clks_name), ctx->clks);
 
return 0;
 }
@@ -649,19 +641,9 @@ static int exynos5433_decon_suspend(struct device *dev)
 static int exynos5433_decon_resume(struct device *dev)
 {
struct decon_context *ctx = dev_get_drvdata(dev);
-   int i, ret;
-
-   for (i = 0; i < ARRAY_SIZE(decon_clks_name); i++) {
-   ret = clk_prepare_enable(ctx->clks[i]);
-   if (ret < 0)
-   goto err;
-   }
-
-   return 0;
+   int ret;
 
-err:
-   while (--i >= 0)
-   clk_disable_unprepare(ctx->clks[i]);
+   ret = clk_bulk_prepare_enable(ARRAY_SIZE(decon_clks_name), ctx->clks);
 
return ret;
 }
@@ -719,7 +701,6 @@ static int exynos5433_decon_probe(struct platform_device 
*pdev)
struct decon_context *ctx;
struct resource *res;
int ret;
-   int i;
 
ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
if (!ctx)
@@ -732,15 +713,14 @@ static int exynos5433_decon_probe(struct platform_device 
*pdev)
if (ctx->out_type & IFTYPE_HDMI)
ctx->first_win = 1;
 
-   for (i = 0; i < ARRAY_SIZE(decon_clks_name); i++) {
-   struct clk *clk;
-
-   clk = devm_clk_get(ctx->dev, decon_clks_name[i]);
-   if (IS_ERR(clk))
-   return PTR_ERR(clk);
+   ctx->clks = devm_clk_bulk_alloc(dev, ARRAY_SIZE(decon_clks_name),
+   decon_clks_name);
+   if (IS_ERR(ctx->clks))
+   return PTR_ERR(ctx->clks);
 
-   ctx->clks[i] = clk;
-   }
+   ret = devm_clk_bulk_get(dev, ARRAY_SIZE(decon_clks_name), ctx->clks);
+   if (ret < 0)
+   return ret;
 
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
ctx->addr = devm_ioremap_resource(dev, res);
-- 
2.7.4



[PATCH 4/8] drm/exynos/dsi: Use clk bulk API

2018-02-19 Thread Maciej Purski
Using bulk clk functions simplifies the driver's code. Use devm_clk_bulk
functions instead of iterating over an array of clks.

In order to achieve consistency with other drivers, define clock names
in driver's variants structures.

Signed-off-by: Maciej Purski 
---
 drivers/gpu/drm/exynos/exynos_drm_dsi.c | 68 +++--
 1 file changed, 30 insertions(+), 38 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c 
b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index 7904ffa..46a8b5c 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -209,11 +209,7 @@
 #define DSI_XFER_TIMEOUT_MS100
 #define DSI_RX_FIFO_EMPTY  0x3082
 
-#define OLD_SCLK_MIPI_CLK_NAME "pll_clk"
-
-static char *clk_names[5] = { "bus_clk", "sclk_mipi",
-   "phyclk_mipidphy0_bitclkdiv8", "phyclk_mipidphy0_rxclkesc0",
-   "sclk_rgb_vclk_to_dsim0" };
+#define DSI_MAX_CLOCKS 5
 
 enum exynos_dsi_transfer_type {
EXYNOS_DSI_TX,
@@ -243,6 +239,7 @@ struct exynos_dsi_driver_data {
unsigned int plltmr_reg;
unsigned int has_freqband:1;
unsigned int has_clklane_stop:1;
+   const char *clock_names[DSI_MAX_CLOCKS];
unsigned int num_clks;
unsigned int max_freq;
unsigned int wait_for_reset;
@@ -259,7 +256,7 @@ struct exynos_dsi {
 
void __iomem *reg_base;
struct phy *phy;
-   struct clk **clks;
+   struct clk_bulk_data *clks;
struct regulator_bulk_data supplies[2];
int irq;
int te_gpio;
@@ -453,6 +450,7 @@ static const struct exynos_dsi_driver_data 
exynos3_dsi_driver_data = {
.plltmr_reg = 0x50,
.has_freqband = 1,
.has_clklane_stop = 1,
+   .clock_names = {"bus_clk", "pll_clk"},
.num_clks = 2,
.max_freq = 1000,
.wait_for_reset = 1,
@@ -465,6 +463,7 @@ static const struct exynos_dsi_driver_data 
exynos4_dsi_driver_data = {
.plltmr_reg = 0x50,
.has_freqband = 1,
.has_clklane_stop = 1,
+   .clock_names = {"bus_clk", "sclk_mipi"},
.num_clks = 2,
.max_freq = 1000,
.wait_for_reset = 1,
@@ -475,6 +474,7 @@ static const struct exynos_dsi_driver_data 
exynos4_dsi_driver_data = {
 static const struct exynos_dsi_driver_data exynos5_dsi_driver_data = {
.reg_ofs = exynos_reg_ofs,
.plltmr_reg = 0x58,
+   .clock_names = {"bus_clk", "pll_clk"},
.num_clks = 2,
.max_freq = 1000,
.wait_for_reset = 1,
@@ -486,6 +486,10 @@ static const struct exynos_dsi_driver_data 
exynos5433_dsi_driver_data = {
.reg_ofs = exynos5433_reg_ofs,
.plltmr_reg = 0xa0,
.has_clklane_stop = 1,
+   .clock_names = {"bus_clk", "phyclk_mipidphy0_bitclkdiv8",
+   "phyclk_mipidphy0_rxclkesc0",
+   "sclk_rgb_vclk_to_dsim0",
+   "sclk_mipi"},
.num_clks = 5,
.max_freq = 1500,
.wait_for_reset = 0,
@@ -497,6 +501,7 @@ static const struct exynos_dsi_driver_data 
exynos5422_dsi_driver_data = {
.reg_ofs = exynos5433_reg_ofs,
.plltmr_reg = 0xa0,
.has_clklane_stop = 1,
+   .clock_names = {"bus_clk", "pll_clk"},
.num_clks = 2,
.max_freq = 1500,
.wait_for_reset = 1,
@@ -1711,7 +1716,7 @@ static int exynos_dsi_probe(struct platform_device *pdev)
struct device *dev = >dev;
struct resource *res;
struct exynos_dsi *dsi;
-   int ret, i;
+   int ret;
 
dsi = devm_kzalloc(dev, sizeof(*dsi), GFP_KERNEL);
if (!dsi)
@@ -1743,26 +1748,15 @@ static int exynos_dsi_probe(struct platform_device 
*pdev)
return -EPROBE_DEFER;
}
 
-   dsi->clks = devm_kzalloc(dev,
-   sizeof(*dsi->clks) * dsi->driver_data->num_clks,
-   GFP_KERNEL);
-   if (!dsi->clks)
-   return -ENOMEM;
+   dsi->clks = devm_clk_bulk_alloc(dev, dsi->driver_data->num_clks,
+   dsi->driver_data->clock_names);
+   if (IS_ERR(dsi->clks))
+   return PTR_ERR(dsi->clks);
 
-   for (i = 0; i < dsi->driver_data->num_clks; i++) {
-   dsi->clks[i] = devm_clk_get(dev, clk_names[i]);
-   if (IS_ERR(dsi->clks[i])) {
-   if (strcmp(clk_names[i], "sclk_mipi") == 0) {
-   strcpy(clk_names[i], OLD_SCLK_MIPI_CLK_NAME);
-   i--;
-   continue;
-   }
-
-   dev_info(dev, "failed to get the clock: %s\n",
-   clk_names[i]);
-   return PTR_ERR(dsi->clks[i]);
-   }
-   }
+   ret = devm_clk_bulk_get(dev, dsi->driver_data->num_clks,
+   dsi->clks);
+   if (ret < 0)
+ 

[PATCH 5/8] drm/exynos: mic: Use clk bulk API

2018-02-19 Thread Maciej Purski
Using bulk clk functions simplifies the driver's code. Use devm_clk_bulk
functions instead of iterating over an array of clks.

Signed-off-by: Maciej Purski 
---
 drivers/gpu/drm/exynos/exynos_drm_mic.c | 41 +++--
 1 file changed, 14 insertions(+), 27 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_mic.c 
b/drivers/gpu/drm/exynos/exynos_drm_mic.c
index 2174814..276558a 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_mic.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_mic.c
@@ -88,7 +88,7 @@
 
 #define MIC_BS_SIZE_2D(x)  ((x) & 0x3fff)
 
-static char *clk_names[] = { "pclk_mic0", "sclk_rgb_vclk_to_mic0" };
+static const char *const clk_names[] = { "pclk_mic0", "sclk_rgb_vclk_to_mic0" 
};
 #define NUM_CLKS   ARRAY_SIZE(clk_names)
 static DEFINE_MUTEX(mic_mutex);
 
@@ -96,7 +96,7 @@ struct exynos_mic {
struct device *dev;
void __iomem *reg;
struct regmap *sysreg;
-   struct clk *clks[NUM_CLKS];
+   struct clk_bulk_data *clks;
 
bool i80_mode;
struct videomode vm;
@@ -338,10 +338,8 @@ static const struct component_ops exynos_mic_component_ops 
= {
 static int exynos_mic_suspend(struct device *dev)
 {
struct exynos_mic *mic = dev_get_drvdata(dev);
-   int i;
 
-   for (i = NUM_CLKS - 1; i > -1; i--)
-   clk_disable_unprepare(mic->clks[i]);
+   clk_bulk_disable_unprepare(NUM_CLKS, mic->clks);
 
return 0;
 }
@@ -349,19 +347,8 @@ static int exynos_mic_suspend(struct device *dev)
 static int exynos_mic_resume(struct device *dev)
 {
struct exynos_mic *mic = dev_get_drvdata(dev);
-   int ret, i;
-
-   for (i = 0; i < NUM_CLKS; i++) {
-   ret = clk_prepare_enable(mic->clks[i]);
-   if (ret < 0) {
-   DRM_ERROR("Failed to enable clock (%s)\n",
-   clk_names[i]);
-   while (--i > -1)
-   clk_disable_unprepare(mic->clks[i]);
-   return ret;
-   }
-   }
-   return 0;
+
+   return clk_bulk_prepare_enable(NUM_CLKS, mic->clks);
 }
 #endif
 
@@ -374,7 +361,7 @@ static int exynos_mic_probe(struct platform_device *pdev)
struct device *dev = >dev;
struct exynos_mic *mic;
struct resource res;
-   int ret, i;
+   int ret;
 
mic = devm_kzalloc(dev, sizeof(*mic), GFP_KERNEL);
if (!mic) {
@@ -405,16 +392,16 @@ static int exynos_mic_probe(struct platform_device *pdev)
goto err;
}
 
-   for (i = 0; i < NUM_CLKS; i++) {
-   mic->clks[i] = devm_clk_get(dev, clk_names[i]);
-   if (IS_ERR(mic->clks[i])) {
-   DRM_ERROR("mic: Failed to get clock (%s)\n",
-   clk_names[i]);
-   ret = PTR_ERR(mic->clks[i]);
-   goto err;
-   }
+   mic->clks = devm_clk_bulk_alloc(dev, NUM_CLKS, clk_names);
+   if (IS_ERR(mic->clks)) {
+   ret = PTR_ERR(mic->clks);
+   goto err;
}
 
+   ret = devm_clk_bulk_get(dev, NUM_CLKS, mic->clks);
+   if (ret < 0)
+   goto err;
+
platform_set_drvdata(pdev, mic);
 
mic->bridge.funcs = _bridge_funcs;
-- 
2.7.4



[PATCH 7/8] [media] exynos-gsc: Use clk bulk API

2018-02-19 Thread Maciej Purski
Using bulk clk functions simplifies the driver's code. Use devm_clk_bulk
functions instead of iterating over an array of clks.

Signed-off-by: Maciej Purski 
---
 drivers/media/platform/exynos-gsc/gsc-core.c | 55 ++--
 drivers/media/platform/exynos-gsc/gsc-core.h |  2 +-
 2 files changed, 20 insertions(+), 37 deletions(-)

diff --git a/drivers/media/platform/exynos-gsc/gsc-core.c 
b/drivers/media/platform/exynos-gsc/gsc-core.c
index 17854a3..fa7e993 100644
--- a/drivers/media/platform/exynos-gsc/gsc-core.c
+++ b/drivers/media/platform/exynos-gsc/gsc-core.c
@@ -1149,7 +1149,6 @@ static int gsc_probe(struct platform_device *pdev)
struct device *dev = >dev;
const struct gsc_driverdata *drv_data = of_device_get_match_data(dev);
int ret;
-   int i;
 
gsc = devm_kzalloc(dev, sizeof(struct gsc_dev), GFP_KERNEL);
if (!gsc)
@@ -1187,25 +1186,19 @@ static int gsc_probe(struct platform_device *pdev)
return -ENXIO;
}
 
-   for (i = 0; i < gsc->num_clocks; i++) {
-   gsc->clock[i] = devm_clk_get(dev, drv_data->clk_names[i]);
-   if (IS_ERR(gsc->clock[i])) {
-   dev_err(dev, "failed to get clock: %s\n",
-   drv_data->clk_names[i]);
-   return PTR_ERR(gsc->clock[i]);
-   }
-   }
+   gsc->clocks = devm_clk_bulk_alloc(dev, gsc->num_clocks,
+ drv_data->clk_names);
+   if (IS_ERR(gsc->clocks))
+   return PTR_ERR(gsc->clocks);
 
-   for (i = 0; i < gsc->num_clocks; i++) {
-   ret = clk_prepare_enable(gsc->clock[i]);
-   if (ret) {
-   dev_err(dev, "clock prepare failed for clock: %s\n",
-   drv_data->clk_names[i]);
-   while (--i >= 0)
-   clk_disable_unprepare(gsc->clock[i]);
-   return ret;
-   }
-   }
+   ret = devm_clk_bulk_get(dev, gsc->num_clocks,
+   gsc->clocks);
+   if (ret)
+   return ret;
+
+   ret = clk_bulk_prepare_enable(gsc->num_clocks, gsc->clocks);
+   if (ret)
+   return ret;
 
ret = devm_request_irq(dev, res->start, gsc_irq_handler,
0, pdev->name, gsc);
@@ -1239,15 +1232,14 @@ static int gsc_probe(struct platform_device *pdev)
 err_v4l2:
v4l2_device_unregister(>v4l2_dev);
 err_clk:
-   for (i = gsc->num_clocks - 1; i >= 0; i--)
-   clk_disable_unprepare(gsc->clock[i]);
+   clk_bulk_disable_unprepare(gsc->num_clocks, gsc->clocks);
+
return ret;
 }
 
 static int gsc_remove(struct platform_device *pdev)
 {
struct gsc_dev *gsc = platform_get_drvdata(pdev);
-   int i;
 
pm_runtime_get_sync(>dev);
 
@@ -1255,8 +1247,7 @@ static int gsc_remove(struct platform_device *pdev)
v4l2_device_unregister(>v4l2_dev);
 
vb2_dma_contig_clear_max_seg_size(>dev);
-   for (i = 0; i < gsc->num_clocks; i++)
-   clk_disable_unprepare(gsc->clock[i]);
+   clk_bulk_disable_unprepare(gsc->num_clocks, gsc->clocks);
 
pm_runtime_put_noidle(>dev);
pm_runtime_disable(>dev);
@@ -1307,18 +1298,12 @@ static int gsc_runtime_resume(struct device *dev)
 {
struct gsc_dev *gsc = dev_get_drvdata(dev);
int ret = 0;
-   int i;
 
pr_debug("gsc%d: state: 0x%lx\n", gsc->id, gsc->state);
 
-   for (i = 0; i < gsc->num_clocks; i++) {
-   ret = clk_prepare_enable(gsc->clock[i]);
-   if (ret) {
-   while (--i >= 0)
-   clk_disable_unprepare(gsc->clock[i]);
-   return ret;
-   }
-   }
+   ret = clk_bulk_prepare_enable(gsc->num_clocks, gsc->clocks);
+   if (ret)
+   return ret;
 
gsc_hw_set_sw_reset(gsc);
gsc_wait_reset(gsc);
@@ -1331,14 +1316,12 @@ static int gsc_runtime_suspend(struct device *dev)
 {
struct gsc_dev *gsc = dev_get_drvdata(dev);
int ret = 0;
-   int i;
 
ret = gsc_m2m_suspend(gsc);
if (ret)
return ret;
 
-   for (i = gsc->num_clocks - 1; i >= 0; i--)
-   clk_disable_unprepare(gsc->clock[i]);
+   clk_bulk_disable_unprepare(gsc->num_clocks, gsc->clocks);
 
pr_debug("gsc%d: state: 0x%lx\n", gsc->id, gsc->state);
return ret;
diff --git a/drivers/media/platform/exynos-gsc/gsc-core.h 
b/drivers/media/platform/exynos-gsc/gsc-core.h
index 715d9c9d..08ff7b9 100644
--- a/drivers/media/platform/exynos-gsc/gsc-core.h
+++ b/drivers/media/platform/exynos-gsc/gsc-core.h
@@ -334,7 +334,7 @@ struct gsc_dev {
struct gsc_variant  *variant;
u16 id;
int 

[PATCH 0/8] Use clk bulk API in exynos5433 drivers

2018-02-19 Thread Maciej Purski
Hi all,

the main goal of this patchset is to simplify clk management code in
exynos5433 drivers by using clk bulk API. In order to achieve that,
patch #1 adds a new function to clk core, which dynamically allocates
clk_bulk_data array and fills its id fields.

Best regards,

Maciej Purski

Maciej Purski (8):
  clk: Add clk_bulk_alloc functions
  media: s5p-jpeg: Use bulk clk API
  drm/exynos/decon: Use clk bulk API
  drm/exynos/dsi: Use clk bulk API
  drm/exynos: mic: Use clk bulk API
  drm/exynos/hdmi: Use clk bulk API
  [media] exynos-gsc: Use clk bulk API
  [media] s5p-mfc: Use clk bulk API

 drivers/clk/clk-bulk.c  | 16 +
 drivers/clk/clk-devres.c| 37 +--
 drivers/gpu/drm/exynos/exynos5433_drm_decon.c   | 50 +--
 drivers/gpu/drm/exynos/exynos_drm_dsi.c | 68 +---
 drivers/gpu/drm/exynos/exynos_drm_mic.c | 44 +
 drivers/gpu/drm/exynos/exynos_hdmi.c| 85 -
 drivers/media/platform/exynos-gsc/gsc-core.c| 55 ++--
 drivers/media/platform/exynos-gsc/gsc-core.h|  2 +-
 drivers/media/platform/s5p-jpeg/jpeg-core.c | 45 ++---
 drivers/media/platform/s5p-jpeg/jpeg-core.h |  2 +-
 drivers/media/platform/s5p-mfc/s5p_mfc_common.h |  6 +-
 drivers/media/platform/s5p-mfc/s5p_mfc_pm.c | 41 +---
 include/linux/clk.h | 64 +++
 13 files changed, 263 insertions(+), 252 deletions(-)

-- 
2.7.4



[PATCH 6/8] drm/exynos/hdmi: Use clk bulk API

2018-02-19 Thread Maciej Purski
Using bulk clk functions simplifies the driver's code. Use devm_clk_bulk
functions instead of iterating over an array of clks.

Signed-off-by: Maciej Purski 
---
 drivers/gpu/drm/exynos/exynos_hdmi.c | 97 ++--
 1 file changed, 27 insertions(+), 70 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c 
b/drivers/gpu/drm/exynos/exynos_hdmi.c
index a4b75a4..6c208f7 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -136,8 +136,8 @@ struct hdmi_context {
int irq;
struct regmap   *pmureg;
struct regmap   *sysreg;
-   struct clk  **clk_gates;
-   struct clk  **clk_muxes;
+   struct clk_bulk_data*clk_gates;
+   struct clk_bulk_data*clk_muxes;
struct regulator_bulk_data  regul_bulk[ARRAY_SIZE(supply)];
struct regulator*reg_hdmi_en;
struct exynos_drm_clk   phy_clk;
@@ -739,43 +739,16 @@ static int hdmiphy_reg_write_buf(struct hdmi_context 
*hdata,
}
 }
 
-static int hdmi_clk_enable_gates(struct hdmi_context *hdata)
-{
-   int i, ret;
-
-   for (i = 0; i < hdata->drv_data->clk_gates.count; ++i) {
-   ret = clk_prepare_enable(hdata->clk_gates[i]);
-   if (!ret)
-   continue;
-
-   dev_err(hdata->dev, "Cannot enable clock '%s', %d\n",
-   hdata->drv_data->clk_gates.data[i], ret);
-   while (i--)
-   clk_disable_unprepare(hdata->clk_gates[i]);
-   return ret;
-   }
-
-   return 0;
-}
-
-static void hdmi_clk_disable_gates(struct hdmi_context *hdata)
-{
-   int i = hdata->drv_data->clk_gates.count;
-
-   while (i--)
-   clk_disable_unprepare(hdata->clk_gates[i]);
-}
-
 static int hdmi_clk_set_parents(struct hdmi_context *hdata, bool to_phy)
 {
struct device *dev = hdata->dev;
int ret = 0;
+   struct clk_bulk_data *clk_muxes = hdata->clk_muxes;
int i;
 
for (i = 0; i < hdata->drv_data->clk_muxes.count; i += 3) {
-   struct clk **c = >clk_muxes[i];
-
-   ret = clk_set_parent(c[2], c[to_phy]);
+   ret = clk_set_parent(clk_muxes[i + 2].clk,
+clk_muxes[i + to_phy].clk);
if (!ret)
continue;
 
@@ -1655,54 +1628,36 @@ static irqreturn_t hdmi_irq_thread(int irq, void *arg)
return IRQ_HANDLED;
 }
 
-static int hdmi_clks_get(struct hdmi_context *hdata,
-const struct string_array_spec *names,
-struct clk **clks)
+static struct clk_bulk_data *hdmi_clks_alloc_get(struct hdmi_context *hdata,
+   const struct string_array_spec *names)
 {
-   struct device *dev = hdata->dev;
-   int i;
-
-   for (i = 0; i < names->count; ++i) {
-   struct clk *clk = devm_clk_get(dev, names->data[i]);
-
-   if (IS_ERR(clk)) {
-   int ret = PTR_ERR(clk);
+   struct clk_bulk_data *ptr;
+   int ret;
 
-   dev_err(dev, "Cannot get clock %s, %d\n",
-   names->data[i], ret);
+   ptr = devm_clk_bulk_alloc(hdata->dev, names->count, names->data);
+   if (IS_ERR(ptr))
+   return ptr;
 
-   return ret;
-   }
-
-   clks[i] = clk;
-   }
+   ret = devm_clk_bulk_get(hdata->dev, names->count, ptr);
+   if (ret < 0)
+   return ERR_PTR(ret);
 
-   return 0;
+   return ptr;
 }
 
 static int hdmi_clk_init(struct hdmi_context *hdata)
 {
const struct hdmi_driver_data *drv_data = hdata->drv_data;
-   int count = drv_data->clk_gates.count + drv_data->clk_muxes.count;
-   struct device *dev = hdata->dev;
-   struct clk **clks;
-   int ret;
 
-   if (!count)
-   return 0;
-
-   clks = devm_kzalloc(dev, sizeof(*clks) * count, GFP_KERNEL);
-   if (!clks)
-   return -ENOMEM;
+   hdata->clk_muxes = hdmi_clks_alloc_get(hdata, _data->clk_muxes);
+   if (IS_ERR(hdata->clk_muxes))
+   return PTR_ERR(hdata->clk_muxes);
 
-   hdata->clk_gates = clks;
-   hdata->clk_muxes = clks + drv_data->clk_gates.count;
+   hdata->clk_gates = hdmi_clks_alloc_get(hdata, _data->clk_gates);
+   if (IS_ERR(hdata->clk_gates))
+   return PTR_ERR(hdata->clk_gates);
 
-   ret = hdmi_clks_get(hdata, _data->clk_gates, hdata->clk_gates);
-   if (ret)
-   return ret;
-
-   return hdmi_clks_get(hdata, _data->clk_muxes, hdata->clk_muxes);
+   return 0;
 }
 
 
@@ -2073,7 +2028,8 @@ static int __maybe_unused exynos_hdmi_suspend(struct 
device *dev)
 {
struct 

[PATCH 8/8] [media] s5p-mfc: Use clk bulk API

2018-02-19 Thread Maciej Purski
Using bulk clk functions simplifies the driver's code. Use devm_clk_bulk
functions instead of iterating over an array of clks.

Signed-off-by: Maciej Purski 
---
 drivers/media/platform/s5p-mfc/s5p_mfc_common.h |  6 ++--
 drivers/media/platform/s5p-mfc/s5p_mfc_pm.c | 41 +
 2 files changed, 18 insertions(+), 29 deletions(-)

diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_common.h 
b/drivers/media/platform/s5p-mfc/s5p_mfc_common.h
index 76119a8..da3f0b3 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc_common.h
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_common.h
@@ -192,9 +192,9 @@ struct s5p_mfc_buf {
  * struct s5p_mfc_pm - power management data structure
  */
 struct s5p_mfc_pm {
-   struct clk  *clock_gate;
-   const char * const *clk_names;
-   struct clk  *clocks[MFC_MAX_CLOCKS];
+   struct clk  *clock_gate;
+   const char * const  *clk_names;
+   struct clk_bulk_data*clocks;
int num_clocks;
booluse_clock_gating;
 
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_pm.c 
b/drivers/media/platform/s5p-mfc/s5p_mfc_pm.c
index eb85ced..857f6ea 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc_pm.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_pm.c
@@ -24,7 +24,7 @@ static atomic_t clk_ref;
 
 int s5p_mfc_init_pm(struct s5p_mfc_dev *dev)
 {
-   int i;
+   int ret;
 
pm = >pm;
p_dev = dev;
@@ -35,17 +35,17 @@ int s5p_mfc_init_pm(struct s5p_mfc_dev *dev)
pm->clock_gate = NULL;
 
/* clock control */
-   for (i = 0; i < pm->num_clocks; i++) {
-   pm->clocks[i] = devm_clk_get(pm->device, pm->clk_names[i]);
-   if (IS_ERR(pm->clocks[i])) {
-   mfc_err("Failed to get clock: %s\n",
-   pm->clk_names[i]);
-   return PTR_ERR(pm->clocks[i]);
-   }
-   }
+   pm->clocks = devm_clk_bulk_alloc(pm->device, pm->num_clocks,
+pm->clk_names);
+   if (IS_ERR(pm->clocks))
+   return PTR_ERR(pm->clocks);
+
+   ret = devm_clk_bulk_get(pm->device, pm->num_clocks, pm->clocks);
+   if (ret < 0)
+   return ret;
 
if (dev->variant->use_clock_gating)
-   pm->clock_gate = pm->clocks[0];
+   pm->clock_gate = pm->clocks[0].clk;
 
pm_runtime_enable(pm->device);
atomic_set(_ref, 0);
@@ -75,43 +75,32 @@ void s5p_mfc_clock_off(void)
 
 int s5p_mfc_power_on(void)
 {
-   int i, ret = 0;
+   int ret = 0;
 
ret = pm_runtime_get_sync(pm->device);
if (ret < 0)
return ret;
 
/* clock control */
-   for (i = 0; i < pm->num_clocks; i++) {
-   ret = clk_prepare_enable(pm->clocks[i]);
-   if (ret < 0) {
-   mfc_err("clock prepare failed for clock: %s\n",
-   pm->clk_names[i]);
-   i++;
-   goto err;
-   }
-   }
+   ret = clk_bulk_prepare_enable(pm->num_clocks, pm->clocks);
+   if (ret < 0)
+   goto err;
 
/* prepare for software clock gating */
clk_disable(pm->clock_gate);
 
return 0;
 err:
-   while (--i > 0)
-   clk_disable_unprepare(pm->clocks[i]);
pm_runtime_put(pm->device);
return ret;
 }
 
 int s5p_mfc_power_off(void)
 {
-   int i;
-
/* finish software clock gating */
clk_enable(pm->clock_gate);
 
-   for (i = 0; i < pm->num_clocks; i++)
-   clk_disable_unprepare(pm->clocks[i]);
+   clk_bulk_disable_unprepare(pm->num_clocks, pm->clocks);
 
return pm_runtime_put_sync(pm->device);
 }
-- 
2.7.4



[PATCH 2/8] media: s5p-jpeg: Use bulk clk API

2018-02-19 Thread Maciej Purski
Using bulk clk functions simplifies the driver's code. Use devm_clk_bulk
functions instead of iterating over an array of clks.

Signed-off-by: Maciej Purski 
---
 drivers/media/platform/s5p-jpeg/jpeg-core.c | 45 -
 drivers/media/platform/s5p-jpeg/jpeg-core.h |  2 +-
 2 files changed, 20 insertions(+), 27 deletions(-)

diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c 
b/drivers/media/platform/s5p-jpeg/jpeg-core.c
index 79b63da..681a515 100644
--- a/drivers/media/platform/s5p-jpeg/jpeg-core.c
+++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c
@@ -2903,7 +2903,7 @@ static int s5p_jpeg_probe(struct platform_device *pdev)
 {
struct s5p_jpeg *jpeg;
struct resource *res;
-   int i, ret;
+   int ret;
 
/* JPEG IP abstraction struct */
jpeg = devm_kzalloc(>dev, sizeof(struct s5p_jpeg), GFP_KERNEL);
@@ -2938,15 +2938,16 @@ static int s5p_jpeg_probe(struct platform_device *pdev)
}
 
/* clocks */
-   for (i = 0; i < jpeg->variant->num_clocks; i++) {
-   jpeg->clocks[i] = devm_clk_get(>dev,
- jpeg->variant->clk_names[i]);
-   if (IS_ERR(jpeg->clocks[i])) {
-   dev_err(>dev, "failed to get clock: %s\n",
-   jpeg->variant->clk_names[i]);
-   return PTR_ERR(jpeg->clocks[i]);
-   }
-   }
+   jpeg->clocks = devm_clk_bulk_alloc(>dev,
+  jpeg->variant->num_clocks,
+  jpeg->variant->clk_names);
+   if (IS_ERR(jpeg->clocks))
+   return PTR_ERR(jpeg->clocks);
+
+   ret = devm_clk_bulk_get(>dev, jpeg->variant->num_clocks,
+   jpeg->clocks);
+   if (ret < 0)
+   return ret;
 
/* v4l2 device */
ret = v4l2_device_register(>dev, >v4l2_dev);
@@ -3047,7 +3048,6 @@ static int s5p_jpeg_probe(struct platform_device *pdev)
 static int s5p_jpeg_remove(struct platform_device *pdev)
 {
struct s5p_jpeg *jpeg = platform_get_drvdata(pdev);
-   int i;
 
pm_runtime_disable(jpeg->dev);
 
@@ -3058,8 +3058,8 @@ static int s5p_jpeg_remove(struct platform_device *pdev)
v4l2_device_unregister(>v4l2_dev);
 
if (!pm_runtime_status_suspended(>dev)) {
-   for (i = jpeg->variant->num_clocks - 1; i >= 0; i--)
-   clk_disable_unprepare(jpeg->clocks[i]);
+   clk_bulk_disable_unprepare(jpeg->variant->num_clocks,
+  jpeg->clocks);
}
 
return 0;
@@ -3069,10 +3069,8 @@ static int s5p_jpeg_remove(struct platform_device *pdev)
 static int s5p_jpeg_runtime_suspend(struct device *dev)
 {
struct s5p_jpeg *jpeg = dev_get_drvdata(dev);
-   int i;
 
-   for (i = jpeg->variant->num_clocks - 1; i >= 0; i--)
-   clk_disable_unprepare(jpeg->clocks[i]);
+   clk_bulk_disable_unprepare(jpeg->variant->num_clocks, jpeg->clocks);
 
return 0;
 }
@@ -3081,16 +3079,11 @@ static int s5p_jpeg_runtime_resume(struct device *dev)
 {
struct s5p_jpeg *jpeg = dev_get_drvdata(dev);
unsigned long flags;
-   int i, ret;
-
-   for (i = 0; i < jpeg->variant->num_clocks; i++) {
-   ret = clk_prepare_enable(jpeg->clocks[i]);
-   if (ret) {
-   while (--i >= 0)
-   clk_disable_unprepare(jpeg->clocks[i]);
-   return ret;
-   }
-   }
+   int ret;
+
+   ret = clk_bulk_prepare_enable(jpeg->variant->num_clocks, jpeg->clocks);
+   if (ret)
+   return ret;
 
spin_lock_irqsave(>slock, flags);
 
diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.h 
b/drivers/media/platform/s5p-jpeg/jpeg-core.h
index a46465e..dc6ed98 100644
--- a/drivers/media/platform/s5p-jpeg/jpeg-core.h
+++ b/drivers/media/platform/s5p-jpeg/jpeg-core.h
@@ -133,7 +133,7 @@ struct s5p_jpeg {
void __iomem*regs;
unsigned intirq;
enum exynos4_jpeg_result irq_ret;
-   struct clk  *clocks[JPEG_MAX_CLOCKS];
+   struct clk_bulk_data*clocks;
struct device   *dev;
struct s5p_jpeg_variant *variant;
u32 irq_status;
-- 
2.7.4



[PATCH 1/8] clk: Add clk_bulk_alloc functions

2018-02-19 Thread Maciej Purski
When a driver is going to use clk_bulk_get() function, it has to
initialize an array of clk_bulk_data, by filling its id fields.

Add a new function to the core, which dynamically allocates
clk_bulk_data array and fills its id fields. Add clk_bulk_free()
function, which frees the array allocated by clk_bulk_alloc() function.
Add a managed version of clk_bulk_alloc().

Signed-off-by: Maciej Purski 
---
 drivers/clk/clk-bulk.c   | 16 
 drivers/clk/clk-devres.c | 37 +---
 include/linux/clk.h  | 64 
 3 files changed, 113 insertions(+), 4 deletions(-)

diff --git a/drivers/clk/clk-bulk.c b/drivers/clk/clk-bulk.c
index 4c10456..2f16941 100644
--- a/drivers/clk/clk-bulk.c
+++ b/drivers/clk/clk-bulk.c
@@ -19,6 +19,22 @@
 #include 
 #include 
 #include 
+#include 
+
+struct clk_bulk_data *clk_bulk_alloc(int num_clocks, const char *const 
*clk_ids)
+{
+   struct clk_bulk_data *ptr;
+   int i;
+
+   ptr = kcalloc(num_clocks, sizeof(*ptr), GFP_KERNEL);
+   if (!ptr)
+   return ERR_PTR(-ENOMEM);
+
+   for (i = 0; i < num_clocks; i++)
+   ptr[i].id = clk_ids[i];
+
+   return ptr;
+}
 
 void clk_bulk_put(int num_clks, struct clk_bulk_data *clks)
 {
diff --git a/drivers/clk/clk-devres.c b/drivers/clk/clk-devres.c
index d854e26..2115b97 100644
--- a/drivers/clk/clk-devres.c
+++ b/drivers/clk/clk-devres.c
@@ -9,6 +9,39 @@
 #include 
 #include 
 
+struct clk_bulk_devres {
+   struct clk_bulk_data *clks;
+   int num_clks;
+};
+
+static void devm_clk_alloc_release(struct device *dev, void *res)
+{
+   struct clk_bulk_devres *devres = res;
+
+   clk_bulk_free(devres->clks);
+}
+
+struct clk_bulk_data *devm_clk_bulk_alloc(struct device *dev, int num_clks,
+ const char *const *clk_ids)
+{
+   struct clk_bulk_data **ptr, *clk_bulk;
+
+   ptr = devres_alloc(devm_clk_alloc_release,
+  num_clks * sizeof(*ptr), GFP_KERNEL);
+   if (!ptr)
+   return ERR_PTR(-ENOMEM);
+
+   clk_bulk = clk_bulk_alloc(num_clks, clk_ids);
+   if (clk_bulk) {
+   *ptr = clk_bulk;
+   devres_add(dev, ptr);
+   } else {
+   devres_free(ptr);
+   }
+
+   return clk_bulk;
+}
+
 static void devm_clk_release(struct device *dev, void *res)
 {
clk_put(*(struct clk **)res);
@@ -34,10 +67,6 @@ struct clk *devm_clk_get(struct device *dev, const char *id)
 }
 EXPORT_SYMBOL(devm_clk_get);
 
-struct clk_bulk_devres {
-   struct clk_bulk_data *clks;
-   int num_clks;
-};
 
 static void devm_clk_bulk_release(struct device *dev, void *res)
 {
diff --git a/include/linux/clk.h b/include/linux/clk.h
index 4c4ef9f..7d66f41 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -15,6 +15,7 @@
 #include 
 #include 
 #include 
+#include 
 
 struct device;
 struct clk;
@@ -240,6 +241,52 @@ static inline void clk_bulk_unprepare(int num_clks, struct 
clk_bulk_data *clks)
 #endif
 
 #ifdef CONFIG_HAVE_CLK
+
+/**
+ * clk_bulk_alloc - allocates an array of clk_bulk_data and fills their
+ * id field
+ * @num_clks: number of clk_bulk_data
+ * @clk_ids: array of clock consumer ID's
+ *
+ * This function allows drivers to dynamically create an array of clk_bulk_data
+ * and fill their id field in one operation. If successful, it allows calling
+ * clk_bulk_get on the pointer returned by this function.
+ *
+ * Returns a pointer to a clk_bulk_data array, or valid IS_ERR() condition
+ * containing errno.
+ */
+struct clk_bulk_data *clk_bulk_alloc(int num_clks, const char *const *clk_ids);
+
+/**
+ * devm_clk_bulk_alloc - allocates an array of clk_bulk_data and fills their
+ *  id field
+ * @dev: device for clock "consumer"
+ * @num_clks: number of clk_bulk_data
+ * @clk_ids: array of clock consumer ID's
+ *
+ * This function allows drivers to dynamically create an array of clk_bulk_data
+ * and fill their id field in one operation with management, the array will
+ * automatically be freed when the device is unbound. If successful, it allows
+ * calling clk_bulk_get on the pointer returned by this function.
+ *
+ * Returns a pointer to a clk_bulk_data array, or valid IS_ERR() condition
+ * containing errno.
+ */
+struct clk_bulk_data *devm_clk_bulk_alloc(struct device *dev, int num_clks,
+ const char * const *clk_ids);
+
+/**
+ * clk_bulk_free - frees the array of clk_bulk_data
+ * @clks: pointer to clk_bulk_data array
+ *
+ * This function frees the array allocated by clk_bulk_data. It must be called
+ * when all clks are freed.
+ */
+static inline void clk_bulk_free(struct clk_bulk_data *clks)
+{
+   kfree(clks);
+}
+
 /**
  * clk_get - lookup and obtain a reference to a clock producer.
  * @dev: device for clock "consumer"
@@ -598,6 +645,23 @@ struct clk *clk_get_sys(const char 

Waiting for your Urgent Responds,

2018-02-19 Thread Mrs.Louisa Benicio
My Sincere Greetings,

I am (Mrs.Louisa Benicio) I have decided to donate ($5.5million
Dollars) to you / Motherless babies/ less privileged/ Churches/ Widows
from what I have inherited from my late Husband because I am
diagnosing of throat Cancer and hospitalize for 2 years and some
months now.

I will appreciate your utmost confidentiality and trust in this matter
to accomplish my heart desire, as I don’t want anything that will
jeopardize my last wish. As soon you get back to me, I shall give you
my info which you will use to contact the bank by quoting my personal
file routing and account information. I know I don't know you but all
is by the Grace of God Almighty, I found your email address through
random search from internet and I decided to contact you.

I am presently sending you this email seeking your assistance in
helping me set up a charity organization in your country by your names
which would be in existence long after am gone out of this world. I
will be going in for a surgery soon and I want to make sure that I
make this donation before undergoing my surgery.

Please if you would be able to use the funds for the work of humanity
as I have stated hear to fulfilled my late husband wishes  kindly
reply back to me through this email address
(mrslouisabeni...@yahoo.com) for more details.

Waiting for your Urgent Responds,
Yours Sincerely.
Mrs.Louisa Benicio.


[bug report] V4L/DVB (3420): Added iocls to configure VBI on tvp5150

2018-02-19 Thread Dan Carpenter
[ This is obviously ancient code.  It's probably fine.  I've just been
  going through all array overflow warnings recently.  - dan ]

Hello Mauro Carvalho Chehab,

The patch 12db56071b47: "V4L/DVB (3420): Added iocls to configure VBI
on tvp5150" from Jan 23, 2006, leads to the following static checker
warning:

drivers/media/i2c/tvp5150.c:730 tvp5150_get_vbi()
error: buffer overflow 'regs' 5 <= 14

drivers/media/i2c/tvp5150.c
   699  static int tvp5150_get_vbi(struct v4l2_subdev *sd,
   700  const struct i2c_vbi_ram_value *regs, int line)
   701  {
   702  struct tvp5150 *decoder = to_tvp5150(sd);
   703  v4l2_std_id std = decoder->norm;
   704  u8 reg;
   705  int pos, type = 0;
   706  int i, ret = 0;
   707  
   708  if (std == V4L2_STD_ALL) {
   709  dev_err(sd->dev, "VBI can't be configured without 
knowing number of lines\n");
   710  return 0;
   711  } else if (std & V4L2_STD_625_50) {
   712  /* Don't follow NTSC Line number convension */
   713  line += 3;
   714  }
   715  
   716  if (line < 6 || line > 27)
   717  return 0;
   718  
   719  reg = ((line - 6) << 1) + TVP5150_LINE_MODE_INI;
   720  
   721  for (i = 0; i <= 1; i++) {
   722  ret = tvp5150_read(sd, reg + i);
   723  if (ret < 0) {
   724  dev_err(sd->dev, "%s: failed with error = %d\n",
   725   __func__, ret);
   726  return 0;
   727  }
   728  pos = ret & 0x0f;
   729  if (pos < 0x0f)
^^
Smatch thinks this implies pos can be 0-14.

   730  type |= regs[pos].type.vbi_type;
^
This array only has 5 elements.

   731  }
   732  
   733  return type;
   734  }


regards,
dan carpenter


Re: [PATCH] staging: imx-media-vdic: fix inconsistent IS_ERR and PTR_ERR

2018-02-19 Thread Philipp Zabel
Hi Gustavo,

On Wed, 2018-02-14 at 14:57 -0600, Gustavo A. R. Silva wrote:
> Hi all,
> 
> I was just wondering about the status of this patch.

It is en route as commit dcd71a9292b1 ("staging: imx-media-vdic: fix
inconsistent IS_ERR and PTR_ERR") in Hans' for-v4.17a branch:
  git://linuxtv.org/hverkuil/media_tree.git for-v4.17a

regards
Philipp


[PATCHv3 04/10] staging: atomisp: Kill subdev s_parm abuse

2018-02-19 Thread Hans Verkuil
From: Sakari Ailus 

Remove sensor driver's interface for setting the use case specific mode
list as well as the mode lists that are related to other than
CI_MODE_PREVIEW. This removes s_parm abuse in using driver specific values
in v4l2_streamparm.capture.capturemode. The drivers already support
[gs]_frame_interval so removing support for [gs]_parm is enough.

Signed-off-by: Sakari Ailus 
Signed-off-by: Hans Verkuil 
---
 drivers/staging/media/atomisp/i2c/atomisp-gc0310.c | 26 -
 drivers/staging/media/atomisp/i2c/atomisp-gc2235.c | 26 -
 drivers/staging/media/atomisp/i2c/atomisp-ov2680.c | 29 -
 drivers/staging/media/atomisp/i2c/atomisp-ov2722.c | 26 -
 drivers/staging/media/atomisp/i2c/gc0310.h | 43 --
 drivers/staging/media/atomisp/i2c/gc2235.h |  1 -
 drivers/staging/media/atomisp/i2c/ov2680.h | 68 --
 .../media/atomisp/i2c/ov5693/atomisp-ov5693.c  | 27 -
 .../media/atomisp/pci/atomisp2/atomisp_cmd.c   |  9 +--
 .../media/atomisp/pci/atomisp2/atomisp_subdev.c| 12 +---
 10 files changed, 3 insertions(+), 264 deletions(-)

diff --git a/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c 
b/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c
index 61b7598469eb..572c9127c24d 100644
--- a/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c
+++ b/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c
@@ -1224,37 +1224,12 @@ static int gc0310_g_parm(struct v4l2_subdev *sd,
if (dev->fmt_idx >= 0 && dev->fmt_idx < N_RES) {
param->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
param->parm.capture.timeperframe.numerator = 1;
-   param->parm.capture.capturemode = dev->run_mode;
param->parm.capture.timeperframe.denominator =
gc0310_res[dev->fmt_idx].fps;
}
return 0;
 }
 
-static int gc0310_s_parm(struct v4l2_subdev *sd,
-   struct v4l2_streamparm *param)
-{
-   struct gc0310_device *dev = to_gc0310_sensor(sd);
-   dev->run_mode = param->parm.capture.capturemode;
-
-   mutex_lock(>input_lock);
-   switch (dev->run_mode) {
-   case CI_MODE_VIDEO:
-   gc0310_res = gc0310_res_video;
-   N_RES = N_RES_VIDEO;
-   break;
-   case CI_MODE_STILL_CAPTURE:
-   gc0310_res = gc0310_res_still;
-   N_RES = N_RES_STILL;
-   break;
-   default:
-   gc0310_res = gc0310_res_preview;
-   N_RES = N_RES_PREVIEW;
-   }
-   mutex_unlock(>input_lock);
-   return 0;
-}
-
 static int gc0310_g_frame_interval(struct v4l2_subdev *sd,
   struct v4l2_subdev_frame_interval *interval)
 {
@@ -1314,7 +1289,6 @@ static const struct v4l2_subdev_sensor_ops 
gc0310_sensor_ops = {
 static const struct v4l2_subdev_video_ops gc0310_video_ops = {
.s_stream = gc0310_s_stream,
.g_parm = gc0310_g_parm,
-   .s_parm = gc0310_s_parm,
.g_frame_interval = gc0310_g_frame_interval,
 };
 
diff --git a/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c 
b/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c
index d8de46da64ae..2bc179f3afe5 100644
--- a/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c
+++ b/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c
@@ -964,37 +964,12 @@ static int gc2235_g_parm(struct v4l2_subdev *sd,
if (dev->fmt_idx >= 0 && dev->fmt_idx < N_RES) {
param->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
param->parm.capture.timeperframe.numerator = 1;
-   param->parm.capture.capturemode = dev->run_mode;
param->parm.capture.timeperframe.denominator =
gc2235_res[dev->fmt_idx].fps;
}
return 0;
 }
 
-static int gc2235_s_parm(struct v4l2_subdev *sd,
-   struct v4l2_streamparm *param)
-{
-   struct gc2235_device *dev = to_gc2235_sensor(sd);
-   dev->run_mode = param->parm.capture.capturemode;
-
-   mutex_lock(>input_lock);
-   switch (dev->run_mode) {
-   case CI_MODE_VIDEO:
-   gc2235_res = gc2235_res_video;
-   N_RES = N_RES_VIDEO;
-   break;
-   case CI_MODE_STILL_CAPTURE:
-   gc2235_res = gc2235_res_still;
-   N_RES = N_RES_STILL;
-   break;
-   default:
-   gc2235_res = gc2235_res_preview;
-   N_RES = N_RES_PREVIEW;
-   }
-   mutex_unlock(>input_lock);
-   return 0;
-}
-
 static int gc2235_g_frame_interval(struct v4l2_subdev *sd,
   struct v4l2_subdev_frame_interval *interval)
 {
@@ -1053,7 +1028,6 @@ static const struct v4l2_subdev_sensor_ops 
gc2235_sensor_ops = {
 static const struct v4l2_subdev_video_ops gc2235_video_ops = {
.s_stream = 

[PATCHv3 06/10] staging: atomisp: i2c: Drop g_parm support in sensor drivers

2018-02-19 Thread Hans Verkuil
From: Sakari Ailus 

These drivers already support g_frame_interval. Therefore just dropping
g_parm is enough.

Signed-off-by: Sakari Ailus 
Signed-off-by: Hans Verkuil 
---
 drivers/staging/media/atomisp/i2c/atomisp-gc0310.c | 27 --
 drivers/staging/media/atomisp/i2c/atomisp-gc2235.c | 27 --
 drivers/staging/media/atomisp/i2c/atomisp-ov2680.c | 27 --
 drivers/staging/media/atomisp/i2c/atomisp-ov2722.c | 27 --
 .../media/atomisp/i2c/ov5693/atomisp-ov5693.c  | 27 --
 5 files changed, 135 deletions(-)

diff --git a/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c 
b/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c
index 572c9127c24d..93753cb96180 100644
--- a/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c
+++ b/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c
@@ -1204,32 +1204,6 @@ static int gc0310_s_config(struct v4l2_subdev *sd,
return ret;
 }
 
-static int gc0310_g_parm(struct v4l2_subdev *sd,
-   struct v4l2_streamparm *param)
-{
-   struct gc0310_device *dev = to_gc0310_sensor(sd);
-   struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-   if (!param)
-   return -EINVAL;
-
-   if (param->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
-   dev_err(>dev,  "unsupported buffer type.\n");
-   return -EINVAL;
-   }
-
-   memset(param, 0, sizeof(*param));
-   param->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
-   if (dev->fmt_idx >= 0 && dev->fmt_idx < N_RES) {
-   param->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
-   param->parm.capture.timeperframe.numerator = 1;
-   param->parm.capture.timeperframe.denominator =
-   gc0310_res[dev->fmt_idx].fps;
-   }
-   return 0;
-}
-
 static int gc0310_g_frame_interval(struct v4l2_subdev *sd,
   struct v4l2_subdev_frame_interval *interval)
 {
@@ -1288,7 +1262,6 @@ static const struct v4l2_subdev_sensor_ops 
gc0310_sensor_ops = {
 
 static const struct v4l2_subdev_video_ops gc0310_video_ops = {
.s_stream = gc0310_s_stream,
-   .g_parm = gc0310_g_parm,
.g_frame_interval = gc0310_g_frame_interval,
 };
 
diff --git a/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c 
b/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c
index 2bc179f3afe5..93f9c618f3d8 100644
--- a/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c
+++ b/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c
@@ -944,32 +944,6 @@ static int gc2235_s_config(struct v4l2_subdev *sd,
return ret;
 }
 
-static int gc2235_g_parm(struct v4l2_subdev *sd,
-   struct v4l2_streamparm *param)
-{
-   struct gc2235_device *dev = to_gc2235_sensor(sd);
-   struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-   if (!param)
-   return -EINVAL;
-
-   if (param->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
-   dev_err(>dev,  "unsupported buffer type.\n");
-   return -EINVAL;
-   }
-
-   memset(param, 0, sizeof(*param));
-   param->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
-   if (dev->fmt_idx >= 0 && dev->fmt_idx < N_RES) {
-   param->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
-   param->parm.capture.timeperframe.numerator = 1;
-   param->parm.capture.timeperframe.denominator =
-   gc2235_res[dev->fmt_idx].fps;
-   }
-   return 0;
-}
-
 static int gc2235_g_frame_interval(struct v4l2_subdev *sd,
   struct v4l2_subdev_frame_interval *interval)
 {
@@ -1027,7 +1001,6 @@ static const struct v4l2_subdev_sensor_ops 
gc2235_sensor_ops = {
 
 static const struct v4l2_subdev_video_ops gc2235_video_ops = {
.s_stream = gc2235_s_stream,
-   .g_parm = gc2235_g_parm,
.g_frame_interval = gc2235_g_frame_interval,
 };
 
diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c 
b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
index e3e0fdd0c816..11412061c40e 100644
--- a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
+++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
@@ -1280,32 +1280,6 @@ static int ov2680_s_config(struct v4l2_subdev *sd,
return ret;
 }
 
-static int ov2680_g_parm(struct v4l2_subdev *sd,
-   struct v4l2_streamparm *param)
-{
-   struct ov2680_device *dev = to_ov2680_sensor(sd);
-   struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-   if (!param)
-   return -EINVAL;
-
-   if (param->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
-   dev_err(>dev,  "unsupported buffer type.\n");
-   return -EINVAL;
-   }
-
-   memset(param, 0, sizeof(*param));
-   param->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
-   if (dev->fmt_idx >= 0 

[PATCHv3 03/10] media: convert g/s_parm to g/s_frame_interval in subdevs

2018-02-19 Thread Hans Verkuil
From: Hans Verkuil 

Convert all g/s_parm calls to g/s_frame_interval. This allows us
to remove the g/s_parm ops since those are a duplicate of
g/s_frame_interval.

Signed-off-by: Hans Verkuil 
Acked-by: Sakari Ailus 
---
 drivers/media/i2c/mt9v011.c | 29 ++-
 drivers/media/i2c/ov6650.c  | 33 --
 drivers/media/i2c/ov7670.c  | 22 ++-
 drivers/media/i2c/ov7740.c  | 29 ++-
 drivers/media/i2c/tvp514x.c | 37 -
 drivers/media/i2c/vs6624.c  | 27 ++
 drivers/media/platform/atmel/atmel-isc.c| 10 ++-
 drivers/media/platform/atmel/atmel-isi.c| 12 ++--
 drivers/media/platform/blackfin/bfin_capture.c  | 14 +++---
 drivers/media/platform/marvell-ccic/mcam-core.c | 12 
 drivers/media/platform/soc_camera/soc_camera.c  | 10 ---
 drivers/media/platform/via-camera.c |  4 +--
 drivers/media/usb/em28xx/em28xx-video.c | 36 
 13 files changed, 110 insertions(+), 165 deletions(-)

diff --git a/drivers/media/i2c/mt9v011.c b/drivers/media/i2c/mt9v011.c
index 5e29064fae91..46ef74a2ca36 100644
--- a/drivers/media/i2c/mt9v011.c
+++ b/drivers/media/i2c/mt9v011.c
@@ -364,33 +364,22 @@ static int mt9v011_set_fmt(struct v4l2_subdev *sd,
return 0;
 }
 
-static int mt9v011_g_parm(struct v4l2_subdev *sd, struct v4l2_streamparm 
*parms)
+static int mt9v011_g_frame_interval(struct v4l2_subdev *sd,
+   struct v4l2_subdev_frame_interval *ival)
 {
-   struct v4l2_captureparm *cp = >parm.capture;
-
-   if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
-   return -EINVAL;
-
-   memset(cp, 0, sizeof(struct v4l2_captureparm));
-   cp->capability = V4L2_CAP_TIMEPERFRAME;
calc_fps(sd,
->timeperframe.numerator,
->timeperframe.denominator);
+>interval.numerator,
+>interval.denominator);
 
return 0;
 }
 
-static int mt9v011_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm 
*parms)
+static int mt9v011_s_frame_interval(struct v4l2_subdev *sd,
+   struct v4l2_subdev_frame_interval *ival)
 {
-   struct v4l2_captureparm *cp = >parm.capture;
-   struct v4l2_fract *tpf = >timeperframe;
+   struct v4l2_fract *tpf = >interval;
u16 speed;
 
-   if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
-   return -EINVAL;
-   if (cp->extendedmode != 0)
-   return -EINVAL;
-
speed = calc_speed(sd, tpf->numerator, tpf->denominator);
 
mt9v011_write(sd, R0A_MT9V011_CLK_SPEED, speed);
@@ -469,8 +458,8 @@ static const struct v4l2_subdev_core_ops mt9v011_core_ops = 
{
 };
 
 static const struct v4l2_subdev_video_ops mt9v011_video_ops = {
-   .g_parm = mt9v011_g_parm,
-   .s_parm = mt9v011_s_parm,
+   .g_frame_interval = mt9v011_g_frame_interval,
+   .s_frame_interval = mt9v011_s_frame_interval,
 };
 
 static const struct v4l2_subdev_pad_ops mt9v011_pad_ops = {
diff --git a/drivers/media/i2c/ov6650.c b/drivers/media/i2c/ov6650.c
index 8975d16b2b24..17a34b4a819d 100644
--- a/drivers/media/i2c/ov6650.c
+++ b/drivers/media/i2c/ov6650.c
@@ -201,7 +201,7 @@ struct ov6650 {
struct v4l2_rectrect;   /* sensor cropping window */
unsigned long   pclk_limit; /* from host */
unsigned long   pclk_max;   /* from resolution and format */
-   struct v4l2_fract   tpf;/* as requested with s_parm */
+   struct v4l2_fract   tpf;/* as requested with 
s_frame_interval */
u32 code;
enum v4l2_colorspacecolorspace;
 };
@@ -723,42 +723,31 @@ static int ov6650_enum_mbus_code(struct v4l2_subdev *sd,
return 0;
 }
 
-static int ov6650_g_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms)
+static int ov6650_g_frame_interval(struct v4l2_subdev *sd,
+  struct v4l2_subdev_frame_interval *ival)
 {
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct ov6650 *priv = to_ov6650(client);
-   struct v4l2_captureparm *cp = >parm.capture;
 
-   if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
-   return -EINVAL;
-
-   memset(cp, 0, sizeof(*cp));
-   cp->capability = V4L2_CAP_TIMEPERFRAME;
-   cp->timeperframe.numerator = GET_CLKRC_DIV(to_clkrc(>tpf,
+   ival->interval.numerator = GET_CLKRC_DIV(to_clkrc(>tpf,
priv->pclk_limit, priv->pclk_max));
-   cp->timeperframe.denominator = FRAME_RATE_MAX;
+   ival->interval.denominator = FRAME_RATE_MAX;
 
dev_dbg(>dev, "Frame interval: %u/%u s\n",
-   

[PATCHv3 07/10] staging: atomisp: mt9m114: Drop empty s_parm callback

2018-02-19 Thread Hans Verkuil
From: Sakari Ailus 

The s_parm callback in mt9m114 driver did nothing, remove it.

Signed-off-by: Sakari Ailus 
Signed-off-by: Hans Verkuil 
---
 drivers/staging/media/atomisp/i2c/atomisp-mt9m114.c | 6 --
 1 file changed, 6 deletions(-)

diff --git a/drivers/staging/media/atomisp/i2c/atomisp-mt9m114.c 
b/drivers/staging/media/atomisp/i2c/atomisp-mt9m114.c
index df253a557c76..834fba8c4fa0 100644
--- a/drivers/staging/media/atomisp/i2c/atomisp-mt9m114.c
+++ b/drivers/staging/media/atomisp/i2c/atomisp-mt9m114.c
@@ -1684,11 +1684,6 @@ static int mt9m114_t_vflip(struct v4l2_subdev *sd, int 
value)
 
return !!err;
 }
-static int mt9m114_s_parm(struct v4l2_subdev *sd,
-   struct v4l2_streamparm *param)
-{
-   return 0;
-}
 
 static int mt9m114_g_frame_interval(struct v4l2_subdev *sd,
   struct v4l2_subdev_frame_interval *interval)
@@ -1781,7 +1776,6 @@ static int mt9m114_g_skip_frames(struct v4l2_subdev *sd, 
u32 *frames)
 }
 
 static const struct v4l2_subdev_video_ops mt9m114_video_ops = {
-   .s_parm = mt9m114_s_parm,
.s_stream = mt9m114_s_stream,
.g_frame_interval = mt9m114_g_frame_interval,
 };
-- 
2.15.1



[PATCHv3 10/10] vidioc-g-parm.rst: also allow _MPLANE buffer types

2018-02-19 Thread Hans Verkuil
From: Hans Verkuil 

The specification mentions that type can be V4L2_BUF_TYPE_VIDEO_CAPTURE,
but the v4l2 core implementation also allows the _MPLANE variant.

Document this.

Signed-off-by: Hans Verkuil 
Acked-by: Sakari Ailus 
---
 Documentation/media/uapi/v4l/vidioc-g-parm.rst | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/Documentation/media/uapi/v4l/vidioc-g-parm.rst 
b/Documentation/media/uapi/v4l/vidioc-g-parm.rst
index 616a5ea3f8fa..e831fa5512f0 100644
--- a/Documentation/media/uapi/v4l/vidioc-g-parm.rst
+++ b/Documentation/media/uapi/v4l/vidioc-g-parm.rst
@@ -66,7 +66,7 @@ union holding separate parameters for input and output 
devices.
   -
   - The buffer (stream) type, same as struct
:c:type:`v4l2_format` ``type``, set by the
-   application. See :c:type:`v4l2_buf_type`
+   application. See :c:type:`v4l2_buf_type`.
 * - union
   - ``parm``
   -
@@ -75,12 +75,13 @@ union holding separate parameters for input and output 
devices.
   - struct :c:type:`v4l2_captureparm`
   - ``capture``
   - Parameters for capture devices, used when ``type`` is
-   ``V4L2_BUF_TYPE_VIDEO_CAPTURE``.
+   ``V4L2_BUF_TYPE_VIDEO_CAPTURE`` or
+   ``V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE``.
 * -
   - struct :c:type:`v4l2_outputparm`
   - ``output``
   - Parameters for output devices, used when ``type`` is
-   ``V4L2_BUF_TYPE_VIDEO_OUTPUT``.
+   ``V4L2_BUF_TYPE_VIDEO_OUTPUT`` or ``V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE``.
 * -
   - __u8
   - ``raw_data``\ [200]
-- 
2.15.1



[PATCHv3 08/10] staging: atomisp: Drop g_parm and s_parm subdev ops use

2018-02-19 Thread Hans Verkuil
From: Sakari Ailus 

The s_parm and g_parm did nothing. Remove them.

Signed-off-by: Sakari Ailus 
Signed-off-by: Hans Verkuil 
---
 .../staging/media/atomisp/pci/atomisp2/atomisp_file.c| 16 
 drivers/staging/media/atomisp/pci/atomisp2/atomisp_tpg.c | 14 --
 2 files changed, 30 deletions(-)

diff --git a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_file.c 
b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_file.c
index 377ec2a9fa6d..c6d96987561d 100644
--- a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_file.c
+++ b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_file.c
@@ -77,20 +77,6 @@ static int file_input_s_stream(struct v4l2_subdev *sd, int 
enable)
return 0;
 }
 
-static int file_input_g_parm(struct v4l2_subdev *sd,
-   struct v4l2_streamparm *param)
-{
-   /*to fake*/
-   return 0;
-}
-
-static int file_input_s_parm(struct v4l2_subdev *sd,
-   struct v4l2_streamparm *param)
-{
-   /*to fake*/
-   return 0;
-}
-
 static int file_input_get_fmt(struct v4l2_subdev *sd,
  struct v4l2_subdev_pad_config *cfg,
  struct v4l2_subdev_format *format)
@@ -166,8 +152,6 @@ static int file_input_enum_frame_ival(struct v4l2_subdev 
*sd,
 
 static const struct v4l2_subdev_video_ops file_input_video_ops = {
.s_stream = file_input_s_stream,
-   .g_parm = file_input_g_parm,
-   .s_parm = file_input_s_parm,
 };
 
 static const struct v4l2_subdev_core_ops file_input_core_ops = {
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_tpg.c 
b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_tpg.c
index b71cc7bcdbab..adc900272f6f 100644
--- a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_tpg.c
+++ b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_tpg.c
@@ -27,18 +27,6 @@ static int tpg_s_stream(struct v4l2_subdev *sd, int enable)
return 0;
 }
 
-static int tpg_g_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *param)
-{
-   /*to fake*/
-   return 0;
-}
-
-static int tpg_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *param)
-{
-   /*to fake*/
-   return 0;
-}
-
 static int tpg_get_fmt(struct v4l2_subdev *sd,
   struct v4l2_subdev_pad_config *cfg,
   struct v4l2_subdev_format *format)
@@ -101,8 +89,6 @@ static int tpg_enum_frame_ival(struct v4l2_subdev *sd,
 
 static const struct v4l2_subdev_video_ops tpg_video_ops = {
.s_stream = tpg_s_stream,
-   .g_parm = tpg_g_parm,
-   .s_parm = tpg_s_parm,
 };
 
 static const struct v4l2_subdev_core_ops tpg_core_ops = {
-- 
2.15.1



[PATCHv3 01/10] v4l2-subdev: clear reserved fields

2018-02-19 Thread Hans Verkuil
Clear the reserved fields for these ioctls according to the specification:

VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL
VIDIOC_SUBDEV_ENUM_FRAME_SIZE
VIDIOC_SUBDEV_ENUM_MBUS_CODE
VIDIOC_SUBDEV_G_CROP, VIDIOC_SUBDEV_S_CROP
VIDIOC_SUBDEV_G_FMT, VIDIOC_SUBDEV_S_FMT
VIDIOC_SUBDEV_G_FRAME_INTERVAL, VIDIOC_SUBDEV_S_FRAME_INTERVAL
VIDIOC_SUBDEV_G_SELECTION, VIDIOC_SUBDEV_S_SELECTION

Found with v4l2-compliance.

Signed-off-by: Hans Verkuil 
Acked-by: Sakari Ailus 
---
 drivers/media/v4l2-core/v4l2-subdev.c | 13 +
 1 file changed, 13 insertions(+)

diff --git a/drivers/media/v4l2-core/v4l2-subdev.c 
b/drivers/media/v4l2-core/v4l2-subdev.c
index c5639817db34..74fe8083cf26 100644
--- a/drivers/media/v4l2-core/v4l2-subdev.c
+++ b/drivers/media/v4l2-core/v4l2-subdev.c
@@ -260,6 +260,8 @@ static long subdev_do_ioctl(struct file *file, unsigned int 
cmd, void *arg)
if (rval)
return rval;
 
+   memset(format->reserved, 0, sizeof(format->reserved));
+   memset(format->format.reserved, 0, 
sizeof(format->format.reserved));
return v4l2_subdev_call(sd, pad, get_fmt, subdev_fh->pad, 
format);
}
 
@@ -270,6 +272,8 @@ static long subdev_do_ioctl(struct file *file, unsigned int 
cmd, void *arg)
if (rval)
return rval;
 
+   memset(format->reserved, 0, sizeof(format->reserved));
+   memset(format->format.reserved, 0, 
sizeof(format->format.reserved));
return v4l2_subdev_call(sd, pad, set_fmt, subdev_fh->pad, 
format);
}
 
@@ -281,6 +285,7 @@ static long subdev_do_ioctl(struct file *file, unsigned int 
cmd, void *arg)
if (rval)
return rval;
 
+   memset(crop->reserved, 0, sizeof(crop->reserved));
memset(, 0, sizeof(sel));
sel.which = crop->which;
sel.pad = crop->pad;
@@ -298,6 +303,7 @@ static long subdev_do_ioctl(struct file *file, unsigned int 
cmd, void *arg)
struct v4l2_subdev_crop *crop = arg;
struct v4l2_subdev_selection sel;
 
+   memset(crop->reserved, 0, sizeof(crop->reserved));
rval = check_crop(sd, crop);
if (rval)
return rval;
@@ -326,6 +332,7 @@ static long subdev_do_ioctl(struct file *file, unsigned int 
cmd, void *arg)
if (code->pad >= sd->entity.num_pads)
return -EINVAL;
 
+   memset(code->reserved, 0, sizeof(code->reserved));
return v4l2_subdev_call(sd, pad, enum_mbus_code, subdev_fh->pad,
code);
}
@@ -340,6 +347,7 @@ static long subdev_do_ioctl(struct file *file, unsigned int 
cmd, void *arg)
if (fse->pad >= sd->entity.num_pads)
return -EINVAL;
 
+   memset(fse->reserved, 0, sizeof(fse->reserved));
return v4l2_subdev_call(sd, pad, enum_frame_size, 
subdev_fh->pad,
fse);
}
@@ -350,6 +358,7 @@ static long subdev_do_ioctl(struct file *file, unsigned int 
cmd, void *arg)
if (fi->pad >= sd->entity.num_pads)
return -EINVAL;
 
+   memset(fi->reserved, 0, sizeof(fi->reserved));
return v4l2_subdev_call(sd, video, g_frame_interval, arg);
}
 
@@ -359,6 +368,7 @@ static long subdev_do_ioctl(struct file *file, unsigned int 
cmd, void *arg)
if (fi->pad >= sd->entity.num_pads)
return -EINVAL;
 
+   memset(fi->reserved, 0, sizeof(fi->reserved));
return v4l2_subdev_call(sd, video, s_frame_interval, arg);
}
 
@@ -372,6 +382,7 @@ static long subdev_do_ioctl(struct file *file, unsigned int 
cmd, void *arg)
if (fie->pad >= sd->entity.num_pads)
return -EINVAL;
 
+   memset(fie->reserved, 0, sizeof(fie->reserved));
return v4l2_subdev_call(sd, pad, enum_frame_interval, 
subdev_fh->pad,
fie);
}
@@ -383,6 +394,7 @@ static long subdev_do_ioctl(struct file *file, unsigned int 
cmd, void *arg)
if (rval)
return rval;
 
+   memset(sel->reserved, 0, sizeof(sel->reserved));
return v4l2_subdev_call(
sd, pad, get_selection, subdev_fh->pad, sel);
}
@@ -394,6 +406,7 @@ static long subdev_do_ioctl(struct file *file, unsigned int 
cmd, void *arg)
if (rval)
return rval;
 
+   memset(sel->reserved, 0, sizeof(sel->reserved));
return v4l2_subdev_call(
sd, pad, set_selection, subdev_fh->pad, sel);
}
-- 
2.15.1



[PATCHv3 09/10] v4l2-subdev.h: remove obsolete g/s_parm

2018-02-19 Thread Hans Verkuil
From: Hans Verkuil 

Signed-off-by: Hans Verkuil 
Acked-by: Sakari Ailus 
---
 include/media/v4l2-subdev.h | 6 --
 1 file changed, 6 deletions(-)

diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h
index 980a86c08fce..457917e9237f 100644
--- a/include/media/v4l2-subdev.h
+++ b/include/media/v4l2-subdev.h
@@ -393,10 +393,6 @@ struct v4l2_mbus_frame_desc {
  *
  * @g_pixelaspect: callback to return the pixelaspect ratio.
  *
- * @g_parm: callback for VIDIOC_G_PARM() ioctl handler code.
- *
- * @s_parm: callback for VIDIOC_S_PARM() ioctl handler code.
- *
  * @g_frame_interval: callback for VIDIOC_SUBDEV_G_FRAME_INTERVAL()
  *   ioctl handler code.
  *
@@ -434,8 +430,6 @@ struct v4l2_subdev_video_ops {
int (*g_input_status)(struct v4l2_subdev *sd, u32 *status);
int (*s_stream)(struct v4l2_subdev *sd, int enable);
int (*g_pixelaspect)(struct v4l2_subdev *sd, struct v4l2_fract *aspect);
-   int (*g_parm)(struct v4l2_subdev *sd, struct v4l2_streamparm *param);
-   int (*s_parm)(struct v4l2_subdev *sd, struct v4l2_streamparm *param);
int (*g_frame_interval)(struct v4l2_subdev *sd,
struct v4l2_subdev_frame_interval *interval);
int (*s_frame_interval)(struct v4l2_subdev *sd,
-- 
2.15.1



[PATCHv3 00/10] media: replace g/s_parm by g/s_frame_interval

2018-02-19 Thread Hans Verkuil
From: Hans Verkuil 

There are currently two subdev ops variants to get/set the frame interval:
g/s_parm and g/s_frame_interval.

This patch series replaces all g/s_parm calls by g/s_frame_interval.

The first patch clears the reserved fields in v4l2-subdev.c. It's taken
from the "Media Controller compliance fixes" series.

The second patch adds helper functions that can be used by bridge drivers.
Only em28xx can't use it and it needs custom code (it uses v4l2_device_call()
to try all subdevs instead of calling a specific subdev).

The next patch converts all non-staging drivers, then come Sakari's
atomisp staging fixes.

The v4l2-subdev.h patch removes the now obsolete g/s_parm ops and the
final patch clarifies the documentation a bit (the core allows for
_MPLANE to be used as well).

I would really like to take the next step and introduce two new ioctls
VIDIOC_G/S_FRAME_INTERVAL (just like the SUBDEV variants that already
exist) and convert all bridge drivers to use that and just have helper
functions in the core for VIDIOC_G/S_PARM.

I hate that ioctl and it always confuses driver developers. It would
also prevent the type of abuse that was present in the atomisp driver.

But that's for later, let's simplify the subdev drivers first.

Regards,

Hans

Changes since v2:

- added patch 1 (v4l2-subdev: clear reserved fields). This is the same
  patch as is included in the "Media Controller compliance fixes" series.
- because of patch 1 we can now drop the memsets in patch 3 as suggested
  by Mauro.
- updated commit message of patch "staging: atomisp: Kill subdev s_parm abuse"
- updated patch "staging: atomisp: i2c: Disable non-preview configurations"
  to the 2.1 version posted by Sakari, with a slight rewording of the commit
  message.

Changes since v1:

- incorporated all comments from Sakari

Hans Verkuil (5):
  v4l2-subdev: clear reserved fields
  v4l2-common: create v4l2_g/s_parm_cap helpers
  media: convert g/s_parm to g/s_frame_interval in subdevs
  v4l2-subdev.h: remove obsolete g/s_parm
  vidioc-g-parm.rst: also allow _MPLANE buffer types

Sakari Ailus (5):
  staging: atomisp: Kill subdev s_parm abuse
  staging: atomisp: i2c: Disable non-preview configurations
  staging: atomisp: i2c: Drop g_parm support in sensor drivers
  staging: atomisp: mt9m114: Drop empty s_parm callback
  staging: atomisp: Drop g_parm and s_parm subdev ops use

 Documentation/media/uapi/v4l/vidioc-g-parm.rst |  7 ++-
 drivers/media/i2c/mt9v011.c| 29 +++--
 drivers/media/i2c/ov6650.c | 33 ---
 drivers/media/i2c/ov7670.c | 22 +++
 drivers/media/i2c/ov7740.c | 29 +++--
 drivers/media/i2c/tvp514x.c| 37 
 drivers/media/i2c/vs6624.c | 27 +++--
 drivers/media/platform/atmel/atmel-isc.c   | 10 +---
 drivers/media/platform/atmel/atmel-isi.c   | 12 +---
 drivers/media/platform/blackfin/bfin_capture.c | 14 ++---
 drivers/media/platform/marvell-ccic/mcam-core.c| 12 ++--
 drivers/media/platform/soc_camera/soc_camera.c | 10 ++--
 drivers/media/platform/via-camera.c|  4 +-
 drivers/media/usb/em28xx/em28xx-video.c| 36 ++--
 drivers/media/v4l2-core/v4l2-common.c  | 48 +++
 drivers/media/v4l2-core/v4l2-subdev.c  | 13 +
 drivers/staging/media/atomisp/i2c/atomisp-gc0310.c | 53 -
 drivers/staging/media/atomisp/i2c/atomisp-gc2235.c | 53 -
 .../staging/media/atomisp/i2c/atomisp-mt9m114.c|  6 --
 drivers/staging/media/atomisp/i2c/atomisp-ov2680.c | 56 --
 drivers/staging/media/atomisp/i2c/atomisp-ov2722.c | 53 -
 drivers/staging/media/atomisp/i2c/gc0310.h | 43 --
 drivers/staging/media/atomisp/i2c/gc2235.h |  7 ++-
 drivers/staging/media/atomisp/i2c/ov2680.h | 68 --
 drivers/staging/media/atomisp/i2c/ov2722.h |  6 ++
 .../media/atomisp/i2c/ov5693/atomisp-ov5693.c  | 54 -
 drivers/staging/media/atomisp/i2c/ov5693/ov5693.h  |  6 ++
 .../media/atomisp/pci/atomisp2/atomisp_cmd.c   |  9 +--
 .../media/atomisp/pci/atomisp2/atomisp_file.c  | 16 -
 .../media/atomisp/pci/atomisp2/atomisp_subdev.c| 12 +---
 .../media/atomisp/pci/atomisp2/atomisp_tpg.c   | 14 -
 include/media/v4l2-common.h| 26 +
 include/media/v4l2-subdev.h|  6 --
 33 files changed, 222 insertions(+), 609 deletions(-)

-- 
2.15.1



[PATCHv3 05/10] staging: atomisp: i2c: Disable non-preview configurations

2018-02-19 Thread Hans Verkuil
From: Sakari Ailus 

These sensor drivers have use case specific mode lists. This is currently
not used nor there is a standard API for selecting the mode list. Disable
configurations for non-preview modes until configuration selection is
improved so that all the configurations are always usable.

Signed-off-by: Sakari Ailus 
[hans.verk...@cisco.com: clarify that this functionality it currently unused]
Signed-off-by: Hans Verkuil 
---
 drivers/staging/media/atomisp/i2c/gc2235.h| 6 ++
 drivers/staging/media/atomisp/i2c/ov2722.h| 6 ++
 drivers/staging/media/atomisp/i2c/ov5693/ov5693.h | 6 ++
 3 files changed, 18 insertions(+)

diff --git a/drivers/staging/media/atomisp/i2c/gc2235.h 
b/drivers/staging/media/atomisp/i2c/gc2235.h
index 45a54fea5466..0e805bcfa4d8 100644
--- a/drivers/staging/media/atomisp/i2c/gc2235.h
+++ b/drivers/staging/media/atomisp/i2c/gc2235.h
@@ -574,6 +574,11 @@ static struct gc2235_resolution gc2235_res_preview[] = {
 };
 #define N_RES_PREVIEW (ARRAY_SIZE(gc2235_res_preview))
 
+/*
+ * Disable non-preview configurations until the configuration selection is
+ * improved.
+ */
+#if 0
 static struct gc2235_resolution gc2235_res_still[] = {
{
.desc = "gc2235_1600_900_30fps",
@@ -658,6 +663,7 @@ static struct gc2235_resolution gc2235_res_video[] = {
 
 };
 #define N_RES_VIDEO (ARRAY_SIZE(gc2235_res_video))
+#endif
 
 static struct gc2235_resolution *gc2235_res = gc2235_res_preview;
 static unsigned long N_RES = N_RES_PREVIEW;
diff --git a/drivers/staging/media/atomisp/i2c/ov2722.h 
b/drivers/staging/media/atomisp/i2c/ov2722.h
index d8a973d71699..028b048f 100644
--- a/drivers/staging/media/atomisp/i2c/ov2722.h
+++ b/drivers/staging/media/atomisp/i2c/ov2722.h
@@ -1148,6 +1148,11 @@ struct ov2722_resolution ov2722_res_preview[] = {
 };
 #define N_RES_PREVIEW (ARRAY_SIZE(ov2722_res_preview))
 
+/*
+ * Disable non-preview configurations until the configuration selection is
+ * improved.
+ */
+#if 0
 struct ov2722_resolution ov2722_res_still[] = {
{
.desc = "ov2722_480P_30fps",
@@ -1250,6 +1255,7 @@ struct ov2722_resolution ov2722_res_video[] = {
},
 };
 #define N_RES_VIDEO (ARRAY_SIZE(ov2722_res_video))
+#endif
 
 static struct ov2722_resolution *ov2722_res = ov2722_res_preview;
 static unsigned long N_RES = N_RES_PREVIEW;
diff --git a/drivers/staging/media/atomisp/i2c/ov5693/ov5693.h 
b/drivers/staging/media/atomisp/i2c/ov5693/ov5693.h
index 68cfcb4a6c3c..6d27dd849a62 100644
--- a/drivers/staging/media/atomisp/i2c/ov5693/ov5693.h
+++ b/drivers/staging/media/atomisp/i2c/ov5693/ov5693.h
@@ -1147,6 +1147,11 @@ struct ov5693_resolution ov5693_res_preview[] = {
 };
 #define N_RES_PREVIEW (ARRAY_SIZE(ov5693_res_preview))
 
+/*
+ * Disable non-preview configurations until the configuration selection is
+ * improved.
+ */
+#if 0
 struct ov5693_resolution ov5693_res_still[] = {
{
.desc = "ov5693_736x496_30fps",
@@ -1364,6 +1369,7 @@ struct ov5693_resolution ov5693_res_video[] = {
},
 };
 #define N_RES_VIDEO (ARRAY_SIZE(ov5693_res_video))
+#endif
 
 static struct ov5693_resolution *ov5693_res = ov5693_res_preview;
 static unsigned long N_RES = N_RES_PREVIEW;
-- 
2.15.1



[PATCHv3 02/10] v4l2-common: create v4l2_g/s_parm_cap helpers

2018-02-19 Thread Hans Verkuil
From: Hans Verkuil 

Create helpers to handle VIDIOC_G/S_PARM by querying the
g/s_frame_interval v4l2_subdev ops.

Signed-off-by: Hans Verkuil 
Acked-by: Sakari Ailus 
---
 drivers/media/v4l2-core/v4l2-common.c | 48 +++
 include/media/v4l2-common.h   | 26 +++
 2 files changed, 74 insertions(+)

diff --git a/drivers/media/v4l2-core/v4l2-common.c 
b/drivers/media/v4l2-core/v4l2-common.c
index 8650ad92b64d..96c1b31de9e3 100644
--- a/drivers/media/v4l2-core/v4l2-common.c
+++ b/drivers/media/v4l2-core/v4l2-common.c
@@ -392,3 +392,51 @@ void v4l2_get_timestamp(struct timeval *tv)
tv->tv_usec = ts.tv_nsec / NSEC_PER_USEC;
 }
 EXPORT_SYMBOL_GPL(v4l2_get_timestamp);
+
+int v4l2_g_parm_cap(struct video_device *vdev,
+   struct v4l2_subdev *sd, struct v4l2_streamparm *a)
+{
+   struct v4l2_subdev_frame_interval ival = { 0 };
+   int ret;
+
+   if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
+   a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
+   return -EINVAL;
+
+   if (vdev->device_caps & V4L2_CAP_READWRITE)
+   a->parm.capture.readbuffers = 2;
+   if (v4l2_subdev_has_op(sd, video, g_frame_interval))
+   a->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
+   ret = v4l2_subdev_call(sd, video, g_frame_interval, );
+   if (!ret)
+   a->parm.capture.timeperframe = ival.interval;
+   return ret;
+}
+EXPORT_SYMBOL_GPL(v4l2_g_parm_cap);
+
+int v4l2_s_parm_cap(struct video_device *vdev,
+   struct v4l2_subdev *sd, struct v4l2_streamparm *a)
+{
+   struct v4l2_subdev_frame_interval ival = {
+   .interval = a->parm.capture.timeperframe
+   };
+   int ret;
+
+   if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
+   a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
+   return -EINVAL;
+
+   memset(>parm, 0, sizeof(a->parm));
+   if (vdev->device_caps & V4L2_CAP_READWRITE)
+   a->parm.capture.readbuffers = 2;
+   else
+   a->parm.capture.readbuffers = 0;
+
+   if (v4l2_subdev_has_op(sd, video, g_frame_interval))
+   a->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
+   ret = v4l2_subdev_call(sd, video, s_frame_interval, );
+   if (!ret)
+   a->parm.capture.timeperframe = ival.interval;
+   return ret;
+}
+EXPORT_SYMBOL_GPL(v4l2_s_parm_cap);
diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h
index e0d95a7c5d48..f3aa1d728c0b 100644
--- a/include/media/v4l2-common.h
+++ b/include/media/v4l2-common.h
@@ -341,4 +341,30 @@ v4l2_find_nearest_format(const struct 
v4l2_frmsize_discrete *sizes,
  */
 void v4l2_get_timestamp(struct timeval *tv);
 
+/**
+ * v4l2_g_parm_cap - helper routine for vidioc_g_parm to fill this in by
+ *  calling the g_frame_interval op of the given subdev. It only works
+ *  for V4L2_BUF_TYPE_VIDEO_CAPTURE(_MPLANE), hence the _cap in the
+ *  function name.
+ *
+ * @vdev: the struct video_device pointer. Used to determine the device caps.
+ * @sd: the sub-device pointer.
+ * @a: the VIDIOC_G_PARM argument.
+ */
+int v4l2_g_parm_cap(struct video_device *vdev,
+   struct v4l2_subdev *sd, struct v4l2_streamparm *a);
+
+/**
+ * v4l2_s_parm_cap - helper routine for vidioc_s_parm to fill this in by
+ *  calling the s_frame_interval op of the given subdev. It only works
+ *  for V4L2_BUF_TYPE_VIDEO_CAPTURE(_MPLANE), hence the _cap in the
+ *  function name.
+ *
+ * @vdev: the struct video_device pointer. Used to determine the device caps.
+ * @sd: the sub-device pointer.
+ * @a: the VIDIOC_S_PARM argument.
+ */
+int v4l2_s_parm_cap(struct video_device *vdev,
+   struct v4l2_subdev *sd, struct v4l2_streamparm *a);
+
 #endif /* V4L2_COMMON_H_ */
-- 
2.15.1



Re: [PATCH v2.1 4/9] staging: atomisp: i2c: Disable non-preview configurations

2018-02-19 Thread Sakari Ailus
On Mon, Feb 19, 2018 at 02:58:45PM +0100, Hans Verkuil wrote:
> On 02/19/2018 02:48 PM, Sakari Ailus wrote:
> > Hi Hans,
> > 
> > On Mon, Feb 19, 2018 at 02:30:18PM +0100, Hans Verkuil wrote:
> >> On 02/19/2018 02:27 PM, Sakari Ailus wrote:
> >>> These sensor drivers have use case specific mode lists. There's no need
> >>> for this nor there is a standard API for selecting the mode list. Disable
> >>> configurations for non-preview modes until configuration selection is
> >>> improved so that all the configurations are always usable.
> >>
> >> It's a bit confusing. This seems contradictory: if there is no need for it,
> >> then it can be removed. Or there is a need for it, but we don't have a
> >> standard API to do it. You can't have both, can you?
> >>
> >> Or did you mean that this functionality is currently unused, and that if
> >> we wanted to use it, we first need a new API? That would actually make 
> >> sense.
> > 
> > Correct. All it takes might be just to put these modes to the common list.
> > But I can't test that as I have no hardware. It's easy to implement that
> > later on though, that's the idea.
> > 
> 
> I've reworded the second sentence slightly:
> 
> "These sensor drivers have use case specific mode lists. This is currently
> not used nor there is a standard API for selecting the mode list. Disable
> configurations for non-preview modes until configuration selection is
> improved so that all the configurations are always usable."
> 
> Is that OK?

Works for me. Thanks!

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


Re: [PATCH v2.1 4/9] staging: atomisp: i2c: Disable non-preview configurations

2018-02-19 Thread Hans Verkuil
On 02/19/2018 02:48 PM, Sakari Ailus wrote:
> Hi Hans,
> 
> On Mon, Feb 19, 2018 at 02:30:18PM +0100, Hans Verkuil wrote:
>> On 02/19/2018 02:27 PM, Sakari Ailus wrote:
>>> These sensor drivers have use case specific mode lists. There's no need
>>> for this nor there is a standard API for selecting the mode list. Disable
>>> configurations for non-preview modes until configuration selection is
>>> improved so that all the configurations are always usable.
>>
>> It's a bit confusing. This seems contradictory: if there is no need for it,
>> then it can be removed. Or there is a need for it, but we don't have a
>> standard API to do it. You can't have both, can you?
>>
>> Or did you mean that this functionality is currently unused, and that if
>> we wanted to use it, we first need a new API? That would actually make sense.
> 
> Correct. All it takes might be just to put these modes to the common list.
> But I can't test that as I have no hardware. It's easy to implement that
> later on though, that's the idea.
> 

I've reworded the second sentence slightly:

"These sensor drivers have use case specific mode lists. This is currently
not used nor there is a standard API for selecting the mode list. Disable
configurations for non-preview modes until configuration selection is
improved so that all the configurations are always usable."

Is that OK?

Regards,

Hans


Re: Bug: Two device nodes created in /dev for a single UVC webcam

2018-02-19 Thread Guennadi Liakhovetski
Hi Kieran,

On Mon, 19 Feb 2018, Kieran Bingham wrote:

> Hi Alexandre,
> 
> Thankyou for your bug report,
> 
> On 17/02/18 20:47, Alexandre-Xavier Labonté-Lamoureux wrote:
> > Hi,
> > 
> > I'm running Linux 4.9.0-5-amd64 on Debian. I built the drivers from
> > the latest git and installed the modules.
> 
> Could you please be specific here?
> 
> Are you referring to linux-media/master branch or such? The latest from 
> Linus' tree?
> 
> Please also detail the steps you have taken to reproduce this issue - and of
> course - if you have made any code changes to make the latest UVC module 
> compile
> against a v4.9 kernel...
> 
> Building the latest git tree and installing as a module on a v4.9 kernel is
> quite a leap... I wouldn't have expected that to work.
> 
> The code would have to be compiled against a v4.9 kernel directly, and I 
> didn't
> think compiling the UVC driver against older kernels worked.
> 
> (at least it didn't work cleanly when I tried to compile v4.15 against a v4.14
> kernel last month)
> 
> > Now, two device nodes are
> > created for my webcam. This is not normal as it has never happened to
> > me before. If I connect another webcam to my laptop, two more device
> > nodes will be created for this webcam. So two new device nodes are
> > created for a single webcam.
> 
> I believe Guennadi's latest work for handling meta-data (in the latest 
> v4.16-rc1
> I think) will create two device nodes.

That's correct. The lower index node (/dev/video0) is a video node, the 
higher videoo node (/dev/video1) is a metadata node.

> > The name of my webcam appears twice in the device comobox in Guvcview
> > because of this. One of them will not work if I select it.
> 
> It would be expected that only the device with video functions as a streaming
> camera device, while the other would not.

Exactly.

> > My webcam has completely stopped working with Cheese and VLC.
> 
> This part is of particular concern however.
> 
> Guennadi - Have you tested Cheese/VLC with your series?

Sure, with cheese you can specify which camera you need by using its 
--device= parameter. Eventually it's expected, that those programs will be 
updated to recognise metadata nodes and not attempt to use them.

Thanks
Guennadi

> Are there any known issues that need looking at ?
> 
> >> v4l2-ctl --list-devices
> > Laptop_Integrated_Webcam_E4HD:  (usb-:00:1a.0-1.5):
> > /dev/video0
> > /dev/video1
> > 
> >> ls /dev/video*
> > /dev/video0  /dev/video1
> >
> > Have a nice day,
> > Alexandre-Xavier
> 
> Regards
> 
> Kieran Bingham
> 
> 


Re: Bug: Two device nodes created in /dev for a single UVC webcam

2018-02-19 Thread Kieran Bingham
Hi Alexandre,

Thankyou for your bug report,

On 17/02/18 20:47, Alexandre-Xavier Labonté-Lamoureux wrote:
> Hi,
> 
> I'm running Linux 4.9.0-5-amd64 on Debian. I built the drivers from
> the latest git and installed the modules.

Could you please be specific here?

Are you referring to linux-media/master branch or such? The latest from Linus' 
tree?

Please also detail the steps you have taken to reproduce this issue - and of
course - if you have made any code changes to make the latest UVC module compile
against a v4.9 kernel...

Building the latest git tree and installing as a module on a v4.9 kernel is
quite a leap... I wouldn't have expected that to work.

The code would have to be compiled against a v4.9 kernel directly, and I didn't
think compiling the UVC driver against older kernels worked.

(at least it didn't work cleanly when I tried to compile v4.15 against a v4.14
kernel last month)

> Now, two device nodes are
> created for my webcam. This is not normal as it has never happened to
> me before. If I connect another webcam to my laptop, two more device
> nodes will be created for this webcam. So two new device nodes are
> created for a single webcam.

I believe Guennadi's latest work for handling meta-data (in the latest v4.16-rc1
I think) will create two device nodes.


> The name of my webcam appears twice in the device comobox in Guvcview
> because of this. One of them will not work if I select it.

It would be expected that only the device with video functions as a streaming
camera device, while the other would not.


> My webcam has completely stopped working with Cheese and VLC.

This part is of particular concern however.

Guennadi - Have you tested Cheese/VLC with your series?

Are there any known issues that need looking at ?

>> v4l2-ctl --list-devices
> Laptop_Integrated_Webcam_E4HD:  (usb-:00:1a.0-1.5):
> /dev/video0
> /dev/video1
> 
>> ls /dev/video*
> /dev/video0  /dev/video1
>
> Have a nice day,
> Alexandre-Xavier

Regards

Kieran Bingham




Re: [PATCH] media: imx.rst: Fix formatting errors

2018-02-19 Thread Philipp Zabel
On Fri, 2018-02-16 at 17:54 -0800, Steve Longerbeam wrote:
> Fix a few formatting errors.
> 
> Signed-off-by: Steve Longerbeam 

Reviewed-by: Philipp Zabel 

regards
Philipp


Re: [PATCH v2.1 4/9] staging: atomisp: i2c: Disable non-preview configurations

2018-02-19 Thread Sakari Ailus
Hi Hans,

On Mon, Feb 19, 2018 at 02:30:18PM +0100, Hans Verkuil wrote:
> On 02/19/2018 02:27 PM, Sakari Ailus wrote:
> > These sensor drivers have use case specific mode lists. There's no need
> > for this nor there is a standard API for selecting the mode list. Disable
> > configurations for non-preview modes until configuration selection is
> > improved so that all the configurations are always usable.
> 
> It's a bit confusing. This seems contradictory: if there is no need for it,
> then it can be removed. Or there is a need for it, but we don't have a
> standard API to do it. You can't have both, can you?
> 
> Or did you mean that this functionality is currently unused, and that if
> we wanted to use it, we first need a new API? That would actually make sense.

Correct. All it takes might be just to put these modes to the common list.
But I can't test that as I have no hardware. It's easy to implement that
later on though, that's the idea.

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


Re: [PATCH v2.1 4/9] staging: atomisp: i2c: Disable non-preview configurations

2018-02-19 Thread Hans Verkuil
On 02/19/2018 02:27 PM, Sakari Ailus wrote:
> These sensor drivers have use case specific mode lists. There's no need
> for this nor there is a standard API for selecting the mode list. Disable
> configurations for non-preview modes until configuration selection is
> improved so that all the configurations are always usable.

It's a bit confusing. This seems contradictory: if there is no need for it,
then it can be removed. Or there is a need for it, but we don't have a
standard API to do it. You can't have both, can you?

Or did you mean that this functionality is currently unused, and that if
we wanted to use it, we first need a new API? That would actually make sense.

Regards,

Hans

> 
> Signed-off-by: Sakari Ailus 
> ---
> Hi Mauro and Hans,
> 
> Would you like this one better?
> 
>  drivers/staging/media/atomisp/i2c/gc2235.h| 6 ++
>  drivers/staging/media/atomisp/i2c/ov2722.h| 6 ++
>  drivers/staging/media/atomisp/i2c/ov5693/ov5693.h | 6 ++
>  3 files changed, 18 insertions(+)
> 
> diff --git a/drivers/staging/media/atomisp/i2c/gc2235.h 
> b/drivers/staging/media/atomisp/i2c/gc2235.h
> index 45a54fea5466..0e805bcfa4d8 100644
> --- a/drivers/staging/media/atomisp/i2c/gc2235.h
> +++ b/drivers/staging/media/atomisp/i2c/gc2235.h
> @@ -574,6 +574,11 @@ static struct gc2235_resolution gc2235_res_preview[] = {
>  };
>  #define N_RES_PREVIEW (ARRAY_SIZE(gc2235_res_preview))
>  
> +/*
> + * Disable non-preview configurations until the configuration selection is
> + * improved.
> + */
> +#if 0
>  static struct gc2235_resolution gc2235_res_still[] = {
>   {
>   .desc = "gc2235_1600_900_30fps",
> @@ -658,6 +663,7 @@ static struct gc2235_resolution gc2235_res_video[] = {
>  
>  };
>  #define N_RES_VIDEO (ARRAY_SIZE(gc2235_res_video))
> +#endif
>  
>  static struct gc2235_resolution *gc2235_res = gc2235_res_preview;
>  static unsigned long N_RES = N_RES_PREVIEW;
> diff --git a/drivers/staging/media/atomisp/i2c/ov2722.h 
> b/drivers/staging/media/atomisp/i2c/ov2722.h
> index d8a973d71699..028b048f 100644
> --- a/drivers/staging/media/atomisp/i2c/ov2722.h
> +++ b/drivers/staging/media/atomisp/i2c/ov2722.h
> @@ -1148,6 +1148,11 @@ struct ov2722_resolution ov2722_res_preview[] = {
>  };
>  #define N_RES_PREVIEW (ARRAY_SIZE(ov2722_res_preview))
>  
> +/*
> + * Disable non-preview configurations until the configuration selection is
> + * improved.
> + */
> +#if 0
>  struct ov2722_resolution ov2722_res_still[] = {
>   {
>   .desc = "ov2722_480P_30fps",
> @@ -1250,6 +1255,7 @@ struct ov2722_resolution ov2722_res_video[] = {
>   },
>  };
>  #define N_RES_VIDEO (ARRAY_SIZE(ov2722_res_video))
> +#endif
>  
>  static struct ov2722_resolution *ov2722_res = ov2722_res_preview;
>  static unsigned long N_RES = N_RES_PREVIEW;
> diff --git a/drivers/staging/media/atomisp/i2c/ov5693/ov5693.h 
> b/drivers/staging/media/atomisp/i2c/ov5693/ov5693.h
> index 68cfcb4a6c3c..6d27dd849a62 100644
> --- a/drivers/staging/media/atomisp/i2c/ov5693/ov5693.h
> +++ b/drivers/staging/media/atomisp/i2c/ov5693/ov5693.h
> @@ -1147,6 +1147,11 @@ struct ov5693_resolution ov5693_res_preview[] = {
>  };
>  #define N_RES_PREVIEW (ARRAY_SIZE(ov5693_res_preview))
>  
> +/*
> + * Disable non-preview configurations until the configuration selection is
> + * improved.
> + */
> +#if 0
>  struct ov5693_resolution ov5693_res_still[] = {
>   {
>   .desc = "ov5693_736x496_30fps",
> @@ -1364,6 +1369,7 @@ struct ov5693_resolution ov5693_res_video[] = {
>   },
>  };
>  #define N_RES_VIDEO (ARRAY_SIZE(ov5693_res_video))
> +#endif
>  
>  static struct ov5693_resolution *ov5693_res = ov5693_res_preview;
>  static unsigned long N_RES = N_RES_PREVIEW;
> 



[PATCH v2.1 4/9] staging: atomisp: i2c: Disable non-preview configurations

2018-02-19 Thread Sakari Ailus
These sensor drivers have use case specific mode lists. There's no need
for this nor there is a standard API for selecting the mode list. Disable
configurations for non-preview modes until configuration selection is
improved so that all the configurations are always usable.

Signed-off-by: Sakari Ailus 
---
Hi Mauro and Hans,

Would you like this one better?

 drivers/staging/media/atomisp/i2c/gc2235.h| 6 ++
 drivers/staging/media/atomisp/i2c/ov2722.h| 6 ++
 drivers/staging/media/atomisp/i2c/ov5693/ov5693.h | 6 ++
 3 files changed, 18 insertions(+)

diff --git a/drivers/staging/media/atomisp/i2c/gc2235.h 
b/drivers/staging/media/atomisp/i2c/gc2235.h
index 45a54fea5466..0e805bcfa4d8 100644
--- a/drivers/staging/media/atomisp/i2c/gc2235.h
+++ b/drivers/staging/media/atomisp/i2c/gc2235.h
@@ -574,6 +574,11 @@ static struct gc2235_resolution gc2235_res_preview[] = {
 };
 #define N_RES_PREVIEW (ARRAY_SIZE(gc2235_res_preview))
 
+/*
+ * Disable non-preview configurations until the configuration selection is
+ * improved.
+ */
+#if 0
 static struct gc2235_resolution gc2235_res_still[] = {
{
.desc = "gc2235_1600_900_30fps",
@@ -658,6 +663,7 @@ static struct gc2235_resolution gc2235_res_video[] = {
 
 };
 #define N_RES_VIDEO (ARRAY_SIZE(gc2235_res_video))
+#endif
 
 static struct gc2235_resolution *gc2235_res = gc2235_res_preview;
 static unsigned long N_RES = N_RES_PREVIEW;
diff --git a/drivers/staging/media/atomisp/i2c/ov2722.h 
b/drivers/staging/media/atomisp/i2c/ov2722.h
index d8a973d71699..028b048f 100644
--- a/drivers/staging/media/atomisp/i2c/ov2722.h
+++ b/drivers/staging/media/atomisp/i2c/ov2722.h
@@ -1148,6 +1148,11 @@ struct ov2722_resolution ov2722_res_preview[] = {
 };
 #define N_RES_PREVIEW (ARRAY_SIZE(ov2722_res_preview))
 
+/*
+ * Disable non-preview configurations until the configuration selection is
+ * improved.
+ */
+#if 0
 struct ov2722_resolution ov2722_res_still[] = {
{
.desc = "ov2722_480P_30fps",
@@ -1250,6 +1255,7 @@ struct ov2722_resolution ov2722_res_video[] = {
},
 };
 #define N_RES_VIDEO (ARRAY_SIZE(ov2722_res_video))
+#endif
 
 static struct ov2722_resolution *ov2722_res = ov2722_res_preview;
 static unsigned long N_RES = N_RES_PREVIEW;
diff --git a/drivers/staging/media/atomisp/i2c/ov5693/ov5693.h 
b/drivers/staging/media/atomisp/i2c/ov5693/ov5693.h
index 68cfcb4a6c3c..6d27dd849a62 100644
--- a/drivers/staging/media/atomisp/i2c/ov5693/ov5693.h
+++ b/drivers/staging/media/atomisp/i2c/ov5693/ov5693.h
@@ -1147,6 +1147,11 @@ struct ov5693_resolution ov5693_res_preview[] = {
 };
 #define N_RES_PREVIEW (ARRAY_SIZE(ov5693_res_preview))
 
+/*
+ * Disable non-preview configurations until the configuration selection is
+ * improved.
+ */
+#if 0
 struct ov5693_resolution ov5693_res_still[] = {
{
.desc = "ov5693_736x496_30fps",
@@ -1364,6 +1369,7 @@ struct ov5693_resolution ov5693_res_video[] = {
},
 };
 #define N_RES_VIDEO (ARRAY_SIZE(ov5693_res_video))
+#endif
 
 static struct ov5693_resolution *ov5693_res = ov5693_res_preview;
 static unsigned long N_RES = N_RES_PREVIEW;
-- 
2.11.0



[RFC PATCH] Add core tuner_standby op, use where needed

2018-02-19 Thread Hans Verkuil
The v4l2_subdev core s_power op was used to two different things: power on/off
sensors or video decoders/encoders and to put a tuner in standby (and only the
tuner). There is no 'tuner wakeup' op, that's done automatically when the tuner
is accessed.

The danger with calling (s_power, 0) to put a tuner into standby is that it is
usually broadcast for all subdevs. So a video receiver subdev that also supports
s_power will also be powered off, and since there is no corresponding (s_power, 
1)
they will never be powered on again.

In addition, this is specifically meant for tuners only since they draw the most
current.

This patch adds a new core op called 'tuner_standby' and replaces all calls to
(s_power, 0) by tuner_standby. This prevents confusion between the two uses of
s_power. Note that there is no overlap: bridge drivers either just want to put
the tuner into standby, or they deal with powering on/off sensors. Never both.

This also makes it easier to replace s_power for the remaining bridge drivers
with some PM code later.

Whether we want something similar for tuners in the future is a separate topic.
There is a lot of legacy code surrounding tuners, and I am very hesitant about
making changes there.

Signed-off-by: Hans Verkuil 
---
diff --git a/drivers/media/pci/cx23885/cx23885-core.c 
b/drivers/media/pci/cx23885/cx23885-core.c
index 8f63df1cb418..4e9cd88e573e 100644
--- a/drivers/media/pci/cx23885/cx23885-core.c
+++ b/drivers/media/pci/cx23885/cx23885-core.c
@@ -965,7 +965,7 @@ static int cx23885_dev_setup(struct cx23885_dev *dev)
cx23885_i2c_register(>i2c_bus[1]);
cx23885_i2c_register(>i2c_bus[2]);
cx23885_card_setup(dev);
-   call_all(dev, core, s_power, 0);
+   call_all(dev, core, tuner_standby);
cx23885_ir_init(dev);

if (dev->board == CX23885_BOARD_VIEWCAST_460E) {
diff --git a/drivers/media/pci/cx23885/cx23885-dvb.c 
b/drivers/media/pci/cx23885/cx23885-dvb.c
index 700422b538c0..d0560fd4501c 100644
--- a/drivers/media/pci/cx23885/cx23885-dvb.c
+++ b/drivers/media/pci/cx23885/cx23885-dvb.c
@@ -2514,8 +2514,8 @@ static int dvb_register(struct cx23885_tsport *port)
fe1->dvb.frontend->ops.ts_bus_ctrl = cx23885_dvb_bus_ctrl;
 #endif

-   /* Put the analog decoder in standby to keep it quiet */
-   call_all(dev, core, s_power, 0);
+   /* Put the tuner in standby to keep it quiet */
+   call_all(dev, core, tuner_standby);

if (fe0->dvb.frontend->ops.analog_ops.standby)
fe0->dvb.frontend->ops.analog_ops.standby(fe0->dvb.frontend);
diff --git a/drivers/media/pci/cx88/cx88-cards.c 
b/drivers/media/pci/cx88/cx88-cards.c
index 6df21b29ea17..cdb15f378db4 100644
--- a/drivers/media/pci/cx88/cx88-cards.c
+++ b/drivers/media/pci/cx88/cx88-cards.c
@@ -3592,7 +3592,7 @@ static void cx88_card_setup(struct cx88_core *core)
ctl.fname);
call_all(core, tuner, s_config, _cfg);
}
-   call_all(core, core, s_power, 0);
+   call_all(core, core, tuner_standby);
 }

 /* -- */
diff --git a/drivers/media/pci/cx88/cx88-dvb.c 
b/drivers/media/pci/cx88/cx88-dvb.c
index 49a335f4603e..0aa56d505004 100644
--- a/drivers/media/pci/cx88/cx88-dvb.c
+++ b/drivers/media/pci/cx88/cx88-dvb.c
@@ -1631,8 +1631,8 @@ static int dvb_register(struct cx8802_dev *dev)
if (fe1)
fe1->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl;

-   /* Put the analog decoder in standby to keep it quiet */
-   call_all(core, core, s_power, 0);
+   /* Put the tuner in standby to keep it quiet */
+   call_all(core, core, tuner_standby);

/* register everything */
res = vb2_dvb_register_bus(>frontends, THIS_MODULE, dev,
diff --git a/drivers/media/pci/saa7134/saa7134-video.c 
b/drivers/media/pci/saa7134/saa7134-video.c
index 1ca6a32ad10e..bd710836a072 100644
--- a/drivers/media/pci/saa7134/saa7134-video.c
+++ b/drivers/media/pci/saa7134/saa7134-video.c
@@ -1200,7 +1200,7 @@ static int video_release(struct file *file)
saa_andorb(SAA7134_OFMT_DATA_A, 0x1f, 0);
saa_andorb(SAA7134_OFMT_DATA_B, 0x1f, 0);

-   saa_call_all(dev, core, s_power, 0);
+   saa_call_all(dev, core, tuner_standby);
if (vdev->vfl_type == VFL_TYPE_RADIO)
saa_call_all(dev, core, ioctl, SAA6588_CMD_CLOSE, );
mutex_unlock(>lock);
diff --git a/drivers/media/tuners/e4000.c b/drivers/media/tuners/e4000.c
index 564a000f503e..2733b7dfe82f 100644
--- a/drivers/media/tuners/e4000.c
+++ b/drivers/media/tuners/e4000.c
@@ -293,18 +293,13 @@ static inline struct e4000_dev 
*e4000_subdev_to_dev(struct v4l2_subdev *sd)
return container_of(sd, struct e4000_dev, sd);
 }

-static int e4000_s_power(struct v4l2_subdev *sd, int on)
+static int e4000_tuner_standby(struct v4l2_subdev *sd)
 {
struct e4000_dev *dev = e4000_subdev_to_dev(sd);

  1   2   >