[PATCH v2] media: i2c: wm9090: replace codec to component

2018-03-28 Thread Kuninori Morimoto

From: Kuninori Morimoto 

Now we can replace Codec to Component. Let's do it.

Note:
xxx_codec_xxx() ->  xxx_component_xxx()
.idle_bias_off = 0  ->  .idle_bias_on = 1
.ignore_pmdown_time = 0 ->  .use_pmdown_time = 1
-   ->  .endianness = 1
-   ->  .non_legacy_dai_naming = 1

Signed-off-by: Kuninori Morimoto 
---
v1 -> v2

 - fixup .remove return

 drivers/media/i2c/tda1997x.c | 21 +++--
 1 file changed, 11 insertions(+), 10 deletions(-)

diff --git a/drivers/media/i2c/tda1997x.c b/drivers/media/i2c/tda1997x.c
index 3021913..2dc4df5 100644
--- a/drivers/media/i2c/tda1997x.c
+++ b/drivers/media/i2c/tda1997x.c
@@ -2444,7 +2444,7 @@ static int tda1997x_pcm_startup(struct snd_pcm_substream 
*substream,
struct snd_soc_dai *dai)
 {
struct tda1997x_state *state = snd_soc_dai_get_drvdata(dai);
-   struct snd_soc_codec *codec = dai->codec;
+   struct snd_soc_component *component = dai->component;
struct snd_pcm_runtime *rtd = substream->runtime;
int rate, err;
 
@@ -2452,11 +2452,11 @@ static int tda1997x_pcm_startup(struct 
snd_pcm_substream *substream,
err = snd_pcm_hw_constraint_minmax(rtd, SNDRV_PCM_HW_PARAM_RATE,
   rate, rate);
if (err < 0) {
-   dev_err(codec->dev, "failed to constrain samplerate to %dHz\n",
+   dev_err(component->dev, "failed to constrain samplerate to 
%dHz\n",
rate);
return err;
}
-   dev_info(codec->dev, "set samplerate constraint to %dHz\n", rate);
+   dev_info(component->dev, "set samplerate constraint to %dHz\n", rate);
 
return 0;
 }
@@ -2479,20 +2479,22 @@ static int tda1997x_pcm_startup(struct 
snd_pcm_substream *substream,
.ops = _dai_ops,
 };
 
-static int tda1997x_codec_probe(struct snd_soc_codec *codec)
+static int tda1997x_codec_probe(struct snd_soc_component *component)
 {
return 0;
 }
 
-static int tda1997x_codec_remove(struct snd_soc_codec *codec)
+static void tda1997x_codec_remove(struct snd_soc_component *component)
 {
-   return 0;
 }
 
-static struct snd_soc_codec_driver tda1997x_codec_driver = {
+static struct snd_soc_component_driver tda1997x_codec_driver = {
.probe = tda1997x_codec_probe,
.remove = tda1997x_codec_remove,
-   .reg_word_size = sizeof(u16),
+   .idle_bias_on   = 1,
+   .use_pmdown_time= 1,
+   .endianness = 1,
+   .non_legacy_dai_naming  = 1,
 };
 
 static int tda1997x_probe(struct i2c_client *client,
@@ -2737,7 +2739,7 @@ static int tda1997x_probe(struct i2c_client *client,
else
formats = SNDRV_PCM_FMTBIT_S16_LE;
tda1997x_audio_dai.capture.formats = formats;
-   ret = snd_soc_register_codec(>client->dev,
+   ret = devm_snd_soc_register_component(>client->dev,
 _codec_driver,
 _audio_dai, 1);
if (ret) {
@@ -2782,7 +2784,6 @@ static int tda1997x_remove(struct i2c_client *client)
struct tda1997x_platform_data *pdata = >pdata;
 
if (pdata->audout_format) {
-   snd_soc_unregister_codec(>dev);
mutex_destroy(>audio_lock);
}
 
-- 
1.9.1



Re: [PATCH] media: i2c: wm9090: replace codec to component

2018-03-28 Thread Kuninori Morimoto
Hi

Thank you for this report.
I will post v2 patch, soon

kbuild test robot wrote:
> 
> [1  ]
> Hi Kuninori,
> 
> Thank you for the patch! Yet something to improve:
> 
> [auto build test ERROR on linuxtv-media/master]
> [also build test ERROR on next-20180328]
> [cannot apply to v4.16-rc7]
> [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/Kuninori-Morimoto/media-i2c-wm9090-replace-codec-to-component/20180329-082843
> 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/i2c/tda1997x.c:2494:12: error: initialization from 
> >> incompatible pointer type [-Werror=incompatible-pointer-types]
>  .remove = tda1997x_codec_remove,
>^
>drivers/media/i2c/tda1997x.c:2494:12: note: (near initialization for 
> 'tda1997x_codec_driver.remove')
>cc1: some warnings being treated as errors
> 
> vim +2494 drivers/media/i2c/tda1997x.c
> 
> 9ac0038d Tim Harvey2018-02-15  2491  
> b534b135 Kuninori Morimoto 2018-03-28  2492  static struct 
> snd_soc_component_driver tda1997x_codec_driver = {
> 9ac0038d Tim Harvey2018-02-15  2493   .probe = tda1997x_codec_probe,
> 9ac0038d Tim Harvey2018-02-15 @2494   .remove = tda1997x_codec_remove,
> b534b135 Kuninori Morimoto 2018-03-28  2495   .idle_bias_on   = 1,
> b534b135 Kuninori Morimoto 2018-03-28  2496   .use_pmdown_time= 1,
> b534b135 Kuninori Morimoto 2018-03-28  2497   .endianness = 1,
> b534b135 Kuninori Morimoto 2018-03-28  2498   .non_legacy_dai_naming  = 1,
> 9ac0038d Tim Harvey2018-02-15  2499  };
> 9ac0038d Tim Harvey2018-02-15  2500  
> 
> :: The code at line 2494 was first introduced by commit
> :: 9ac0038db9a7e10fc8f425010ec98b7afc2ff621 media: i2c: Add TDA1997x HDMI 
> receiver driver
> 
> :: TO: Tim Harvey <thar...@gateworks.com>
> :: CC: Mauro Carvalho Chehab <mche...@s-opensource.com>
> 
> ---
> 0-DAY kernel test infrastructureOpen Source Technology Center
> https://lists.01.org/pipermail/kbuild-all   Intel Corporation
> [2 .config.gz ]
> 


Re: [PATCH for v3.18 00/18] Backport CVE-2017-13166 fixes to Kernel 3.18

2018-03-28 Thread Greg KH
On Thu, Mar 29, 2018 at 08:22:08AM +0900, Inki Dae wrote:
> Really thanks for doing this. :) There would be many users who use
> Linux-3.18 for their products yet.

For new products?  They really should not be.  The kernel is officially
end-of-life, but I'm keeping it alive for a short while longer just
because too many people seem to still be using it.  However, they are
not actually updating the kernel in their devices, so I don't think I
will be doing many more new 3.18.y releases.

It's a problem when people ask for support, and then don't use the
releases given to them :(

What is keeping you on 3.18.y and not allowing you to move to a newer
kernel version?

thanks,

greg k-h


cron job: media_tree daily build: WARNINGS

2018-03-28 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:   Thu Mar 29 05:00:13 CEST 2018
media-tree git hash:6ccd228e0cfce2a4f44558422d25c60fcb1a6710
media_build git hash:   d16c7406ed6cc5fc20c87c3711741c43039275d2
v4l-utils git hash: 098e402950fd45b5a572cccfe1d103661d418417
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.101-i686: WARNINGS
linux-3.0.101-x86_64: WARNINGS
linux-3.1.10-i686: WARNINGS
linux-3.1.10-x86_64: WARNINGS
linux-3.2.100-i686: WARNINGS
linux-3.2.100-x86_64: WARNINGS
linux-3.3.8-i686: WARNINGS
linux-3.3.8-x86_64: WARNINGS
linux-3.4.113-i686: WARNINGS
linux-3.4.113-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.10-i686: WARNINGS
linux-3.7.10-x86_64: WARNINGS
linux-3.8.13-i686: WARNINGS
linux-3.8.13-x86_64: WARNINGS
linux-3.9.11-i686: WARNINGS
linux-3.9.11-x86_64: WARNINGS
linux-3.10.108-i686: WARNINGS
linux-3.10.108-x86_64: WARNINGS
linux-3.11.10-i686: WARNINGS
linux-3.11.10-x86_64: WARNINGS
linux-3.12.74-i686: WARNINGS
linux-3.12.74-x86_64: WARNINGS
linux-3.13.11-i686: WARNINGS
linux-3.13.11-x86_64: WARNINGS
linux-3.14.79-i686: WARNINGS
linux-3.14.79-x86_64: WARNINGS
linux-3.15.10-i686: WARNINGS
linux-3.15.10-x86_64: WARNINGS
linux-3.16.55-i686: WARNINGS
linux-3.16.55-x86_64: WARNINGS
linux-3.17.8-i686: WARNINGS
linux-3.17.8-x86_64: WARNINGS
linux-3.18.100-i686: WARNINGS
linux-3.18.100-x86_64: WARNINGS
linux-3.19.8-i686: WARNINGS
linux-3.19.8-x86_64: WARNINGS
linux-4.0.9-i686: WARNINGS
linux-4.0.9-x86_64: WARNINGS
linux-4.1.50-i686: WARNINGS
linux-4.1.50-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.99-i686: OK
linux-4.4.99-x86_64: OK
linux-4.5.7-i686: WARNINGS
linux-4.5.7-x86_64: OK
linux-4.6.7-i686: OK
linux-4.6.7-x86_64: OK
linux-4.7.10-i686: OK
linux-4.7.10-x86_64: WARNINGS
linux-4.8.17-i686: OK
linux-4.8.17-x86_64: OK
linux-4.9.87-i686: OK
linux-4.9.87-x86_64: OK
linux-4.10.17-i686: OK
linux-4.10.17-x86_64: OK
linux-4.11.12-i686: OK
linux-4.11.12-x86_64: OK
linux-4.12.14-i686: OK
linux-4.12.14-x86_64: OK
linux-4.13.16-i686: OK
linux-4.13.16-x86_64: OK
linux-4.14.27-i686: OK
linux-4.14.27-x86_64: OK
linux-4.15.10-i686: OK
linux-4.15.10-x86_64: OK
linux-4.16-rc5-i686: OK
linux-4.16-rc5-x86_64: OK
apps: WARNINGS
spec-git: OK
sparse: WARNINGS
smatch: OK

Detailed results are available here:

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

Full logs are available here:

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

The Media Infrastructure API from this daily build is here:

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


Re: [PATCH] media: i2c: wm9090: replace codec to component

2018-03-28 Thread kbuild test robot
Hi Kuninori,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on linuxtv-media/master]
[also build test ERROR on next-20180328]
[cannot apply to v4.16-rc7]
[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/Kuninori-Morimoto/media-i2c-wm9090-replace-codec-to-component/20180329-082843
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/i2c/tda1997x.c:2494:12: error: initialization from 
>> incompatible pointer type [-Werror=incompatible-pointer-types]
 .remove = tda1997x_codec_remove,
   ^
   drivers/media/i2c/tda1997x.c:2494:12: note: (near initialization for 
'tda1997x_codec_driver.remove')
   cc1: some warnings being treated as errors

vim +2494 drivers/media/i2c/tda1997x.c

9ac0038d Tim Harvey2018-02-15  2491  
b534b135 Kuninori Morimoto 2018-03-28  2492  static struct 
snd_soc_component_driver tda1997x_codec_driver = {
9ac0038d Tim Harvey2018-02-15  2493 .probe = tda1997x_codec_probe,
9ac0038d Tim Harvey2018-02-15 @2494 .remove = tda1997x_codec_remove,
b534b135 Kuninori Morimoto 2018-03-28  2495 .idle_bias_on   = 1,
b534b135 Kuninori Morimoto 2018-03-28  2496 .use_pmdown_time= 1,
b534b135 Kuninori Morimoto 2018-03-28  2497 .endianness = 1,
b534b135 Kuninori Morimoto 2018-03-28  2498 .non_legacy_dai_naming  = 1,
9ac0038d Tim Harvey2018-02-15  2499  };
9ac0038d Tim Harvey2018-02-15  2500  

:: The code at line 2494 was first introduced by commit
:: 9ac0038db9a7e10fc8f425010ec98b7afc2ff621 media: i2c: Add TDA1997x HDMI 
receiver driver

:: TO: Tim Harvey <thar...@gateworks.com>
:: CC: Mauro Carvalho Chehab <mche...@s-opensource.com>

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


.config.gz
Description: application/gzip


Re: [linux-sunxi] [PATCH v9 0/2] Initial Allwinner V3s CSI Support

2018-03-28 Thread Yong
Hi,

On Wed, 28 Mar 2018 16:29:47 -0700
Martin Kelly  wrote:

> On 03/05/2018 05:51 PM, Yong Deng wrote:
> > This patchset add initial support for Allwinner V3s CSI.
> > 
> > Allwinner V3s SoC features two CSI module. CSI0 is used for MIPI CSI-2
> > interface and CSI1 is used for parallel interface. This is not
> > documented in datasheet but by test and guess.
> > 
> > This patchset implement a v4l2 framework driver and add a binding
> > documentation for it.
> > 
> > Currently, the driver only support the parallel interface. And has been
> > tested with a BT1120 signal which generating from FPGA. The following
> > fetures are not support with this patchset:
> >- ISP
> >- MIPI-CSI2
> >- Master clock for camera sensor
> >- Power regulator for the front end IC
> > 
> 
> Hi Yong,
> 
> Thanks so much, this driver is a great contribution!
> 
> Unfortunately the board I'm working with (nanopi neo air) uses the MIPI 
> CSI-2 CSI0 interface rather than CSI1. Do you have any plans to support 
> the MIPI CSI-2 interface at some point? If not, do you know the scope of 
> what would be involved?

AFAIK, there is no document about MIPI CSI-2. You can take a look at the
source code in BSP:
https://github.com/friendlyarm/h3_lichee/tree/master/linux-3.4/drivers/media/video/sunxi-vfe/mipi_csi
And try to port it to mainline.

Thanks,
Yong


Re: [linux-sunxi] [PATCH v9 0/2] Initial Allwinner V3s CSI Support

2018-03-28 Thread Martin Kelly

On 03/05/2018 05:51 PM, Yong Deng wrote:

This patchset add initial support for Allwinner V3s CSI.

Allwinner V3s SoC features two CSI module. CSI0 is used for MIPI CSI-2
interface and CSI1 is used for parallel interface. This is not
documented in datasheet but by test and guess.

This patchset implement a v4l2 framework driver and add a binding
documentation for it.

Currently, the driver only support the parallel interface. And has been
tested with a BT1120 signal which generating from FPGA. The following
fetures are not support with this patchset:
   - ISP
   - MIPI-CSI2
   - Master clock for camera sensor
   - Power regulator for the front end IC



Hi Yong,

Thanks so much, this driver is a great contribution!

Unfortunately the board I'm working with (nanopi neo air) uses the MIPI 
CSI-2 CSI0 interface rather than CSI1. Do you have any plans to support 
the MIPI CSI-2 interface at some point? If not, do you know the scope of 
what would be involved?


Re: [PATCH for v3.18 00/18] Backport CVE-2017-13166 fixes to Kernel 3.18

2018-03-28 Thread Inki Dae
Hi Mauro,

2018년 03월 29일 03:12에 Mauro Carvalho Chehab 이(가) 쓴 글:
> Hi Greg,
> 
> Those are the backports meant to solve CVE-2017-13166 on Kernel 3.18.
> 
> It contains two v4l2-ctrls fixes that are required to avoid crashes
> at the test application.
> 
> I wrote two patches myself for Kernel 3.18 in order to solve some
> issues specific for Kernel 3.18 with aren't needed upstream.
> one is actually a one-line change backport. The other one makes
> sure that both 32-bits and 64-bits version of some ioctl calls
> will return the same value for a reserved field.
> 
> I noticed an extra bug while testing it, but the bug also hits upstream,
> and should be backported all the way down all stable/LTS versions.
> So, I'll send it the usual way, after merging upsream.

Really thanks for doing this. :) There would be many users who use Linux-3.18 
for their products yet.

Thanks,
Inki Dae

> 
> Regards,
> Mauro
> 
> 
> Daniel Mentz (2):
>   media: v4l2-compat-ioctl32: Copy v4l2_window->global_alpha
>   media: v4l2-compat-ioctl32.c: refactor compat ioctl32 logic
> 
> Hans Verkuil (12):
>   media: v4l2-ioctl.c: don't copy back the result for -ENOTTY
>   media: v4l2-compat-ioctl32.c: add missing VIDIOC_PREPARE_BUF
>   media: v4l2-compat-ioctl32.c: fix the indentation
>   media: v4l2-compat-ioctl32.c: move 'helper' functions to
> __get/put_v4l2_format32
>   media: v4l2-compat-ioctl32.c: avoid sizeof(type)
>   media: v4l2-compat-ioctl32.c: copy m.userptr in put_v4l2_plane32
>   media: v4l2-compat-ioctl32.c: fix ctrl_is_pointer
>   media: v4l2-compat-ioctl32.c: make ctrl_is_pointer work for subdevs
>   media: v4l2-compat-ioctl32.c: copy clip list in put_v4l2_window32
>   media: v4l2-compat-ioctl32.c: drop pr_info for unknown buffer type
>   media: v4l2-compat-ioctl32.c: don't copy back the result for certain
> errors
>   media: v4l2-ctrls: fix sparse warning
> 
> Mauro Carvalho Chehab (2):
>   media: v4l2-compat-ioctl32: use compat_u64 for video standard
>   media: v4l2-compat-ioctl32: initialize a reserved field
> 
> Ricardo Ribalda (2):
>   vb2: V4L2_BUF_FLAG_DONE is set after DQBUF
>   media: media/v4l2-ctrls: volatiles should not generate CH_VALUE
> 
>  drivers/media/v4l2-core/v4l2-compat-ioctl32.c | 1020 
> +++--
>  drivers/media/v4l2-core/v4l2-ctrls.c  |   96 ++-
>  drivers/media/v4l2-core/v4l2-ioctl.c  |5 +-
>  drivers/media/v4l2-core/videobuf2-core.c  |5 +
>  4 files changed, 691 insertions(+), 435 deletions(-)
> 


Re: [PATCH v4 1/5] dvb-frontends/dvb-pll: add i2c driver support

2018-03-28 Thread Antti Palosaari

On 03/28/2018 08:00 PM, tsk...@gmail.com wrote:

From: Akihiro Tsukada 

registers the module as an i2c driver,
but keeps dvb_pll_attach() untouched for compatibility.

Signed-off-by: Akihiro Tsukada 
---
Changes since v3:
- use standard i2c_device_id instead of dvb_pll_config

  drivers/media/dvb-frontends/dvb-pll.c | 67 +++
  drivers/media/dvb-frontends/dvb-pll.h | 24 +
  2 files changed, 91 insertions(+)

diff --git a/drivers/media/dvb-frontends/dvb-pll.c 
b/drivers/media/dvb-frontends/dvb-pll.c
index 5553b89b804..e2a93aae04f 100644
--- a/drivers/media/dvb-frontends/dvb-pll.c
+++ b/drivers/media/dvb-frontends/dvb-pll.c
@@ -827,6 +827,73 @@ struct dvb_frontend *dvb_pll_attach(struct dvb_frontend 
*fe, int pll_addr,
  }
  EXPORT_SYMBOL(dvb_pll_attach);
  
+

+static int
+dvb_pll_probe(struct i2c_client *client, const struct i2c_device_id *id)
+{
+   struct dvb_pll_config *cfg;
+   struct dvb_frontend *fe;
+   unsigned int desc_id;
+
+   cfg = client->dev.platform_data;
+   fe = cfg->fe;
+   i2c_set_clientdata(client, fe);
+   desc_id = (unsigned int) id->driver_data;
+
+   if (!dvb_pll_attach(fe, client->addr, client->adapter, desc_id))
+   return -ENOMEM;
+
+   dev_info(>dev, "DVB Simple Tuner attached.\n");


Print used pll chip name here


+   return 0;
+}
+
+static int dvb_pll_remove(struct i2c_client *client)
+{
+   struct dvb_frontend *fe;
+
+   fe = i2c_get_clientdata(client);
+   dvb_pll_release(fe);
+   return 0;
+}
+
+
+static const struct i2c_device_id dvb_pll_id[] = {
+   {DVB_PLL_THOMSON_DTT7579_NAME,DVB_PLL_THOMSON_DTT7579},
+   {DVB_PLL_THOMSON_DTT759X_NAME,DVB_PLL_THOMSON_DTT759X},
+   {DVB_PLL_LG_Z201_NAME,DVB_PLL_LG_Z201},
+   {DVB_PLL_UNKNOWN_1_NAME,  DVB_PLL_UNKNOWN_1},
+   {DVB_PLL_TUA6010XS_NAME,  DVB_PLL_TUA6010XS},
+   {DVB_PLL_ENV57H1XD5_NAME, DVB_PLL_ENV57H1XD5},
+   {DVB_PLL_TUA6034_NAME,DVB_PLL_TUA6034},
+   {DVB_PLL_TDA665X_NAME,DVB_PLL_TDA665X},
+   {DVB_PLL_TDED4_NAME,  DVB_PLL_TDED4},
+   {DVB_PLL_TDHU2_NAME,  DVB_PLL_TDHU2},
+   {DVB_PLL_SAMSUNG_TBMV_NAME,   DVB_PLL_SAMSUNG_TBMV},
+   {DVB_PLL_PHILIPS_SD1878_TDA8261_NAME, DVB_PLL_PHILIPS_SD1878_TDA8261},
+   {DVB_PLL_OPERA1_NAME, DVB_PLL_OPERA1},
+   {DVB_PLL_SAMSUNG_DTOS403IH102A_NAME,  DVB_PLL_SAMSUNG_DTOS403IH102A},
+   {DVB_PLL_SAMSUNG_TDTC9251DH0_NAME,DVB_PLL_SAMSUNG_TDTC9251DH0},
+   {DVB_PLL_SAMSUNG_TBDU18132_NAME,  DVB_PLL_SAMSUNG_TBDU18132},
+   {DVB_PLL_SAMSUNG_TBMU24112_NAME,  DVB_PLL_SAMSUNG_TBMU24112},
+   {DVB_PLL_TDEE4_NAME,  DVB_PLL_TDEE4},
+   {DVB_PLL_THOMSON_DTT7520X_NAME,   DVB_PLL_THOMSON_DTT7520X},
+   {}
+};
+
+
+MODULE_DEVICE_TABLE(i2c, dvb_pll_id);
+
+static struct i2c_driver dvb_pll_driver = {
+   .driver = {
+   .name = "dvb_pll",
+   },
+   .probe= dvb_pll_probe,
+   .remove   = dvb_pll_remove,
+   .id_table = dvb_pll_id,
+};
+
+module_i2c_driver(dvb_pll_driver);
+
  MODULE_DESCRIPTION("dvb pll library");
  MODULE_AUTHOR("Gerd Knorr");
  MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb-frontends/dvb-pll.h 
b/drivers/media/dvb-frontends/dvb-pll.h
index ca885e71d2f..e96994bf668 100644
--- a/drivers/media/dvb-frontends/dvb-pll.h
+++ b/drivers/media/dvb-frontends/dvb-pll.h
@@ -30,6 +30,30 @@
  #define DVB_PLL_TDEE418
  #define DVB_PLL_THOMSON_DTT7520X   19
  
+#define DVB_PLL_THOMSON_DTT7579_NAME	"dtt7579"

+#define DVB_PLL_THOMSON_DTT759X_NAME"dtt759x"
+#define DVB_PLL_LG_Z201_NAME"z201"
+#define DVB_PLL_UNKNOWN_1_NAME  "unknown_1"
+#define DVB_PLL_TUA6010XS_NAME  "tua6010xs"
+#define DVB_PLL_ENV57H1XD5_NAME "env57h1xd5"
+#define DVB_PLL_TUA6034_NAME"tua6034"
+#define DVB_PLL_TDA665X_NAME"tda665x"
+#define DVB_PLL_TDED4_NAME  "tded4"
+#define DVB_PLL_TDHU2_NAME  "tdhu2"
+#define DVB_PLL_SAMSUNG_TBMV_NAME   "tbmv"
+#define DVB_PLL_PHILIPS_SD1878_TDA8261_NAME "sd1878_tda8261"
+#define DVB_PLL_OPERA1_NAME "opera1"
+#define DVB_PLL_SAMSUNG_DTOS403IH102A_NAME  "dtos403ih102a"
+#define DVB_PLL_SAMSUNG_TDTC9251DH0_NAME"tdtc9251dh0"
+#define DVB_PLL_SAMSUNG_TBDU18132_NAME  "tbdu18132"
+#define DVB_PLL_SAMSUNG_TBMU24112_NAME  "tbmu24112"
+#define DVB_PLL_TDEE4_NAME  "tdee4"
+#define DVB_PLL_THOMSON_DTT7520X_NAME   "dtt7520x"


Defining these names like that does not give any value. IMHO better to 
just add those chip names directly to chip id table.



+
+struct dvb_pll_config {
+   struct dvb_frontend *fe;
+};
+
  #if IS_REACHABLE(CONFIG_DVB_PLL)
  /**

Re: [PATCH v4] dvb-usb/friio, dvb-usb-v2/gl861: decompose friio and merge with gl861

2018-03-28 Thread Antti Palosaari



On 03/28/2018 03:37 PM, Akihiro TSUKADA wrote:

Hi,
thanks for the comment.


You should implement i2c adapter to demod driver and not add such glue
to that USB-bridge. I mean that "relayed" stuff, i2c communication to
tuner via demod. I2C-mux may not work I think as there is no gate-style
multiplexing so you probably need plain i2c adapter. There is few
examples already on some demod drivers.


I am afraid that the glue is actually necessary.

host - USB -> gl861 - I2C(1) -> tc90522 (addr:X)
   \- I2C(2) -> tua6034 (addr:Y)

To send an i2c read message to tua6034,
one has to issue two transactions:
  1. write via I2C(1) to addr:X, [ reg:0xfe, val: Y ]
  2. read via I2C(1) from addr:X, [ out_data0, out_data1, ]

The problem is that the transaction 1 is (somehow) implemented with
the different USB request than the other i2c transactions on I2C(1).
(this is confirmed by a packet capture on Windows box).

Although tc90522 already creats the i2c adapter for I2C(2),
tc90522 cannot know/control the USB implementation of I2C(1),
only the bridge driver can do this.


I simply cannot see why it cannot work. Just add i2c adapter and 
suitable logic there. Transaction on your example is simply and there is 
no problem to implement that kind of logic to demod i2c adapter.


If gl861 driver i2c adapter logic is broken it can be fixed easily too. 
It seems to support only i2c writes with len 1 and 2 bytes, but fixing 
it should be easy if you has some sniffs.




Antti

--
http://palosaari.fi/


Re: [PATCH] media: v4l2-compat-ioctl32: don't oops on overlay

2018-03-28 Thread Sakari Ailus
Hi Mauro,

On Wed, Mar 28, 2018 at 02:59:22PM -0300, Mauro Carvalho Chehab wrote:
> At put_v4l2_window32(), it tries to access kp->clips. However,
> kp points to an userspace pointer. So, it should be obtained
> via get_user(), otherwise it can OOPS:
> 
>  vivid-000: ==  END STATUS  ==
>  BUG: unable to handle kernel paging request at fffb18e0
>  IP: [] __put_v4l2_format32+0x169/0x220 [videodev]
>  PGD 3f5776067 PUD 3f576f067 PMD 3f5769067 PTE 80042548f067
>  Oops: 0001 [#1] SMP
>  Modules linked in: vivid videobuf2_vmalloc videobuf2_memops v4l2_dv_timings 
> videobuf2_core v4l2_common videodev media xt_CHECKSUM iptable_mangle 
> ipt_MASQUERADE nf_nat_masquerade_ipv4 iptable_nat nf_nat_ipv4 nf_nat 
> nf_conntrack_ipv4 nf_defrag_ipv4 xt_conntrack nf_conntrack tun bridge stp llc 
> ebtable_filter ebtables ip6table_filter ip6_tables bluetooth rfkill 
> binfmt_misc snd_hda_codec_hdmi i915 snd_hda_intel snd_hda_controller 
> snd_hda_codec intel_rapl x86_pkg_temp_thermal snd_hwdep intel_powerclamp 
> snd_pcm coretemp snd_seq_midi kvm_intel kvm snd_seq_midi_event snd_rawmidi 
> i2c_algo_bit drm_kms_helper snd_seq drm crct10dif_pclmul e1000e 
> snd_seq_device crc32_pclmul snd_timer ghash_clmulni_intel snd mei_me mei ptp 
> pps_core soundcore lpc_ich video crc32c_intel [last unloaded: media]
>  CPU: 2 PID: 28332 Comm: v4l2-compliance Not tainted 3.18.102+ #107
>  Hardware name:  /NUC5i7RYB, BIOS 
> RYBDWi35.86A.0364.2017.0511.0949 05/11/2017
>  task: 8804293f8000 ti: 8803f564 task.ti: 8803f564
>  RIP: 0010:[]  [] 
> __put_v4l2_format32+0x169/0x220 [videodev]
>  RSP: 0018:8803f5643e28  EFLAGS: 00010246
>  RAX:  RBX:  RCX: fffb1ab4
>  RDX: fffb1a68 RSI: fffb18d8 RDI: fffb1aa8
>  RBP: 8803f5643e48 R08: 0001 R09: 8803f54b0378
>  R10:  R11: 0168 R12: fffb18c0
>  R13: fffb1a94 R14: fffb18c8 R15: 
>  FS:  () GS:880456d0(0063) knlGS:f7100980
>  CS:  0010 DS: 002b ES: 002b CR0: 80050033
>  CR2: fffb18e0 CR3: 0003f552b000 CR4: 003407e0
>  Stack:
>   fffb1a94 c0cc5640 0056 8804274f3600
>   8803f5643ed0 c0547e16 0003 8803f5643eb0
>   81301460 88009db44b01 880441942520 8800c0d05640
>  Call Trace:
>   [] v4l2_compat_ioctl32+0x12d6/0x1b1d [videodev]
>   [] ? file_has_perm+0x70/0xc0
>   [] compat_SyS_ioctl+0xec/0x1200
>   [] sysenter_dispatch+0x7/0x21
>  Code: 00 00 48 8b 80 48 c0 ff ff 48 83 e8 38 49 39 c6 0f 87 2b ff ff ff 49 
> 8d 45 1c e8 a3 ce e3 c0 85 c0 0f 85 1a ff ff ff 41 8d 40 ff <4d> 8b 64 24 20 
> 41 89 d5 48 8d 44 40 03 4d 8d 34 c4 eb 15 0f 1f
>  RIP  [] __put_v4l2_format32+0x169/0x220 [videodev]
>  RSP 
>  CR2: fffb18e0
> 
> Tested with vivid driver on Kernel v3.18.102.
> 
> Same bug happens upstream too:
> 
>  BUG: KASAN: user-memory-access in __put_v4l2_format32+0x98/0x4d0 [videodev]
>  Read of size 8 at addr ffe48400 by task v4l2-compliance/8713
> 
>  CPU: 0 PID: 8713 Comm: v4l2-compliance Not tainted 4.16.0-rc4+ #108
>  Hardware name:  /NUC5i7RYB, BIOS RYBDWi35.86A.0364.2017.0511.0949 05/11/2017
>  Call Trace:
>   dump_stack+0x5c/0x7c
>   kasan_report+0x164/0x380
>   ? __put_v4l2_format32+0x98/0x4d0 [videodev]
>   __put_v4l2_format32+0x98/0x4d0 [videodev]
>   v4l2_compat_ioctl32+0x1aec/0x27a0 [videodev]
>   ? __fsnotify_inode_delete+0x20/0x20
>   ? __put_v4l2_format32+0x4d0/0x4d0 [videodev]
>   compat_SyS_ioctl+0x646/0x14d0
>   ? do_ioctl+0x30/0x30
>   do_fast_syscall_32+0x191/0x3f4
>   entry_SYSENTER_compat+0x6b/0x7a
>  ==
>  Disabling lock debugging due to kernel taint
>  BUG: unable to handle kernel paging request at ffe48400
>  IP: __put_v4l2_format32+0x98/0x4d0 [videodev]
>  PGD 3a22fb067 P4D 3a22fb067 PUD 39b6f0067 PMD 39b6f1067 PTE 8003256af067
>  Oops: 0001 [#1] SMP KASAN
>  Modules linked in: vivid videobuf2_vmalloc videobuf2_dma_contig 
> videobuf2_memops v4l2_tpg v4l2_dv_timings videobuf2_v4l2 videobuf2_common 
> v4l2_common videodev xt_CHECKSUM iptable_mangle ipt_MASQUERADE 
> nf_nat_masquerade_ipv4 iptable_nat nf_nat_ipv4 nf_nat nf_conntrack_ipv4 
> nf_defrag_ipv4 xt_conntrack nf_conntrack libcrc32c tun bridge stp llc 
> ebtable_filter ebtables ip6table_filter ip6_tables bluetooth rfkill 
> ecdh_generic binfmt_misc snd_hda_codec_hdmi intel_rapl x86_pkg_temp_thermal 
> intel_powerclamp i915 coretemp snd_hda_intel snd_hda_codec kvm_intel 
> snd_hwdep snd_hda_core kvm snd_pcm irqbypass crct10dif_pclmul crc32_pclmul 
> snd_seq_midi ghash_clmulni_intel snd_seq_midi_event i2c_algo_bit intel_cstate 
> snd_rawmidi intel_uncore snd_seq drm_kms_helper e1000e snd_seq_device 
> snd_timer intel_rapl_perf
>   drm ptp snd mei_me mei lpc_ich pps_core 

Re: [PATCH 2/8] PCI: Add pci_find_common_upstream_dev()

2018-03-28 Thread Logan Gunthorpe


On 28/03/18 01:44 PM, Christian König wrote:
> Well, isn't that exactly what dma_map_resource() is good for? As far as 
> I can see it makes sure IOMMU is aware of the access route and 
> translates a CPU address into a PCI Bus address.

> I'm using that with the AMD IOMMU driver and at least there it works 
> perfectly fine.

Yes, it would be nice, but no arch has implemented this yet. We are just
lucky in the x86 case because that arch is simple and doesn't need to do
anything for P2P (partially due to the Bus and CPU addresses being the
same). But in the general case, you can't rely on it.

>>> Yeah, but not for ours. See if you want to do real peer 2 peer you need
>>> to keep both the operation as well as the direction into account.
>> Not sure what you are saying here... I'm pretty sure we are doing "real"
>> peer 2 peer...
>>
>>> For example when you can do writes between A and B that doesn't mean
>>> that writes between B and A work. And reads are generally less likely to
>>> work than writes. etc...
>> If both devices are behind a switch then the PCI spec guarantees that A
>> can both read and write B and vice versa.
> 
> Sorry to say that, but I know a whole bunch of PCI devices which 
> horrible ignores that.

Can you elaborate? As far as the device is concerned it shouldn't know
whether a request comes from a peer or from the host. If it does do
crazy stuff like that it's well out of spec. It's up to the switch (or
root complex if good support exists) to route the request to the device
and it's the root complex that tends to be what drops the load requests
which causes the asymmetries.

Logan


Re: [PATCH 2/8] PCI: Add pci_find_common_upstream_dev()

2018-03-28 Thread Christian König

Am 28.03.2018 um 20:57 schrieb Logan Gunthorpe:


On 28/03/18 12:28 PM, Christian König wrote:

I'm just using amdgpu as blueprint because I'm the co-maintainer of it
and know it mostly inside out.

Ah, I see.


The resource addresses are translated using dma_map_resource(). As far
as I know that should be sufficient to offload all the architecture
specific stuff to the DMA subsystem.

It's not. The dma_map infrastructure currently has no concept of
peer-to-peer mappings and is designed for system memory only. No
architecture I'm aware of will translate PCI CPU addresses into PCI Bus
addresses which is necessary for any transfer that doesn't go through
the root complex (though on arches like x86 the CPU and Bus address
happen to be the same). There's a lot of people that would like to see
this change but it's likely going to be a long road before it does.


Well, isn't that exactly what dma_map_resource() is good for? As far as 
I can see it makes sure IOMMU is aware of the access route and 
translates a CPU address into a PCI Bus address.



Furthermore, one of the reasons our patch-set avoids going through the
root complex at all is that IOMMU drivers will need to be made aware
that it is operating on P2P memory and do arch-specific things
accordingly. There will also need to be flags that indicate whether a
given IOMMU driver supports this. None of this work is done or easy.


I'm using that with the AMD IOMMU driver and at least there it works 
perfectly fine.



Yeah, but not for ours. See if you want to do real peer 2 peer you need
to keep both the operation as well as the direction into account.

Not sure what you are saying here... I'm pretty sure we are doing "real"
peer 2 peer...


For example when you can do writes between A and B that doesn't mean
that writes between B and A work. And reads are generally less likely to
work than writes. etc...

If both devices are behind a switch then the PCI spec guarantees that A
can both read and write B and vice versa.


Sorry to say that, but I know a whole bunch of PCI devices which 
horrible ignores that.


For example all AMD APUs fall under that category...


Only once you involve root
complexes do you have this problem. Ie. you have unknown support which
may be no support, or partial support (stores but not loads); or
sometimes bad performance; or a combination of both... and you need some
way to figure out all this mess and that is hard. Whoever tries to
implement a white list will have to sort all this out.


Yes, exactly and unfortunately it looks like I'm the poor guy who needs 
to do this :)


Regards,
Christian.



Logan
___
amd-gfx mailing list
amd-...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx




Re: [PATCH 02/15] v4l: vsp1: Remove outdated comment

2018-03-28 Thread Kieran Bingham
On 28/03/18 13:27, Kieran Bingham wrote:
> Hi Laurent,
> 
> Thank you for the patch.
> 
> On 26/02/18 21:45, Laurent Pinchart wrote:
>> The entities in the pipeline are all started when the LIF is setup.
>> Remove the outdated comment that state otherwise.
>>
>> Signed-off-by: Laurent Pinchart 
> 
> I'll start with the easy ones :-)

In fact, couldn't this patch be squashed into [PATCH 01/15] in this series ?

--
Kieran


> Reviewed-by: Kieran Bingham 
> 
>> ---
>>  drivers/media/platform/vsp1/vsp1_drm.c | 6 +-
>>  1 file changed, 1 insertion(+), 5 deletions(-)
>>
>> diff --git a/drivers/media/platform/vsp1/vsp1_drm.c 
>> b/drivers/media/platform/vsp1/vsp1_drm.c
>> index e31fb371eaf9..a1f2ba044092 100644
>> --- a/drivers/media/platform/vsp1/vsp1_drm.c
>> +++ b/drivers/media/platform/vsp1/vsp1_drm.c
>> @@ -221,11 +221,7 @@ int vsp1_du_setup_lif(struct device *dev, unsigned int 
>> pipe_index,
>>  return -EPIPE;
>>  }
>>  
>> -/*
>> - * Enable the VSP1. We don't start the entities themselves right at this
>> - * point as there's no plane configured yet, so we can't start
>> - * processing buffers.
>> - */
>> +/* Enable the VSP1. */
>>  ret = vsp1_device_get(vsp1);
>>  if (ret < 0)
>>  return ret;
>>


Re: [PATCH 08/15] v4l: vsp1: Setup BRU at atomic commit time

2018-03-28 Thread Kieran Bingham
Hi Laurent,

On 26/02/18 21:45, Laurent Pinchart wrote:
> To implement fully dynamic plane assignment to pipelines, we need to
> reassign the BRU and BRS to the DRM pipelines in the atomic commit
> handler. In preparation for this setup factor out the BRU source pad
> code and call it both at LIF setup and atomic commit time.
> 
> Signed-off-by: Laurent Pinchart 

Oops .. skipped one.

But this looks ok to me.

Reviewed-by: Kieran Bingham 

> ---
>  drivers/media/platform/vsp1/vsp1_drm.c | 56 
> +-
>  drivers/media/platform/vsp1/vsp1_drm.h |  5 +++
>  2 files changed, 60 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/media/platform/vsp1/vsp1_drm.c 
> b/drivers/media/platform/vsp1/vsp1_drm.c
> index 7bf697ba7969..6ad8aa6c8138 100644
> --- a/drivers/media/platform/vsp1/vsp1_drm.c
> +++ b/drivers/media/platform/vsp1/vsp1_drm.c
> @@ -148,12 +148,51 @@ static int vsp1_du_pipeline_setup_rpf(struct 
> vsp1_device *vsp1,
>   return 0;
>  }
>  
> +/* Setup the BRU source pad. */
> +static int vsp1_du_pipeline_setup_bru(struct vsp1_device *vsp1,
> +   struct vsp1_pipeline *pipe)
> +{
> + struct vsp1_drm_pipeline *drm_pipe = to_vsp1_drm_pipeline(pipe);
> + struct v4l2_subdev_format format = {
> + .which = V4L2_SUBDEV_FORMAT_ACTIVE,
> + };
> + int ret;
> +
> + /*
> +  * Configure the format on the BRU source and verify that it matches the
> +  * requested format. We don't set the media bus code as it is configured
> +  * on the BRU sink pad 0 and propagated inside the entity, not on the
> +  * source pad.
> +  */
> + format.pad = pipe->bru->source_pad;
> + format.format.width = drm_pipe->width;
> + format.format.height = drm_pipe->height;
> + format.format.field = V4L2_FIELD_NONE;
> +
> + ret = v4l2_subdev_call(>bru->subdev, pad, set_fmt, NULL,
> +);
> + if (ret < 0)
> + return ret;
> +
> + dev_dbg(vsp1->dev, "%s: set format %ux%u (%x) on %s pad %u\n",
> + __func__, format.format.width, format.format.height,
> + format.format.code, BRU_NAME(pipe->bru), pipe->bru->source_pad);
> +
> + if (format.format.width != drm_pipe->width ||
> + format.format.height != drm_pipe->height) {
> + dev_dbg(vsp1->dev, "%s: format mismatch\n", __func__);
> + return -EPIPE;
> + }
> +
> + return 0;
> +}
> +
>  static unsigned int rpf_zpos(struct vsp1_device *vsp1, struct vsp1_rwpf *rpf)
>  {
>   return vsp1->drm->inputs[rpf->entity.index].zpos;
>  }
>  
> -/* Setup the input side of the pipeline (RPFs and BRU sink pads). */
> +/* Setup the input side of the pipeline (RPFs and BRU). */
>  static int vsp1_du_pipeline_setup_input(struct vsp1_device *vsp1,
>   struct vsp1_pipeline *pipe)
>  {
> @@ -191,6 +230,18 @@ static int vsp1_du_pipeline_setup_input(struct 
> vsp1_device *vsp1,
>   inputs[j] = rpf;
>   }
>  
> + /*
> +  * Setup the BRU. This must be done before setting up the RPF input
> +  * pipelines as the BRU sink compose rectangles depend on the BRU source
> +  * format.
> +  */
> + ret = vsp1_du_pipeline_setup_bru(vsp1, pipe);
> + if (ret < 0) {
> + dev_err(vsp1->dev, "%s: failed to setup %s source\n", __func__,
> + BRU_NAME(pipe->bru));
> + return ret;
> + }
> +
>   /* Setup the RPF input pipeline for every enabled input. */
>   for (i = 0; i < pipe->bru->source_pad; ++i) {
>   struct vsp1_rwpf *rpf = inputs[i];
> @@ -355,6 +406,9 @@ int vsp1_du_setup_lif(struct device *dev, unsigned int 
> pipe_index,
>   return 0;
>   }
>  
> + drm_pipe->width = cfg->width;
> + drm_pipe->height = cfg->height;
> +
>   dev_dbg(vsp1->dev, "%s: configuring LIF%u with format %ux%u\n",
>   __func__, pipe_index, cfg->width, cfg->height);
>  
> diff --git a/drivers/media/platform/vsp1/vsp1_drm.h 
> b/drivers/media/platform/vsp1/vsp1_drm.h
> index 9aa19325cbe9..c8dd75ba01f6 100644
> --- a/drivers/media/platform/vsp1/vsp1_drm.h
> +++ b/drivers/media/platform/vsp1/vsp1_drm.h
> @@ -20,12 +20,17 @@
>  /**
>   * vsp1_drm_pipeline - State for the API exposed to the DRM driver
>   * @pipe: the VSP1 pipeline used for display
> + * @width: output display width
> + * @height: output display height
>   * @du_complete: frame completion callback for the DU driver (optional)
>   * @du_private: data to be passed to the du_complete callback
>   */
>  struct vsp1_drm_pipeline {
>   struct vsp1_pipeline pipe;
>  
> + unsigned int width;
> + unsigned int height;
> +
>   /* Frame synchronisation */
>   void (*du_complete)(void *, bool);
>   void *du_private;
> 


Re: [PATCH 2/8] PCI: Add pci_find_common_upstream_dev()

2018-03-28 Thread Logan Gunthorpe


On 28/03/18 12:28 PM, Christian König wrote:
> I'm just using amdgpu as blueprint because I'm the co-maintainer of it 
> and know it mostly inside out.

Ah, I see.

> The resource addresses are translated using dma_map_resource(). As far 
> as I know that should be sufficient to offload all the architecture 
> specific stuff to the DMA subsystem.

It's not. The dma_map infrastructure currently has no concept of
peer-to-peer mappings and is designed for system memory only. No
architecture I'm aware of will translate PCI CPU addresses into PCI Bus
addresses which is necessary for any transfer that doesn't go through
the root complex (though on arches like x86 the CPU and Bus address
happen to be the same). There's a lot of people that would like to see
this change but it's likely going to be a long road before it does.

Furthermore, one of the reasons our patch-set avoids going through the
root complex at all is that IOMMU drivers will need to be made aware
that it is operating on P2P memory and do arch-specific things
accordingly. There will also need to be flags that indicate whether a
given IOMMU driver supports this. None of this work is done or easy.

> Yeah, but not for ours. See if you want to do real peer 2 peer you need 
> to keep both the operation as well as the direction into account.

Not sure what you are saying here... I'm pretty sure we are doing "real"
peer 2 peer...

> For example when you can do writes between A and B that doesn't mean 
> that writes between B and A work. And reads are generally less likely to 
> work than writes. etc...

If both devices are behind a switch then the PCI spec guarantees that A
can both read and write B and vice versa. Only once you involve root
complexes do you have this problem. Ie. you have unknown support which
may be no support, or partial support (stores but not loads); or
sometimes bad performance; or a combination of both... and you need some
way to figure out all this mess and that is hard. Whoever tries to
implement a white list will have to sort all this out.

Logan


Re: [PATCH 0/3] Improve latency of IR decoding

2018-03-28 Thread Matthias Reichl
Hi Sean,

On Sat, Mar 24, 2018 at 02:50:42PM +, Sean Young wrote:
> The current IR decoding is much too slow. Many IR protocols rely on
> a trailing space for decoding (e.g. rc-6 needs to know when the bits
> end). The trailing space is generated by the IR timeout, and if this
> is longer than required, keys can be perceived as sticky and slugish.
> 
> The other issue the keyup timer. IR has no concept of a keyup message,
> this is implied by the absence of IR. So, minimising the timeout for
> this further improves the handling.
> 
> With these patches in place, using IR with the builtin decoders is much
> improved and feels very snappy.

thanks a lot for the patches!

I didn't have much time to test yet, but quick checks on
Amlogic/meson-ir (kernel 4.16-rc7 + media tree + your patches)
and Raspberry Pi (RPi foundation kernel 4.14 + my backport of
your patches) look really promising.

I found one issue, though, in ir-sharp-decoder.c max_space must
be set to SHARP_ECHO_SPACE - otherwise we get a timeout between
the normal and inverted message part and decoding fails.

One thing I'm wondering is if the keyup timer marging might
be too tight now. Basically we have just the fixed 10ms marging
from idle timeout. The repeat periods of the protocols are rather
accurate/strict, so (programmable) remotes not sticking to the
official timing might cause repeated keyup/down events if they
are repeating a tad to slow.

I'm not sure if this could be an issue, but maybe we should
add a safety margin to the repeat periods as well? For example
10 or 20 percent of the specced repeat periods. What do you think?

To get some more test coverage I've asked my colleague to
include my backport patch in the LibreELEC testbuilds for
x86 and RPi. We've got some 500 regular users of these so if
something's not working we should find out soon. I just hope I
didn't mess up the backport... Here's the link to my 4.14 patch:

https://github.com/HiassofT/LibreELEC.tv/blob/le9-ir-latency/packages/linux/patches/default/linux-999-improve-ir-timeout-handling.patch

so long & thanks,

Hias

> 
> Sean Young (3):
>   media: rc: set timeout to smallest value required by enabled protocols
>   media: rc: add ioctl to get the current timeout
>   media: rc: per-protocol repeat period and minimum keyup timer
> 
>  Documentation/media/uapi/rc/lirc-func.rst  |  1 +
>  .../media/uapi/rc/lirc-set-rec-timeout.rst | 14 +++--
>  drivers/media/cec/cec-core.c   |  2 +-
>  drivers/media/rc/ir-imon-decoder.c |  1 +
>  drivers/media/rc/ir-jvc-decoder.c  |  1 +
>  drivers/media/rc/ir-mce_kbd-decoder.c  |  1 +
>  drivers/media/rc/ir-nec-decoder.c  |  1 +
>  drivers/media/rc/ir-rc5-decoder.c  |  1 +
>  drivers/media/rc/ir-rc6-decoder.c  |  1 +
>  drivers/media/rc/ir-sanyo-decoder.c|  1 +
>  drivers/media/rc/ir-sharp-decoder.c|  1 +
>  drivers/media/rc/ir-sony-decoder.c |  1 +
>  drivers/media/rc/ir-xmp-decoder.c  |  1 +
>  drivers/media/rc/lirc_dev.c|  9 ++-
>  drivers/media/rc/rc-core-priv.h|  1 +
>  drivers/media/rc/rc-ir-raw.c   | 31 +-
>  drivers/media/rc/rc-main.c | 68 
> +++---
>  include/uapi/linux/lirc.h  |  6 ++
>  18 files changed, 101 insertions(+), 41 deletions(-)
> 
> -- 
> 2.14.3
> 


Re: [PATCH 2/8] PCI: Add pci_find_common_upstream_dev()

2018-03-28 Thread Christian König

Am 28.03.2018 um 18:25 schrieb Logan Gunthorpe:


On 28/03/18 10:02 AM, Christian König wrote:

Yeah, that looks very similar to what I picked up from the older
patches, going to read up on that after my vacation.

Yeah, I was just reading through your patchset and there are a lot of
similarities. Though, I'm not sure what you're trying to accomplish as I
could not find a cover letter and it seems to only enable one driver.


Yeah, it was the last day before my easter vacation and I wanted it out 
of the door.



Is it meant to enable DMA transactions only between two AMD GPUs?


Not really, DMA-buf is a general framework for sharing buffers between 
device drivers.


It is widely used in the GFX stack on laptops with both Intel+AMD, 
Intel+NVIDIA or AMD+AMD graphics devices.


Additional to that ARM uses it quite massively for their GFX stacks 
because they have rendering and displaying device separated.


I'm just using amdgpu as blueprint because I'm the co-maintainer of it 
and know it mostly inside out.



I also don't see where you've taken into account the PCI bus address. On
some architectures this is not the same as the CPU physical address.


The resource addresses are translated using dma_map_resource(). As far 
as I know that should be sufficient to offload all the architecture 
specific stuff to the DMA subsystem.





Just in general why are you interested in the "distance" of the devices?

We've taken a general approach where some drivers may provide p2p memory
(ie. an NVMe card or an RDMA NIC) and other drivers make use of it (ie.
the NVMe-of driver). The orchestrator driver needs to find the most
applicable provider device for a transaction in a situation that may
have multiple providers and multiple clients. So the most applicable
provider is the one that's closest ("distance"-wise) to all the clients
for the P2P transaction.


That seems to make sense.




And BTW: At least for writes that Peer 2 Peer transactions between
different root complexes work is actually more common than the other way
around.

Maybe on x86 with hardware made in the last few years. But on PowerPC,
ARM64, and likely a lot more the chance of support is *much* less. Also,
hardware that only supports P2P stores is hardly full support and is
insufficient for our needs.


Yeah, but not for ours. See if you want to do real peer 2 peer you need 
to keep both the operation as well as the direction into account.


For example when you can do writes between A and B that doesn't mean 
that writes between B and A work. And reads are generally less likely to 
work than writes. etc...


Since the use case I'm targeting for is GFX or GFX+V4L (or GFX+NIC in 
the future) I really need to handle all such use cases as well.





So I'm a bit torn between using a blacklist or a whitelist. A whitelist
is certainly more conservative approach, but that could get a bit long.

I think a whitelist approach is correct. Given old hardware and other
architectures, a black list is going to be too long and too difficult to
comprehensively populate.


Yeah, it would certainly be better if we have something in the root 
complex capabilities. But you're right that a whitelist sounds the less 
painful way.


Regards,
Christian.




Logan
___
amd-gfx mailing list
amd-...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx




[PATCH for v3.18 07/18] media: v4l2-compat-ioctl32.c: copy m.userptr in put_v4l2_plane32

2018-03-28 Thread Mauro Carvalho Chehab
From: Hans Verkuil 

commit 8ed5a59dcb47a6f76034ee760b36e089f3e82529 upstream.

The struct v4l2_plane32 should set m.userptr as well. The same
happens in v4l2_buffer32 and v4l2-compliance tests for this.

Signed-off-by: Hans Verkuil 
Acked-by: Sakari Ailus 
Signed-off-by: Mauro Carvalho Chehab 
Signed-off-by: Sasha Levin 
---
 drivers/media/v4l2-core/v4l2-compat-ioctl32.c | 47 ---
 1 file changed, 28 insertions(+), 19 deletions(-)

diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c 
b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
index b7dd98168a68..a27fd9105948 100644
--- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
+++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
@@ -287,19 +287,24 @@ static int get_v4l2_plane32(struct v4l2_plane __user *up, 
struct v4l2_plane32 __
 sizeof(up->data_offset)))
return -EFAULT;
 
-   if (memory == V4L2_MEMORY_USERPTR) {
+   switch (memory) {
+   case V4L2_MEMORY_MMAP:
+   case V4L2_MEMORY_OVERLAY:
+   if (copy_in_user(>m.mem_offset, >m.mem_offset,
+sizeof(up32->m.mem_offset)))
+   return -EFAULT;
+   break;
+   case V4L2_MEMORY_USERPTR:
if (get_user(p, >m.userptr))
return -EFAULT;
up_pln = compat_ptr(p);
if (put_user((unsigned long)up_pln, >m.userptr))
return -EFAULT;
-   } else if (memory == V4L2_MEMORY_DMABUF) {
+   break;
+   case V4L2_MEMORY_DMABUF:
if (copy_in_user(>m.fd, >m.fd, sizeof(up32->m.fd)))
return -EFAULT;
-   } else {
-   if (copy_in_user(>m.mem_offset, >m.mem_offset,
-sizeof(up32->m.mem_offset)))
-   return -EFAULT;
+   break;
}
 
return 0;
@@ -308,22 +313,32 @@ static int get_v4l2_plane32(struct v4l2_plane __user *up, 
struct v4l2_plane32 __
 static int put_v4l2_plane32(struct v4l2_plane __user *up, struct v4l2_plane32 
__user *up32,
enum v4l2_memory memory)
 {
+   unsigned long p;
+
if (copy_in_user(up32, up, 2 * sizeof(__u32)) ||
copy_in_user(>data_offset, >data_offset,
 sizeof(up->data_offset)))
return -EFAULT;
 
-   /* For MMAP, driver might've set up the offset, so copy it back.
-* USERPTR stays the same (was userspace-provided), so no copying. */
-   if (memory == V4L2_MEMORY_MMAP)
+   switch (memory) {
+   case V4L2_MEMORY_MMAP:
+   case V4L2_MEMORY_OVERLAY:
if (copy_in_user(>m.mem_offset, >m.mem_offset,
 sizeof(up->m.mem_offset)))
return -EFAULT;
-   /* For DMABUF, driver might've set up the fd, so copy it back. */
-   if (memory == V4L2_MEMORY_DMABUF)
+   break;
+   case V4L2_MEMORY_USERPTR:
+   if (get_user(p, >m.userptr) ||
+   put_user((compat_ulong_t)ptr_to_compat((__force void *)p),
+>m.userptr))
+   return -EFAULT;
+   break;
+   case V4L2_MEMORY_DMABUF:
if (copy_in_user(>m.fd, >m.fd,
 sizeof(up->m.fd)))
return -EFAULT;
+   break;
+   }
 
return 0;
 }
@@ -383,6 +398,7 @@ static int get_v4l2_buffer32(struct v4l2_buffer *kp, struct 
v4l2_buffer32 __user
} else {
switch (kp->memory) {
case V4L2_MEMORY_MMAP:
+   case V4L2_MEMORY_OVERLAY:
if (get_user(kp->m.offset, >m.offset))
return -EFAULT;
break;
@@ -396,10 +412,6 @@ static int get_v4l2_buffer32(struct v4l2_buffer *kp, 
struct v4l2_buffer32 __user
kp->m.userptr = (unsigned long)compat_ptr(tmp);
}
break;
-   case V4L2_MEMORY_OVERLAY:
-   if (get_user(kp->m.offset, >m.offset))
-   return -EFAULT;
-   break;
case V4L2_MEMORY_DMABUF:
if (get_user(kp->m.fd, >m.fd))
return -EFAULT;
@@ -456,6 +468,7 @@ static int put_v4l2_buffer32(struct v4l2_buffer *kp, struct 
v4l2_buffer32 __user
} else {
switch (kp->memory) {
case V4L2_MEMORY_MMAP:
+   case V4L2_MEMORY_OVERLAY:
if (put_user(kp->m.offset, >m.offset))
return -EFAULT;
break;
@@ -463,10 +476,6 @@ static int 

[PATCH for v3.18 03/18] media: v4l2-compat-ioctl32.c: add missing VIDIOC_PREPARE_BUF

2018-03-28 Thread Mauro Carvalho Chehab
From: Hans Verkuil 

commit 3ee6d040719ae09110e5cdf24d5386abe5d1b776 upstream.

The result of the VIDIOC_PREPARE_BUF ioctl was never copied back
to userspace since it was missing in the switch.

Signed-off-by: Hans Verkuil 
Acked-by: Sakari Ailus 
Signed-off-by: Mauro Carvalho Chehab 
Signed-off-by: Sasha Levin 
Signed-off-by: Mauro Carvalho Chehab 
---
 drivers/media/v4l2-core/v4l2-compat-ioctl32.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c 
b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
index aa11f02c0a8f..fc4f92a0c985 100644
--- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
+++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
@@ -996,6 +996,7 @@ static long do_video_ioctl(struct file *file, unsigned int 
cmd, unsigned long ar
err = put_v4l2_create32(, up);
break;
 
+   case VIDIOC_PREPARE_BUF:
case VIDIOC_QUERYBUF:
case VIDIOC_QBUF:
case VIDIOC_DQBUF:
-- 
2.14.3



[PATCH for v3.18 15/18] media: v4l2-ctrls: fix sparse warning

2018-03-28 Thread Mauro Carvalho Chehab
From: Hans Verkuil 

The warning is simple:

drivers/media/v4l2-core/v4l2-ctrls.c:1685:15: warning: incorrect type in 
assignment (different address spaces)

but the fix isn't.

The core problem was that the conversion from user to kernelspace was
done at too low a level and that needed to be moved up. That made it possible
to drop pointers to v4l2_ext_control from set_ctrl and validate_new and
clean up this sparse warning because those functions now always operate
on kernelspace pointers.

Signed-off-by: Hans Verkuil 
Signed-off-by: Mauro Carvalho Chehab 
Signed-off-by: Mauro Carvalho Chehab 
---
 drivers/media/v4l2-core/v4l2-ctrls.c | 87 +---
 1 file changed, 52 insertions(+), 35 deletions(-)

diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c 
b/drivers/media/v4l2-core/v4l2-ctrls.c
index 7905ad9ffa35..3c4e22855652 100644
--- a/drivers/media/v4l2-core/v4l2-ctrls.c
+++ b/drivers/media/v4l2-core/v4l2-ctrls.c
@@ -1668,10 +1668,8 @@ static int check_range(enum v4l2_ctrl_type type,
 }
 
 /* Validate a new control */
-static int validate_new(const struct v4l2_ctrl *ctrl,
-   struct v4l2_ext_control *c)
+static int validate_new(const struct v4l2_ctrl *ctrl, union v4l2_ctrl_ptr 
p_new)
 {
-   union v4l2_ctrl_ptr ptr;
unsigned idx;
int err = 0;
 
@@ -1684,19 +1682,14 @@ static int validate_new(const struct v4l2_ctrl *ctrl,
case V4L2_CTRL_TYPE_BOOLEAN:
case V4L2_CTRL_TYPE_BUTTON:
case V4L2_CTRL_TYPE_CTRL_CLASS:
-   ptr.p_s32 = >value;
-   return ctrl->type_ops->validate(ctrl, 0, ptr);
-
case V4L2_CTRL_TYPE_INTEGER64:
-   ptr.p_s64 = >value64;
-   return ctrl->type_ops->validate(ctrl, 0, ptr);
+   return ctrl->type_ops->validate(ctrl, 0, p_new);
default:
break;
}
}
-   ptr.p = c->ptr;
-   for (idx = 0; !err && idx < c->size / ctrl->elem_size; idx++)
-   err = ctrl->type_ops->validate(ctrl, idx, ptr);
+   for (idx = 0; !err && idx < ctrl->elems; idx++)
+   err = ctrl->type_ops->validate(ctrl, idx, p_new);
return err;
 }
 
@@ -3020,6 +3013,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;
+   union v4l2_ctrl_ptr p_new;
 
cs->error_idx = i;
 
@@ -3033,7 +3027,17 @@ static int validate_ctrls(struct v4l2_ext_controls *cs,
   best-effort to avoid that. */
if (set && (ctrl->flags & V4L2_CTRL_FLAG_GRABBED))
return -EBUSY;
-   ret = validate_new(ctrl, >controls[i]);
+   /*
+* Skip validation for now if the payload needs to be copied
+* from userspace into kernelspace. We'll validate those later.
+*/
+   if (ctrl->is_ptr)
+   continue;
+   if (ctrl->type == V4L2_CTRL_TYPE_INTEGER64)
+   p_new.p_s64 = >controls[i].value64;
+   else
+   p_new.p_s32 = >controls[i].value;
+   ret = validate_new(ctrl, p_new);
if (ret)
return ret;
}
@@ -3128,7 +3132,11 @@ 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 {
-   ret = user_to_new(cs->controls + idx, 
helpers[idx].ctrl);
+   struct v4l2_ctrl *ctrl = helpers[idx].ctrl;
+
+   ret = user_to_new(cs->controls + idx, ctrl);
+   if (!ret && ctrl->is_ptr)
+   ret = validate_new(ctrl, ctrl->p_new);
idx = helpers[idx].next;
} while (!ret && idx);
 
@@ -3178,10 +3186,10 @@ int v4l2_subdev_s_ext_ctrls(struct v4l2_subdev *sd, 
struct v4l2_ext_controls *cs
 EXPORT_SYMBOL(v4l2_subdev_s_ext_ctrls);
 
 /* Helper function for VIDIOC_S_CTRL compatibility */
-static int set_ctrl(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl,
-   struct v4l2_ext_control *c, u32 ch_flags)
+static int set_ctrl(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl, u32 ch_flags)
 {
struct v4l2_ctrl *master = ctrl->cluster[0];
+   int ret;
int i;
 
/* Reset the 'is_new' flags of the cluster */
@@ -3189,8 +3197,9 @@ static int set_ctrl(struct v4l2_fh *fh, struct v4l2_ctrl 
*ctrl,
if (master->cluster[i])
master->cluster[i]->is_new = 0;
 
-   if (c)
-  

[PATCH for v3.18 09/18] media: v4l2-compat-ioctl32.c: make ctrl_is_pointer work for subdevs

2018-03-28 Thread Mauro Carvalho Chehab
From: Hans Verkuil 

commit 273caa260035c03d89ad63d72d8cd3d9e5c5e3f1 upstream.

If the device is of type VFL_TYPE_SUBDEV then vdev->ioctl_ops
is NULL so the 'if (!ops->vidioc_query_ext_ctrl)' check would crash.
Add a test for !ops to the condition.

All sub-devices that have controls will use the control framework,
so they do not have an equivalent to ops->vidioc_query_ext_ctrl.
Returning false if ops is NULL is the correct thing to do here.

Fixes: b8c601e8af ("v4l2-compat-ioctl32.c: fix ctrl_is_pointer")

Signed-off-by: Hans Verkuil 
Acked-by: Sakari Ailus 
Reported-by: Laurent Pinchart 
Reviewed-by: Laurent Pinchart 
Signed-off-by: Mauro Carvalho Chehab 
Signed-off-by: Sasha Levin 
---
 drivers/media/v4l2-core/v4l2-compat-ioctl32.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c 
b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
index c78462e79a0a..bd4890769e0b 100644
--- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
+++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
@@ -600,7 +600,7 @@ static inline bool ctrl_is_pointer(struct file *file, u32 
id)
return ctrl && ctrl->is_ptr;
}
 
-   if (!ops->vidioc_query_ext_ctrl)
+   if (!ops || !ops->vidioc_query_ext_ctrl)
return false;
 
return !ops->vidioc_query_ext_ctrl(file, fh, ) &&
-- 
2.14.3



[PATCH for v3.18 04/18] media: v4l2-compat-ioctl32.c: fix the indentation

2018-03-28 Thread Mauro Carvalho Chehab
From: Hans Verkuil 

commit b7b957d429f601d6d1942122b339474f31191d75 upstream.

The indentation of this source is all over the place. Fix this.
This patch only changes whitespace.

Signed-off-by: Hans Verkuil 
Acked-by: Sakari Ailus 
Signed-off-by: Mauro Carvalho Chehab 
Signed-off-by: Sasha Levin 
Signed-off-by: Mauro Carvalho Chehab 
---
 drivers/media/v4l2-core/v4l2-compat-ioctl32.c | 216 +-
 1 file changed, 108 insertions(+), 108 deletions(-)

diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c 
b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
index fc4f92a0c985..866019bbf513 100644
--- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
+++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
@@ -48,11 +48,11 @@ struct v4l2_window32 {
 static int get_v4l2_window32(struct v4l2_window *kp, struct v4l2_window32 
__user *up)
 {
if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_window32)) ||
-   copy_from_user(>w, >w, sizeof(up->w)) ||
-   get_user(kp->field, >field) ||
-   get_user(kp->chromakey, >chromakey) ||
-   get_user(kp->clipcount, >clipcount))
-   return -EFAULT;
+   copy_from_user(>w, >w, sizeof(up->w)) ||
+   get_user(kp->field, >field) ||
+   get_user(kp->chromakey, >chromakey) ||
+   get_user(kp->clipcount, >clipcount))
+   return -EFAULT;
if (kp->clipcount > 2048)
return -EINVAL;
if (kp->clipcount) {
@@ -82,10 +82,10 @@ static int get_v4l2_window32(struct v4l2_window *kp, struct 
v4l2_window32 __user
 static int put_v4l2_window32(struct v4l2_window *kp, struct v4l2_window32 
__user *up)
 {
if (copy_to_user(>w, >w, sizeof(kp->w)) ||
-   put_user(kp->field, >field) ||
-   put_user(kp->chromakey, >chromakey) ||
-   put_user(kp->clipcount, >clipcount))
-   return -EFAULT;
+   put_user(kp->field, >field) ||
+   put_user(kp->chromakey, >chromakey) ||
+   put_user(kp->clipcount, >clipcount))
+   return -EFAULT;
return 0;
 }
 
@@ -97,7 +97,7 @@ static inline int get_v4l2_pix_format(struct v4l2_pix_format 
*kp, struct v4l2_pi
 }
 
 static inline int get_v4l2_pix_format_mplane(struct v4l2_pix_format_mplane *kp,
-   struct v4l2_pix_format_mplane __user *up)
+struct v4l2_pix_format_mplane 
__user *up)
 {
if (copy_from_user(kp, up, sizeof(struct v4l2_pix_format_mplane)))
return -EFAULT;
@@ -112,7 +112,7 @@ static inline int put_v4l2_pix_format(struct 
v4l2_pix_format *kp, struct v4l2_pi
 }
 
 static inline int put_v4l2_pix_format_mplane(struct v4l2_pix_format_mplane *kp,
-   struct v4l2_pix_format_mplane __user *up)
+struct v4l2_pix_format_mplane 
__user *up)
 {
if (copy_to_user(up, kp, sizeof(struct v4l2_pix_format_mplane)))
return -EFAULT;
@@ -200,7 +200,7 @@ static int __get_v4l2_format32(struct v4l2_format *kp, 
struct v4l2_format32 __us
return get_v4l2_sliced_vbi_format(>fmt.sliced, 
>fmt.sliced);
default:
printk(KERN_INFO "compat_ioctl32: unexpected VIDIOC_FMT type 
%d\n",
-   kp->type);
+  kp->type);
return -EINVAL;
}
 }
@@ -241,7 +241,7 @@ static int __put_v4l2_format32(struct v4l2_format *kp, 
struct v4l2_format32 __us
return put_v4l2_sliced_vbi_format(>fmt.sliced, 
>fmt.sliced);
default:
printk(KERN_INFO "compat_ioctl32: unexpected VIDIOC_FMT type 
%d\n",
-   kp->type);
+  kp->type);
return -EINVAL;
}
 }
@@ -275,7 +275,7 @@ static int get_v4l2_standard32(struct v4l2_standard *kp, 
struct v4l2_standard32
 {
/* other fields are not set by the user, nor used by the driver */
if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_standard32)) ||
-   get_user(kp->index, >index))
+   get_user(kp->index, >index))
return -EFAULT;
return 0;
 }
@@ -283,13 +283,13 @@ static int get_v4l2_standard32(struct v4l2_standard *kp, 
struct v4l2_standard32
 static int put_v4l2_standard32(struct v4l2_standard *kp, struct 
v4l2_standard32 __user *up)
 {
if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_standard32)) ||
-   put_user(kp->index, >index) ||
-   copy_to_user(up->id, >id, sizeof(__u64)) ||
-   copy_to_user(up->name, kp->name, 24) ||
-   copy_to_user(>frameperiod, >frameperiod, 

[PATCH for v3.18 10/18] media: v4l2-compat-ioctl32: Copy v4l2_window->global_alpha

2018-03-28 Thread Mauro Carvalho Chehab
From: Daniel Mentz 

commit 025a26fa14f8fd55d50ab284a30c016a5be953d0 upstream.

Commit b2787845fb91 ("V4L/DVB (5289): Add support for video output
overlays.") added the field global_alpha to struct v4l2_window but did
not update the compat layer accordingly. This change adds global_alpha
to struct v4l2_window32 and copies the value for global_alpha back and
forth.

Signed-off-by: Daniel Mentz 
Signed-off-by: Hans Verkuil 
Signed-off-by: Mauro Carvalho Chehab 
Signed-off-by: Sasha Levin 
---
 drivers/media/v4l2-core/v4l2-compat-ioctl32.c | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c 
b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
index bd4890769e0b..fd32c9ccc2bb 100644
--- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
+++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
@@ -45,6 +45,7 @@ struct v4l2_window32 {
compat_caddr_t  clips; /* actually struct v4l2_clip32 * */
__u32   clipcount;
compat_caddr_t  bitmap;
+   __u8global_alpha;
 };
 
 static int get_v4l2_window32(struct v4l2_window *kp, struct v4l2_window32 
__user *up)
@@ -53,7 +54,8 @@ static int get_v4l2_window32(struct v4l2_window *kp, struct 
v4l2_window32 __user
copy_from_user(>w, >w, sizeof(up->w)) ||
get_user(kp->field, >field) ||
get_user(kp->chromakey, >chromakey) ||
-   get_user(kp->clipcount, >clipcount))
+   get_user(kp->clipcount, >clipcount) ||
+   get_user(kp->global_alpha, >global_alpha))
return -EFAULT;
if (kp->clipcount > 2048)
return -EINVAL;
@@ -86,7 +88,8 @@ static int put_v4l2_window32(struct v4l2_window *kp, struct 
v4l2_window32 __user
if (copy_to_user(>w, >w, sizeof(kp->w)) ||
put_user(kp->field, >field) ||
put_user(kp->chromakey, >chromakey) ||
-   put_user(kp->clipcount, >clipcount))
+   put_user(kp->clipcount, >clipcount) ||
+   put_user(kp->global_alpha, >global_alpha))
return -EFAULT;
return 0;
 }
-- 
2.14.3



[PATCH for v3.18 05/18] media: v4l2-compat-ioctl32.c: move 'helper' functions to __get/put_v4l2_format32

2018-03-28 Thread Mauro Carvalho Chehab
From: Hans Verkuil 

commit 486c521510c44a04cd756a9267e7d1e271c8a4ba upstream.

These helper functions do not really help. Move the code to the
__get/put_v4l2_format32 functions.

Signed-off-by: Hans Verkuil 
Acked-by: Sakari Ailus 
Signed-off-by: Mauro Carvalho Chehab 
Signed-off-by: Sasha Levin 
Signed-off-by: Mauro Carvalho Chehab 
---
 drivers/media/v4l2-core/v4l2-compat-ioctl32.c | 84 +--
 1 file changed, 16 insertions(+), 68 deletions(-)

diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c 
b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
index 866019bbf513..702757012dc7 100644
--- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
+++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
@@ -89,64 +89,6 @@ static int put_v4l2_window32(struct v4l2_window *kp, struct 
v4l2_window32 __user
return 0;
 }
 
-static inline int get_v4l2_pix_format(struct v4l2_pix_format *kp, struct 
v4l2_pix_format __user *up)
-{
-   if (copy_from_user(kp, up, sizeof(struct v4l2_pix_format)))
-   return -EFAULT;
-   return 0;
-}
-
-static inline int get_v4l2_pix_format_mplane(struct v4l2_pix_format_mplane *kp,
-struct v4l2_pix_format_mplane 
__user *up)
-{
-   if (copy_from_user(kp, up, sizeof(struct v4l2_pix_format_mplane)))
-   return -EFAULT;
-   return 0;
-}
-
-static inline int put_v4l2_pix_format(struct v4l2_pix_format *kp, struct 
v4l2_pix_format __user *up)
-{
-   if (copy_to_user(up, kp, sizeof(struct v4l2_pix_format)))
-   return -EFAULT;
-   return 0;
-}
-
-static inline int put_v4l2_pix_format_mplane(struct v4l2_pix_format_mplane *kp,
-struct v4l2_pix_format_mplane 
__user *up)
-{
-   if (copy_to_user(up, kp, sizeof(struct v4l2_pix_format_mplane)))
-   return -EFAULT;
-   return 0;
-}
-
-static inline int get_v4l2_vbi_format(struct v4l2_vbi_format *kp, struct 
v4l2_vbi_format __user *up)
-{
-   if (copy_from_user(kp, up, sizeof(struct v4l2_vbi_format)))
-   return -EFAULT;
-   return 0;
-}
-
-static inline int put_v4l2_vbi_format(struct v4l2_vbi_format *kp, struct 
v4l2_vbi_format __user *up)
-{
-   if (copy_to_user(up, kp, sizeof(struct v4l2_vbi_format)))
-   return -EFAULT;
-   return 0;
-}
-
-static inline int get_v4l2_sliced_vbi_format(struct v4l2_sliced_vbi_format 
*kp, struct v4l2_sliced_vbi_format __user *up)
-{
-   if (copy_from_user(kp, up, sizeof(struct v4l2_sliced_vbi_format)))
-   return -EFAULT;
-   return 0;
-}
-
-static inline int put_v4l2_sliced_vbi_format(struct v4l2_sliced_vbi_format 
*kp, struct v4l2_sliced_vbi_format __user *up)
-{
-   if (copy_to_user(up, kp, sizeof(struct v4l2_sliced_vbi_format)))
-   return -EFAULT;
-   return 0;
-}
-
 struct v4l2_format32 {
__u32   type;   /* enum v4l2_buf_type */
union {
@@ -184,20 +126,23 @@ static int __get_v4l2_format32(struct v4l2_format *kp, 
struct v4l2_format32 __us
switch (kp->type) {
case V4L2_BUF_TYPE_VIDEO_CAPTURE:
case V4L2_BUF_TYPE_VIDEO_OUTPUT:
-   return get_v4l2_pix_format(>fmt.pix, >fmt.pix);
+   return copy_from_user(>fmt.pix, >fmt.pix,
+ sizeof(kp->fmt.pix)) ? -EFAULT : 0;
case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
-   return get_v4l2_pix_format_mplane(>fmt.pix_mp,
- >fmt.pix_mp);
+   return copy_from_user(>fmt.pix_mp, >fmt.pix_mp,
+ sizeof(kp->fmt.pix_mp)) ? -EFAULT : 0;
case V4L2_BUF_TYPE_VIDEO_OVERLAY:
case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
return get_v4l2_window32(>fmt.win, >fmt.win);
case V4L2_BUF_TYPE_VBI_CAPTURE:
case V4L2_BUF_TYPE_VBI_OUTPUT:
-   return get_v4l2_vbi_format(>fmt.vbi, >fmt.vbi);
+   return copy_from_user(>fmt.vbi, >fmt.vbi,
+ sizeof(kp->fmt.vbi)) ? -EFAULT : 0;
case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
-   return get_v4l2_sliced_vbi_format(>fmt.sliced, 
>fmt.sliced);
+   return copy_from_user(>fmt.sliced, >fmt.sliced,
+ sizeof(kp->fmt.sliced)) ? -EFAULT : 0;
default:
printk(KERN_INFO "compat_ioctl32: unexpected VIDIOC_FMT type 
%d\n",
   kp->type);
@@ -225,20 +170,23 @@ static int __put_v4l2_format32(struct v4l2_format *kp, 
struct v4l2_format32 __us
switch (kp->type) {
case V4L2_BUF_TYPE_VIDEO_CAPTURE:
case V4L2_BUF_TYPE_VIDEO_OUTPUT:
-  

[PATCH for v3.18 13/18] media: v4l2-compat-ioctl32.c: don't copy back the result for certain errors

2018-03-28 Thread Mauro Carvalho Chehab
From: Hans Verkuil 

commit d83a8243aaefe62ace433e4384a4f077bed86acb upstream.

Some ioctls need to copy back the result even if the ioctl returned
an error. However, don't do this for the error code -ENOTTY.
It makes no sense in that cases.

Signed-off-by: Hans Verkuil 
Acked-by: Sakari Ailus 
Signed-off-by: Mauro Carvalho Chehab 
Signed-off-by: Sasha Levin 
---
 drivers/media/v4l2-core/v4l2-compat-ioctl32.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c 
b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
index a5f74a508f58..9e5807842dad 100644
--- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
+++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
@@ -943,6 +943,9 @@ static long do_video_ioctl(struct file *file, unsigned int 
cmd, unsigned long ar
set_fs(old_fs);
}
 
+   if (err == -ENOTTY)
+   return err;
+
/* Special case: even after an error we need to put the
   results back for these ioctls since the error_idx will
   contain information on which control failed. */
-- 
2.14.3



[PATCH for v3.18 11/18] media: v4l2-compat-ioctl32.c: copy clip list in put_v4l2_window32

2018-03-28 Thread Mauro Carvalho Chehab
From: Hans Verkuil 

commit a751be5b142ef6bcbbb96d9899516f4d9c8d0ef4 upstream.

put_v4l2_window32() didn't copy back the clip list to userspace.
Drivers can update the clip rectangles, so this should be done.

Signed-off-by: Hans Verkuil 
Acked-by: Sakari Ailus 
Signed-off-by: Mauro Carvalho Chehab 
Signed-off-by: Sasha Levin 
---
 drivers/media/v4l2-core/v4l2-compat-ioctl32.c | 61 ++-
 1 file changed, 41 insertions(+), 20 deletions(-)

diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c 
b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
index fd32c9ccc2bb..8a5c93ce4348 100644
--- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
+++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
@@ -50,6 +50,11 @@ struct v4l2_window32 {
 
 static int get_v4l2_window32(struct v4l2_window *kp, struct v4l2_window32 
__user *up)
 {
+   struct v4l2_clip32 __user *uclips;
+   struct v4l2_clip __user *kclips;
+   compat_caddr_t p;
+   u32 n;
+
if (!access_ok(VERIFY_READ, up, sizeof(*up)) ||
copy_from_user(>w, >w, sizeof(up->w)) ||
get_user(kp->field, >field) ||
@@ -59,38 +64,54 @@ static int get_v4l2_window32(struct v4l2_window *kp, struct 
v4l2_window32 __user
return -EFAULT;
if (kp->clipcount > 2048)
return -EINVAL;
-   if (kp->clipcount) {
-   struct v4l2_clip32 __user *uclips;
-   struct v4l2_clip __user *kclips;
-   int n = kp->clipcount;
-   compat_caddr_t p;
-
-   if (get_user(p, >clips))
-   return -EFAULT;
-   uclips = compat_ptr(p);
-   kclips = compat_alloc_user_space(n * sizeof(*kclips));
-   kp->clips = kclips;
-   while (--n >= 0) {
-   if (copy_in_user(>c, >c, 
sizeof(uclips->c)))
-   return -EFAULT;
-   if (put_user(n ? kclips + 1 : NULL, >next))
-   return -EFAULT;
-   uclips += 1;
-   kclips += 1;
-   }
-   } else
+   if (!kp->clipcount) {
kp->clips = NULL;
+   return 0;
+   }
+
+   n = kp->clipcount;
+   if (get_user(p, >clips))
+   return -EFAULT;
+   uclips = compat_ptr(p);
+   kclips = compat_alloc_user_space(n * sizeof(*kclips));
+   kp->clips = kclips;
+   while (n--) {
+   if (copy_in_user(>c, >c, sizeof(uclips->c)))
+   return -EFAULT;
+   if (put_user(n ? kclips + 1 : NULL, >next))
+   return -EFAULT;
+   uclips++;
+   kclips++;
+   }
return 0;
 }
 
 static int put_v4l2_window32(struct v4l2_window *kp, struct v4l2_window32 
__user *up)
 {
+   struct v4l2_clip __user *kclips = kp->clips;
+   struct v4l2_clip32 __user *uclips;
+   u32 n = kp->clipcount;
+   compat_caddr_t p;
+
if (copy_to_user(>w, >w, sizeof(kp->w)) ||
put_user(kp->field, >field) ||
put_user(kp->chromakey, >chromakey) ||
put_user(kp->clipcount, >clipcount) ||
put_user(kp->global_alpha, >global_alpha))
return -EFAULT;
+
+   if (!kp->clipcount)
+   return 0;
+
+   if (get_user(p, >clips))
+   return -EFAULT;
+   uclips = compat_ptr(p);
+   while (n--) {
+   if (copy_in_user(>c, >c, sizeof(uclips->c)))
+   return -EFAULT;
+   uclips++;
+   kclips++;
+   }
return 0;
 }
 
-- 
2.14.3



[PATCH for v3.18 17/18] media: v4l2-compat-ioctl32: use compat_u64 for video standard

2018-03-28 Thread Mauro Carvalho Chehab
Instead of using the "v4l2_std_id" typedef, use compat_u64,
as otherwise it fails to properly handle some ioctls.

Signed-off-by: Mauro Carvalho Chehab 
---
 drivers/media/v4l2-core/v4l2-compat-ioctl32.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c 
b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
index e03aa0961360..c76438dd3ead 100644
--- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
+++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
@@ -686,7 +686,7 @@ struct v4l2_input32 {
__u32type;  /*  Type of input */
__u32audioset;  /*  Associated audios (bitfield) */
__u32tuner; /*  Associated tuner */
-   v4l2_std_id  std;
+   compat_u64   std;
__u32status;
__u32capabilities;
__u32reserved[3];
-- 
2.14.3



[PATCH for v3.18 16/18] media: media/v4l2-ctrls: volatiles should not generate CH_VALUE

2018-03-28 Thread Mauro Carvalho Chehab
From: Ricardo Ribalda 

Volatile controls should not generate CH_VALUE events.

Set has_changed to false to prevent this happening.

Signed-off-by: Ricardo Ribalda Delgado 
Signed-off-by: Hans Verkuil 
Signed-off-by: Mauro Carvalho Chehab 
Signed-off-by: Mauro Carvalho Chehab 
---
 drivers/media/v4l2-core/v4l2-ctrls.c | 9 +
 1 file changed, 9 insertions(+)

diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c 
b/drivers/media/v4l2-core/v4l2-ctrls.c
index 3c4e22855652..2bdb2a3512a4 100644
--- a/drivers/media/v4l2-core/v4l2-ctrls.c
+++ b/drivers/media/v4l2-core/v4l2-ctrls.c
@@ -1619,6 +1619,15 @@ static int cluster_changed(struct v4l2_ctrl *master)
 
if (ctrl == NULL)
continue;
+   /*
+* Set has_changed to false to avoid generating
+* the event V4L2_EVENT_CTRL_CH_VALUE
+*/
+   if (ctrl->flags & V4L2_CTRL_FLAG_VOLATILE) {
+   ctrl->has_changed = false;
+   continue;
+   }
+
for (idx = 0; !ctrl_changed && idx < ctrl->elems; idx++)
ctrl_changed = !ctrl->type_ops->equal(ctrl, idx,
ctrl->p_cur, ctrl->p_new);
-- 
2.14.3



[PATCH for v3.18 08/18] media: v4l2-compat-ioctl32.c: fix ctrl_is_pointer

2018-03-28 Thread Mauro Carvalho Chehab
From: Hans Verkuil 

commit b8c601e8af2d08f733d74defa8465303391bb930 upstream.

ctrl_is_pointer just hardcoded two known string controls, but that
caused problems when using e.g. custom controls that use a pointer
for the payload.

Reimplement this function: it now finds the v4l2_ctrl (if the driver
uses the control framework) or it calls vidioc_query_ext_ctrl (if the
driver implements that directly).

In both cases it can now check if the control is a pointer control
or not.

Signed-off-by: Hans Verkuil 
Acked-by: Sakari Ailus 
Signed-off-by: Mauro Carvalho Chehab 
Signed-off-by: Sasha Levin 
---
 drivers/media/v4l2-core/v4l2-compat-ioctl32.c | 57 ++-
 1 file changed, 38 insertions(+), 19 deletions(-)

diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c 
b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
index a27fd9105948..c78462e79a0a 100644
--- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
+++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
@@ -18,6 +18,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 #include 
 
 static long native_ioctl(struct file *file, unsigned int cmd, unsigned long 
arg)
@@ -575,24 +577,39 @@ struct v4l2_ext_control32 {
};
 } __attribute__ ((packed));
 
-/* The following function really belong in v4l2-common, but that causes
-   a circular dependency between modules. We need to think about this, but
-   for now this will do. */
-
-/* Return non-zero if this control is a pointer type. Currently only
-   type STRING is a pointer type. */
-static inline int ctrl_is_pointer(u32 id)
+/* Return true if this control is a pointer type. */
+static inline bool ctrl_is_pointer(struct file *file, u32 id)
 {
-   switch (id) {
-   case V4L2_CID_RDS_TX_PS_NAME:
-   case V4L2_CID_RDS_TX_RADIO_TEXT:
-   return 1;
-   default:
-   return 0;
+   struct video_device *vdev = video_devdata(file);
+   struct v4l2_fh *fh = NULL;
+   struct v4l2_ctrl_handler *hdl = NULL;
+   struct v4l2_query_ext_ctrl qec = { id };
+   const struct v4l2_ioctl_ops *ops = vdev->ioctl_ops;
+
+   if (test_bit(V4L2_FL_USES_V4L2_FH, >flags))
+   fh = file->private_data;
+
+   if (fh && fh->ctrl_handler)
+   hdl = fh->ctrl_handler;
+   else if (vdev->ctrl_handler)
+   hdl = vdev->ctrl_handler;
+
+   if (hdl) {
+   struct v4l2_ctrl *ctrl = v4l2_ctrl_find(hdl, id);
+
+   return ctrl && ctrl->is_ptr;
}
+
+   if (!ops->vidioc_query_ext_ctrl)
+   return false;
+
+   return !ops->vidioc_query_ext_ctrl(file, fh, ) &&
+   (qec.flags & V4L2_CTRL_FLAG_HAS_PAYLOAD);
 }
 
-static int get_v4l2_ext_controls32(struct v4l2_ext_controls *kp, struct 
v4l2_ext_controls32 __user *up)
+static int get_v4l2_ext_controls32(struct file *file,
+  struct v4l2_ext_controls *kp,
+  struct v4l2_ext_controls32 __user *up)
 {
struct v4l2_ext_control32 __user *ucontrols;
struct v4l2_ext_control __user *kcontrols;
@@ -624,7 +641,7 @@ static int get_v4l2_ext_controls32(struct v4l2_ext_controls 
*kp, struct v4l2_ext
return -EFAULT;
if (get_user(id, >id))
return -EFAULT;
-   if (ctrl_is_pointer(id)) {
+   if (ctrl_is_pointer(file, id)) {
void __user *s;
 
if (get_user(p, >string))
@@ -639,7 +656,9 @@ static int get_v4l2_ext_controls32(struct v4l2_ext_controls 
*kp, struct v4l2_ext
return 0;
 }
 
-static int put_v4l2_ext_controls32(struct v4l2_ext_controls *kp, struct 
v4l2_ext_controls32 __user *up)
+static int put_v4l2_ext_controls32(struct file *file,
+  struct v4l2_ext_controls *kp,
+  struct v4l2_ext_controls32 __user *up)
 {
struct v4l2_ext_control32 __user *ucontrols;
struct v4l2_ext_control __user *kcontrols =
@@ -671,7 +690,7 @@ static int put_v4l2_ext_controls32(struct v4l2_ext_controls 
*kp, struct v4l2_ext
/* Do not modify the pointer when copying a pointer control.
   The contents of the pointer was changed, not the pointer
   itself. */
-   if (ctrl_is_pointer(id))
+   if (ctrl_is_pointer(file, id))
size -= sizeof(ucontrols->value64);
if (copy_in_user(ucontrols, kcontrols, size))
return -EFAULT;
@@ -884,7 +903,7 @@ static long do_video_ioctl(struct file *file, unsigned int 
cmd, unsigned long ar
case VIDIOC_G_EXT_CTRLS:
case VIDIOC_S_EXT_CTRLS:
case VIDIOC_TRY_EXT_CTRLS:
-   err = get_v4l2_ext_controls32(, up);
+   

[PATCH for v3.18 02/18] vb2: V4L2_BUF_FLAG_DONE is set after DQBUF

2018-03-28 Thread Mauro Carvalho Chehab
From: Ricardo Ribalda 

commit 3171cc2b4eb9831ab4df1d80d0410a945b8bc84e upstream.

According to the doc, V4L2_BUF_FLAG_DONE is cleared after DQBUF:

V4L2_BUF_FLAG_DONE 0x0004  ... After calling the VIDIOC_QBUF or
VIDIOC_DQBUF it is always cleared ...

Unfortunately, it seems that videobuf2 keeps it set after DQBUF. This
can be tested with vivid and dev_debug:

[257604.338082] video1: VIDIOC_DQBUF: 71:33:25.00260479 index=3,
type=vid-cap, flags=0x2004, field=none, sequence=163,
memory=userptr, bytesused=460800, offset/userptr=0x344b000,
length=460800

This patch forces FLAG_DONE to 0 after calling DQBUF.

Reported-by: Dimitrios Katsaros 
Signed-off-by: Ricardo Ribalda Delgado 
Signed-off-by: Hans Verkuil 
Signed-off-by: Mauro Carvalho Chehab 
Signed-off-by: Sasha Levin 
Signed-off-by: Mauro Carvalho Chehab 
---
 drivers/media/v4l2-core/videobuf2-core.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/media/v4l2-core/videobuf2-core.c 
b/drivers/media/v4l2-core/videobuf2-core.c
index d5c300150cf4..f0811b7e900d 100644
--- a/drivers/media/v4l2-core/videobuf2-core.c
+++ b/drivers/media/v4l2-core/videobuf2-core.c
@@ -2075,6 +2075,11 @@ static int vb2_internal_dqbuf(struct vb2_queue *q, 
struct v4l2_buffer *b, bool n
dprintk(1, "dqbuf of buffer %d, with state %d\n",
vb->v4l2_buf.index, vb->state);
 
+   /*
+* After calling the VIDIOC_DQBUF V4L2_BUF_FLAG_DONE must be
+* cleared.
+*/
+   b->flags &= ~V4L2_BUF_FLAG_DONE;
return 0;
 }
 
-- 
2.14.3



[PATCH for v3.18 12/18] media: v4l2-compat-ioctl32.c: drop pr_info for unknown buffer type

2018-03-28 Thread Mauro Carvalho Chehab
From: Hans Verkuil 

commit 169f24ca68bf0f247d111aef07af00dd3a02ae88 upstream.

There is nothing wrong with using an unknown buffer type. So
stop spamming the kernel log whenever this happens. The kernel
will just return -EINVAL to signal this.

Signed-off-by: Hans Verkuil 
Acked-by: Sakari Ailus 
Signed-off-by: Mauro Carvalho Chehab 
Signed-off-by: Sasha Levin 
---
 drivers/media/v4l2-core/v4l2-compat-ioctl32.c | 4 
 1 file changed, 4 deletions(-)

diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c 
b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
index 8a5c93ce4348..a5f74a508f58 100644
--- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
+++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
@@ -170,8 +170,6 @@ static int __get_v4l2_format32(struct v4l2_format *kp, 
struct v4l2_format32 __us
return copy_from_user(>fmt.sliced, >fmt.sliced,
  sizeof(kp->fmt.sliced)) ? -EFAULT : 0;
default:
-   printk(KERN_INFO "compat_ioctl32: unexpected VIDIOC_FMT type 
%d\n",
-  kp->type);
return -EINVAL;
}
 }
@@ -214,8 +212,6 @@ static int __put_v4l2_format32(struct v4l2_format *kp, 
struct v4l2_format32 __us
return copy_to_user(>fmt.sliced, >fmt.sliced,
sizeof(kp->fmt.sliced)) ?  -EFAULT : 0;
default:
-   printk(KERN_INFO "compat_ioctl32: unexpected VIDIOC_FMT type 
%d\n",
-  kp->type);
return -EINVAL;
}
 }
-- 
2.14.3



[PATCH for v3.18 01/18] media: v4l2-ioctl.c: don't copy back the result for -ENOTTY

2018-03-28 Thread Mauro Carvalho Chehab
From: Hans Verkuil 

commit 181a4a2d5a0a7b43cab08a70710d727e7764ccdd upstream.

If the ioctl returned -ENOTTY, then don't bother copying
back the result as there is no point.

Signed-off-by: Hans Verkuil 
Acked-by: Sakari Ailus 
Signed-off-by: Mauro Carvalho Chehab 
Signed-off-by: Sasha Levin 
Signed-off-by: Mauro Carvalho Chehab 
---
 drivers/media/v4l2-core/v4l2-ioctl.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c 
b/drivers/media/v4l2-core/v4l2-ioctl.c
index 9ccb19a435ef..bb2387fcbfee 100644
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
@@ -2539,8 +2539,11 @@ video_usercopy(struct file *file, unsigned int cmd, 
unsigned long arg,
 
/* Handles IOCTL */
err = func(file, cmd, parg);
-   if (err == -ENOIOCTLCMD)
+   if (err == -ENOTTY || err == -ENOIOCTLCMD) {
err = -ENOTTY;
+   goto out;
+   }
+
if (err == 0) {
if (cmd == VIDIOC_DQBUF)
trace_v4l2_dqbuf(video_devdata(file)->minor, parg);
-- 
2.14.3



[PATCH for v3.18 06/18] media: v4l2-compat-ioctl32.c: avoid sizeof(type)

2018-03-28 Thread Mauro Carvalho Chehab
From: Hans Verkuil 

commit 333b1e9f96ce05f7498b581509bb30cde03018bf upstream.

Instead of doing sizeof(struct foo) use sizeof(*up). There even were
cases where 4 * sizeof(__u32) was used instead of sizeof(kp->reserved),
which is very dangerous when the size of the reserved array changes.

Signed-off-by: Hans Verkuil 
Acked-by: Sakari Ailus 
Signed-off-by: Mauro Carvalho Chehab 
Signed-off-by: Sasha Levin 
Signed-off-by: Mauro Carvalho Chehab 
---
 drivers/media/v4l2-core/v4l2-compat-ioctl32.c | 80 +--
 1 file changed, 38 insertions(+), 42 deletions(-)

diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c 
b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
index 702757012dc7..b7dd98168a68 100644
--- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
+++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
@@ -47,7 +47,7 @@ struct v4l2_window32 {
 
 static int get_v4l2_window32(struct v4l2_window *kp, struct v4l2_window32 
__user *up)
 {
-   if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_window32)) ||
+   if (!access_ok(VERIFY_READ, up, sizeof(*up)) ||
copy_from_user(>w, >w, sizeof(up->w)) ||
get_user(kp->field, >field) ||
get_user(kp->chromakey, >chromakey) ||
@@ -64,7 +64,7 @@ static int get_v4l2_window32(struct v4l2_window *kp, struct 
v4l2_window32 __user
if (get_user(p, >clips))
return -EFAULT;
uclips = compat_ptr(p);
-   kclips = compat_alloc_user_space(n * sizeof(struct v4l2_clip));
+   kclips = compat_alloc_user_space(n * sizeof(*kclips));
kp->clips = kclips;
while (--n >= 0) {
if (copy_in_user(>c, >c, 
sizeof(uclips->c)))
@@ -152,14 +152,14 @@ static int __get_v4l2_format32(struct v4l2_format *kp, 
struct v4l2_format32 __us
 
 static int get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 
__user *up)
 {
-   if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_format32)))
+   if (!access_ok(VERIFY_READ, up, sizeof(*up)))
return -EFAULT;
return __get_v4l2_format32(kp, up);
 }
 
 static int get_v4l2_create32(struct v4l2_create_buffers *kp, struct 
v4l2_create_buffers32 __user *up)
 {
-   if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_create_buffers32)) ||
+   if (!access_ok(VERIFY_READ, up, sizeof(*up)) ||
copy_from_user(kp, up, offsetof(struct v4l2_create_buffers32, 
format)))
return -EFAULT;
return __get_v4l2_format32(>format, >format);
@@ -196,17 +196,17 @@ static int __put_v4l2_format32(struct v4l2_format *kp, 
struct v4l2_format32 __us
 
 static int put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 
__user *up)
 {
-   if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_format32)) ||
-   put_user(kp->type, >type))
+   if (!access_ok(VERIFY_WRITE, up, sizeof(*up)))
return -EFAULT;
return __put_v4l2_format32(kp, up);
 }
 
 static int put_v4l2_create32(struct v4l2_create_buffers *kp, struct 
v4l2_create_buffers32 __user *up)
 {
-   if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_create_buffers32)) 
||
-   copy_to_user(up, kp, offsetof(struct v4l2_create_buffers32, 
format.fmt)))
-   return -EFAULT;
+   if (!access_ok(VERIFY_WRITE, up, sizeof(*up)) ||
+   copy_to_user(up, kp, offsetof(struct v4l2_create_buffers32, 
format)) ||
+   copy_to_user(up->reserved, kp->reserved, sizeof(kp->reserved)))
+   return -EFAULT;
return __put_v4l2_format32(>format, >format);
 }
 
@@ -222,7 +222,7 @@ struct v4l2_standard32 {
 static int get_v4l2_standard32(struct v4l2_standard *kp, struct 
v4l2_standard32 __user *up)
 {
/* other fields are not set by the user, nor used by the driver */
-   if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_standard32)) ||
+   if (!access_ok(VERIFY_READ, up, sizeof(*up)) ||
get_user(kp->index, >index))
return -EFAULT;
return 0;
@@ -230,13 +230,13 @@ static int get_v4l2_standard32(struct v4l2_standard *kp, 
struct v4l2_standard32
 
 static int put_v4l2_standard32(struct v4l2_standard *kp, struct 
v4l2_standard32 __user *up)
 {
-   if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_standard32)) ||
+   if (!access_ok(VERIFY_WRITE, up, sizeof(*up)) ||
put_user(kp->index, >index) ||
copy_to_user(up->id, >id, sizeof(__u64)) ||
-   copy_to_user(up->name, kp->name, 24) ||
+   copy_to_user(up->name, kp->name, sizeof(up->name)) ||
copy_to_user(>frameperiod, >frameperiod, 
sizeof(kp->frameperiod)) ||
put_user(kp->framelines, >framelines) ||
-   copy_to_user(up->reserved, kp->reserved, 4 * 

[PATCH for v3.18 14/18] media: v4l2-compat-ioctl32.c: refactor compat ioctl32 logic

2018-03-28 Thread Mauro Carvalho Chehab
From: Daniel Mentz 

commit a1dfb4c48cc1e64eeb7800a27c66a6f7e88d075a upstream.

The 32-bit compat v4l2 ioctl handling is implemented based on its 64-bit
equivalent. It converts 32-bit data structures into its 64-bit
equivalents and needs to provide the data to the 64-bit ioctl in user
space memory which is commonly allocated using
compat_alloc_user_space().

However, due to how that function is implemented, it can only be called
a single time for every syscall invocation.

Supposedly to avoid this limitation, the existing code uses a mix of
memory from the kernel stack and memory allocated through
compat_alloc_user_space().

Under normal circumstances, this would not work, because the 64-bit
ioctl expects all pointers to point to user space memory. As a
workaround, set_fs(KERNEL_DS) is called to temporarily disable this
extra safety check and allow kernel pointers. However, this might
introduce a security vulnerability: The result of the 32-bit to 64-bit
conversion is writeable by user space because the output buffer has been
allocated via compat_alloc_user_space(). A malicious user space process
could then manipulate pointers inside this output buffer, and due to the
previous set_fs(KERNEL_DS) call, functions like get_user() or put_user()
no longer prevent kernel memory access.

The new approach is to pre-calculate the total amount of user space
memory that is needed, allocate it using compat_alloc_user_space() and
then divide up the allocated memory to accommodate all data structures
that need to be converted.

An alternative approach would have been to retain the union type karg
that they allocated on the kernel stack in do_video_ioctl(), copy all
data from user space into karg and then back to user space. However, we
decided against this approach because it does not align with other
compat syscall implementations. Instead, we tried to replicate the
get_user/put_user pairs as found in other places in the kernel:

if (get_user(clipcount, >clipcount) ||
put_user(clipcount, >clipcount)) return -EFAULT;

Notes from hans.verk...@cisco.com:

This patch was taken from:

https://github.com/LineageOS/android_kernel_samsung_apq8084/commit/97b733953c06e4f0398ade18850f0817778255f7

Clearly nobody could be bothered to upstream this patch or at minimum
tell us :-( We only heard about this a week ago.

This patch was rebased and cleaned up. Compared to the original I
also swapped the order of the convert_in_user arguments so that they
matched copy_in_user. It was hard to review otherwise. I also replaced
the ALLOC_USER_SPACE/ALLOC_AND_GET by a normal function.

Fixes: 6b5a9492ca ("v4l: introduce string control support.")

Signed-off-by: Daniel Mentz 
Co-developed-by: Hans Verkuil 
Acked-by: Sakari Ailus 
Signed-off-by: Hans Verkuil 
Signed-off-by: Mauro Carvalho Chehab 
Signed-off-by: Sasha Levin 
---
 drivers/media/v4l2-core/v4l2-compat-ioctl32.c | 747 +-
 1 file changed, 486 insertions(+), 261 deletions(-)

diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c 
b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
index 9e5807842dad..e03aa0961360 100644
--- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
+++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
@@ -22,6 +22,14 @@
 #include 
 #include 
 
+/* Use the same argument order as copy_in_user */
+#define assign_in_user(to, from)   \
+({ \
+   typeof(*from) __assign_tmp; \
+   \
+   get_user(__assign_tmp, from) || put_user(__assign_tmp, to); \
+})
+
 static long native_ioctl(struct file *file, unsigned int cmd, unsigned long 
arg)
 {
long ret = -ENOIOCTLCMD;
@@ -35,12 +43,12 @@ static long native_ioctl(struct file *file, unsigned int 
cmd, unsigned long arg)
 
 struct v4l2_clip32 {
struct v4l2_rectc;
-   compat_caddr_t  next;
+   compat_caddr_t  next;
 };
 
 struct v4l2_window32 {
struct v4l2_rectw;
-   __u32   field;  /* enum v4l2_field */
+   __u32   field;  /* enum v4l2_field */
__u32   chromakey;
compat_caddr_t  clips; /* actually struct v4l2_clip32 * */
__u32   clipcount;
@@ -48,37 +56,41 @@ struct v4l2_window32 {
__u8global_alpha;
 };
 
-static int get_v4l2_window32(struct v4l2_window *kp, struct v4l2_window32 
__user *up)
+static int get_v4l2_window32(struct v4l2_window __user *kp,
+struct v4l2_window32 __user *up,
+void __user *aux_buf, u32 aux_space)
 {
struct 

[PATCH for v3.18 18/18] media: v4l2-compat-ioctl32: initialize a reserved field

2018-03-28 Thread Mauro Carvalho Chehab
The get_v4l2_create32() function is missing a logic with
would be cleaning a reserved field, causing v4l2-compliance
to complain:

 Buffer ioctls (Input 0):
fail: v4l2-test-buffers.cpp(506): check_0(crbufs.reserved, 
sizeof(crbufs.reserved))
test VIDIOC_REQBUFS/CREATE_BUFS/QUERYBUF: FAIL

Signed-off-by: Mauro Carvalho Chehab 
---
 drivers/media/v4l2-core/v4l2-compat-ioctl32.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c 
b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
index c76438dd3ead..ca0a43ad4ec8 100644
--- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
+++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
@@ -247,7 +247,8 @@ static int get_v4l2_create32(struct v4l2_create_buffers 
__user *kp,
 {
if (!access_ok(VERIFY_READ, up, sizeof(*up)) ||
copy_in_user(kp, up,
-offsetof(struct v4l2_create_buffers32, format)))
+offsetof(struct v4l2_create_buffers32, format)) ||
+   copy_in_user(kp->reserved, up->reserved, sizeof(kp->reserved)))
return -EFAULT;
return __get_v4l2_format32(>format, >format,
   aux_buf, aux_space);
-- 
2.14.3



[PATCH for v3.18 00/18] Backport CVE-2017-13166 fixes to Kernel 3.18

2018-03-28 Thread Mauro Carvalho Chehab
Hi Greg,

Those are the backports meant to solve CVE-2017-13166 on Kernel 3.18.

It contains two v4l2-ctrls fixes that are required to avoid crashes
at the test application.

I wrote two patches myself for Kernel 3.18 in order to solve some
issues specific for Kernel 3.18 with aren't needed upstream.
one is actually a one-line change backport. The other one makes
sure that both 32-bits and 64-bits version of some ioctl calls
will return the same value for a reserved field.

I noticed an extra bug while testing it, but the bug also hits upstream,
and should be backported all the way down all stable/LTS versions.
So, I'll send it the usual way, after merging upsream.

Regards,
Mauro


Daniel Mentz (2):
  media: v4l2-compat-ioctl32: Copy v4l2_window->global_alpha
  media: v4l2-compat-ioctl32.c: refactor compat ioctl32 logic

Hans Verkuil (12):
  media: v4l2-ioctl.c: don't copy back the result for -ENOTTY
  media: v4l2-compat-ioctl32.c: add missing VIDIOC_PREPARE_BUF
  media: v4l2-compat-ioctl32.c: fix the indentation
  media: v4l2-compat-ioctl32.c: move 'helper' functions to
__get/put_v4l2_format32
  media: v4l2-compat-ioctl32.c: avoid sizeof(type)
  media: v4l2-compat-ioctl32.c: copy m.userptr in put_v4l2_plane32
  media: v4l2-compat-ioctl32.c: fix ctrl_is_pointer
  media: v4l2-compat-ioctl32.c: make ctrl_is_pointer work for subdevs
  media: v4l2-compat-ioctl32.c: copy clip list in put_v4l2_window32
  media: v4l2-compat-ioctl32.c: drop pr_info for unknown buffer type
  media: v4l2-compat-ioctl32.c: don't copy back the result for certain
errors
  media: v4l2-ctrls: fix sparse warning

Mauro Carvalho Chehab (2):
  media: v4l2-compat-ioctl32: use compat_u64 for video standard
  media: v4l2-compat-ioctl32: initialize a reserved field

Ricardo Ribalda (2):
  vb2: V4L2_BUF_FLAG_DONE is set after DQBUF
  media: media/v4l2-ctrls: volatiles should not generate CH_VALUE

 drivers/media/v4l2-core/v4l2-compat-ioctl32.c | 1020 +++--
 drivers/media/v4l2-core/v4l2-ctrls.c  |   96 ++-
 drivers/media/v4l2-core/v4l2-ioctl.c  |5 +-
 drivers/media/v4l2-core/videobuf2-core.c  |5 +
 4 files changed, 691 insertions(+), 435 deletions(-)

-- 
2.14.3




[PATCH] media: v4l2-compat-ioctl32: don't oops on overlay

2018-03-28 Thread Mauro Carvalho Chehab
At put_v4l2_window32(), it tries to access kp->clips. However,
kp points to an userspace pointer. So, it should be obtained
via get_user(), otherwise it can OOPS:

 vivid-000: ==  END STATUS  ==
 BUG: unable to handle kernel paging request at fffb18e0
 IP: [] __put_v4l2_format32+0x169/0x220 [videodev]
 PGD 3f5776067 PUD 3f576f067 PMD 3f5769067 PTE 80042548f067
 Oops: 0001 [#1] SMP
 Modules linked in: vivid videobuf2_vmalloc videobuf2_memops v4l2_dv_timings 
videobuf2_core v4l2_common videodev media xt_CHECKSUM iptable_mangle 
ipt_MASQUERADE nf_nat_masquerade_ipv4 iptable_nat nf_nat_ipv4 nf_nat 
nf_conntrack_ipv4 nf_defrag_ipv4 xt_conntrack nf_conntrack tun bridge stp llc 
ebtable_filter ebtables ip6table_filter ip6_tables bluetooth rfkill binfmt_misc 
snd_hda_codec_hdmi i915 snd_hda_intel snd_hda_controller snd_hda_codec 
intel_rapl x86_pkg_temp_thermal snd_hwdep intel_powerclamp snd_pcm coretemp 
snd_seq_midi kvm_intel kvm snd_seq_midi_event snd_rawmidi i2c_algo_bit 
drm_kms_helper snd_seq drm crct10dif_pclmul e1000e snd_seq_device crc32_pclmul 
snd_timer ghash_clmulni_intel snd mei_me mei ptp pps_core soundcore lpc_ich 
video crc32c_intel [last unloaded: media]
 CPU: 2 PID: 28332 Comm: v4l2-compliance Not tainted 3.18.102+ #107
 Hardware name:  /NUC5i7RYB, BIOS 
RYBDWi35.86A.0364.2017.0511.0949 05/11/2017
 task: 8804293f8000 ti: 8803f564 task.ti: 8803f564
 RIP: 0010:[]  [] 
__put_v4l2_format32+0x169/0x220 [videodev]
 RSP: 0018:8803f5643e28  EFLAGS: 00010246
 RAX:  RBX:  RCX: fffb1ab4
 RDX: fffb1a68 RSI: fffb18d8 RDI: fffb1aa8
 RBP: 8803f5643e48 R08: 0001 R09: 8803f54b0378
 R10:  R11: 0168 R12: fffb18c0
 R13: fffb1a94 R14: fffb18c8 R15: 
 FS:  () GS:880456d0(0063) knlGS:f7100980
 CS:  0010 DS: 002b ES: 002b CR0: 80050033
 CR2: fffb18e0 CR3: 0003f552b000 CR4: 003407e0
 Stack:
  fffb1a94 c0cc5640 0056 8804274f3600
  8803f5643ed0 c0547e16 0003 8803f5643eb0
  81301460 88009db44b01 880441942520 8800c0d05640
 Call Trace:
  [] v4l2_compat_ioctl32+0x12d6/0x1b1d [videodev]
  [] ? file_has_perm+0x70/0xc0
  [] compat_SyS_ioctl+0xec/0x1200
  [] sysenter_dispatch+0x7/0x21
 Code: 00 00 48 8b 80 48 c0 ff ff 48 83 e8 38 49 39 c6 0f 87 2b ff ff ff 49 8d 
45 1c e8 a3 ce e3 c0 85 c0 0f 85 1a ff ff ff 41 8d 40 ff <4d> 8b 64 24 20 41 89 
d5 48 8d 44 40 03 4d 8d 34 c4 eb 15 0f 1f
 RIP  [] __put_v4l2_format32+0x169/0x220 [videodev]
 RSP 
 CR2: fffb18e0

Tested with vivid driver on Kernel v3.18.102.

Same bug happens upstream too:

 BUG: KASAN: user-memory-access in __put_v4l2_format32+0x98/0x4d0 [videodev]
 Read of size 8 at addr ffe48400 by task v4l2-compliance/8713

 CPU: 0 PID: 8713 Comm: v4l2-compliance Not tainted 4.16.0-rc4+ #108
 Hardware name:  /NUC5i7RYB, BIOS RYBDWi35.86A.0364.2017.0511.0949 05/11/2017
 Call Trace:
  dump_stack+0x5c/0x7c
  kasan_report+0x164/0x380
  ? __put_v4l2_format32+0x98/0x4d0 [videodev]
  __put_v4l2_format32+0x98/0x4d0 [videodev]
  v4l2_compat_ioctl32+0x1aec/0x27a0 [videodev]
  ? __fsnotify_inode_delete+0x20/0x20
  ? __put_v4l2_format32+0x4d0/0x4d0 [videodev]
  compat_SyS_ioctl+0x646/0x14d0
  ? do_ioctl+0x30/0x30
  do_fast_syscall_32+0x191/0x3f4
  entry_SYSENTER_compat+0x6b/0x7a
 ==
 Disabling lock debugging due to kernel taint
 BUG: unable to handle kernel paging request at ffe48400
 IP: __put_v4l2_format32+0x98/0x4d0 [videodev]
 PGD 3a22fb067 P4D 3a22fb067 PUD 39b6f0067 PMD 39b6f1067 PTE 8003256af067
 Oops: 0001 [#1] SMP KASAN
 Modules linked in: vivid videobuf2_vmalloc videobuf2_dma_contig 
videobuf2_memops v4l2_tpg v4l2_dv_timings videobuf2_v4l2 videobuf2_common 
v4l2_common videodev xt_CHECKSUM iptable_mangle ipt_MASQUERADE 
nf_nat_masquerade_ipv4 iptable_nat nf_nat_ipv4 nf_nat nf_conntrack_ipv4 
nf_defrag_ipv4 xt_conntrack nf_conntrack libcrc32c tun bridge stp llc 
ebtable_filter ebtables ip6table_filter ip6_tables bluetooth rfkill 
ecdh_generic binfmt_misc snd_hda_codec_hdmi intel_rapl x86_pkg_temp_thermal 
intel_powerclamp i915 coretemp snd_hda_intel snd_hda_codec kvm_intel snd_hwdep 
snd_hda_core kvm snd_pcm irqbypass crct10dif_pclmul crc32_pclmul snd_seq_midi 
ghash_clmulni_intel snd_seq_midi_event i2c_algo_bit intel_cstate snd_rawmidi 
intel_uncore snd_seq drm_kms_helper e1000e snd_seq_device snd_timer 
intel_rapl_perf
  drm ptp snd mei_me mei lpc_ich pps_core soundcore video crc32c_intel
 CPU: 0 PID: 8713 Comm: v4l2-compliance Tainted: GB4.16.0-rc4+ 
#108
 Hardware name:  /NUC5i7RYB, BIOS RYBDWi35.86A.0364.2017.0511.0949 05/11/2017
 RIP: 0010:__put_v4l2_format32+0x98/0x4d0 [videodev]
 RSP: 

[PATCH v2 2/5] tuners: add new i2c driver for Sharp qm1d1b0004 ISDB-S tuner

2018-03-28 Thread tskd08
From: Akihiro Tsukada 

The tuner is used in Earthsoft PT1/PT2 DVB boards,
and  the driver was extraced from (the former) va1j5jf8007s.c of PT1.
it might contain PT1 specific configs.

Signed-off-by: Akihiro Tsukada 
---
Changes since v1:
- none

 drivers/media/tuners/Kconfig  |   7 +
 drivers/media/tuners/Makefile |   1 +
 drivers/media/tuners/qm1d1b0004.c | 264 ++
 drivers/media/tuners/qm1d1b0004.h |  24 
 4 files changed, 296 insertions(+)
 create mode 100644 drivers/media/tuners/qm1d1b0004.c
 create mode 100644 drivers/media/tuners/qm1d1b0004.h

diff --git a/drivers/media/tuners/Kconfig b/drivers/media/tuners/Kconfig
index 6687514df97..147f3cd0bb9 100644
--- a/drivers/media/tuners/Kconfig
+++ b/drivers/media/tuners/Kconfig
@@ -284,4 +284,11 @@ config MEDIA_TUNER_QM1D1C0042
default m if !MEDIA_SUBDRV_AUTOSELECT
help
  Sharp QM1D1C0042 trellis coded 8PSK tuner driver.
+
+config MEDIA_TUNER_QM1D1B0004
+   tristate "Sharp QM1D1B0004 tuner"
+   depends on MEDIA_SUPPORT && I2C
+   default m if !MEDIA_SUBDRV_AUTOSELECT
+   help
+ Sharp QM1D1B0004 ISDB-S tuner driver.
 endmenu
diff --git a/drivers/media/tuners/Makefile b/drivers/media/tuners/Makefile
index 0ff21f1c7ee..7b4f8423501 100644
--- a/drivers/media/tuners/Makefile
+++ b/drivers/media/tuners/Makefile
@@ -41,6 +41,7 @@ obj-$(CONFIG_MEDIA_TUNER_IT913X) += it913x.o
 obj-$(CONFIG_MEDIA_TUNER_R820T) += r820t.o
 obj-$(CONFIG_MEDIA_TUNER_MXL301RF) += mxl301rf.o
 obj-$(CONFIG_MEDIA_TUNER_QM1D1C0042) += qm1d1c0042.o
+obj-$(CONFIG_MEDIA_TUNER_QM1D1B0004) += qm1d1b0004.o
 obj-$(CONFIG_MEDIA_TUNER_M88RS6000T) += m88rs6000t.o
 obj-$(CONFIG_MEDIA_TUNER_TDA18250) += tda18250.o
 
diff --git a/drivers/media/tuners/qm1d1b0004.c 
b/drivers/media/tuners/qm1d1b0004.c
new file mode 100644
index 000..9dac1b875c1
--- /dev/null
+++ b/drivers/media/tuners/qm1d1b0004.c
@@ -0,0 +1,264 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Sharp QM1D1B0004 satellite tuner
+ *
+ * Copyright (C) 2014 Akihiro Tsukada 
+ *
+ * based on (former) drivers/media/pci/pt1/va1j5jf8007s.c.
+ */
+
+/*
+ * Note:
+ * Since the data-sheet of this tuner chip is not available,
+ * this driver lacks some tuner_ops and config options.
+ * In addition, the implementation might be dependent on the specific use
+ * in the FE module: VA1J5JF8007S and/or in the product: Earthsoft PT1/PT2.
+ */
+
+#include 
+#include 
+#include 
+#include "qm1d1b0004.h"
+
+/*
+ * Tuner I/F (copied from the former va1j5jf8007s.c)
+ * b[0] I2C addr
+ * b[1] "0":1, BG:2, divider_quotient[7:3]:5
+ * b[2] divider_quotient[2:0]:3, divider_remainder:5
+ * b[3] "111":3, LPF[3:2]:2, TM:1, "0":1, REF:1
+ * b[4] BANDX, PSC:1, LPF[1:0]:2, DIV:1, "0":1
+ *
+ * PLL frequency step :=
+ *REF == 0 -> PLL XTL frequency(4MHz) / 8
+ *REF == 1 -> PLL XTL frequency(4MHz) / 4
+ *
+ * PreScaler :=
+ *PSC == 0 -> x32
+ *PSC == 1 -> x16
+ *
+ * divider_quotient := (frequency / PLL frequency step) / PreScaler
+ * divider_remainder := (frequency / PLL frequency step) % PreScaler
+ *
+ * LPF := LPF Frequency / 1000 / 2 - 2
+ * LPF Frequency @ baudrate=28.86Mbps = 3
+ *
+ * band (1..9)
+ *   band 1 (freq <  986000) -> DIV:1, BANDX:5, PSC:1
+ *   band 2 (freq < 1072000) -> DIV:1, BANDX:6, PSC:1
+ *   band 3 (freq < 1154000) -> DIV:1, BANDX:7, PSC:0
+ *   band 4 (freq < 1291000) -> DIV:0, BANDX:1, PSC:0
+ *   band 5 (freq < 1447000) -> DIV:0, BANDX:2, PSC:0
+ *   band 6 (freq < 1615000) -> DIV:0, BANDX:3, PSC:0
+ *   band 7 (freq < 1791000) -> DIV:0, BANDX:4, PSC:0
+ *   band 8 (freq < 1972000) -> DIV:0, BANDX:5, PSC:0
+ *   band 9 (freq < 215) -> DIV:0, BANDX:6, PSC:0
+ */
+
+#define QM1D1B0004_PSC_MASK (1 << 4)
+
+#define QM1D1B0004_XTL_FREQ 4000
+#define QM1D1B0004_LPF_FALLBACK 3
+
+static const struct qm1d1b0004_config default_cfg = {
+   .lpf_freq = QM1D1B0004_CFG_LPF_DFLT,
+   .half_step = false,
+};
+
+struct qm1d1b0004_state {
+   struct qm1d1b0004_config cfg;
+   struct i2c_client *i2c;
+};
+
+
+struct qm1d1b0004_cb_map {
+   u32 frequency;
+   u8 cb;
+};
+
+static const struct qm1d1b0004_cb_map cb_maps[] = {
+   {  986000, 0xb2 },
+   { 1072000, 0xd2 },
+   { 1154000, 0xe2 },
+   { 1291000, 0x20 },
+   { 1447000, 0x40 },
+   { 1615000, 0x60 },
+   { 1791000, 0x80 },
+   { 1972000, 0xa0 },
+};
+
+static u8 lookup_cb(u32 frequency)
+{
+   int i;
+   const struct qm1d1b0004_cb_map *map;
+
+   for (i = 0; i < ARRAY_SIZE(cb_maps); i++) {
+   map = _maps[i];
+   if (frequency < map->frequency)
+   return map->cb;
+   }
+   return 0xc0;
+}
+
+static int qm1d1b0004_set_params(struct dvb_frontend *fe)
+{
+   struct qm1d1b0004_state *state;
+   u32 frequency, pll, lpf_freq;
+   u16 word;
+   u8 buf[4], cb, lpf;
+   int ret;
+
+   state 

[PATCH v2 5/5] dvb: earth-pt1: replace schedule_timeout with usleep_range

2018-03-28 Thread tskd08
From: Akihiro Tsukada 

As described in Document/timers/timers-howto.txt,
hrtimer-based delay should be used for small sleeps.

Signed-off-by: Akihiro Tsukada 
---
Changes since v1:
- none

 drivers/media/pci/pt1/pt1.c | 34 +++---
 1 file changed, 23 insertions(+), 11 deletions(-)

diff --git a/drivers/media/pci/pt1/pt1.c b/drivers/media/pci/pt1/pt1.c
index 80510616c4c..43249269469 100644
--- a/drivers/media/pci/pt1/pt1.c
+++ b/drivers/media/pci/pt1/pt1.c
@@ -18,7 +18,10 @@
  */
 
 #include 
+#include 
 #include 
+#include 
+#include 
 #include 
 #include 
 #include 
@@ -321,7 +324,7 @@ static int pt1_unlock(struct pt1 *pt1)
for (i = 0; i < 3; i++) {
if (pt1_read_reg(pt1, 0) & 0x8000)
return 0;
-   schedule_timeout_uninterruptible((HZ + 999) / 1000);
+   usleep_range(1000, 2000);
}
dev_err(>pdev->dev, "could not unlock\n");
return -EIO;
@@ -335,7 +338,7 @@ static int pt1_reset_pci(struct pt1 *pt1)
for (i = 0; i < 10; i++) {
if (pt1_read_reg(pt1, 0) & 0x0001)
return 0;
-   schedule_timeout_uninterruptible((HZ + 999) / 1000);
+   usleep_range(1000, 2000);
}
dev_err(>pdev->dev, "could not reset PCI\n");
return -EIO;
@@ -349,7 +352,7 @@ static int pt1_reset_ram(struct pt1 *pt1)
for (i = 0; i < 10; i++) {
if (pt1_read_reg(pt1, 0) & 0x0002)
return 0;
-   schedule_timeout_uninterruptible((HZ + 999) / 1000);
+   usleep_range(1000, 2000);
}
dev_err(>pdev->dev, "could not reset RAM\n");
return -EIO;
@@ -366,7 +369,7 @@ static int pt1_do_enable_ram(struct pt1 *pt1)
if ((pt1_read_reg(pt1, 0) & 0x0004) != status)
return 0;
}
-   schedule_timeout_uninterruptible((HZ + 999) / 1000);
+   usleep_range(1000, 2000);
}
dev_err(>pdev->dev, "could not enable RAM\n");
return -EIO;
@@ -376,7 +379,7 @@ static int pt1_enable_ram(struct pt1 *pt1)
 {
int i, ret;
int phase;
-   schedule_timeout_uninterruptible((HZ + 999) / 1000);
+   usleep_range(1000, 2000);
phase = pt1->pdev->device == 0x211a ? 128 : 166;
for (i = 0; i < phase; i++) {
ret = pt1_do_enable_ram(pt1);
@@ -463,6 +466,9 @@ static int pt1_thread(void *data)
struct pt1_buffer_page *page;
bool was_frozen;
 
+#define PT1_FETCH_DELAY 10
+#define PT1_FETCH_DELAY_DELTA 2
+
pt1 = data;
set_freezable();
 
@@ -476,7 +482,13 @@ static int pt1_thread(void *data)
 
page = pt1->tables[pt1->table_index].bufs[pt1->buf_index].page;
if (!pt1_filter(pt1, page)) {
-   schedule_timeout_interruptible((HZ + 999) / 1000);
+   ktime_t delay;
+
+   delay = PT1_FETCH_DELAY * NSEC_PER_MSEC;
+   set_current_state(TASK_INTERRUPTIBLE);
+   schedule_hrtimeout_range(,
+   PT1_FETCH_DELAY_DELTA * NSEC_PER_MSEC,
+   HRTIMER_MODE_REL);
continue;
}
 
@@ -712,7 +724,7 @@ pt1_update_power(struct pt1 *pt1)
adap = pt1->adaps[i];
switch (adap->voltage) {
case SEC_VOLTAGE_13: /* actually 11V */
-   bits |= 1 << 1;
+   bits |= 1 << 2;
break;
case SEC_VOLTAGE_18: /* actually 15V */
bits |= 1 << 1 | 1 << 2;
@@ -766,7 +778,7 @@ static int pt1_wakeup(struct dvb_frontend *fe)
adap = container_of(fe->dvb, struct pt1_adapter, adap);
adap->sleep = 0;
pt1_update_power(adap->pt1);
-   schedule_timeout_uninterruptible((HZ + 999) / 1000);
+   usleep_range(1000, 2000);
 
ret = config_demod(adap->demod_i2c_client, adap->pt1->fe_clk);
if (ret == 0 && adap->orig_init)
@@ -1073,7 +1085,7 @@ static int pt1_i2c_end(struct pt1 *pt1, int addr)
do {
if (signal_pending(current))
return -EINTR;
-   schedule_timeout_interruptible((HZ + 999) / 1000);
+   usleep_range(1000, 2000);
} while (pt1_read_reg(pt1, 0) & 0x0080);
return 0;
 }
@@ -1376,11 +1388,11 @@ static int pt1_probe(struct pci_dev *pdev, const struct 
pci_device_id *ent)
 
pt1->power = 1;
pt1_update_power(pt1);
-   schedule_timeout_uninterruptible((HZ + 49) / 50);
+   msleep(20);
 
pt1->reset = 0;
pt1_update_power(pt1);
-   schedule_timeout_uninterruptible((HZ + 999) / 1000);
+   usleep_range(1000, 2000);
 
ret = 

[PATCH v2 3/5] dvb: earth-pt1: decompose pt1 driver into sub drivers

2018-03-28 Thread tskd08
From: Akihiro Tsukada 

earth-pt1 was a monolithic module and included demod/tuner drivers.
This patch removes those FE parts and  attach demod/tuner i2c drivers.

Signed-off-by: Akihiro Tsukada 
---
Changes since v1:
- use i2c_board_info.name to specify pll_desc of the tuner

 drivers/media/pci/pt1/Kconfig|   3 +
 drivers/media/pci/pt1/Makefile   |   3 +-
 drivers/media/pci/pt1/pt1.c  | 329 +++-
 drivers/media/pci/pt1/va1j5jf8007s.c | 732 ---
 drivers/media/pci/pt1/va1j5jf8007s.h |  42 --
 drivers/media/pci/pt1/va1j5jf8007t.c | 532 -
 drivers/media/pci/pt1/va1j5jf8007t.h |  42 --
 7 files changed, 227 insertions(+), 1456 deletions(-)
 delete mode 100644 drivers/media/pci/pt1/va1j5jf8007s.c
 delete mode 100644 drivers/media/pci/pt1/va1j5jf8007s.h
 delete mode 100644 drivers/media/pci/pt1/va1j5jf8007t.c
 delete mode 100644 drivers/media/pci/pt1/va1j5jf8007t.h

diff --git a/drivers/media/pci/pt1/Kconfig b/drivers/media/pci/pt1/Kconfig
index 24501d5bf70..2718b4c6b7c 100644
--- a/drivers/media/pci/pt1/Kconfig
+++ b/drivers/media/pci/pt1/Kconfig
@@ -1,6 +1,9 @@
 config DVB_PT1
tristate "PT1 cards"
depends on DVB_CORE && PCI && I2C
+   select DVB_TC90522 if MEDIA_SUBDRV_AUTOSELECT
+   select DVB_PLL if MEDIA_SUBDRV_AUTOSELECT
+   select MEDIA_TUNER_QM1D1B0004 if MEDIA_SUBDRV_AUTOSELECT
help
  Support for Earthsoft PT1 PCI cards.
 
diff --git a/drivers/media/pci/pt1/Makefile b/drivers/media/pci/pt1/Makefile
index ab873ae088a..bc491e08dd6 100644
--- a/drivers/media/pci/pt1/Makefile
+++ b/drivers/media/pci/pt1/Makefile
@@ -1,5 +1,6 @@
-earth-pt1-objs := pt1.o va1j5jf8007s.o va1j5jf8007t.o
+earth-pt1-objs := pt1.o
 
 obj-$(CONFIG_DVB_PT1) += earth-pt1.o
 
 ccflags-y += -Idrivers/media/dvb-frontends
+ccflags-y += -Idrivers/media/tuners
diff --git a/drivers/media/pci/pt1/pt1.c b/drivers/media/pci/pt1/pt1.c
index 4f6867af831..60bf517e7fe 100644
--- a/drivers/media/pci/pt1/pt1.c
+++ b/drivers/media/pci/pt1/pt1.c
@@ -26,6 +26,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 
 #include 
 #include 
@@ -33,8 +35,9 @@
 #include 
 #include 
 
-#include "va1j5jf8007t.h"
-#include "va1j5jf8007s.h"
+#include "tc90522.h"
+#include "qm1d1b0004.h"
+#include "dvb-pll.h"
 
 #define DRIVER_NAME "earth-pt1"
 
@@ -63,6 +66,11 @@ struct pt1_table {
struct pt1_buffer bufs[PT1_NR_BUFS];
 };
 
+enum pt1_fe_clk {
+   PT1_FE_CLK_20MHZ,   /* PT1 */
+   PT1_FE_CLK_25MHZ,   /* PT2 */
+};
+
 #define PT1_NR_ADAPS 4
 
 struct pt1_adapter;
@@ -81,6 +89,8 @@ struct pt1 {
struct mutex lock;
int power;
int reset;
+
+   enum pt1_fe_clk fe_clk;
 };
 
 struct pt1_adapter {
@@ -97,6 +107,8 @@ struct pt1_adapter {
int users;
struct dmxdev dmxdev;
struct dvb_frontend *fe;
+   struct i2c_client *demod_i2c_client;
+   struct i2c_client *tuner_i2c_client;
int (*orig_set_voltage)(struct dvb_frontend *fe,
enum fe_sec_voltage voltage);
int (*orig_sleep)(struct dvb_frontend *fe);
@@ -106,6 +118,144 @@ struct pt1_adapter {
int sleep;
 };
 
+union pt1_tuner_config {
+   struct qm1d1b0004_config qm1d1b0004;
+   struct dvb_pll_config tda6651;
+};
+
+struct pt1_config {
+   struct i2c_board_info demod_info;
+   struct tc90522_config demod_cfg;
+
+   struct i2c_board_info tuner_info;
+   union pt1_tuner_config tuner_cfg;
+};
+
+static const struct pt1_config pt1_configs[PT1_NR_ADAPS] = {
+   {
+   .demod_info = {
+   I2C_BOARD_INFO(TC90522_I2C_DEV_SAT, 0x1b),
+   },
+   .tuner_info = {
+   I2C_BOARD_INFO("qm1d1b0004", 0x60),
+   },
+   },
+   {
+   .demod_info = {
+   I2C_BOARD_INFO(TC90522_I2C_DEV_TER, 0x1a),
+   },
+   .tuner_info = {
+   I2C_BOARD_INFO(DVB_PLL_TDA665X_EARTH_PT1_NAME, 0x61),
+   },
+   },
+   {
+   .demod_info = {
+   I2C_BOARD_INFO(TC90522_I2C_DEV_SAT, 0x19),
+   },
+   .tuner_info = {
+   I2C_BOARD_INFO("qm1d1b0004", 0x60),
+   },
+   },
+   {
+   .demod_info = {
+   I2C_BOARD_INFO(TC90522_I2C_DEV_TER, 0x18),
+   },
+   .tuner_info = {
+   I2C_BOARD_INFO(DVB_PLL_TDA665X_EARTH_PT1_NAME, 0x61),
+   },
+   },
+};
+
+static const u8 va1j5jf8007s_20mhz_configs[][2] = {
+   {0x04, 0x02}, {0x0d, 0x55}, {0x11, 0x40}, {0x13, 0x80}, {0x17, 0x01},
+   {0x1c, 0x0a}, {0x1d, 0xaa}, {0x1e, 0x20}, {0x1f, 0x88}, {0x51, 0xb0},
+   {0x52, 0x89}, {0x53, 0xb3}, {0x5a, 0x2d}, {0x5b, 0xd3}, {0x85, 0x69},
+   {0x87, 0x04}, {0x8e, 0x02}, {0xa3, 

[PATCH v2 4/5] dvb: earth-pt1: add support for suspend/resume

2018-03-28 Thread tskd08
From: Akihiro Tsukada 

Without this patch, re-loading of the module was required after resume.

Signed-off-by: Akihiro Tsukada 
---
Changes since v1:
- none

 drivers/media/pci/pt1/pt1.c | 107 +++-
 1 file changed, 105 insertions(+), 2 deletions(-)

diff --git a/drivers/media/pci/pt1/pt1.c b/drivers/media/pci/pt1/pt1.c
index 60bf517e7fe..80510616c4c 100644
--- a/drivers/media/pci/pt1/pt1.c
+++ b/drivers/media/pci/pt1/pt1.c
@@ -461,12 +461,18 @@ static int pt1_thread(void *data)
 {
struct pt1 *pt1;
struct pt1_buffer_page *page;
+   bool was_frozen;
 
pt1 = data;
set_freezable();
 
-   while (!kthread_should_stop()) {
-   try_to_freeze();
+   while (!kthread_freezable_should_stop(_frozen)) {
+   if (was_frozen) {
+   int i;
+
+   for (i = 0; i < PT1_NR_ADAPS; i++)
+   pt1_set_stream(pt1, i, !!pt1->adaps[i]->users);
+   }
 
page = pt1->tables[pt1->table_index].bufs[pt1->buf_index].page;
if (!pt1_filter(pt1, page)) {
@@ -1165,6 +1171,98 @@ static void pt1_i2c_init(struct pt1 *pt1)
pt1_i2c_emit(pt1, i, 0, 0, 1, 1, 0);
 }
 
+#ifdef CONFIG_PM_SLEEP
+
+static int pt1_suspend(struct device *dev)
+{
+   struct pci_dev *pdev = to_pci_dev(dev);
+   struct pt1 *pt1 = pci_get_drvdata(pdev);
+
+   pt1_init_streams(pt1);
+   pt1_disable_ram(pt1);
+   pt1->power = 0;
+   pt1->reset = 1;
+   pt1_update_power(pt1);
+   return 0;
+}
+
+static int pt1_resume(struct device *dev)
+{
+   struct pci_dev *pdev = to_pci_dev(dev);
+   struct pt1 *pt1 = pci_get_drvdata(pdev);
+   int ret;
+   int i;
+
+   pt1->power = 0;
+   pt1->reset = 1;
+   pt1_update_power(pt1);
+
+   pt1_i2c_init(pt1);
+   pt1_i2c_wait(pt1);
+
+   ret = pt1_sync(pt1);
+   if (ret < 0)
+   goto resume_err;
+
+   pt1_identify(pt1);
+
+   ret = pt1_unlock(pt1);
+   if (ret < 0)
+   goto resume_err;
+
+   ret = pt1_reset_pci(pt1);
+   if (ret < 0)
+   goto resume_err;
+
+   ret = pt1_reset_ram(pt1);
+   if (ret < 0)
+   goto resume_err;
+
+   ret = pt1_enable_ram(pt1);
+   if (ret < 0)
+   goto resume_err;
+
+   pt1_init_streams(pt1);
+
+   pt1->power = 1;
+   pt1_update_power(pt1);
+   msleep(20);
+
+   pt1->reset = 0;
+   pt1_update_power(pt1);
+   usleep_range(1000, 2000);
+
+   for (i = 0; i < PT1_NR_ADAPS; i++)
+   dvb_frontend_reinitialise(pt1->adaps[i]->fe);
+
+   pt1_init_table_count(pt1);
+   for (i = 0; i < pt1_nr_tables; i++) {
+   int j;
+
+   for (j = 0; j < PT1_NR_BUFS; j++)
+   pt1->tables[i].bufs[j].page->upackets[PT1_NR_UPACKETS-1]
+   = 0;
+   pt1_increment_table_count(pt1);
+   }
+   pt1_register_tables(pt1, pt1->tables[0].addr >> PT1_PAGE_SHIFT);
+
+   pt1->table_index = 0;
+   pt1->buf_index = 0;
+   for (i = 0; i < PT1_NR_ADAPS; i++) {
+   pt1->adaps[i]->upacket_count = 0;
+   pt1->adaps[i]->packet_count = 0;
+   pt1->adaps[i]->st_count = -1;
+   }
+
+   return 0;
+
+resume_err:
+   dev_info(>pdev->dev, "failed to resume PT1/PT2.");
+   return 0;   /* resume anyway */
+}
+
+#endif /* CONFIG_PM_SLEEP */
+
 static void pt1_remove(struct pci_dev *pdev)
 {
struct pt1 *pt1;
@@ -1325,11 +1423,16 @@ static const struct pci_device_id pt1_id_table[] = {
 };
 MODULE_DEVICE_TABLE(pci, pt1_id_table);
 
+static SIMPLE_DEV_PM_OPS(pt1_pm_ops, pt1_suspend, pt1_resume);
+
 static struct pci_driver pt1_driver = {
.name   = DRIVER_NAME,
.probe  = pt1_probe,
.remove = pt1_remove,
.id_table   = pt1_id_table,
+#if CONFIG_PM_SLEEP
+   .driver.pm  = _pm_ops,
+#endif
 };
 
 module_pci_driver(pt1_driver);
-- 
2.16.3



[PATCH v2 1/5] dvb-frontends/dvb-pll: add tda6651 ISDB-T pll_desc

2018-03-28 Thread tskd08
From: Akihiro Tsukada 

This patch adds a PLL "description" of Philips TDA6651 for ISDB-T.
It was extracted from (the former) va1j5jf8007t.c of EarthSoft PT1,
thus the desc might include PT1 specific configs.

Signed-off-by: Akihiro Tsukada 
---
Changes since v1:
- use new style of specifying pll_desc of the tuner

 drivers/media/dvb-frontends/dvb-pll.c | 24 
 drivers/media/dvb-frontends/dvb-pll.h |  2 ++
 2 files changed, 26 insertions(+)

diff --git a/drivers/media/dvb-frontends/dvb-pll.c 
b/drivers/media/dvb-frontends/dvb-pll.c
index deb27aefb9b..62363786e98 100644
--- a/drivers/media/dvb-frontends/dvb-pll.c
+++ b/drivers/media/dvb-frontends/dvb-pll.c
@@ -550,6 +550,28 @@ static const struct dvb_pll_desc dvb_pll_tua6034_friio = {
}
 };
 
+/* Philips TDA6651 ISDB-T, used in Earthsoft PT1 */
+static const struct dvb_pll_desc dvb_pll_tda665x_earth_pt1 = {
+   .name   = "Philips TDA6651 ISDB-T (EarthSoft PT1)",
+   .min=  9000,
+   .max= 77000,
+   .iffreq =  5700,
+   .initdata = (u8[]){ 5, 0x0e, 0x7f, 0xc1, 0x80, 0x80 },
+   .count = 10,
+   .entries = {
+   { 14000, 142857, 0xc1, 0x81 },
+   { 17000, 142857, 0xc1, 0xa1 },
+   { 22000, 142857, 0xc1, 0x62 },
+   { 33000, 142857, 0xc1, 0xa2 },
+   { 40200, 142857, 0xc1, 0xe2 },
+   { 45000, 142857, 0xc1, 0x64 },
+   { 55000, 142857, 0xc1, 0x84 },
+   { 6, 142857, 0xc1, 0xa4 },
+   { 7, 142857, 0xc1, 0xc4 },
+   { 77000, 142857, 0xc1, 0xe4 },
+   }
+};
+
 /* --- */
 
 static const struct dvb_pll_desc *pll_list[] = {
@@ -574,6 +596,7 @@ static const struct dvb_pll_desc *pll_list[] = {
[DVB_PLL_SAMSUNG_TBDU18132]  = _pll_samsung_tbdu18132,
[DVB_PLL_SAMSUNG_TBMU24112]  = _pll_samsung_tbmu24112,
[DVB_PLL_TUA6034_FRIIO]  = _pll_tua6034_friio,
+   [DVB_PLL_TDA665X_EARTH_PT1]  = _pll_tda665x_earth_pt1,
 };
 
 /* --- */
@@ -896,6 +919,7 @@ static const struct i2c_device_id dvb_pll_id[] = {
{DVB_PLL_TDEE4_NAME,  DVB_PLL_TDEE4},
{DVB_PLL_THOMSON_DTT7520X_NAME,   DVB_PLL_THOMSON_DTT7520X},
{DVB_PLL_TUA6034_FRIIO_NAME,  DVB_PLL_TUA6034_FRIIO},
+   {DVB_PLL_TDA665X_EARTH_PT1_NAME,  DVB_PLL_TDA665X_EARTH_PT1},
{}
 };
 
diff --git a/drivers/media/dvb-frontends/dvb-pll.h 
b/drivers/media/dvb-frontends/dvb-pll.h
index c1c27c0d1b1..ddaa5d2efd8 100644
--- a/drivers/media/dvb-frontends/dvb-pll.h
+++ b/drivers/media/dvb-frontends/dvb-pll.h
@@ -30,6 +30,7 @@
 #define DVB_PLL_TDEE4 18
 #define DVB_PLL_THOMSON_DTT7520X   19
 #define DVB_PLL_TUA6034_FRIIO  20
+#define DVB_PLL_TDA665X_EARTH_PT1  21
 
 #define DVB_PLL_THOMSON_DTT7579_NAME   "dtt7579"
 #define DVB_PLL_THOMSON_DTT759X_NAME"dtt759x"
@@ -51,6 +52,7 @@
 #define DVB_PLL_TDEE4_NAME  "tdee4"
 #define DVB_PLL_THOMSON_DTT7520X_NAME   "dtt7520x"
 #define DVB_PLL_TUA6034_FRIIO_NAME  "tua6034_friio"
+#define DVB_PLL_TDA665X_EARTH_PT1_NAME  "tda665x_earthpt1"
 
 struct dvb_pll_config {
struct dvb_frontend *fe;
-- 
2.16.3



[PATCH v2 0/5] dvb/pci/pt1: decompose earth-pt1 into sub drivers

2018-03-28 Thread tskd08
From: Akihiro Tsukada 

Changes since v1:
- use new style of specifying pll_desc of the terrestrial tuner

Akihiro Tsukada (5):
  dvb-frontends/dvb-pll: add tda6651 ISDB-T pll_desc
  tuners: add new i2c driver for  Sharp qm1d1b0004 ISDB-S tuner
  dvb: earth-pt1: decompose pt1 driver into sub drivers
  dvb: earth-pt1: add support for suspend/resume
  dvb: earth-pt1:  replace schedule_timeout with usleep_range

 drivers/media/dvb-frontends/dvb-pll.c |  24 ++
 drivers/media/dvb-frontends/dvb-pll.h |   2 +
 drivers/media/pci/pt1/Kconfig |   3 +
 drivers/media/pci/pt1/Makefile|   3 +-
 drivers/media/pci/pt1/pt1.c   | 470 --
 drivers/media/pci/pt1/va1j5jf8007s.c  | 732 --
 drivers/media/pci/pt1/va1j5jf8007s.h  |  42 --
 drivers/media/pci/pt1/va1j5jf8007t.c  | 532 
 drivers/media/pci/pt1/va1j5jf8007t.h  |  42 --
 drivers/media/tuners/Kconfig  |   7 +
 drivers/media/tuners/Makefile |   1 +
 drivers/media/tuners/qm1d1b0004.c | 264 
 drivers/media/tuners/qm1d1b0004.h |  24 ++
 13 files changed, 677 insertions(+), 1469 deletions(-)
 delete mode 100644 drivers/media/pci/pt1/va1j5jf8007s.c
 delete mode 100644 drivers/media/pci/pt1/va1j5jf8007s.h
 delete mode 100644 drivers/media/pci/pt1/va1j5jf8007t.c
 delete mode 100644 drivers/media/pci/pt1/va1j5jf8007t.h
 create mode 100644 drivers/media/tuners/qm1d1b0004.c
 create mode 100644 drivers/media/tuners/qm1d1b0004.h

-- 
2.16.3



[PATCH] media: coda: do not try to propagate format if capture queue busy

2018-03-28 Thread Philipp Zabel
The driver helpfully resets the capture queue format and selection
rectangle whenever output format is changed. This only works while
the capture queue is not busy.

Signed-off-by: Philipp Zabel 
---
 drivers/media/platform/coda/coda-common.c | 28 +++-
 1 file changed, 15 insertions(+), 13 deletions(-)

diff --git a/drivers/media/platform/coda/coda-common.c 
b/drivers/media/platform/coda/coda-common.c
index 04e35d70ce2e..d3e22c14fad4 100644
--- a/drivers/media/platform/coda/coda-common.c
+++ b/drivers/media/platform/coda/coda-common.c
@@ -786,9 +786,8 @@ static int coda_s_fmt_vid_out(struct file *file, void *priv,
  struct v4l2_format *f)
 {
struct coda_ctx *ctx = fh_to_ctx(priv);
-   struct coda_q_data *q_data_src;
struct v4l2_format f_cap;
-   struct v4l2_rect r;
+   struct vb2_queue *dst_vq;
int ret;
 
ret = coda_try_fmt_vid_out(file, priv, f);
@@ -804,23 +803,26 @@ static int coda_s_fmt_vid_out(struct file *file, void 
*priv,
ctx->ycbcr_enc = f->fmt.pix.ycbcr_enc;
ctx->quantization = f->fmt.pix.quantization;
 
+   dst_vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
+   if (!dst_vq)
+   return -EINVAL;
+
+   /*
+* Setting the capture queue format is not possible while the capture
+* queue is still busy. This is not an error, but the user will have to
+* make sure themselves that the capture format is set correctly before
+* starting the output queue again.
+*/
+   if (vb2_is_busy(dst_vq))
+   return 0;
+
memset(_cap, 0, sizeof(f_cap));
f_cap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
coda_g_fmt(file, priv, _cap);
f_cap.fmt.pix.width = f->fmt.pix.width;
f_cap.fmt.pix.height = f->fmt.pix.height;
 
-   ret = coda_try_fmt_vid_cap(file, priv, _cap);
-   if (ret)
-   return ret;
-
-   q_data_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
-   r.left = 0;
-   r.top = 0;
-   r.width = q_data_src->width;
-   r.height = q_data_src->height;
-
-   return coda_s_fmt(ctx, _cap, );
+   return coda_s_fmt_vid_cap(file, priv, _cap);
 }
 
 static int coda_reqbufs(struct file *file, void *priv,
-- 
2.16.1



[PATCH v4 2/5] dvb-frontends/dvb-pll: add tua6034 ISDB-T tuner used in Friio

2018-03-28 Thread tskd08
From: Akihiro Tsukada 

This driver already contains tua6034-based device settings,
but they are not for ISDB-T and have different parameters.

Signed-off-by: Akihiro Tsukada 
---
Changes since v3:
- rebase on the new style of specifying pll_desc

Changes since v2:
(patch #27927 dvb: tua6034: add a new driver for Infineon tua6034 tuner)
- extends dvb-pll instead of creating a new driver

 drivers/media/dvb-frontends/dvb-pll.c | 19 +++
 drivers/media/dvb-frontends/dvb-pll.h |  2 ++
 2 files changed, 21 insertions(+)

diff --git a/drivers/media/dvb-frontends/dvb-pll.c 
b/drivers/media/dvb-frontends/dvb-pll.c
index e2a93aae04f..deb27aefb9b 100644
--- a/drivers/media/dvb-frontends/dvb-pll.c
+++ b/drivers/media/dvb-frontends/dvb-pll.c
@@ -533,6 +533,23 @@ static const struct dvb_pll_desc dvb_pll_alps_tdee4 = {
}
 };
 
+/* Infineon TUA6034 ISDB-T, used in Friio */
+/* CP cur. 50uA, AGC takeover: 103dBuV, PORT3 on */
+static const struct dvb_pll_desc dvb_pll_tua6034_friio = {
+   .name   = "Infineon TUA6034 ISDB-T (Friio)",
+   .min=  9000,
+   .max= 77000,
+   .iffreq =  5700,
+   .initdata = (u8[]){ 4, 0x9a, 0x50, 0xb2, 0x08 },
+   .sleepdata = (u8[]){ 4, 0x9a, 0x70, 0xb3, 0x0b },
+   .count = 3,
+   .entries = {
+   { 17000, 142857, 0xba, 0x09 },
+   { 47000, 142857, 0xba, 0x0a },
+   { 77000, 142857, 0xb2, 0x08 },
+   }
+};
+
 /* --- */
 
 static const struct dvb_pll_desc *pll_list[] = {
@@ -556,6 +573,7 @@ static const struct dvb_pll_desc *pll_list[] = {
[DVB_PLL_SAMSUNG_TDTC9251DH0]= _pll_samsung_tdtc9251dh0,
[DVB_PLL_SAMSUNG_TBDU18132]  = _pll_samsung_tbdu18132,
[DVB_PLL_SAMSUNG_TBMU24112]  = _pll_samsung_tbmu24112,
+   [DVB_PLL_TUA6034_FRIIO]  = _pll_tua6034_friio,
 };
 
 /* --- */
@@ -877,6 +895,7 @@ static const struct i2c_device_id dvb_pll_id[] = {
{DVB_PLL_SAMSUNG_TBMU24112_NAME,  DVB_PLL_SAMSUNG_TBMU24112},
{DVB_PLL_TDEE4_NAME,  DVB_PLL_TDEE4},
{DVB_PLL_THOMSON_DTT7520X_NAME,   DVB_PLL_THOMSON_DTT7520X},
+   {DVB_PLL_TUA6034_FRIIO_NAME,  DVB_PLL_TUA6034_FRIIO},
{}
 };
 
diff --git a/drivers/media/dvb-frontends/dvb-pll.h 
b/drivers/media/dvb-frontends/dvb-pll.h
index e96994bf668..c1c27c0d1b1 100644
--- a/drivers/media/dvb-frontends/dvb-pll.h
+++ b/drivers/media/dvb-frontends/dvb-pll.h
@@ -29,6 +29,7 @@
 #define DVB_PLL_SAMSUNG_TBMU24112  17
 #define DVB_PLL_TDEE4 18
 #define DVB_PLL_THOMSON_DTT7520X   19
+#define DVB_PLL_TUA6034_FRIIO  20
 
 #define DVB_PLL_THOMSON_DTT7579_NAME   "dtt7579"
 #define DVB_PLL_THOMSON_DTT759X_NAME"dtt759x"
@@ -49,6 +50,7 @@
 #define DVB_PLL_SAMSUNG_TBMU24112_NAME  "tbmu24112"
 #define DVB_PLL_TDEE4_NAME  "tdee4"
 #define DVB_PLL_THOMSON_DTT7520X_NAME   "dtt7520x"
+#define DVB_PLL_TUA6034_FRIIO_NAME  "tua6034_friio"
 
 struct dvb_pll_config {
struct dvb_frontend *fe;
-- 
2.16.3



[PATCH v4 4/5] dvb-usb-v2/gl861: use usleep_range() for short delay

2018-03-28 Thread tskd08
From: Akihiro Tsukada 

As the kernel doc "timers-howto.txt" reads,
short delay with msleep() can take much longer.
In a case of raspbery-pi platform where CONFIG_HZ_100 was set,
it actually affected the init of Friio devices
since it issues lots of i2c transactions with short delay.

Signed-off-by: Akihiro Tsukada 
---
Changes since v3:
- none

 drivers/media/usb/dvb-usb-v2/gl861.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/usb/dvb-usb-v2/gl861.c 
b/drivers/media/usb/dvb-usb-v2/gl861.c
index a0280126bfc..6f6dfa65bba 100644
--- a/drivers/media/usb/dvb-usb-v2/gl861.c
+++ b/drivers/media/usb/dvb-usb-v2/gl861.c
@@ -45,7 +45,7 @@ static int gl861_i2c_msg(struct dvb_usb_device *d, u8 addr,
return -EINVAL;
}
 
-   msleep(1); /* avoid I2C errors */
+   usleep_range(1000, 2000); /* avoid I2C errors */
 
return usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), req, type,
   value, index, rbuf, rlen, 2000);
-- 
2.16.3



[PATCH v4 5/5] dvb-usb-v2/gl861: ensure USB message buffers DMA'able

2018-03-28 Thread tskd08
From: Akihiro Tsukada 

i2c message buf might be on stack.

Signed-off-by: Akihiro Tsukada 
---
Changes since v3:
- none

 drivers/media/usb/dvb-usb-v2/gl861.c | 20 +---
 1 file changed, 17 insertions(+), 3 deletions(-)

diff --git a/drivers/media/usb/dvb-usb-v2/gl861.c 
b/drivers/media/usb/dvb-usb-v2/gl861.c
index 6f6dfa65bba..a5c83b561a4 100644
--- a/drivers/media/usb/dvb-usb-v2/gl861.c
+++ b/drivers/media/usb/dvb-usb-v2/gl861.c
@@ -22,6 +22,8 @@ static int gl861_i2c_msg(struct dvb_usb_device *d, u8 addr,
u16 value = addr << (8 + 1);
int wo = (rbuf == NULL || rlen == 0); /* write-only */
u8 req, type;
+   u8 *buf;
+   int ret;
 
if (wo) {
req = GL861_REQ_I2C_WRITE;
@@ -44,11 +46,23 @@ static int gl861_i2c_msg(struct dvb_usb_device *d, u8 addr,
KBUILD_MODNAME, wlen);
return -EINVAL;
}
-
+   buf = NULL;
+   if (rlen > 0) {
+   buf = kmalloc(rlen, GFP_KERNEL);
+   if (!buf)
+   return -ENOMEM;
+   }
usleep_range(1000, 2000); /* avoid I2C errors */
 
-   return usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), req, type,
-  value, index, rbuf, rlen, 2000);
+   ret = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), req, type,
+ value, index, buf, rlen, 2000);
+   if (rlen > 0) {
+   if (ret > 0)
+   memcpy(rbuf, buf, rlen);
+   kfree(buf);
+   }
+
+   return ret;
 }
 
 /* Friio specific I2C read/write */
-- 
2.16.3



[PATCH v5 3/5] dvb-usb/friio, dvb-usb-v2/gl861: decompose friio and merge with gl861

2018-03-28 Thread tskd08
From: Akihiro Tsukada 

Friio device contains "gl861" bridge and "tc90522" demod,
for which the separate drivers are already in the kernel.
But friio driver was monolithic and did not use them,
practically copying those features.
This patch decomposes friio driver into sub drivers and
re-uses existing ones, thus reduces some code.

It adds some features to gl861,
to support the friio-specific init/config of the devices
and implement i2c communications to the tuner via demod
with USB vendor requests.

Signed-off-by: Akihiro Tsukada 
---
Changes since v4:
- use new style of specifying pll_desc of the tuner driver

Changes since v3:
- make dvb_usb_device_properties static

Changes since v2:
(patch #27928, dvb-usb-friio: split and merge into dvb-usbv2-gl861)
 - used the new i2c binding helpers instead of my own one
 - merged gl861-friio.c with gl861.c

 drivers/media/usb/dvb-usb-v2/Kconfig |   5 +-
 drivers/media/usb/dvb-usb-v2/gl861.c | 465 ++-
 drivers/media/usb/dvb-usb-v2/gl861.h |   1 +
 drivers/media/usb/dvb-usb/Kconfig|   6 -
 drivers/media/usb/dvb-usb/Makefile   |   3 -
 drivers/media/usb/dvb-usb/friio-fe.c | 441 -
 drivers/media/usb/dvb-usb/friio.c| 522 ---
 drivers/media/usb/dvb-usb/friio.h|  99 ---
 8 files changed, 462 insertions(+), 1080 deletions(-)
 delete mode 100644 drivers/media/usb/dvb-usb/friio-fe.c
 delete mode 100644 drivers/media/usb/dvb-usb/friio.c
 delete mode 100644 drivers/media/usb/dvb-usb/friio.h

diff --git a/drivers/media/usb/dvb-usb-v2/Kconfig 
b/drivers/media/usb/dvb-usb-v2/Kconfig
index 0e4944b2b0f..e0a1f377295 100644
--- a/drivers/media/usb/dvb-usb-v2/Kconfig
+++ b/drivers/media/usb/dvb-usb-v2/Kconfig
@@ -95,10 +95,13 @@ config DVB_USB_GL861
tristate "Genesys Logic GL861 USB2.0 support"
depends on DVB_USB_V2
select DVB_ZL10353 if MEDIA_SUBDRV_AUTOSELECT
+   select DVB_TC90522 if MEDIA_SUBDRV_AUTOSELECT
select MEDIA_TUNER_QT1010 if MEDIA_SUBDRV_AUTOSELECT
+   select DVB_PLL if MEDIA_SUBDRV_AUTOSELECT
help
  Say Y here to support the MSI Megasky 580 (55801) DVB-T USB2.0
- receiver with USB ID 0db0:5581.
+ receiver with USB ID 0db0:5581, Friio White ISDB-T receiver
+ with USB ID 0x7a69:0001.
 
 config DVB_USB_LME2510
tristate "LME DM04/QQBOX DVB-S USB2.0 support"
diff --git a/drivers/media/usb/dvb-usb-v2/gl861.c 
b/drivers/media/usb/dvb-usb-v2/gl861.c
index b1b09c54786..a0280126bfc 100644
--- a/drivers/media/usb/dvb-usb-v2/gl861.c
+++ b/drivers/media/usb/dvb-usb-v2/gl861.c
@@ -10,6 +10,8 @@
 
 #include "zl10353.h"
 #include "qt1010.h"
+#include "tc90522.h"
+#include "dvb-pll.h"
 
 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
 
@@ -49,6 +51,80 @@ static int gl861_i2c_msg(struct dvb_usb_device *d, u8 addr,
   value, index, rbuf, rlen, 2000);
 }
 
+/* Friio specific I2C read/write */
+/* special USB request is used in Friio's init/config */
+static int
+gl861_i2c_rawwrite(struct dvb_usb_device *d, u8 addr, u8 *wbuf, u16 wlen)
+{
+   u8 *buf;
+   int ret;
+
+   buf = kmalloc(wlen, GFP_KERNEL);
+   if (!buf)
+   return -ENOMEM;
+
+   usleep_range(1000, 2000); /* avoid I2C errors */
+   memcpy(buf, wbuf, wlen);
+   ret = usb_control_msg(d->udev, usb_sndctrlpipe(d->udev, 0),
+GL861_REQ_I2C_RAW, GL861_WRITE,
+addr << (8 + 1), 0x0100, buf, wlen, 2000);
+   kfree(buf);
+   return ret;
+}
+
+/*
+ * In Friio,
+ * I2C commnucations to the tuner are relay'ed via the demod (via the bridge),
+ * so its encapsulation to USB message is different from the one to the demod.
+ */
+static int
+gl861_i2c_rawread(struct dvb_usb_device *d, u8 addr, u8 *rbuf, u16 rlen)
+{
+   u8 *buf;
+   int ret;
+
+   buf = kmalloc(rlen, GFP_KERNEL);
+   if (!buf)
+   return -ENOMEM;
+
+   usleep_range(1000, 2000); /* avoid I2C errors */
+
+   ret = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0),
+GL861_REQ_I2C_READ, GL861_READ,
+addr << (8 + 1), 0x0100, buf, rlen, 2000);
+   if (ret > 0 && rbuf)
+   memcpy(rbuf, buf, rlen);
+   kfree(buf);
+
+   return ret;
+}
+
+static int
+gl861_i2c_relay_write(struct dvb_usb_device *d, struct i2c_msg *msg)
+{
+   u8 *buf;
+   int ret;
+
+   if (msg->flags & I2C_M_RD)
+   return -EINVAL;
+   if (msg->len < 2)
+   return -EINVAL;
+
+   buf = kmalloc(msg->len - 1, GFP_KERNEL);
+   if (!buf)
+   return -ENOMEM;
+   memcpy(buf, msg->buf + 1, msg->len - 1);
+
+   usleep_range(1000, 2000); /* avoid I2C errors */
+
+   ret = usb_control_msg(d->udev, usb_sndctrlpipe(d->udev, 0),
+GL861_REQ_I2C_RAW, 

[PATCH v4 1/5] dvb-frontends/dvb-pll: add i2c driver support

2018-03-28 Thread tskd08
From: Akihiro Tsukada 

registers the module as an i2c driver,
but keeps dvb_pll_attach() untouched for compatibility.

Signed-off-by: Akihiro Tsukada 
---
Changes since v3:
- use standard i2c_device_id instead of dvb_pll_config

 drivers/media/dvb-frontends/dvb-pll.c | 67 +++
 drivers/media/dvb-frontends/dvb-pll.h | 24 +
 2 files changed, 91 insertions(+)

diff --git a/drivers/media/dvb-frontends/dvb-pll.c 
b/drivers/media/dvb-frontends/dvb-pll.c
index 5553b89b804..e2a93aae04f 100644
--- a/drivers/media/dvb-frontends/dvb-pll.c
+++ b/drivers/media/dvb-frontends/dvb-pll.c
@@ -827,6 +827,73 @@ struct dvb_frontend *dvb_pll_attach(struct dvb_frontend 
*fe, int pll_addr,
 }
 EXPORT_SYMBOL(dvb_pll_attach);
 
+
+static int
+dvb_pll_probe(struct i2c_client *client, const struct i2c_device_id *id)
+{
+   struct dvb_pll_config *cfg;
+   struct dvb_frontend *fe;
+   unsigned int desc_id;
+
+   cfg = client->dev.platform_data;
+   fe = cfg->fe;
+   i2c_set_clientdata(client, fe);
+   desc_id = (unsigned int) id->driver_data;
+
+   if (!dvb_pll_attach(fe, client->addr, client->adapter, desc_id))
+   return -ENOMEM;
+
+   dev_info(>dev, "DVB Simple Tuner attached.\n");
+   return 0;
+}
+
+static int dvb_pll_remove(struct i2c_client *client)
+{
+   struct dvb_frontend *fe;
+
+   fe = i2c_get_clientdata(client);
+   dvb_pll_release(fe);
+   return 0;
+}
+
+
+static const struct i2c_device_id dvb_pll_id[] = {
+   {DVB_PLL_THOMSON_DTT7579_NAME,DVB_PLL_THOMSON_DTT7579},
+   {DVB_PLL_THOMSON_DTT759X_NAME,DVB_PLL_THOMSON_DTT759X},
+   {DVB_PLL_LG_Z201_NAME,DVB_PLL_LG_Z201},
+   {DVB_PLL_UNKNOWN_1_NAME,  DVB_PLL_UNKNOWN_1},
+   {DVB_PLL_TUA6010XS_NAME,  DVB_PLL_TUA6010XS},
+   {DVB_PLL_ENV57H1XD5_NAME, DVB_PLL_ENV57H1XD5},
+   {DVB_PLL_TUA6034_NAME,DVB_PLL_TUA6034},
+   {DVB_PLL_TDA665X_NAME,DVB_PLL_TDA665X},
+   {DVB_PLL_TDED4_NAME,  DVB_PLL_TDED4},
+   {DVB_PLL_TDHU2_NAME,  DVB_PLL_TDHU2},
+   {DVB_PLL_SAMSUNG_TBMV_NAME,   DVB_PLL_SAMSUNG_TBMV},
+   {DVB_PLL_PHILIPS_SD1878_TDA8261_NAME, DVB_PLL_PHILIPS_SD1878_TDA8261},
+   {DVB_PLL_OPERA1_NAME, DVB_PLL_OPERA1},
+   {DVB_PLL_SAMSUNG_DTOS403IH102A_NAME,  DVB_PLL_SAMSUNG_DTOS403IH102A},
+   {DVB_PLL_SAMSUNG_TDTC9251DH0_NAME,DVB_PLL_SAMSUNG_TDTC9251DH0},
+   {DVB_PLL_SAMSUNG_TBDU18132_NAME,  DVB_PLL_SAMSUNG_TBDU18132},
+   {DVB_PLL_SAMSUNG_TBMU24112_NAME,  DVB_PLL_SAMSUNG_TBMU24112},
+   {DVB_PLL_TDEE4_NAME,  DVB_PLL_TDEE4},
+   {DVB_PLL_THOMSON_DTT7520X_NAME,   DVB_PLL_THOMSON_DTT7520X},
+   {}
+};
+
+
+MODULE_DEVICE_TABLE(i2c, dvb_pll_id);
+
+static struct i2c_driver dvb_pll_driver = {
+   .driver = {
+   .name = "dvb_pll",
+   },
+   .probe= dvb_pll_probe,
+   .remove   = dvb_pll_remove,
+   .id_table = dvb_pll_id,
+};
+
+module_i2c_driver(dvb_pll_driver);
+
 MODULE_DESCRIPTION("dvb pll library");
 MODULE_AUTHOR("Gerd Knorr");
 MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb-frontends/dvb-pll.h 
b/drivers/media/dvb-frontends/dvb-pll.h
index ca885e71d2f..e96994bf668 100644
--- a/drivers/media/dvb-frontends/dvb-pll.h
+++ b/drivers/media/dvb-frontends/dvb-pll.h
@@ -30,6 +30,30 @@
 #define DVB_PLL_TDEE4 18
 #define DVB_PLL_THOMSON_DTT7520X   19
 
+#define DVB_PLL_THOMSON_DTT7579_NAME   "dtt7579"
+#define DVB_PLL_THOMSON_DTT759X_NAME"dtt759x"
+#define DVB_PLL_LG_Z201_NAME"z201"
+#define DVB_PLL_UNKNOWN_1_NAME  "unknown_1"
+#define DVB_PLL_TUA6010XS_NAME  "tua6010xs"
+#define DVB_PLL_ENV57H1XD5_NAME "env57h1xd5"
+#define DVB_PLL_TUA6034_NAME"tua6034"
+#define DVB_PLL_TDA665X_NAME"tda665x"
+#define DVB_PLL_TDED4_NAME  "tded4"
+#define DVB_PLL_TDHU2_NAME  "tdhu2"
+#define DVB_PLL_SAMSUNG_TBMV_NAME   "tbmv"
+#define DVB_PLL_PHILIPS_SD1878_TDA8261_NAME "sd1878_tda8261"
+#define DVB_PLL_OPERA1_NAME "opera1"
+#define DVB_PLL_SAMSUNG_DTOS403IH102A_NAME  "dtos403ih102a"
+#define DVB_PLL_SAMSUNG_TDTC9251DH0_NAME"tdtc9251dh0"
+#define DVB_PLL_SAMSUNG_TBDU18132_NAME  "tbdu18132"
+#define DVB_PLL_SAMSUNG_TBMU24112_NAME  "tbmu24112"
+#define DVB_PLL_TDEE4_NAME  "tdee4"
+#define DVB_PLL_THOMSON_DTT7520X_NAME   "dtt7520x"
+
+struct dvb_pll_config {
+   struct dvb_frontend *fe;
+};
+
 #if IS_REACHABLE(CONFIG_DVB_PLL)
 /**
  * Attach a dvb-pll to the supplied frontend structure.
-- 
2.16.3



[PATCH v4 0/5] dvb-usb-friio: decompose friio and merge with gl861

2018-03-28 Thread tskd08
From: Akihiro Tsukada 

This series decomposes dvb-usb-friio into sub drivers
and merge the bridge driver with dvb-usb-gl861.
As to the demod & tuner drivers, existing drivers are re-used.

Changes since v3:
- dvb-pll,gl681: use i2c_device_id/i2c_board_info to specify pll_desc

Changes since v2:
- used the new i2c binding helpers instead of my own one
- extends dvb-pll instead of creating a new tuner driver
- merged gl861-friio.c with gl861.c
- improved module counting
- made i2c communications on USB robust (regarding DMA)

Replaces:
patch #27927, dvb: tua6034: add a new driver for Infineon tua6034 tuner
patch #27928, dvb-usb-friio: split and merge into dvb-usbv2-gl861

Akihiro Tsukada (5):
  dvb-frontends/dvb-pll: add i2c driver support
  dvb-frontends/dvb-pll: add tua6034 ISDB-T tuner used in Friio
  dvb-usb/friio, dvb-usb-v2/gl861: decompose friio and merge with gl861
  dvb-usb-v2/gl861: use usleep_range() for short delay
  dvb-usb-v2/gl861: ensure  USB message buffers DMA'able

 drivers/media/dvb-frontends/dvb-pll.c |  86 ++
 drivers/media/dvb-frontends/dvb-pll.h |  26 ++
 drivers/media/usb/dvb-usb-v2/Kconfig  |   5 +-
 drivers/media/usb/dvb-usb-v2/gl861.c  | 485 ++-
 drivers/media/usb/dvb-usb-v2/gl861.h  |   1 +
 drivers/media/usb/dvb-usb/Kconfig |   6 -
 drivers/media/usb/dvb-usb/Makefile|   3 -
 drivers/media/usb/dvb-usb/friio-fe.c  | 441 
 drivers/media/usb/dvb-usb/friio.c | 522 --
 drivers/media/usb/dvb-usb/friio.h |  99 ---
 10 files changed, 591 insertions(+), 1083 deletions(-)
 delete mode 100644 drivers/media/usb/dvb-usb/friio-fe.c
 delete mode 100644 drivers/media/usb/dvb-usb/friio.c
 delete mode 100644 drivers/media/usb/dvb-usb/friio.h

-- 
2.16.3



Re: [PATCH v4] dvb-usb/friio, dvb-usb-v2/gl861: decompose friio and merge with gl861

2018-03-28 Thread kbuild test robot
Hi Akihiro,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on linuxtv-media/master]
[also build test ERROR on v4.16-rc7 next-20180328]
[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/tskd08-gmail-com/dvb-usb-friio-dvb-usb-v2-gl861-decompose-friio-and-merge-with-gl861/20180329-001436
base:   git://linuxtv.org/media_tree.git master
config: x86_64-randconfig-x019-201812 (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=x86_64 

All errors (new ones prefixed by >>):

>> drivers/media/usb/dvb-usb-v2/gl861.c:203:24: error: field 'tuner_cfg' has 
>> incomplete type
 struct dvb_pll_config tuner_cfg;
   ^
>> drivers/media/usb/dvb-usb-v2/gl861.c:210:3: error: field name not in record 
>> or union initializer
  .desc_id = DVB_PLL_TUA6034_FRIIO,
  ^
   drivers/media/usb/dvb-usb-v2/gl861.c:210:3: note: (near initialization for 
'friio_config.tuner_cfg')
>> drivers/media/usb/dvb-usb-v2/gl861.c:210:14: error: 'DVB_PLL_TUA6034_FRIIO' 
>> undeclared here (not in a function); did you mean 'DVB_PLL_TUA6034'?
  .desc_id = DVB_PLL_TUA6034_FRIIO,
 ^
 DVB_PLL_TUA6034
   drivers/media/usb/dvb-usb-v2/gl861.c: In function 'friio_tuner_attach':
>> drivers/media/usb/dvb-usb-v2/gl861.c:414:24: error: storage size of 'cfg' 
>> isn't known
 struct dvb_pll_config cfg;
   ^~~
   drivers/media/usb/dvb-usb-v2/gl861.c:414:24: warning: unused variable 'cfg' 
[-Wunused-variable]

vim +/tuner_cfg +203 drivers/media/usb/dvb-usb-v2/gl861.c

   197  
   198  struct friio_config {
   199  struct i2c_board_info demod_info;
   200  struct tc90522_config demod_cfg;
   201  
   202  struct i2c_board_info tuner_info;
 > 203  struct dvb_pll_config tuner_cfg;
   204  };
   205  
   206  static const struct friio_config friio_config = {
   207  .demod_info = { I2C_BOARD_INFO(TC90522_I2C_DEV_TER, 0x18), },
   208  .tuner_info = { I2C_BOARD_INFO("dvb_pll", 0x60), },
   209  .tuner_cfg = {
 > 210  .desc_id = DVB_PLL_TUA6034_FRIIO,
   211  },
   212  };
   213  

---
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] PCI: Add pci_find_common_upstream_dev()

2018-03-28 Thread Logan Gunthorpe


On 28/03/18 10:02 AM, Christian König wrote:
> Yeah, that looks very similar to what I picked up from the older 
> patches, going to read up on that after my vacation.

Yeah, I was just reading through your patchset and there are a lot of
similarities. Though, I'm not sure what you're trying to accomplish as I
could not find a cover letter and it seems to only enable one driver. Is
it meant to enable DMA transactions only between two AMD GPUs?

I also don't see where you've taken into account the PCI bus address. On
some architectures this is not the same as the CPU physical address.

> Just in general why are you interested in the "distance" of the devices?

We've taken a general approach where some drivers may provide p2p memory
(ie. an NVMe card or an RDMA NIC) and other drivers make use of it (ie.
the NVMe-of driver). The orchestrator driver needs to find the most
applicable provider device for a transaction in a situation that may
have multiple providers and multiple clients. So the most applicable
provider is the one that's closest ("distance"-wise) to all the clients
for the P2P transaction.

> And BTW: At least for writes that Peer 2 Peer transactions between 
> different root complexes work is actually more common than the other way 
> around.

Maybe on x86 with hardware made in the last few years. But on PowerPC,
ARM64, and likely a lot more the chance of support is *much* less. Also,
hardware that only supports P2P stores is hardly full support and is
insufficient for our needs.

> So I'm a bit torn between using a blacklist or a whitelist. A whitelist 
> is certainly more conservative approach, but that could get a bit long.

I think a whitelist approach is correct. Given old hardware and other
architectures, a black list is going to be too long and too difficult to
comprehensively populate.

Logan


Re: [PATCH 2/8] PCI: Add pci_find_common_upstream_dev()

2018-03-28 Thread Christian König

Am 28.03.2018 um 17:47 schrieb Logan Gunthorpe:


On 28/03/18 09:07 AM, Christian König wrote:

Am 28.03.2018 um 14:38 schrieb Christoph Hellwig:

On Sun, Mar 25, 2018 at 12:59:54PM +0200, Christian König wrote:

From: "wda...@nvidia.com" 

Add an interface to find the first device which is upstream of both
devices.

Please work with Logan and base this on top of the outstanding peer
to peer patchset.

Can you point me to that? The last code I could find about that was from
2015.

The latest posted series is here:

https://lkml.org/lkml/2018/3/12/830

However, we've made some significant changes to the area that's similar
to what you are doing. You can find lasted un-posted here:

https://github.com/sbates130272/linux-p2pmem/tree/pci-p2p-v4-pre2

Specifically this function would be of interest to you:

https://github.com/sbates130272/linux-p2pmem/blob/0e9468ae2a5a5198513dd12990151e09105f0351/drivers/pci/p2pdma.c#L239

However, the difference between what we are doing is that we are
interested in the distance through the common upstream device and you
appear to be finding the actual common device.


Yeah, that looks very similar to what I picked up from the older 
patches, going to read up on that after my vacation.


Just in general why are you interested in the "distance" of the devices?

And BTW: At least for writes that Peer 2 Peer transactions between 
different root complexes work is actually more common than the other way 
around.


So I'm a bit torn between using a blacklist or a whitelist. A whitelist 
is certainly more conservative approach, but that could get a bit long.


Thanks,
Christian.



Thanks,

Logan




Re: [PATCH 2/8] PCI: Add pci_find_common_upstream_dev()

2018-03-28 Thread Logan Gunthorpe


On 28/03/18 09:07 AM, Christian König wrote:
> Am 28.03.2018 um 14:38 schrieb Christoph Hellwig:
>> On Sun, Mar 25, 2018 at 12:59:54PM +0200, Christian König wrote:
>>> From: "wda...@nvidia.com" 
>>>
>>> Add an interface to find the first device which is upstream of both
>>> devices.
>> Please work with Logan and base this on top of the outstanding peer
>> to peer patchset.
> 
> Can you point me to that? The last code I could find about that was from 
> 2015.

The latest posted series is here:

https://lkml.org/lkml/2018/3/12/830

However, we've made some significant changes to the area that's similar
to what you are doing. You can find lasted un-posted here:

https://github.com/sbates130272/linux-p2pmem/tree/pci-p2p-v4-pre2

Specifically this function would be of interest to you:

https://github.com/sbates130272/linux-p2pmem/blob/0e9468ae2a5a5198513dd12990151e09105f0351/drivers/pci/p2pdma.c#L239

However, the difference between what we are doing is that we are
interested in the distance through the common upstream device and you
appear to be finding the actual common device.

Thanks,

Logan


Re: [PATCH 2/8] PCI: Add pci_find_common_upstream_dev()

2018-03-28 Thread Christian König

Am 28.03.2018 um 14:38 schrieb Christoph Hellwig:

On Sun, Mar 25, 2018 at 12:59:54PM +0200, Christian König wrote:

From: "wda...@nvidia.com" 

Add an interface to find the first device which is upstream of both
devices.

Please work with Logan and base this on top of the outstanding peer
to peer patchset.


Can you point me to that? The last code I could find about that was from 
2015.


Thanks,
Christian.


Re: [PATCH 09/15] v4l: vsp1: Replace manual DRM pipeline input setup in vsp1_du_setup_lif

2018-03-28 Thread Kieran Bingham
Hi Laurent,

On 26/02/18 21:45, Laurent Pinchart wrote:
> The vsp1_du_setup_lif() function setups the DRM pipeline input manually.

s/ setups the / sets up the /

> This duplicates the code from the vsp1_du_pipeline_setup_input()
> function. Replace the manual implementation by a call to the function.
> 
> As the pipeline has no enabled input in vsp1_du_setup_lif(), the
> vsp1_du_pipeline_setup_input() function will not setup any RPF, and will
> thus not setup formats on the BRU sink pads. This isn't a problem as all
> inputs are disabled, and the BRU sink pads will be reconfigured from the
> atomic commit handler when inputs will be enabled.
> 
> Signed-off-by: Laurent Pinchart 

Aside from the above,

Reviewed-by: Kieran Bingham 

> ---
>  drivers/media/platform/vsp1/vsp1_drm.c | 40 
> +-
>  1 file changed, 6 insertions(+), 34 deletions(-)
> 
> diff --git a/drivers/media/platform/vsp1/vsp1_drm.c 
> b/drivers/media/platform/vsp1/vsp1_drm.c
> index 6ad8aa6c8138..00ce99bd1605 100644
> --- a/drivers/media/platform/vsp1/vsp1_drm.c
> +++ b/drivers/media/platform/vsp1/vsp1_drm.c
> @@ -412,47 +412,19 @@ int vsp1_du_setup_lif(struct device *dev, unsigned int 
> pipe_index,
>   dev_dbg(vsp1->dev, "%s: configuring LIF%u with format %ux%u\n",
>   __func__, pipe_index, cfg->width, cfg->height);
>  
> - /*
> -  * Configure the format at the BRU sinks and propagate it through the
> -  * pipeline.
> -  */
> + /* Setup formats through the pipeline. */
> + ret = vsp1_du_pipeline_setup_input(vsp1, pipe);
> + if (ret < 0)
> + return ret;
> +
>   memset(, 0, sizeof(format));
>   format.which = V4L2_SUBDEV_FORMAT_ACTIVE;
> -
> - for (i = 0; i < pipe->bru->source_pad; ++i) {
> - format.pad = i;
> -
> - format.format.width = cfg->width;
> - format.format.height = cfg->height;
> - format.format.code = MEDIA_BUS_FMT_ARGB_1X32;
> - format.format.field = V4L2_FIELD_NONE;
> -
> - ret = v4l2_subdev_call(>bru->subdev, pad,
> -set_fmt, NULL, );
> - if (ret < 0)
> - return ret;
> -
> - dev_dbg(vsp1->dev, "%s: set format %ux%u (%x) on %s pad %u\n",
> - __func__, format.format.width, format.format.height,
> - format.format.code, BRU_NAME(pipe->bru), i);
> - }
> -
> - format.pad = pipe->bru->source_pad;
> + format.pad = RWPF_PAD_SINK;
>   format.format.width = cfg->width;
>   format.format.height = cfg->height;
>   format.format.code = MEDIA_BUS_FMT_ARGB_1X32;
>   format.format.field = V4L2_FIELD_NONE;
>  
> - ret = v4l2_subdev_call(>bru->subdev, pad, set_fmt, NULL,
> -);
> - if (ret < 0)
> - return ret;
> -
> - dev_dbg(vsp1->dev, "%s: set format %ux%u (%x) on %s pad %u\n",
> - __func__, format.format.width, format.format.height,
> - format.format.code, BRU_NAME(pipe->bru), i);
> -
> - format.pad = RWPF_PAD_SINK;
>   ret = v4l2_subdev_call(>output->entity.subdev, pad, set_fmt, NULL,
>  );
>   if (ret < 0)
> 


Re: [PATCH 07/15] v4l: vsp1: Move DRM atomic commit pipeline setup to separate function

2018-03-28 Thread Kieran Bingham
Hi Laurent,

On 26/02/18 21:45, Laurent Pinchart wrote:
> The DRM pipeline setup code used at atomic commit time is similar to the
> setup code used when enabling the pipeline. Move it to a separate
> function in order to share it.
> 
> Signed-off-by: Laurent Pinchart 

Assuming no hidden secret code addition in this code move that I haven't seen..

Only a minor nit below asking if the function should be pluralised (_inputs,
rather than _input)

Reviewed-by: Kieran Bingham 


> ---
>  drivers/media/platform/vsp1/vsp1_drm.c | 347 
> +
>  1 file changed, 180 insertions(+), 167 deletions(-)
> 
> diff --git a/drivers/media/platform/vsp1/vsp1_drm.c 
> b/drivers/media/platform/vsp1/vsp1_drm.c
> index 9a043a915c0b..7bf697ba7969 100644
> --- a/drivers/media/platform/vsp1/vsp1_drm.c
> +++ b/drivers/media/platform/vsp1/vsp1_drm.c
> @@ -46,6 +46,185 @@ static void vsp1_du_pipeline_frame_end(struct 
> vsp1_pipeline *pipe,
>   * Pipeline Configuration
>   */
>  
> +/* Setup one RPF and the connected BRU sink pad. */
> +static int vsp1_du_pipeline_setup_rpf(struct vsp1_device *vsp1,
> +   struct vsp1_pipeline *pipe,
> +   struct vsp1_rwpf *rpf,
> +   unsigned int bru_input)
> +{
> + struct v4l2_subdev_selection sel;
> + struct v4l2_subdev_format format;
> + const struct v4l2_rect *crop;
> + int ret;
> +
> + /*
> +  * Configure the format on the RPF sink pad and propagate it up to the
> +  * BRU sink pad.
> +  */
> + crop = >drm->inputs[rpf->entity.index].crop;
> +
> + memset(, 0, sizeof(format));
> + format.which = V4L2_SUBDEV_FORMAT_ACTIVE;
> + format.pad = RWPF_PAD_SINK;
> + format.format.width = crop->width + crop->left;
> + format.format.height = crop->height + crop->top;
> + format.format.code = rpf->fmtinfo->mbus;
> + format.format.field = V4L2_FIELD_NONE;
> +
> + ret = v4l2_subdev_call(>entity.subdev, pad, set_fmt, NULL,
> +);
> + if (ret < 0)
> + return ret;
> +
> + dev_dbg(vsp1->dev,
> + "%s: set format %ux%u (%x) on RPF%u sink\n",
> + __func__, format.format.width, format.format.height,
> + format.format.code, rpf->entity.index);
> +
> + memset(, 0, sizeof(sel));
> + sel.which = V4L2_SUBDEV_FORMAT_ACTIVE;
> + sel.pad = RWPF_PAD_SINK;
> + sel.target = V4L2_SEL_TGT_CROP;
> + sel.r = *crop;
> +
> + ret = v4l2_subdev_call(>entity.subdev, pad, set_selection, NULL,
> +);
> + if (ret < 0)
> + return ret;
> +
> + dev_dbg(vsp1->dev,
> + "%s: set selection (%u,%u)/%ux%u on RPF%u sink\n",
> + __func__, sel.r.left, sel.r.top, sel.r.width, sel.r.height,
> + rpf->entity.index);
> +
> + /*
> +  * RPF source, hardcode the format to ARGB to turn on format
> +  * conversion if needed.
> +  */
> + format.pad = RWPF_PAD_SOURCE;
> +
> + ret = v4l2_subdev_call(>entity.subdev, pad, get_fmt, NULL,
> +);
> + if (ret < 0)
> + return ret;
> +
> + dev_dbg(vsp1->dev,
> + "%s: got format %ux%u (%x) on RPF%u source\n",
> + __func__, format.format.width, format.format.height,
> + format.format.code, rpf->entity.index);
> +
> + format.format.code = MEDIA_BUS_FMT_ARGB_1X32;
> +
> + ret = v4l2_subdev_call(>entity.subdev, pad, set_fmt, NULL,
> +);
> + if (ret < 0)
> + return ret;
> +
> + /* BRU sink, propagate the format from the RPF source. */
> + format.pad = bru_input;
> +
> + ret = v4l2_subdev_call(>bru->subdev, pad, set_fmt, NULL,
> +);
> + if (ret < 0)
> + return ret;
> +
> + dev_dbg(vsp1->dev, "%s: set format %ux%u (%x) on %s pad %u\n",
> + __func__, format.format.width, format.format.height,
> + format.format.code, BRU_NAME(pipe->bru), format.pad);
> +
> + sel.pad = bru_input;
> + sel.target = V4L2_SEL_TGT_COMPOSE;
> + sel.r = vsp1->drm->inputs[rpf->entity.index].compose;
> +
> + ret = v4l2_subdev_call(>bru->subdev, pad, set_selection, NULL,
> +);
> + if (ret < 0)
> + return ret;
> +
> + dev_dbg(vsp1->dev, "%s: set selection (%u,%u)/%ux%u on %s pad %u\n",
> + __func__, sel.r.left, sel.r.top, sel.r.width, sel.r.height,
> + BRU_NAME(pipe->bru), sel.pad);
> +
> + return 0;
> +}
> +
> +static unsigned int rpf_zpos(struct vsp1_device *vsp1, struct vsp1_rwpf *rpf)
> +{
> + return vsp1->drm->inputs[rpf->entity.index].zpos;
> +}
> +
> +/* Setup the input side of the pipeline (RPFs and BRU sink pads). */
> +static int 

Re: [PATCH 12/18] media: staging: atomisp: avoid a warning if 32 bits build

2018-03-28 Thread Mauro Carvalho Chehab
Em Wed, 28 Mar 2018 17:13:29 +0300
Dan Carpenter  escreveu:

> On Mon, Mar 26, 2018 at 05:10:45PM -0400, Mauro Carvalho Chehab wrote:
> > Checking if a size_t value is bigger than ULONG_INT only makes
> > sense if building on 64 bits, as warned by:
> > 
> > drivers/staging/media/atomisp/platform/intel-mid/atomisp_gmin_platform.c:697
> >  gmin_get_config_var() warn: impossible condition '(*out_len > (~0)) => 
> > (0-u32max > u32max)'
> > 
> > Signed-off-by: Mauro Carvalho Chehab 
> > ---
> >  .../staging/media/atomisp/platform/intel-mid/atomisp_gmin_platform.c| 
> > 2 ++
> >  1 file changed, 2 insertions(+)
> > 
> > diff --git 
> > a/drivers/staging/media/atomisp/platform/intel-mid/atomisp_gmin_platform.c 
> > b/drivers/staging/media/atomisp/platform/intel-mid/atomisp_gmin_platform.c
> > index be0c5e11e86b..3283c1b05d6a 100644
> > --- 
> > a/drivers/staging/media/atomisp/platform/intel-mid/atomisp_gmin_platform.c
> > +++ 
> > b/drivers/staging/media/atomisp/platform/intel-mid/atomisp_gmin_platform.c
> > @@ -693,9 +693,11 @@ static int gmin_get_config_var(struct device *dev, 
> > const char *var,
> > for (i = 0; i < sizeof(var8) && var8[i]; i++)
> > var16[i] = var8[i];
> >  
> > +#ifdef CONFIG_64BIT
> > /* To avoid owerflows when calling the efivar API */
> > if (*out_len > ULONG_MAX)
> > return -EINVAL;
> > +#endif  
> 
> I should just silence this particular warning in Smatch.  I feel like
> this is a pretty common thing and the ifdefs aren't very pretty.  :(

Smatch actually warned about a real thing here: atomisp is
doing a check in 32bits that it is always true. So, IMO,
something is needed to prevent 32bits extra useless code somehow,
perhaps via some EFI-var specific function that would do nothing
on 32 bits.

That's the first time I noticed this code on media (although I might
have missed something), so I guess this kind of checking is actually
not that common.

Regards,
Mauro


Re: [PATCH 06/15] v4l: vsp1: Share duplicated DRM pipeline configuration code

2018-03-28 Thread Kieran Bingham


On 26/02/18 21:45, Laurent Pinchart wrote:
> Move the duplicated DRM pipeline configuration code to a function and
> call it from vsp1_du_setup_lif() and vsp1_du_atomic_flush().
> 
> Signed-off-by: Laurent Pinchart 

LGTM.

I thought I had a bit of deja-vu on this patch ... but I can't seem to find
anything already posted.

Reviewed-by: Kieran Bingham 

> ---
>  drivers/media/platform/vsp1/vsp1_drm.c | 95 
> +++---
>  1 file changed, 43 insertions(+), 52 deletions(-)
> 
> diff --git a/drivers/media/platform/vsp1/vsp1_drm.c 
> b/drivers/media/platform/vsp1/vsp1_drm.c
> index e210917fdc3f..9a043a915c0b 100644
> --- a/drivers/media/platform/vsp1/vsp1_drm.c
> +++ b/drivers/media/platform/vsp1/vsp1_drm.c
> @@ -42,6 +42,47 @@ static void vsp1_du_pipeline_frame_end(struct 
> vsp1_pipeline *pipe,
>   drm_pipe->du_complete(drm_pipe->du_private, completed);
>  }
>  
> +/* 
> -
> + * Pipeline Configuration
> + */
> +
> +/* Configure all entities in the pipeline. */
> +static void vsp1_du_pipeline_configure(struct vsp1_pipeline *pipe)
> +{
> + struct vsp1_entity *entity;
> + struct vsp1_entity *next;
> + struct vsp1_dl_list *dl;
> +
> + dl = vsp1_dl_list_get(pipe->output->dlm);
> +
> + list_for_each_entry_safe(entity, next, >entities, list_pipe) {
> + /* Disconnect unused RPFs from the pipeline. */
> + if (entity->type == VSP1_ENTITY_RPF &&
> + !pipe->inputs[entity->index]) {
> + vsp1_dl_list_write(dl, entity->route->reg,
> +VI6_DPR_NODE_UNUSED);
> +
> + entity->pipe = NULL;
> + list_del(>list_pipe);
> +
> + continue;
> + }
> +
> + vsp1_entity_route_setup(entity, pipe, dl);
> +
> + if (entity->ops->configure) {
> + entity->ops->configure(entity, pipe, dl,
> +VSP1_ENTITY_PARAMS_INIT);
> + entity->ops->configure(entity, pipe, dl,
> +VSP1_ENTITY_PARAMS_RUNTIME);
> + entity->ops->configure(entity, pipe, dl,
> +VSP1_ENTITY_PARAMS_PARTITION);
> + }
> + }
> +
> + vsp1_dl_list_commit(dl);
> +}
> +
>  /* 
> -
>   * DU Driver API
>   */
> @@ -85,9 +126,6 @@ int vsp1_du_setup_lif(struct device *dev, unsigned int 
> pipe_index,
>   struct vsp1_drm_pipeline *drm_pipe;
>   struct vsp1_pipeline *pipe;
>   struct vsp1_bru *bru;
> - struct vsp1_entity *entity;
> - struct vsp1_entity *next;
> - struct vsp1_dl_list *dl;
>   struct v4l2_subdev_format format;
>   unsigned long flags;
>   unsigned int i;
> @@ -239,22 +277,7 @@ int vsp1_du_setup_lif(struct device *dev, unsigned int 
> pipe_index,
>   vsp1_write(vsp1, VI6_DISP_IRQ_ENB, 0);
>  
>   /* Configure all entities in the pipeline. */
> - dl = vsp1_dl_list_get(pipe->output->dlm);
> -
> - list_for_each_entry_safe(entity, next, >entities, list_pipe) {
> - vsp1_entity_route_setup(entity, pipe, dl);
> -
> - if (entity->ops->configure) {
> - entity->ops->configure(entity, pipe, dl,
> -VSP1_ENTITY_PARAMS_INIT);
> - entity->ops->configure(entity, pipe, dl,
> -VSP1_ENTITY_PARAMS_RUNTIME);
> - entity->ops->configure(entity, pipe, dl,
> -VSP1_ENTITY_PARAMS_PARTITION);
> - }
> - }
> -
> - vsp1_dl_list_commit(dl);
> + vsp1_du_pipeline_configure(pipe);
>  
>   /* Start the pipeline. */
>   spin_lock_irqsave(>irqlock, flags);
> @@ -490,15 +513,9 @@ void vsp1_du_atomic_flush(struct device *dev, unsigned 
> int pipe_index)
>   struct vsp1_pipeline *pipe = _pipe->pipe;
>   struct vsp1_rwpf *inputs[VSP1_MAX_RPF] = { NULL, };
>   struct vsp1_bru *bru = to_bru(>bru->subdev);
> - struct vsp1_entity *entity;
> - struct vsp1_entity *next;
> - struct vsp1_dl_list *dl;
>   unsigned int i;
>   int ret;
>  
> - /* Prepare the display list. */
> - dl = vsp1_dl_list_get(pipe->output->dlm);
> -
>   /* Count the number of enabled inputs and sort them by Z-order. */
>   pipe->num_inputs = 0;
>  
> @@ -557,33 +574,7 @@ void vsp1_du_atomic_flush(struct device *dev, unsigned 
> int pipe_index)
>   __func__, rpf->entity.index);
>   }
>  
> - /* Configure all entities in the pipeline. */
> - list_for_each_entry_safe(entity, next, >entities, 

Re: [PATCH 12/18] media: staging: atomisp: avoid a warning if 32 bits build

2018-03-28 Thread Dan Carpenter
On Mon, Mar 26, 2018 at 05:10:45PM -0400, Mauro Carvalho Chehab wrote:
> Checking if a size_t value is bigger than ULONG_INT only makes
> sense if building on 64 bits, as warned by:
>   
> drivers/staging/media/atomisp/platform/intel-mid/atomisp_gmin_platform.c:697 
> gmin_get_config_var() warn: impossible condition '(*out_len > (~0)) => 
> (0-u32max > u32max)'
> 
> Signed-off-by: Mauro Carvalho Chehab 
> ---
>  .../staging/media/atomisp/platform/intel-mid/atomisp_gmin_platform.c| 2 
> ++
>  1 file changed, 2 insertions(+)
> 
> diff --git 
> a/drivers/staging/media/atomisp/platform/intel-mid/atomisp_gmin_platform.c 
> b/drivers/staging/media/atomisp/platform/intel-mid/atomisp_gmin_platform.c
> index be0c5e11e86b..3283c1b05d6a 100644
> --- a/drivers/staging/media/atomisp/platform/intel-mid/atomisp_gmin_platform.c
> +++ b/drivers/staging/media/atomisp/platform/intel-mid/atomisp_gmin_platform.c
> @@ -693,9 +693,11 @@ static int gmin_get_config_var(struct device *dev, const 
> char *var,
>   for (i = 0; i < sizeof(var8) && var8[i]; i++)
>   var16[i] = var8[i];
>  
> +#ifdef CONFIG_64BIT
>   /* To avoid owerflows when calling the efivar API */
>   if (*out_len > ULONG_MAX)
>   return -EINVAL;
> +#endif

I should just silence this particular warning in Smatch.  I feel like
this is a pretty common thing and the ifdefs aren't very pretty.  :(

regards,
dan carpenter



Re: [PATCH 05/15] v4l: vsp1: Use vsp1_entity.pipe to check if entity belongs to a pipeline

2018-03-28 Thread Kieran Bingham
Hi Laurent,

On 26/02/18 21:45, Laurent Pinchart wrote:
> The DRM pipeline handling code uses the entity's pipe list head to check
> whether the entity is already included in a pipeline. This method is a
> bit fragile in the sense that it uses list_empty() on a list_head that
> is a list member. Replace it by a simpler check for the entity pipe
> pointer.

Yes, excellent.

> 
> Signed-off-by: Laurent Pinchart 

Reviewed-by: Kieran Bingham 

> ---
>  drivers/media/platform/vsp1/vsp1_drm.c | 8 
>  1 file changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/media/platform/vsp1/vsp1_drm.c 
> b/drivers/media/platform/vsp1/vsp1_drm.c
> index a7ad85ab0b08..e210917fdc3f 100644
> --- a/drivers/media/platform/vsp1/vsp1_drm.c
> +++ b/drivers/media/platform/vsp1/vsp1_drm.c
> @@ -119,9 +119,9 @@ int vsp1_du_setup_lif(struct device *dev, unsigned int 
> pipe_index,
>* Remove the RPF from the pipe and the list of BRU
>* inputs.
>*/
> - WARN_ON(list_empty(>entity.list_pipe));
> + WARN_ON(!rpf->entity.pipe);

Does this WARN_ON() have much value any more ?

I think it could probably be removed... unless there is a race between potential
calls through vsp1_du_atomic_flush() and vsp1_du_setup_lif() - but I would be
very surprised if that wasn't protected at the DRM levels.

 (Removing it if chosen doesn't need to be in this patch though)

>   rpf->entity.pipe = NULL;
> - list_del_init(>entity.list_pipe);
> + list_del(>entity.list_pipe);
>   pipe->inputs[i] = NULL;
>  
>   bru->inputs[rpf->bru_input].rpf = NULL;
> @@ -537,7 +537,7 @@ void vsp1_du_atomic_flush(struct device *dev, unsigned 
> int pipe_index)
>   continue;
>   }
>  
> - if (list_empty(>entity.list_pipe)) {
> + if (!rpf->entity.pipe) {
>   rpf->entity.pipe = pipe;
>   list_add_tail(>entity.list_pipe, >entities);
>   }
> @@ -566,7 +566,7 @@ void vsp1_du_atomic_flush(struct device *dev, unsigned 
> int pipe_index)
>  VI6_DPR_NODE_UNUSED);
>  
>   entity->pipe = NULL;
> - list_del_init(>list_pipe);
> + list_del(>list_pipe);
>  
>   continue;
>   }
> 


[PATCH 22/29] videobuf2-core: add vb2_core_request_has_buffers

2018-03-28 Thread Hans Verkuil
From: Hans Verkuil 

Add a new helper function that returns true if a media_request
contains buffers.

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

diff --git a/drivers/media/common/videobuf2/videobuf2-core.c 
b/drivers/media/common/videobuf2/videobuf2-core.c
index 7499221da1c5..b9d898b116c4 100644
--- a/drivers/media/common/videobuf2/videobuf2-core.c
+++ b/drivers/media/common/videobuf2/videobuf2-core.c
@@ -1333,6 +1333,18 @@ static const struct media_request_object_ops 
vb2_core_req_ops = {
.release = vb2_req_release,
 };
 
+bool vb2_core_request_has_buffers(struct media_request *req)
+{
+   struct media_request_object *obj;
+
+   list_for_each_entry(obj, >objects, list) {
+   if (obj->ops == _core_req_ops)
+   return true;
+   }
+   return false;
+}
+EXPORT_SYMBOL_GPL(vb2_core_request_has_buffers);
+
 int vb2_core_prepare_buf(struct vb2_queue *q, unsigned int index, void *pb,
 struct media_request *req)
 {
diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h
index 72663c2a3ba3..e23dc028aee7 100644
--- a/include/media/videobuf2-core.h
+++ b/include/media/videobuf2-core.h
@@ -1158,4 +1158,6 @@ bool vb2_buffer_in_use(struct vb2_queue *q, struct 
vb2_buffer *vb);
  */
 int vb2_verify_memory_type(struct vb2_queue *q,
enum vb2_memory memory, unsigned int type);
+
+bool vb2_core_request_has_buffers(struct media_request *req);
 #endif /* _MEDIA_VIDEOBUF2_CORE_H */
-- 
2.15.1



[PATCH 20/29] videobuf2-core: integrate with media requests

2018-03-28 Thread Hans Verkuil
From: Hans Verkuil 

Buffers can now be prepared or queued for a request.

A buffer is unbound from the request at vb2_buffer_done time or
when the queue is cancelled.

Signed-off-by: Hans Verkuil 
---
 drivers/media/common/videobuf2/videobuf2-core.c | 106 +---
 drivers/media/common/videobuf2/videobuf2-v4l2.c |   4 +-
 drivers/media/dvb-core/dvb_vb2.c|   2 +-
 include/media/videobuf2-core.h  |  17 +++-
 4 files changed, 113 insertions(+), 16 deletions(-)

diff --git a/drivers/media/common/videobuf2/videobuf2-core.c 
b/drivers/media/common/videobuf2/videobuf2-core.c
index 3d436ccb61f8..7499221da1c5 100644
--- a/drivers/media/common/videobuf2/videobuf2-core.c
+++ b/drivers/media/common/videobuf2/videobuf2-core.c
@@ -930,6 +930,14 @@ void vb2_buffer_done(struct vb2_buffer *vb, enum 
vb2_buffer_state state)
vb->state = state;
}
atomic_dec(>owned_by_drv_count);
+
+   if (vb->req_obj.req) {
+   /* This is not supported at the moment */
+   WARN_ON(state == VB2_BUF_STATE_REQUEUEING);
+   media_request_object_unbind(>req_obj);
+   media_request_object_put(>req_obj);
+   }
+
spin_unlock_irqrestore(>done_lock, flags);
 
trace_vb2_buf_done(q, vb);
@@ -1276,11 +1284,60 @@ static int __buf_prepare(struct vb2_buffer *vb, const 
void *pb)
return 0;
 }
 
-int vb2_core_prepare_buf(struct vb2_queue *q, unsigned int index, void *pb)
+static int vb2_req_prepare(struct media_request_object *obj)
 {
-   struct vb2_buffer *vb;
+   struct vb2_buffer *vb = container_of(obj, struct vb2_buffer, req_obj);
int ret;
 
+   if (WARN_ON(vb->state != VB2_BUF_STATE_IN_REQUEST))
+   return -EINVAL;
+
+   ret = __buf_prepare(vb, NULL);
+   if (ret)
+   vb->state = VB2_BUF_STATE_IN_REQUEST;
+   return ret;
+}
+
+static void __vb2_dqbuf(struct vb2_buffer *vb);
+static void vb2_req_unprepare(struct media_request_object *obj)
+{
+   struct vb2_buffer *vb = container_of(obj, struct vb2_buffer, req_obj);
+
+   __vb2_dqbuf(vb);
+   vb->state = VB2_BUF_STATE_IN_REQUEST;
+   WARN_ON(!vb->req_obj.req);
+}
+
+int vb2_core_qbuf(struct vb2_queue *q, unsigned int index, void *pb,
+ struct media_request *req);
+
+static void vb2_req_queue(struct media_request_object *obj)
+{
+   struct vb2_buffer *vb = container_of(obj, struct vb2_buffer, req_obj);
+
+   vb2_core_qbuf(vb->vb2_queue, vb->index, NULL, NULL);
+}
+
+static void vb2_req_release(struct media_request_object *obj)
+{
+   struct vb2_buffer *vb = container_of(obj, struct vb2_buffer, req_obj);
+
+   if (vb->state == VB2_BUF_STATE_IN_REQUEST)
+   vb->state = VB2_BUF_STATE_DEQUEUED;
+}
+
+static const struct media_request_object_ops vb2_core_req_ops = {
+   .prepare = vb2_req_prepare,
+   .unprepare = vb2_req_unprepare,
+   .queue = vb2_req_queue,
+   .release = vb2_req_release,
+};
+
+int vb2_core_prepare_buf(struct vb2_queue *q, unsigned int index, void *pb,
+struct media_request *req)
+{
+   struct vb2_buffer *vb;
+
vb = q->bufs[index];
if (vb->state != VB2_BUF_STATE_DEQUEUED) {
dprintk(1, "invalid buffer state %d\n",
@@ -1288,16 +1345,24 @@ int vb2_core_prepare_buf(struct vb2_queue *q, unsigned 
int index, void *pb)
return -EINVAL;
}
 
-   ret = __buf_prepare(vb, pb);
-   if (ret)
-   return ret;
+   if (req) {
+   vb->state = VB2_BUF_STATE_IN_REQUEST;
+   media_request_object_init(>req_obj);
+   media_request_object_bind(req, _core_req_ops,
+ q, >req_obj);
+   } else {
+   int ret = __buf_prepare(vb, pb);
+
+   if (ret)
+   return ret;
+   }
 
/* Fill buffer information for the userspace */
call_void_bufop(q, fill_user_buffer, vb, pb);
 
dprintk(2, "prepare of buffer %d succeeded\n", vb->index);
 
-   return ret;
+   return 0;
 }
 EXPORT_SYMBOL_GPL(vb2_core_prepare_buf);
 
@@ -1364,13 +1429,27 @@ static int vb2_start_streaming(struct vb2_queue *q)
return ret;
 }
 
-int vb2_core_qbuf(struct vb2_queue *q, unsigned int index, void *pb)
+int vb2_core_qbuf(struct vb2_queue *q, unsigned int index, void *pb,
+ struct media_request *req)
 {
struct vb2_buffer *vb;
int ret;
 
vb = q->bufs[index];
 
+   if (vb->state == VB2_BUF_STATE_DEQUEUED && req) {
+   vb->state = VB2_BUF_STATE_IN_REQUEST;
+   media_request_object_init(>req_obj);
+   media_request_object_bind(req, _core_req_ops,
+ q, >req_obj);
+   /* Fill buffer information for the userspace */
+   if 

[PATCH 23/29] videobuf2-v4l2: add vb2_request_queue helper

2018-03-28 Thread Hans Verkuil
From: Hans Verkuil 

Generic helper function that checks if there are buffers in
the request and if so, prepares and queues all objects in the
request.

Signed-off-by: Hans Verkuil 
---
 drivers/media/common/videobuf2/videobuf2-v4l2.c | 39 +
 include/media/videobuf2-v4l2.h  |  3 ++
 2 files changed, 42 insertions(+)

diff --git a/drivers/media/common/videobuf2/videobuf2-v4l2.c 
b/drivers/media/common/videobuf2/videobuf2-v4l2.c
index d3ea5ec697a6..ebb951db7a8f 100644
--- a/drivers/media/common/videobuf2/videobuf2-v4l2.c
+++ b/drivers/media/common/videobuf2/videobuf2-v4l2.c
@@ -1054,6 +1054,45 @@ void vb2_ops_wait_finish(struct vb2_queue *vq)
 }
 EXPORT_SYMBOL_GPL(vb2_ops_wait_finish);
 
+int vb2_request_queue(struct media_request *req)
+{
+   struct media_request_object *obj;
+   struct media_request_object *failed_obj = NULL;
+   int ret = 0;
+
+   if (!vb2_core_request_has_buffers(req))
+   return -ENOENT;
+
+   list_for_each_entry(obj, >objects, list) {
+   if (!obj->ops->prepare)
+   continue;
+
+   ret = obj->ops->prepare(obj);
+
+   if (ret) {
+   failed_obj = obj;
+   break;
+   }
+   }
+
+   if (ret) {
+   list_for_each_entry(obj, >objects, list) {
+   if (obj == failed_obj)
+   break;
+   if (obj->ops->unprepare)
+   obj->ops->unprepare(obj);
+   }
+   return ret;
+   }
+
+   list_for_each_entry(obj, >objects, list) {
+   if (obj->ops->queue)
+   obj->ops->queue(obj);
+   }
+   return 0;
+}
+EXPORT_SYMBOL_GPL(vb2_request_queue);
+
 MODULE_DESCRIPTION("Driver helper framework for Video for Linux 2");
 MODULE_AUTHOR("Pawel Osciak , Marek Szyprowski");
 MODULE_LICENSE("GPL");
diff --git a/include/media/videobuf2-v4l2.h b/include/media/videobuf2-v4l2.h
index cf312ab4e7e8..0baa3023d7ad 100644
--- a/include/media/videobuf2-v4l2.h
+++ b/include/media/videobuf2-v4l2.h
@@ -301,4 +301,7 @@ void vb2_ops_wait_prepare(struct vb2_queue *vq);
  */
 void vb2_ops_wait_finish(struct vb2_queue *vq);
 
+struct media_request;
+int vb2_request_queue(struct media_request *req);
+
 #endif /* _MEDIA_VIDEOBUF2_V4L2_H */
-- 
2.15.1



[PATCH 27/29] vim2m: support requests

2018-03-28 Thread Hans Verkuil
From: Hans Verkuil 

Add support for requests to vim2m.

Signed-off-by: Hans Verkuil 
---
 drivers/media/platform/vim2m.c | 25 +
 1 file changed, 25 insertions(+)

diff --git a/drivers/media/platform/vim2m.c b/drivers/media/platform/vim2m.c
index 9b18b32c255d..2dcf0ea85705 100644
--- a/drivers/media/platform/vim2m.c
+++ b/drivers/media/platform/vim2m.c
@@ -387,8 +387,26 @@ 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);
 
+   /* Apply request if needed */
+   if (src_buf->vb2_buf.req_obj.req)
+   v4l2_ctrl_request_setup(src_buf->vb2_buf.req_obj.req,
+   >hdl);
+   if (dst_buf->vb2_buf.req_obj.req &&
+   dst_buf->vb2_buf.req_obj.req != src_buf->vb2_buf.req_obj.req)
+   v4l2_ctrl_request_setup(dst_buf->vb2_buf.req_obj.req,
+   >hdl);
+
device_process(ctx, src_buf, dst_buf);
 
+   /* Complete request if needed */
+   if (src_buf->vb2_buf.req_obj.req)
+   v4l2_ctrl_request_complete(src_buf->vb2_buf.req_obj.req,
+   >hdl);
+   if (dst_buf->vb2_buf.req_obj.req &&
+   dst_buf->vb2_buf.req_obj.req != src_buf->vb2_buf.req_obj.req)
+   v4l2_ctrl_request_complete(dst_buf->vb2_buf.req_obj.req,
+   >hdl);
+
/* Run a timer, which simulates a hardware irq  */
schedule_irq(dev, ctx->transtime);
 }
@@ -823,6 +841,8 @@ static void vim2m_stop_streaming(struct vb2_queue *q)
vbuf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
if (vbuf == NULL)
return;
+   v4l2_ctrl_request_complete(vbuf->vb2_buf.req_obj.req,
+  >hdl);
spin_lock_irqsave(>dev->irqlock, flags);
v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR);
spin_unlock_irqrestore(>dev->irqlock, flags);
@@ -1003,6 +1023,10 @@ static const struct v4l2_m2m_ops m2m_ops = {
.job_abort  = job_abort,
 };
 
+static const struct media_device_ops m2m_media_ops = {
+   .req_queue = vb2_request_queue,
+};
+
 static int vim2m_probe(struct platform_device *pdev)
 {
struct vim2m_dev *dev;
@@ -1027,6 +1051,7 @@ static int vim2m_probe(struct platform_device *pdev)
dev->mdev.dev = >dev;
strlcpy(dev->mdev.model, "vim2m", sizeof(dev->mdev.model));
media_device_init(>mdev);
+   dev->mdev.ops = _media_ops;
dev->v4l2_dev.mdev = >mdev;
dev->pad[0].flags = MEDIA_PAD_FL_SINK;
dev->pad[1].flags = MEDIA_PAD_FL_SOURCE;
-- 
2.15.1



[PATCH 21/29] videobuf2-v4l2: integrate with media requests

2018-03-28 Thread Hans Verkuil
From: Hans Verkuil 

This implements the V4L2 part of the request support. The main
change is that vb2_qbuf and vb2_prepare_buf now have a new
media_device pointer. This required changes to several drivers
that did not use the vb2_ioctl_qbuf/prepare_buf helper functions.

Signed-off-by: Hans Verkuil 
---
 drivers/media/common/videobuf2/videobuf2-v4l2.c  | 77 
 drivers/media/platform/omap3isp/ispvideo.c   |  2 +-
 drivers/media/platform/s3c-camif/camif-capture.c |  4 +-
 drivers/media/platform/s5p-mfc/s5p_mfc_dec.c |  4 +-
 drivers/media/platform/s5p-mfc/s5p_mfc_enc.c |  4 +-
 drivers/media/platform/soc_camera/soc_camera.c   |  4 +-
 drivers/media/usb/uvc/uvc_queue.c|  5 +-
 drivers/media/usb/uvc/uvc_v4l2.c |  3 +-
 drivers/media/usb/uvc/uvcvideo.h |  1 +
 drivers/media/v4l2-core/v4l2-mem2mem.c   |  7 ++-
 drivers/staging/media/davinci_vpfe/vpfe_video.c  |  3 +-
 drivers/staging/media/omap4iss/iss_video.c   |  3 +-
 drivers/usb/gadget/function/uvc_queue.c  |  2 +-
 include/media/videobuf2-v4l2.h   | 12 +++-
 14 files changed, 99 insertions(+), 32 deletions(-)

diff --git a/drivers/media/common/videobuf2/videobuf2-v4l2.c 
b/drivers/media/common/videobuf2/videobuf2-v4l2.c
index b8d370b97cca..d3ea5ec697a6 100644
--- a/drivers/media/common/videobuf2/videobuf2-v4l2.c
+++ b/drivers/media/common/videobuf2/videobuf2-v4l2.c
@@ -25,6 +25,7 @@
 #include 
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -40,10 +41,12 @@ module_param(debug, int, 0644);
pr_info("vb2-v4l2: %s: " fmt, __func__, ## arg); \
} while (0)
 
-/* Flags that are set by the vb2 core */
+/* Flags that are set by us */
 #define V4L2_BUFFER_MASK_FLAGS (V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_QUEUED | \
 V4L2_BUF_FLAG_DONE | V4L2_BUF_FLAG_ERROR | \
 V4L2_BUF_FLAG_PREPARED | \
+V4L2_BUF_FLAG_IN_REQUEST | \
+V4L2_BUF_FLAG_REQUEST_FD | \
 V4L2_BUF_FLAG_TIMESTAMP_MASK)
 /* Output buffer flags that should be passed on to the driver */
 #define V4L2_BUFFER_OUT_FLAGS  (V4L2_BUF_FLAG_PFRAME | V4L2_BUF_FLAG_BFRAME | \
@@ -318,13 +321,17 @@ static int vb2_fill_vb2_v4l2_buffer(struct vb2_buffer 
*vb, struct v4l2_buffer *b
return 0;
 }
 
-static int vb2_queue_or_prepare_buf(struct vb2_queue *q, struct v4l2_buffer *b,
-   const char *opname)
+static int vb2_queue_or_prepare_buf(struct vb2_queue *q, struct media_device 
*mdev,
+   struct v4l2_buffer *b,
+   const char *opname,
+   struct media_request **p_req)
 {
+   struct media_request *req;
struct vb2_v4l2_buffer *vbuf;
struct vb2_buffer *vb;
int ret;
 
+   *p_req = NULL;
if (b->type != q->type) {
dprintk(1, "%s: invalid buffer type\n", opname);
return -EINVAL;
@@ -354,7 +361,31 @@ static int vb2_queue_or_prepare_buf(struct vb2_queue *q, 
struct v4l2_buffer *b,
 
/* Copy relevant information provided by the userspace */
memset(vbuf->planes, 0, sizeof(vbuf->planes[0]) * vb->num_planes);
-   return vb2_fill_vb2_v4l2_buffer(vb, b);
+   ret = vb2_fill_vb2_v4l2_buffer(vb, b);
+   if (ret)
+   return ret;
+
+   if (!(b->flags & V4L2_BUF_FLAG_REQUEST_FD))
+   return 0;
+
+   if (vb->state != VB2_BUF_STATE_DEQUEUED) {
+   dprintk(1, "%s: buffer is not in dequeued state\n", opname);
+   return -EINVAL;
+   }
+
+   if (b->request_fd < 0) {
+   dprintk(1, "%s: request_fd < 0\n", opname);
+   return -EINVAL;
+   }
+
+   req = media_request_find(mdev, b->request_fd);
+   if (IS_ERR(req)) {
+   dprintk(1, "%s: invalid request_fd\n", opname);
+   return PTR_ERR(req);
+   }
+   *p_req = req;
+
+   return 0;
 }
 
 /*
@@ -437,6 +468,9 @@ static void __fill_v4l2_buffer(struct vb2_buffer *vb, void 
*pb)
case VB2_BUF_STATE_ACTIVE:
b->flags |= V4L2_BUF_FLAG_QUEUED;
break;
+   case VB2_BUF_STATE_IN_REQUEST:
+   b->flags |= V4L2_BUF_FLAG_IN_REQUEST;
+   break;
case VB2_BUF_STATE_ERROR:
b->flags |= V4L2_BUF_FLAG_ERROR;
/* fall through */
@@ -455,6 +489,10 @@ static void __fill_v4l2_buffer(struct vb2_buffer *vb, void 
*pb)
 
if (vb2_buffer_in_use(q, vb))
b->flags |= V4L2_BUF_FLAG_MAPPED;
+   if (vb->req_obj.req) {
+   b->flags |= V4L2_BUF_FLAG_REQUEST_FD;
+   b->request_fd = -1;
+   }
 
if (!q->is_output &&
b->flags & 

[PATCH 25/29] media: vim2m: add media device

2018-03-28 Thread Hans Verkuil
From: Alexandre Courbot 

Request API requires a media node. Add one to the vim2m driver so we can
use requests with it.

This probably needs a bit more work to correctly represent m2m
hardware in the media topology.

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

diff --git a/drivers/media/platform/vim2m.c b/drivers/media/platform/vim2m.c
index 065483e62db4..ef970434af13 100644
--- a/drivers/media/platform/vim2m.c
+++ b/drivers/media/platform/vim2m.c
@@ -140,6 +140,10 @@ static struct vim2m_fmt *find_format(struct v4l2_format *f)
 struct vim2m_dev {
struct v4l2_device  v4l2_dev;
struct video_device vfd;
+#ifdef CONFIG_MEDIA_CONTROLLER
+   struct media_device mdev;
+   struct media_padpad[2];
+#endif
 
atomic_tnum_inst;
struct mutexdev_mutex;
@@ -1000,11 +1004,6 @@ static int vim2m_probe(struct platform_device *pdev)
return -ENOMEM;
 
spin_lock_init(>irqlock);
-
-   ret = v4l2_device_register(>dev, >v4l2_dev);
-   if (ret)
-   return ret;
-
atomic_set(>num_inst, 0);
mutex_init(>dev_mutex);
 
@@ -1013,6 +1012,22 @@ static int vim2m_probe(struct platform_device *pdev)
vfd->lock = >dev_mutex;
vfd->v4l2_dev = >v4l2_dev;
 
+#ifdef CONFIG_MEDIA_CONTROLLER
+   dev->mdev.dev = >dev;
+   strlcpy(dev->mdev.model, "vim2m", sizeof(dev->mdev.model));
+   media_device_init(>mdev);
+   dev->v4l2_dev.mdev = >mdev;
+   dev->pad[0].flags = MEDIA_PAD_FL_SINK;
+   dev->pad[1].flags = MEDIA_PAD_FL_SOURCE;
+   ret = media_entity_pads_init(>entity, 2, dev->pad);
+   if (ret)
+   return ret;
+#endif
+
+   ret = v4l2_device_register(>dev, >v4l2_dev);
+   if (ret)
+   goto unreg_media;
+
ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0);
if (ret) {
v4l2_err(>v4l2_dev, "Failed to register video device\n");
@@ -1034,6 +1049,13 @@ static int vim2m_probe(struct platform_device *pdev)
goto err_m2m;
}
 
+#ifdef CONFIG_MEDIA_CONTROLLER
+   /* Register the media device node */
+   ret = media_device_register(>mdev);
+   if (ret)
+   goto err_m2m;
+#endif
+
return 0;
 
 err_m2m:
@@ -1041,6 +1063,10 @@ static int vim2m_probe(struct platform_device *pdev)
video_unregister_device(>vfd);
 unreg_dev:
v4l2_device_unregister(>v4l2_dev);
+unreg_media:
+#ifdef CONFIG_MEDIA_CONTROLLER
+   media_device_unregister(>mdev);
+#endif
 
return ret;
 }
@@ -1050,6 +1076,13 @@ static int vim2m_remove(struct platform_device *pdev)
struct vim2m_dev *dev = platform_get_drvdata(pdev);
 
v4l2_info(>v4l2_dev, "Removing " MEM2MEM_NAME);
+
+#ifdef CONFIG_MEDIA_CONTROLLER
+   if (media_devnode_is_registered(dev->mdev.devnode))
+   media_device_unregister(>mdev);
+   media_device_cleanup(>mdev);
+#endif
+
v4l2_m2m_release(dev->m2m_dev);
del_timer_sync(>timer);
video_unregister_device(>vfd);
-- 
2.15.1



[PATCH 24/29] Documentation: v4l: document request API

2018-03-28 Thread Hans Verkuil
From: 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|  19 +-
 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  |  22 ++-
 .../media/uapi/v4l/vidioc-new-request.rst  |  64 +++
 Documentation/media/uapi/v4l/vidioc-qbuf.rst   |   8 +
 7 files changed, 308 insertions(+), 6 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 e2c85ddc990b..e23eae12905c 100644
--- a/Documentation/media/uapi/v4l/buffer.rst
+++ b/Documentation/media/uapi/v4l/buffer.rst
@@ -306,10 +306,13 @@ struct v4l2_buffer
   - A place holder for future extensions. Drivers and applications
must set this to 0.
 * - __u32
-  - ``reserved``
+  - ``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
+and flag ``V4L2_BUF_FLAG_REQUEST_FD`` is set, then the buffer will be
+   queued to that request. This is set by the user when calling
+   :ref:`VIDIOC_QBUF` and :ref:`VIDIOC_PREPARE_BUF` and ignored by other
+   ioctls.
 
 
 
@@ -514,6 +517,11 @@ Buffer Flags
streaming may continue as normal and the buffer may be reused
normally. Drivers set this flag when the ``VIDIOC_DQBUF`` ioctl is
called.
+* .. _`V4L2-BUF-FLAG-IN-REQUEST`:
+
+  - ``V4L2_BUF_FLAG_IN_REQUEST``
+  - 0x0080
+  - This buffer is part of a request the hasn't been queued yet.
 * .. _`V4L2-BUF-FLAG-KEYFRAME`:
 
   - ``V4L2_BUF_FLAG_KEYFRAME``
@@ -589,6 +597,11 @@ Buffer Flags
the format. Any Any subsequent call to the
:ref:`VIDIOC_DQBUF ` ioctl will not block anymore,
but return an ``EPIPE`` error code.
+* .. _`V4L2-BUF-FLAG-REQUEST-FD`:
+
+  - ``V4L2_BUF_FLAG_REQUEST_FD``
+  - 0x0080
+  - The ``request_fd`` field contains a valid file descriptor.
 * .. _`V4L2-BUF-FLAG-TIMESTAMP-MASK`:
 
   - ``V4L2_BUF_FLAG_TIMESTAMP_MASK``
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 

[PATCH 28/29] vivid: add mc

2018-03-28 Thread Hans Verkuil
From: Hans Verkuil 

Add support for the media_device to vivid. This is a prerequisite
for request support.

Signed-off-by: Hans Verkuil 
---
 drivers/media/platform/vivid/vivid-core.c | 61 +++
 drivers/media/platform/vivid/vivid-core.h |  8 
 2 files changed, 69 insertions(+)

diff --git a/drivers/media/platform/vivid/vivid-core.c 
b/drivers/media/platform/vivid/vivid-core.c
index 82ec216f2ad8..69386b26d5dd 100644
--- a/drivers/media/platform/vivid/vivid-core.c
+++ b/drivers/media/platform/vivid/vivid-core.c
@@ -657,6 +657,15 @@ static int vivid_create_instance(struct platform_device 
*pdev, int inst)
 
dev->inst = inst;
 
+#ifdef CONFIG_MEDIA_CONTROLLER
+   dev->v4l2_dev.mdev = >mdev;
+
+   /* Initialize media device */
+   strlcpy(dev->mdev.model, VIVID_MODULE_NAME, sizeof(dev->mdev.model));
+   dev->mdev.dev = >dev;
+   media_device_init(>mdev);
+#endif
+
/* register v4l2_device */
snprintf(dev->v4l2_dev.name, sizeof(dev->v4l2_dev.name),
"%s-%03d", VIVID_MODULE_NAME, inst);
@@ -1173,6 +1182,13 @@ static int vivid_create_instance(struct platform_device 
*pdev, int inst)
vfd->lock = >mutex;
video_set_drvdata(vfd, dev);
 
+#ifdef CONFIG_MEDIA_CONTROLLER
+   dev->vid_cap_pad.flags = MEDIA_PAD_FL_SINK;
+   ret = media_entity_pads_init(>entity, 1, 
>vid_cap_pad);
+   if (ret)
+   goto unreg_dev;
+#endif
+
 #ifdef CONFIG_VIDEO_VIVID_CEC
if (in_type_counter[HDMI]) {
struct cec_adapter *adap;
@@ -1225,6 +1241,13 @@ static int vivid_create_instance(struct platform_device 
*pdev, int inst)
vfd->lock = >mutex;
video_set_drvdata(vfd, dev);
 
+#ifdef CONFIG_MEDIA_CONTROLLER
+   dev->vid_out_pad.flags = MEDIA_PAD_FL_SOURCE;
+   ret = media_entity_pads_init(>entity, 1, 
>vid_out_pad);
+   if (ret)
+   goto unreg_dev;
+#endif
+
 #ifdef CONFIG_VIDEO_VIVID_CEC
for (i = 0; i < dev->num_outputs; i++) {
struct cec_adapter *adap;
@@ -1274,6 +1297,13 @@ static int vivid_create_instance(struct platform_device 
*pdev, int inst)
vfd->tvnorms = tvnorms_cap;
video_set_drvdata(vfd, dev);
 
+#ifdef CONFIG_MEDIA_CONTROLLER
+   dev->vbi_cap_pad.flags = MEDIA_PAD_FL_SINK;
+   ret = media_entity_pads_init(>entity, 1, 
>vbi_cap_pad);
+   if (ret)
+   goto unreg_dev;
+#endif
+
ret = video_register_device(vfd, VFL_TYPE_VBI, 
vbi_cap_nr[inst]);
if (ret < 0)
goto unreg_dev;
@@ -1299,6 +1329,13 @@ static int vivid_create_instance(struct platform_device 
*pdev, int inst)
vfd->tvnorms = tvnorms_out;
video_set_drvdata(vfd, dev);
 
+#ifdef CONFIG_MEDIA_CONTROLLER
+   dev->vbi_out_pad.flags = MEDIA_PAD_FL_SOURCE;
+   ret = media_entity_pads_init(>entity, 1, 
>vbi_out_pad);
+   if (ret)
+   goto unreg_dev;
+#endif
+
ret = video_register_device(vfd, VFL_TYPE_VBI, 
vbi_out_nr[inst]);
if (ret < 0)
goto unreg_dev;
@@ -1322,6 +1359,13 @@ static int vivid_create_instance(struct platform_device 
*pdev, int inst)
vfd->lock = >mutex;
video_set_drvdata(vfd, dev);
 
+#ifdef CONFIG_MEDIA_CONTROLLER
+   dev->sdr_cap_pad.flags = MEDIA_PAD_FL_SINK;
+   ret = media_entity_pads_init(>entity, 1, 
>sdr_cap_pad);
+   if (ret)
+   goto unreg_dev;
+#endif
+
ret = video_register_device(vfd, VFL_TYPE_SDR, 
sdr_cap_nr[inst]);
if (ret < 0)
goto unreg_dev;
@@ -1368,12 +1412,25 @@ static int vivid_create_instance(struct platform_device 
*pdev, int inst)
  video_device_node_name(vfd));
}
 
+#ifdef CONFIG_MEDIA_CONTROLLER
+   /* Register the media device */
+   ret = media_device_register(>mdev);
+   if (ret) {
+   dev_err(dev->mdev.dev,
+   "media device register failed (err=%d)\n", ret);
+   goto unreg_dev;
+   }
+#endif
+
/* Now that everything is fine, let's add it to device list */
vivid_devs[inst] = dev;
 
return 0;
 
 unreg_dev:
+#ifdef CONFIG_MEDIA_CONTROLLER
+   media_device_unregister(>mdev);
+#endif
video_unregister_device(>radio_tx_dev);
video_unregister_device(>radio_rx_dev);
video_unregister_device(>sdr_cap_dev);
@@ -1444,6 +1501,10 @@ static int vivid_remove(struct platform_device *pdev)
if (!dev)
continue;
 
+#ifdef CONFIG_MEDIA_CONTROLLER
+ 

[PATCH 17/29] videodev2.h: Add request_fd field to v4l2_buffer

2018-03-28 Thread Hans Verkuil
From: Hans Verkuil 

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

If V4L2_BUF_FLAG_REQUEST_FD is set, then request_fd is used as
the file descriptor.

If a buffer is stored in a request, but not yet queued to the
driver, then V4L2_BUF_FLAG_IN_REQUEST is set.

Signed-off-by: Hans Verkuil 
---
 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  | 10 +-
 5 files changed, 19 insertions(+), 8 deletions(-)

diff --git a/drivers/media/common/videobuf2/videobuf2-v4l2.c 
b/drivers/media/common/videobuf2/videobuf2-v4l2.c
index 886a2d8d5c6c..4e9c77f21858 100644
--- a/drivers/media/common/videobuf2/videobuf2-v4l2.c
+++ b/drivers/media/common/videobuf2/videobuf2-v4l2.c
@@ -204,7 +204,7 @@ static void __fill_v4l2_buffer(struct vb2_buffer *vb, void 
*pb)
b->timecode = vbuf->timecode;
b->sequence = vbuf->sequence;
b->reserved2 = 0;
-   b->reserved = 0;
+   b->request_fd = 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..13aee9f67d05 100644
--- a/drivers/media/usb/cpia2/cpia2_v4l.c
+++ b/drivers/media/usb/cpia2/cpia2_v4l.c
@@ -949,7 +949,7 @@ static int cpia2_dqbuf(struct file *file, void *fh, struct 
v4l2_buffer *buf)
buf->m.offset = cam->buffers[buf->index].data - cam->frame_buffer;
buf->length = cam->frame_size;
buf->reserved2 = 0;
-   buf->reserved = 0;
+   buf->request_fd = 0;
memset(>timecode, 0, sizeof(buf->timecode));
 
DBG("DQBUF #%d status:%d seq:%d length:%d\n", buf->index,
diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c 
b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
index 0782b3666deb..7e27d0feac94 100644
--- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
+++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
@@ -387,7 +387,7 @@ struct v4l2_buffer32 {
} m;
__u32   length;
__u32   reserved2;
-   __u32   reserved;
+   __s32   request_fd;
 };
 
 static int get_v4l2_plane32(struct v4l2_plane __user *up,
@@ -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))
@@ -605,7 +608,7 @@ static int put_v4l2_buffer32(struct v4l2_buffer __user *kp,
copy_in_user(>timecode, >timecode, sizeof(kp->timecode)) ||
assign_in_user(>sequence, >sequence) ||
assign_in_user(>reserved2, >reserved2) ||
-   assign_in_user(>reserved, >reserved) ||
+   assign_in_user(>request_fd, >request_fd) ||
get_user(length, >length) ||
put_user(length, >length))
return -EFAULT;
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c 
b/drivers/media/v4l2-core/v4l2-ioctl.c
index ceeb6df0ef19..fd31f18b0aef 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=%d, 
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 6f41baa53787..88e2264b68f8 100644
--- a/include/uapi/linux/videodev2.h
+++ b/include/uapi/linux/videodev2.h
@@ 

[PATCH 29/29] vivid: add request support

2018-03-28 Thread Hans Verkuil
From: Hans Verkuil 

Add support for requests to vivid.

Signed-off-by: Hans Verkuil 
---
 drivers/media/platform/vivid/vivid-core.c|  7 +++
 drivers/media/platform/vivid/vivid-kthread-cap.c | 12 
 drivers/media/platform/vivid/vivid-kthread-out.c | 12 
 drivers/media/platform/vivid/vivid-sdr-cap.c |  8 
 drivers/media/platform/vivid/vivid-vbi-cap.c |  2 ++
 drivers/media/platform/vivid/vivid-vbi-out.c |  2 ++
 drivers/media/platform/vivid/vivid-vid-cap.c |  2 ++
 drivers/media/platform/vivid/vivid-vid-out.c |  2 ++
 8 files changed, 47 insertions(+)

diff --git a/drivers/media/platform/vivid/vivid-core.c 
b/drivers/media/platform/vivid/vivid-core.c
index 69386b26d5dd..20e74d36b673 100644
--- a/drivers/media/platform/vivid/vivid-core.c
+++ b/drivers/media/platform/vivid/vivid-core.c
@@ -627,6 +627,12 @@ static void vivid_dev_release(struct v4l2_device *v4l2_dev)
kfree(dev);
 }
 
+#ifdef CONFIG_MEDIA_CONTROLLER
+static const struct media_device_ops vivid_media_ops = {
+   .req_queue = vb2_request_queue,
+};
+#endif
+
 static int vivid_create_instance(struct platform_device *pdev, int inst)
 {
static const struct v4l2_dv_timings def_dv_timings =
@@ -664,6 +670,7 @@ static int vivid_create_instance(struct platform_device 
*pdev, int inst)
strlcpy(dev->mdev.model, VIVID_MODULE_NAME, sizeof(dev->mdev.model));
dev->mdev.dev = >dev;
media_device_init(>mdev);
+   dev->mdev.ops = _media_ops;
 #endif
 
/* register v4l2_device */
diff --git a/drivers/media/platform/vivid/vivid-kthread-cap.c 
b/drivers/media/platform/vivid/vivid-kthread-cap.c
index 3fdb280c36ca..c192b4b1b9de 100644
--- a/drivers/media/platform/vivid/vivid-kthread-cap.c
+++ b/drivers/media/platform/vivid/vivid-kthread-cap.c
@@ -703,6 +703,8 @@ static void vivid_thread_vid_cap_tick(struct vivid_dev 
*dev, int dropped_bufs)
goto update_mv;
 
if (vid_cap_buf) {
+   v4l2_ctrl_request_setup(vid_cap_buf->vb.vb2_buf.req_obj.req,
+   >ctrl_hdl_vid_cap);
/* Fill buffer */
vivid_fillbuff(dev, vid_cap_buf);
dprintk(dev, 1, "filled buffer %d\n",
@@ -713,6 +715,8 @@ static void vivid_thread_vid_cap_tick(struct vivid_dev 
*dev, int dropped_bufs)
dev->fb_cap.fmt.pixelformat == dev->fmt_cap->fourcc)
vivid_overlay(dev, vid_cap_buf);
 
+   v4l2_ctrl_request_complete(vid_cap_buf->vb.vb2_buf.req_obj.req,
+  >ctrl_hdl_vid_cap);
vb2_buffer_done(_cap_buf->vb.vb2_buf, dev->dqbuf_error ?
VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE);
dprintk(dev, 2, "vid_cap buffer %d done\n",
@@ -720,10 +724,14 @@ static void vivid_thread_vid_cap_tick(struct vivid_dev 
*dev, int dropped_bufs)
}
 
if (vbi_cap_buf) {
+   v4l2_ctrl_request_setup(vbi_cap_buf->vb.vb2_buf.req_obj.req,
+   >ctrl_hdl_vbi_cap);
if (dev->stream_sliced_vbi_cap)
vivid_sliced_vbi_cap_process(dev, vbi_cap_buf);
else
vivid_raw_vbi_cap_process(dev, vbi_cap_buf);
+   v4l2_ctrl_request_complete(vbi_cap_buf->vb.vb2_buf.req_obj.req,
+  >ctrl_hdl_vbi_cap);
vb2_buffer_done(_cap_buf->vb.vb2_buf, dev->dqbuf_error ?
VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE);
dprintk(dev, 2, "vbi_cap %d done\n",
@@ -891,6 +899,8 @@ void vivid_stop_generating_vid_cap(struct vivid_dev *dev, 
bool *pstreaming)
buf = list_entry(dev->vid_cap_active.next,
 struct vivid_buffer, list);
list_del(>list);
+   v4l2_ctrl_request_complete(buf->vb.vb2_buf.req_obj.req,
+  >ctrl_hdl_vid_cap);
vb2_buffer_done(>vb.vb2_buf, VB2_BUF_STATE_ERROR);
dprintk(dev, 2, "vid_cap buffer %d done\n",
buf->vb.vb2_buf.index);
@@ -904,6 +914,8 @@ void vivid_stop_generating_vid_cap(struct vivid_dev *dev, 
bool *pstreaming)
buf = list_entry(dev->vbi_cap_active.next,
 struct vivid_buffer, list);
list_del(>list);
+   v4l2_ctrl_request_complete(buf->vb.vb2_buf.req_obj.req,
+  >ctrl_hdl_vbi_cap);
vb2_buffer_done(>vb.vb2_buf, VB2_BUF_STATE_ERROR);
dprintk(dev, 2, "vbi_cap buffer %d done\n",
buf->vb.vb2_buf.index);
diff --git 

[PATCH 26/29] vim2m: use workqueue

2018-03-28 Thread Hans Verkuil
From: Hans Verkuil 

v4l2_ctrl uses mutexes, so we can't setup a ctrl_handler in
interrupt context. Switch to a workqueue instead.

Signed-off-by: Hans Verkuil 
---
 drivers/media/platform/vim2m.c | 15 +--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/drivers/media/platform/vim2m.c b/drivers/media/platform/vim2m.c
index ef970434af13..9b18b32c255d 100644
--- a/drivers/media/platform/vim2m.c
+++ b/drivers/media/platform/vim2m.c
@@ -150,6 +150,7 @@ struct vim2m_dev {
spinlock_t  irqlock;
 
struct timer_list   timer;
+   struct work_struct  work_run;
 
struct v4l2_m2m_dev *m2m_dev;
 };
@@ -392,9 +393,10 @@ static void device_run(void *priv)
schedule_irq(dev, ctx->transtime);
 }
 
-static void device_isr(struct timer_list *t)
+static void device_work(struct work_struct *w)
 {
-   struct vim2m_dev *vim2m_dev = from_timer(vim2m_dev, t, timer);
+   struct vim2m_dev *vim2m_dev =
+   container_of(w, struct vim2m_dev, work_run);
struct vim2m_ctx *curr_ctx;
struct vb2_v4l2_buffer *src_vb, *dst_vb;
unsigned long flags;
@@ -426,6 +428,13 @@ static void device_isr(struct timer_list *t)
}
 }
 
+static void device_isr(struct timer_list *t)
+{
+   struct vim2m_dev *vim2m_dev = from_timer(vim2m_dev, t, timer);
+
+   schedule_work(_dev->work_run);
+}
+
 /*
  * video ioctls
  */
@@ -806,6 +815,7 @@ static void vim2m_stop_streaming(struct vb2_queue *q)
struct vb2_v4l2_buffer *vbuf;
unsigned long flags;
 
+   flush_scheduled_work();
for (;;) {
if (V4L2_TYPE_IS_OUTPUT(q->type))
vbuf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
@@ -1011,6 +1021,7 @@ static int vim2m_probe(struct platform_device *pdev)
vfd = >vfd;
vfd->lock = >dev_mutex;
vfd->v4l2_dev = >v4l2_dev;
+   INIT_WORK(>work_run, device_work);
 
 #ifdef CONFIG_MEDIA_CONTROLLER
dev->mdev.dev = >dev;
-- 
2.15.1



[PATCH 18/29] vb2: store userspace data in vb2_v4l2_buffer

2018-03-28 Thread Hans Verkuil
From: Hans Verkuil 

The userspace-provided plane data needs to be stored in
vb2_v4l2_buffer. Currently this information is applied by
__fill_vb2_buffer() which is called by the core prepare_buf
and qbuf functions, but when using requests these functions
aren't called yet since the buffer won't be prepared until
the media request is actually queued.

In the meantime this information has to be stored somewhere
and vb2_v4l2_buffer is a good place for it.

The __fill_vb2_buffer callback now just copies the relevant
information from vb2_v4l2_buffer into the planes array.

Signed-off-by: Hans Verkuil 
---
 drivers/media/common/videobuf2/videobuf2-core.c |  25 +-
 drivers/media/common/videobuf2/videobuf2-v4l2.c | 324 +---
 drivers/media/dvb-core/dvb_vb2.c|   3 +-
 include/media/videobuf2-core.h  |   3 +-
 include/media/videobuf2-v4l2.h  |   2 +
 5 files changed, 197 insertions(+), 160 deletions(-)

diff --git a/drivers/media/common/videobuf2/videobuf2-core.c 
b/drivers/media/common/videobuf2/videobuf2-core.c
index d3f7bb33a54d..3d436ccb61f8 100644
--- a/drivers/media/common/videobuf2/videobuf2-core.c
+++ b/drivers/media/common/videobuf2/videobuf2-core.c
@@ -968,9 +968,8 @@ static int __prepare_mmap(struct vb2_buffer *vb, const void 
*pb)
 {
int ret = 0;
 
-   if (pb)
-   ret = call_bufop(vb->vb2_queue, fill_vb2_buffer,
-vb, pb, vb->planes);
+   ret = call_bufop(vb->vb2_queue, fill_vb2_buffer,
+vb, vb->planes);
return ret ? ret : call_vb_qop(vb, buf_prepare, vb);
 }
 
@@ -988,12 +987,10 @@ static int __prepare_userptr(struct vb2_buffer *vb, const 
void *pb)
 
memset(planes, 0, sizeof(planes[0]) * vb->num_planes);
/* Copy relevant information provided by the userspace */
-   if (pb) {
-   ret = call_bufop(vb->vb2_queue, fill_vb2_buffer,
-vb, pb, planes);
-   if (ret)
-   return ret;
-   }
+   ret = call_bufop(vb->vb2_queue, fill_vb2_buffer,
+vb, planes);
+   if (ret)
+   return ret;
 
for (plane = 0; plane < vb->num_planes; ++plane) {
/* Skip the plane if already verified */
@@ -1104,12 +1101,10 @@ static int __prepare_dmabuf(struct vb2_buffer *vb, 
const void *pb)
 
memset(planes, 0, sizeof(planes[0]) * vb->num_planes);
/* Copy relevant information provided by the userspace */
-   if (pb) {
-   ret = call_bufop(vb->vb2_queue, fill_vb2_buffer,
-vb, pb, planes);
-   if (ret)
-   return ret;
-   }
+   ret = call_bufop(vb->vb2_queue, fill_vb2_buffer,
+vb, planes);
+   if (ret)
+   return ret;
 
for (plane = 0; plane < vb->num_planes; ++plane) {
struct dma_buf *dbuf = dma_buf_get(planes[plane].m.fd);
diff --git a/drivers/media/common/videobuf2/videobuf2-v4l2.c 
b/drivers/media/common/videobuf2/videobuf2-v4l2.c
index 4e9c77f21858..bf7a3ba9fed0 100644
--- a/drivers/media/common/videobuf2/videobuf2-v4l2.c
+++ b/drivers/media/common/videobuf2/videobuf2-v4l2.c
@@ -154,9 +154,177 @@ static void vb2_warn_zero_bytesused(struct vb2_buffer *vb)
pr_warn("use the actual size instead.\n");
 }
 
+static int vb2_fill_vb2_v4l2_buffer(struct vb2_buffer *vb, struct v4l2_buffer 
*b)
+{
+   struct vb2_queue *q = vb->vb2_queue;
+   struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+   struct vb2_plane *planes = vbuf->planes;
+   unsigned int plane;
+   int ret;
+
+   ret = __verify_length(vb, b);
+   if (ret < 0) {
+   dprintk(1, "plane parameters verification failed: %d\n", ret);
+   return ret;
+   }
+   if (b->field == V4L2_FIELD_ALTERNATE && q->is_output) {
+   /*
+* If the format's field is ALTERNATE, then the buffer's field
+* should be either TOP or BOTTOM, not ALTERNATE since that
+* makes no sense. The driver has to know whether the
+* buffer represents a top or a bottom field in order to
+* program any DMA correctly. Using ALTERNATE is wrong, since
+* that just says that it is either a top or a bottom field,
+* but not which of the two it is.
+*/
+   dprintk(1, "the field is incorrectly set to ALTERNATE for an 
output buffer\n");
+   return -EINVAL;
+   }
+   vbuf->sequence = 0;
+
+   if (V4L2_TYPE_IS_MULTIPLANAR(b->type)) {
+   switch (b->memory) {
+   case VB2_MEMORY_USERPTR:
+   for (plane = 0; plane < vb->num_planes; ++plane) {
+   planes[plane].m.userptr =
+  

[PATCH 19/29] videobuf2-core: embed media_request_object

2018-03-28 Thread Hans Verkuil
From: Hans Verkuil 

Make vb2_buffer a request object.

Signed-off-by: Hans Verkuil 
---
 include/media/videobuf2-core.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h
index 224c4820a044..3d54654c3cd4 100644
--- a/include/media/videobuf2-core.h
+++ b/include/media/videobuf2-core.h
@@ -17,6 +17,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #define VB2_MAX_FRAME  (32)
 #define VB2_MAX_PLANES (8)
@@ -238,6 +239,7 @@ struct vb2_queue;
  * @num_planes:number of planes in the buffer
  * on an internal driver queue.
  * @timestamp: frame timestamp in ns.
+ * @req_obj:   used to bind this buffer to a request
  */
 struct vb2_buffer {
struct vb2_queue*vb2_queue;
@@ -246,6 +248,7 @@ struct vb2_buffer {
unsigned intmemory;
unsigned intnum_planes;
u64 timestamp;
+   struct media_request_object req_obj;
 
/* private: internal use only
 *
-- 
2.15.1



Re: [RFCv9 PATCH 00/29] Request API

2018-03-28 Thread Hans Verkuil
On 03/28/2018 03:50 PM, Hans Verkuil wrote:
> From: Hans Verkuil 
> 
> Hi all,
> 
> This patch series is an attempt to pick the best parts of
> Alexandre's RFCv4:

"sending too many recipients in a short time. Please try again later."

So patches 17 and up will appear a bit later. I'll drop the CC list to
avoid hitting this issue again. My ISP is not friendly for kernel
developers who need to post large series to many people :-(

Regards,

Hans


[RFCv9 PATCH 11/29] v4l2-ctrls: use ref in helper instead of ctrl

2018-03-28 Thread Hans Verkuil
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 e8d6dee375ef..fc13f328c6fc 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;
@@ -2887,6 +2887,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;
@@ -2909,7 +2910,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 */
@@ -2994,7 +2994,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++) {
@@ -3029,7 +3029,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);
}
@@ -3168,7 +3168,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;
@@ -3280,7 +3280,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);
@@ -3293,7 +3293,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)
@@ -3309,7 +3309,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



[RFCv9 PATCH 04/29] media-request: core request support

2018-03-28 Thread Hans Verkuil
From: Hans Verkuil 

Implement the core of the media request processing.

Drivers can bind request objects to a request. These objects
can then be marked completed if the driver finished using them,
or just be unbound if the results do not need to be kept (e.g.
in the case of buffers).

Once all objects that were added are either unbound or completed,
the request is marked 'complete' and a POLLPRI signal is sent
via poll.

Both requests and request objects are refcounted.

While a request is queued its refcount is incremented (since it
is in use by a driver). Once it is completed the refcount is
decremented. When the user closes the request file descriptor
the refcount is also decremented. Once it reaches 0 all request
objects in the request are unbound and put() and the request
itself is freed.

Signed-off-by: Hans Verkuil 
---
 drivers/media/media-request.c | 269 +-
 include/media/media-request.h | 148 +++
 2 files changed, 416 insertions(+), 1 deletion(-)

diff --git a/drivers/media/media-request.c b/drivers/media/media-request.c
index ead78613fdbe..8135d9d32af9 100644
--- a/drivers/media/media-request.c
+++ b/drivers/media/media-request.c
@@ -16,8 +16,275 @@
 #include 
 #include 
 
+static const char * const request_state[] = {
+   "idle",
+   "queueing",
+   "queued",
+   "complete",
+   "cleaning",
+};
+
+static const char *
+media_request_state_str(enum media_request_state state)
+{
+   if (WARN_ON(state >= ARRAY_SIZE(request_state)))
+   return "unknown";
+   return request_state[state];
+}
+
+static void media_request_clean(struct media_request *req)
+{
+   struct media_request_object *obj, *obj_safe;
+
+   WARN_ON(req->state != MEDIA_REQUEST_STATE_CLEANING);
+
+   list_for_each_entry_safe(obj, obj_safe, >objects, list) {
+   media_request_object_unbind(obj);
+   media_request_object_put(obj);
+   }
+
+   req->num_incomplete_objects = 0;
+   wake_up_interruptible(>poll_wait);
+}
+
+static void media_request_release(struct kref *kref)
+{
+   struct media_request *req =
+   container_of(kref, struct media_request, kref);
+   struct media_device *mdev = req->mdev;
+   unsigned long flags;
+
+   dev_dbg(mdev->dev, "request: release %s\n", req->debug_str);
+
+   spin_lock_irqsave(>lock, flags);
+   req->state = MEDIA_REQUEST_STATE_CLEANING;
+   spin_unlock_irqrestore(>lock, flags);
+
+   media_request_clean(req);
+
+   if (mdev->ops->req_free)
+   mdev->ops->req_free(req);
+   else
+   kfree(req);
+}
+
+void media_request_put(struct media_request *req)
+{
+   kref_put(>kref, media_request_release);
+}
+EXPORT_SYMBOL_GPL(media_request_put);
+
+static int media_request_close(struct inode *inode, struct file *filp)
+{
+   struct media_request *req = filp->private_data;
+
+   media_request_put(req);
+   return 0;
+}
+
+static unsigned int media_request_poll(struct file *filp,
+  struct poll_table_struct *wait)
+{
+   struct media_request *req = filp->private_data;
+   unsigned long flags;
+   enum media_request_state state;
+
+   if (!(poll_requested_events(wait) & POLLPRI))
+   return 0;
+
+   spin_lock_irqsave(>lock, flags);
+   state = req->state;
+   spin_unlock_irqrestore(>lock, flags);
+
+   if (state == MEDIA_REQUEST_STATE_COMPLETE)
+   return POLLPRI;
+   if (state == MEDIA_REQUEST_STATE_IDLE)
+   return POLLERR;
+
+   poll_wait(filp, >poll_wait, wait);
+   return 0;
+}
+
+static long media_request_ioctl(struct file *filp, unsigned int cmd,
+   unsigned long __arg)
+{
+   return -ENOIOCTLCMD;
+}
+
+static const struct file_operations request_fops = {
+   .owner = THIS_MODULE,
+   .poll = media_request_poll,
+   .unlocked_ioctl = media_request_ioctl,
+   .release = media_request_close,
+};
+
 int media_request_alloc(struct media_device *mdev,
struct media_request_alloc *alloc)
 {
-   return -ENOMEM;
+   struct media_request *req;
+   struct file *filp;
+   char comm[TASK_COMM_LEN];
+   int fd;
+   int ret;
+
+   fd = get_unused_fd_flags(O_CLOEXEC);
+   if (fd < 0)
+   return fd;
+
+   filp = anon_inode_getfile("request", _fops, NULL, O_CLOEXEC);
+   if (IS_ERR(filp)) {
+   ret = PTR_ERR(filp);
+   goto err_put_fd;
+   }
+
+   if (mdev->ops->req_alloc)
+   req = mdev->ops->req_alloc(mdev);
+   else
+   req = kzalloc(sizeof(*req), GFP_KERNEL);
+   if (!req) {
+   ret = -ENOMEM;
+   goto err_fput;
+   }
+
+   filp->private_data = req;
+   req->mdev = mdev;
+   req->state = 

[RFCv9 PATCH 08/29] v4l2-ctrls: v4l2_ctrl_add_handler: add from_other_dev

2018-03-28 Thread Hans Verkuil
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 +-
 drivers/media/platform/exynos4-is/fimc-capture.c |  2 +-
 drivers/media/platform/rcar-vin/rcar-v4l2.c  |  3 +-
 drivers/media/platform/rcar_drif.c   |  2 +-
 drivers/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   |  8 -
 21 files changed, 62 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);
 
/* 

[RFCv9 PATCH 03/29] media-request: allocate media requests

2018-03-28 Thread Hans Verkuil
From: Hans Verkuil 

Add support for allocating a new request. This is only supported
if mdev->ops->req_queue is set, i.e. the driver indicates that it
supports queueing requests.

Signed-off-by: Hans Verkuil 
---
 drivers/media/Makefile|  3 ++-
 drivers/media/media-device.c  | 14 ++
 drivers/media/media-request.c | 23 +++
 include/media/media-device.h  | 13 +
 include/media/media-request.h | 22 ++
 5 files changed, 74 insertions(+), 1 deletion(-)
 create mode 100644 drivers/media/media-request.c
 create mode 100644 include/media/media-request.h

diff --git a/drivers/media/Makefile b/drivers/media/Makefile
index 594b462ddf0e..985d35ec6b29 100644
--- a/drivers/media/Makefile
+++ b/drivers/media/Makefile
@@ -3,7 +3,8 @@
 # Makefile for the kernel multimedia device drivers.
 #
 
-media-objs := media-device.o media-devnode.o media-entity.o
+media-objs := media-device.o media-devnode.o media-entity.o \
+  media-request.o
 
 #
 # I2C drivers should come before other drivers, otherwise they'll fail
diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c
index 35e81f7c0d2f..acb583c0eacd 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
 
@@ -366,6 +367,15 @@ static long media_device_get_topology(struct media_device 
*mdev,
return ret;
 }
 
+static long media_device_request_alloc(struct media_device *mdev,
+  struct media_request_alloc *alloc)
+{
+   if (!mdev->ops || !mdev->ops->req_queue)
+   return -ENOTTY;
+
+   return media_request_alloc(mdev, alloc);
+}
+
 static long copy_arg_from_user(void *karg, void __user *uarg, unsigned int cmd)
 {
/* All media IOCTLs are _IOWR() */
@@ -414,6 +424,7 @@ static const struct media_ioctl_info ioctl_info[] = {
MEDIA_IOC(ENUM_LINKS, media_device_enum_links, 
MEDIA_IOC_FL_GRAPH_MUTEX),
MEDIA_IOC(SETUP_LINK, media_device_setup_link, 
MEDIA_IOC_FL_GRAPH_MUTEX),
MEDIA_IOC(G_TOPOLOGY, media_device_get_topology, 
MEDIA_IOC_FL_GRAPH_MUTEX),
+   MEDIA_IOC(REQUEST_ALLOC, media_device_request_alloc, 0),
 };
 
 static long media_device_ioctl(struct file *filp, unsigned int cmd,
@@ -686,6 +697,9 @@ void media_device_init(struct media_device *mdev)
INIT_LIST_HEAD(>pads);
INIT_LIST_HEAD(>links);
INIT_LIST_HEAD(>entity_notify);
+
+   spin_lock_init(>req_lock);
+   mutex_init(>req_queue_mutex);
mutex_init(>graph_mutex);
ida_init(>entity_internal_idx);
 
diff --git a/drivers/media/media-request.c b/drivers/media/media-request.c
new file mode 100644
index ..ead78613fdbe
--- /dev/null
+++ b/drivers/media/media-request.c
@@ -0,0 +1,23 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Media device request objects
+ *
+ * Copyright (C) 2018 Intel Corporation
+ * Copyright (C) 2018, The Chromium OS Authors.  All rights reserved.
+ *
+ * Author: Sakari Ailus 
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+
+int media_request_alloc(struct media_device *mdev,
+   struct media_request_alloc *alloc)
+{
+   return -ENOMEM;
+}
diff --git a/include/media/media-device.h b/include/media/media-device.h
index bcc6ec434f1f..07e323c57202 100644
--- a/include/media/media-device.h
+++ b/include/media/media-device.h
@@ -19,6 +19,7 @@
 #ifndef _MEDIA_DEVICE_H
 #define _MEDIA_DEVICE_H
 
+#include 
 #include 
 #include 
 
@@ -27,6 +28,7 @@
 
 struct ida;
 struct device;
+struct media_device;
 
 /**
  * struct media_entity_notify - Media Entity Notify
@@ -50,10 +52,16 @@ struct media_entity_notify {
  * struct media_device_ops - Media device operations
  * @link_notify: Link state change notification callback. This callback is
  *  called with the graph_mutex held.
+ * @req_alloc: Allocate a request
+ * @req_free: Free a request
+ * @req_queue: Queue a request
  */
 struct media_device_ops {
int (*link_notify)(struct media_link *link, u32 flags,
   unsigned int notification);
+   struct media_request *(*req_alloc)(struct media_device *mdev);
+   void (*req_free)(struct media_request *req);
+   int (*req_queue)(struct media_request *req);
 };
 
 /**
@@ -88,6 +96,8 @@ struct media_device_ops {
  * @disable_source: Disable Source Handler function pointer
  *
  * @ops:   Operation handler callbacks
+ * @req_lock:  Serialise access to requests
+ * @req_queue_mutex: Serialise validating and queueing requests
  *
  * This structure represents an abstract high-level media device. It allows 
easy
  * access to entities and provides basic media device-level support. The
@@ -158,6 +168,9 @@ struct media_device {
void (*disable_source)(struct 

[RFCv9 PATCH 02/29] uapi/linux/media.h: add request API

2018-03-28 Thread Hans Verkuil
From: Hans Verkuil 

Define the public request API.

This adds the new MEDIA_IOC_REQUEST_ALLOC ioctl to allocate a request
and two ioctls that operate on a request in order to queue the
contents of the request to the driver and to re-initialize the
request.

Signed-off-by: Hans Verkuil 
---
 include/uapi/linux/media.h | 8 
 1 file changed, 8 insertions(+)

diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h
index c7e9a5cba24e..f8769e74f847 100644
--- a/include/uapi/linux/media.h
+++ b/include/uapi/linux/media.h
@@ -342,11 +342,19 @@ struct media_v2_topology {
 
 /* ioctls */
 
+struct __attribute__ ((packed)) media_request_alloc {
+   __s32 fd;
+};
+
 #define MEDIA_IOC_DEVICE_INFO  _IOWR('|', 0x00, struct media_device_info)
 #define MEDIA_IOC_ENUM_ENTITIES_IOWR('|', 0x01, struct 
media_entity_desc)
 #define MEDIA_IOC_ENUM_LINKS   _IOWR('|', 0x02, struct media_links_enum)
 #define MEDIA_IOC_SETUP_LINK   _IOWR('|', 0x03, struct media_link_desc)
 #define MEDIA_IOC_G_TOPOLOGY   _IOWR('|', 0x04, struct media_v2_topology)
+#define MEDIA_IOC_REQUEST_ALLOC_IOWR('|', 0x05, struct 
media_request_alloc)
+
+#define MEDIA_REQUEST_IOC_QUEUE_IO('|',  0x80)
+#define MEDIA_REQUEST_IOC_REINIT   _IO('|',  0x81)
 
 #if !defined(__KERNEL__) || defined(__NEED_MEDIA_LEGACY_API)
 
-- 
2.16.1



[RFCv9 PATCH 05/29] media-request: add request ioctls

2018-03-28 Thread Hans Verkuil
From: Hans Verkuil 

Implement the MEDIA_REQUEST_IOC_QUEUE and MEDIA_REQUEST_IOC_REINIT
ioctls.

Signed-off-by: Hans Verkuil 
---
 drivers/media/media-request.c | 80 +--
 1 file changed, 78 insertions(+), 2 deletions(-)

diff --git a/drivers/media/media-request.c b/drivers/media/media-request.c
index 8135d9d32af9..3ee3b27fd644 100644
--- a/drivers/media/media-request.c
+++ b/drivers/media/media-request.c
@@ -105,10 +105,86 @@ static unsigned int media_request_poll(struct file *filp,
return 0;
 }
 
+static long media_request_ioctl_queue(struct media_request *req)
+{
+   struct media_device *mdev = req->mdev;
+   unsigned long flags;
+   int ret = 0;
+
+   dev_dbg(mdev->dev, "request: queue %s\n", req->debug_str);
+
+   spin_lock_irqsave(>lock, flags);
+   if (req->state != MEDIA_REQUEST_STATE_IDLE) {
+   dev_dbg(mdev->dev,
+   "request: unable to queue %s, request in state %s\n",
+   req->debug_str, media_request_state_str(req->state));
+   spin_unlock_irqrestore(>lock, flags);
+   return -EINVAL;
+   }
+   req->state = MEDIA_REQUEST_STATE_QUEUEING;
+
+   spin_unlock_irqrestore(>lock, flags);
+
+   /*
+* Ensure the request that is validated will be the one that gets queued
+* next by serialising the queueing process.
+*/
+   mutex_lock(>req_queue_mutex);
+
+   ret = mdev->ops->req_queue(req);
+   spin_lock_irqsave(>lock, flags);
+   req->state = ret ? MEDIA_REQUEST_STATE_IDLE : 
MEDIA_REQUEST_STATE_QUEUED;
+   spin_unlock_irqrestore(>lock, flags);
+   mutex_unlock(>req_queue_mutex);
+
+   if (ret) {
+   dev_dbg(mdev->dev, "request: can't queue %s (%d)\n",
+   req->debug_str, ret);
+   } else {
+   media_request_get(req);
+   }
+
+   return ret;
+}
+
+static long media_request_ioctl_reinit(struct media_request *req)
+{
+   struct media_device *mdev = req->mdev;
+   unsigned long flags;
+
+   spin_lock_irqsave(>lock, flags);
+   if (req->state != MEDIA_REQUEST_STATE_IDLE &&
+   req->state != MEDIA_REQUEST_STATE_COMPLETE) {
+   dev_dbg(mdev->dev,
+   "request: %s not in idle or complete state, cannot 
reinit\n",
+   req->debug_str);
+   spin_unlock_irqrestore(>lock, flags);
+   return -EINVAL;
+   }
+   req->state = MEDIA_REQUEST_STATE_CLEANING;
+   spin_unlock_irqrestore(>lock, flags);
+
+   media_request_clean(req);
+
+   spin_lock_irqsave(>lock, flags);
+   req->state = MEDIA_REQUEST_STATE_IDLE;
+   spin_unlock_irqrestore(>lock, flags);
+   return 0;
+}
+
 static long media_request_ioctl(struct file *filp, unsigned int cmd,
-   unsigned long __arg)
+   unsigned long arg)
 {
-   return -ENOIOCTLCMD;
+   struct media_request *req = filp->private_data;
+
+   switch (cmd) {
+   case MEDIA_REQUEST_IOC_QUEUE:
+   return media_request_ioctl_queue(req);
+   case MEDIA_REQUEST_IOC_REINIT:
+   return media_request_ioctl_reinit(req);
+   default:
+   return -ENOIOCTLCMD;
+   }
 }
 
 static const struct file_operations request_fops = {
-- 
2.16.1



[RFCv9 PATCH 06/29] media-request: add media_request_find

2018-03-28 Thread Hans Verkuil
From: Hans Verkuil 

Add media_request_find() to find a request based on the file
descriptor.

The caller has to call media_request_put() for the returned
request since this function increments the refcount.

Signed-off-by: Hans Verkuil 
---
 drivers/media/media-request.c | 47 +++
 include/media/media-request.h |  9 +
 2 files changed, 56 insertions(+)

diff --git a/drivers/media/media-request.c b/drivers/media/media-request.c
index 3ee3b27fd644..d54fd353d8a6 100644
--- a/drivers/media/media-request.c
+++ b/drivers/media/media-request.c
@@ -194,6 +194,53 @@ static const struct file_operations request_fops = {
.release = media_request_close,
 };
 
+/**
+ * media_request_find - Find a request based on the file descriptor
+ * @mdev: The media device
+ * @request: The request file handle
+ *
+ * Find and return the request associated with the given file descriptor, or
+ * an error if no such request exists.
+ *
+ * When the function returns a request it increases its reference count. The
+ * caller is responsible for releasing the reference by calling
+ * media_request_put() on the request.
+ */
+struct media_request *
+media_request_find(struct media_device *mdev, int request_fd)
+{
+   struct file *filp;
+   struct media_request *req;
+
+   if (!mdev || !mdev->ops || !mdev->ops->req_queue)
+   return ERR_PTR(-ENOENT);
+
+   filp = fget(request_fd);
+   if (!filp)
+   return ERR_PTR(-ENOENT);
+
+   if (filp->f_op != _fops)
+   goto err_fput;
+   req = filp->private_data;
+   media_request_get(req);
+
+   if (req->mdev != mdev)
+   goto err_kref_put;
+
+   fput(filp);
+
+   return req;
+
+err_kref_put:
+   media_request_put(req);
+
+err_fput:
+   fput(filp);
+
+   return ERR_PTR(-EBADF);
+}
+EXPORT_SYMBOL_GPL(media_request_find);
+
 int media_request_alloc(struct media_device *mdev,
struct media_request_alloc *alloc)
 {
diff --git a/include/media/media-request.h b/include/media/media-request.h
index baed99eb1279..c01b05570a31 100644
--- a/include/media/media-request.h
+++ b/include/media/media-request.h
@@ -57,6 +57,9 @@ static inline void media_request_get(struct media_request 
*req)
 
 void media_request_put(struct media_request *req);
 
+struct media_request *
+media_request_find(struct media_device *mdev, int request_fd);
+
 int media_request_alloc(struct media_device *mdev,
struct media_request_alloc *alloc);
 #else
@@ -67,6 +70,12 @@ static inline void media_request_get(struct media_request 
*req)
 static inline void media_request_put(struct media_request *req)
 {
 }
+
+static inline struct media_request *
+media_request_find(struct media_device *mdev, int request_fd)
+{
+   return ERR_PTR(-ENOENT);
+}
 #endif
 
 struct media_request_object_ops {
-- 
2.16.1



[RFCv9 PATCH 07/29] media-request: add media_request_object_find

2018-03-28 Thread Hans Verkuil
From: Hans Verkuil 

Add media_request_object_find to find a request object inside a
request based on ops and/or priv values.

Objects of the same type (vb2 buffer, control handler) will have
the same ops value. And objects that refer to the same 'parent'
object (e.g. the v4l2_ctrl_handler that has the current driver
state) will have the same priv value.

The caller has to call media_request_object_put() for the returned
object since this function increments the refcount.

Signed-off-by: Hans Verkuil 
---
 drivers/media/media-request.c | 26 ++
 include/media/media-request.h | 25 +
 2 files changed, 51 insertions(+)

diff --git a/drivers/media/media-request.c b/drivers/media/media-request.c
index d54fd353d8a6..10a05dd7b571 100644
--- a/drivers/media/media-request.c
+++ b/drivers/media/media-request.c
@@ -309,6 +309,32 @@ static void media_request_object_release(struct kref *kref)
obj->ops->release(obj);
 }
 
+struct media_request_object *
+media_request_object_find(struct media_request *req,
+ const struct media_request_object_ops *ops,
+ void *priv)
+{
+   struct media_request_object *obj;
+   struct media_request_object *found = NULL;
+   unsigned long flags;
+
+   if (!ops && !priv)
+   return NULL;
+
+   spin_lock_irqsave(>lock, flags);
+   list_for_each_entry(obj, >objects, list) {
+   if ((!ops || obj->ops == ops) &&
+   (!priv || obj->priv == priv)) {
+   media_request_object_get(obj);
+   found = obj;
+   break;
+   }
+   }
+   spin_unlock_irqrestore(>lock, flags);
+   return found;
+}
+EXPORT_SYMBOL_GPL(media_request_object_find);
+
 void media_request_object_put(struct media_request_object *obj)
 {
kref_put(>kref, media_request_object_release);
diff --git a/include/media/media-request.h b/include/media/media-request.h
index c01b05570a31..570f3a205776 100644
--- a/include/media/media-request.h
+++ b/include/media/media-request.h
@@ -122,6 +122,23 @@ static inline void media_request_object_get(struct 
media_request_object *obj)
  */
 void media_request_object_put(struct media_request_object *obj);
 
+/**
+ * media_request_object_find - Find an object in a request
+ *
+ * @ops: Find an object with this ops value, may be NULL.
+ * @priv: Find an object with this priv value, may be NULL.
+ *
+ * At least one of @ops and @priv must be non-NULL. If one of
+ * these is NULL, then skip checking for that field.
+ *
+ * Returns NULL if not found or the object (the refcount is increased
+ * in that case).
+ */
+struct media_request_object *
+media_request_object_find(struct media_request *req,
+ const struct media_request_object_ops *ops,
+ void *priv);
+
 /**
  * media_request_object_init - Initialise a media request object
  *
@@ -154,6 +171,14 @@ static inline void media_request_object_put(struct 
media_request_object *obj)
 {
 }
 
+static inline struct media_request_object *
+media_request_object_find(struct media_request *req,
+ const struct media_request_object_ops *ops,
+ void *priv)
+{
+   return NULL;
+}
+
 static inline void media_request_object_init(struct media_request_object *obj)
 {
obj->ops = NULL;
-- 
2.16.1



[RFCv9 PATCH 16/29] v4l2-ctrls: integrate with requests

2018-03-28 Thread Hans Verkuil
From: Hans Verkuil 

Add the media_device pointer to the v4l2_g/s/try_ext_ctrls
functions and pass that in from the v4l2 core. The control
framework will look up the request from the request_fd file
descriptor and bind/unbind the request objects.

Signed-off-by: Hans Verkuil 
---
 drivers/media/platform/omap3isp/ispvideo.c |   2 +-
 drivers/media/v4l2-core/v4l2-ctrls.c   | 136 ++---
 drivers/media/v4l2-core/v4l2-ioctl.c   |  12 +--
 drivers/media/v4l2-core/v4l2-subdev.c  |   9 +-
 include/media/v4l2-ctrls.h |  13 ++-
 5 files changed, 148 insertions(+), 24 deletions(-)

diff --git a/drivers/media/platform/omap3isp/ispvideo.c 
b/drivers/media/platform/omap3isp/ispvideo.c
index a751c89a3ea8..bd564c2e767f 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(pipe->external->ctrl_handler, NULL, );
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 6cf6b2154462..e31bce0207b4 100644
--- a/drivers/media/v4l2-core/v4l2-ctrls.c
+++ b/drivers/media/v4l2-core/v4l2-ctrls.c
@@ -1898,6 +1898,7 @@ int v4l2_ctrl_handler_init_class(struct v4l2_ctrl_handler 
*hdl,
lockdep_set_class_and_name(hdl->lock, key, name);
INIT_LIST_HEAD(>ctrls);
INIT_LIST_HEAD(>ctrl_refs);
+   INIT_LIST_HEAD(>requests);
hdl->nr_of_buckets = 1 + nr_of_controls_hint / 8;
hdl->buckets = kvmalloc_array(hdl->nr_of_buckets,
  sizeof(hdl->buckets[0]),
@@ -1918,6 +1919,14 @@ void v4l2_ctrl_handler_free(struct v4l2_ctrl_handler 
*hdl)
if (hdl == NULL || hdl->buckets == NULL)
return;
 
+   if (!hdl->req_obj.req && !list_empty(>requests)) {
+   struct v4l2_ctrl_handler *req, *next_req;
+
+   list_for_each_entry_safe(req, next_req, >requests, 
requests) {
+   media_request_object_unbind(>req_obj);
+   media_request_object_put(>req_obj);
+   }
+   }
mutex_lock(hdl->lock);
/* Free all nodes */
list_for_each_entry_safe(ref, next_ref, >ctrl_refs, node) {
@@ -2844,6 +2853,7 @@ static int v4l2_ctrl_request_clone(struct 
v4l2_ctrl_handler *hdl,
bool (*filter)(const struct v4l2_ctrl *ctrl))
 {
struct v4l2_ctrl_ref *ref;
+   struct media_request *req = hdl->req_obj.req;
int err;
 
if (WARN_ON(!hdl || hdl == from))
@@ -2857,6 +2867,7 @@ static int v4l2_ctrl_request_clone(struct 
v4l2_ctrl_handler *hdl,
err = v4l2_ctrl_handler_init(hdl, (from->nr_of_buckets - 1) * 8);
if (err)
return err;
+   hdl->req_obj.req = req;
if (!from)
return 0;
 
@@ -2892,6 +2903,14 @@ static int v4l2_ctrl_request_clone(struct 
v4l2_ctrl_handler *hdl,
return err;
 }
 
+static void v4l2_ctrl_request_unbind(struct media_request_object *obj)
+{
+   struct v4l2_ctrl_handler *hdl =
+   container_of(obj, struct v4l2_ctrl_handler, req_obj);
+
+   list_del_init(>requests);
+}
+
 static void v4l2_ctrl_request_release(struct media_request_object *obj)
 {
struct v4l2_ctrl_handler *hdl =
@@ -2902,6 +2921,7 @@ static void v4l2_ctrl_request_release(struct 
media_request_object *obj)
 }
 
 static const struct media_request_object_ops req_ops = {
+   .unbind = v4l2_ctrl_request_unbind,
.release = v4l2_ctrl_request_release,
 };
 
@@ -2910,10 +2930,16 @@ static int v4l2_ctrl_request_bind(struct media_request 
*req,
   struct v4l2_ctrl_handler *from,
   bool (*filter)(const struct v4l2_ctrl *ctrl))
 {
-   int ret = v4l2_ctrl_request_clone(hdl, from, filter);
+   int ret;
 
-   if (!ret)
+   hdl->req_obj.req = req;
+   ret = v4l2_ctrl_request_clone(hdl, from, filter);
+   hdl->req_obj.req = NULL;
+
+   if (!ret) {
+   list_add_tail(>requests, >requests);
media_request_object_bind(req, _ops, from, >req_obj);
+   }
return ret;
 }
 
@@ -2977,6 +3003,7 @@ static int prepare_ext_ctrls(struct v4l2_ctrl_handler 
*hdl,
 
if (cs->which &&
cs->which != V4L2_CTRL_WHICH_DEF_VAL &&
+   cs->which != V4L2_CTRL_WHICH_REQUEST &&
V4L2_CTRL_ID2WHICH(id) != cs->which)
return -EINVAL;
 
@@ -3056,15 +3083,15 @@ static int prepare_ext_ctrls(struct v4l2_ctrl_handler 
*hdl,
whether there 

[RFCv9 PATCH 13/29] v4l2-ctrls: add core request API

2018-03-28 Thread Hans Verkuil
From: Hans Verkuil 

Add the two core request functions:

v4l2_ctrl_request_setup() applies the contents of the request
to the current driver state.

v4l2_ctrl_request_complete() marks the request complete. After
this the contents is fixed.

Signed-off-by: Hans Verkuil 
---
 drivers/media/v4l2-core/v4l2-ctrls.c | 172 +++
 include/media/v4l2-ctrls.h   |   9 ++
 2 files changed, 181 insertions(+)

diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c 
b/drivers/media/v4l2-core/v4l2-ctrls.c
index 80714c5bad8b..62f91c0f1e5f 100644
--- a/drivers/media/v4l2-core/v4l2-ctrls.c
+++ b/drivers/media/v4l2-core/v4l2-ctrls.c
@@ -1781,6 +1781,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)
@@ -2831,6 +2839,78 @@ int v4l2_querymenu(struct v4l2_ctrl_handler *hdl, struct 
v4l2_querymenu *qm)
 }
 EXPORT_SYMBOL(v4l2_querymenu);
 
+static 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);
+   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;
+   /* And buttons and control classes */
+   if (ctrl->type == V4L2_CTRL_TYPE_BUTTON ||
+   ctrl->type == V4L2_CTRL_TYPE_CTRL_CLASS)
+   continue;
+   /* Filter any unwanted controls */
+   if (filter && !filter(ctrl))
+   continue;
+   err = handler_new_ref(hdl, ctrl, _ref, false);
+   if (err)
+   break;
+   if (from->req_obj.req)
+   ptr_to_ptr(ctrl, ref->p_req, new_ref->p_req);
+   else
+   ptr_to_ptr(ctrl, ctrl->p_cur, new_ref->p_req);
+   }
+   mutex_unlock(from->lock);
+   return err;
+}
+
+static void v4l2_ctrl_request_release(struct media_request_object *obj)
+{
+   struct v4l2_ctrl_handler *hdl =
+   container_of(obj, struct v4l2_ctrl_handler, req_obj);
+
+   v4l2_ctrl_handler_free(hdl);
+   kfree(hdl);
+}
+
+static const struct media_request_object_ops req_ops = {
+   .release = v4l2_ctrl_request_release,
+};
+
+static int v4l2_ctrl_request_bind(struct media_request *req,
+  struct v4l2_ctrl_handler *hdl,
+  struct v4l2_ctrl_handler *from,
+  bool (*filter)(const struct v4l2_ctrl *ctrl))
+{
+   int ret = v4l2_ctrl_request_clone(hdl, from, filter);
+
+   if (!ret)
+   media_request_object_bind(req, _ops, from, >req_obj);
+   return ret;
+}
 
 /* Some general notes on the atomic requirements of VIDIOC_G/TRY/S_EXT_CTRLS:
 
@@ -3458,6 +3538,98 @@ int __v4l2_ctrl_s_ctrl_string(struct v4l2_ctrl *ctrl, 
const char *s)
 }
 EXPORT_SYMBOL(__v4l2_ctrl_s_ctrl_string);
 
+void v4l2_ctrl_request_complete(struct media_request *req,
+   struct v4l2_ctrl_handler *hdl)
+{
+   struct media_request_object *obj;
+
+   if (!req || !hdl)
+   return;
+
+   obj = media_request_object_find(req, _ops, hdl);
+   if (!obj)
+   return;
+
+   media_request_object_complete(obj);
+   media_request_object_put(obj);
+}
+EXPORT_SYMBOL(v4l2_ctrl_request_complete);
+
+void v4l2_ctrl_request_setup(struct media_request *req,
+struct v4l2_ctrl_handler *hdl)
+{
+   struct media_request_object *obj;
+   struct v4l2_ctrl_ref *ref;
+
+   if (!req || !hdl)
+   return;
+
+   obj = media_request_object_find(req, _ops, hdl);
+   if (!obj)
+   return;
+   if (obj->completed) {
+   media_request_object_put(obj);
+   return;
+   }
+   

[RFCv9 PATCH 14/29] v4l2-ctrls: do not clone non-standard controls

2018-03-28 Thread Hans Verkuil
From: 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 62f91c0f1e5f..6cf6b2154462 100644
--- a/drivers/media/v4l2-core/v4l2-ctrls.c
+++ b/drivers/media/v4l2-core/v4l2-ctrls.c
@@ -2876,6 +2876,11 @@ static 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->req_obj.req)
-- 
2.16.1



[RFCv9 PATCH 15/29] videodev2.h: add request_fd field to v4l2_ext_controls

2018-03-28 Thread Hans Verkuil
From: Alexandre Courbot 

If which is V4L2_CTRL_WHICH_REQUEST, then the request_fd field can be
used to specify a request for the G/S/TRY_EXT_CTRLS ioctls.

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

diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c 
b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
index 5198c9eeb348..0782b3666deb 100644
--- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
+++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
@@ -732,7 +732,8 @@ struct v4l2_ext_controls32 {
__u32 which;
__u32 count;
__u32 error_idx;
-   __u32 reserved[2];
+   __s32 request_fd;
+   __u32 reserved[1];
compat_caddr_t controls; /* actually struct v4l2_ext_control32 * */
 };
 
@@ -807,6 +808,7 @@ static int get_v4l2_ext_controls32(struct file *file,
get_user(count, >count) ||
put_user(count, >count) ||
assign_in_user(>error_idx, >error_idx) ||
+   assign_in_user(>request_fd, >request_fd) ||
copy_in_user(kp->reserved, up->reserved, sizeof(kp->reserved)))
return -EFAULT;
 
@@ -865,6 +867,7 @@ static int put_v4l2_ext_controls32(struct file *file,
get_user(count, >count) ||
put_user(count, >count) ||
assign_in_user(>error_idx, >error_idx) ||
+   assign_in_user(>request_fd, >request_fd) ||
copy_in_user(up->reserved, kp->reserved, sizeof(up->reserved)) ||
get_user(kcontrols, >controls))
return -EFAULT;
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c 
b/drivers/media/v4l2-core/v4l2-ioctl.c
index a5dab16ff2d2..2c623da33155 100644
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
@@ -553,8 +553,8 @@ static void v4l_print_ext_controls(const void *arg, bool 
write_only)
const struct v4l2_ext_controls *p = arg;
int i;
 
-   pr_cont("which=0x%x, count=%d, error_idx=%d",
-   p->which, p->count, p->error_idx);
+   pr_cont("which=0x%x, count=%d, error_idx=%d, request_fd=%d",
+   p->which, p->count, p->error_idx, p->request_fd);
for (i = 0; i < p->count; i++) {
if (!p->controls[i].size)
pr_cont(", id/val=0x%x/0x%x",
@@ -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 600877be5c22..6f41baa53787 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;
 };
 
@@ -1605,6 +1606,7 @@ struct v4l2_ext_controls {
 #define V4L2_CTRL_MAX_DIMS   (4)
 #define V4L2_CTRL_WHICH_CUR_VAL   0
 #define V4L2_CTRL_WHICH_DEF_VAL   0x0f00
+#define V4L2_CTRL_WHICH_REQUEST   0x0f01
 
 enum v4l2_ctrl_type {
V4L2_CTRL_TYPE_INTEGER   = 1,
-- 
2.16.1



[RFCv9 PATCH 12/29] v4l2-ctrls: support g/s_ext_ctrls for requests

2018-03-28 Thread Hans Verkuil
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 fc13f328c6fc..80714c5bad8b 100644
--- a/drivers/media/v4l2-core/v4l2-ctrls.c
+++ b/drivers/media/v4l2-core/v4l2-ctrls.c
@@ -1647,6 +1647,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)
 {
@@ -1766,6 +1773,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)
@@ -3002,7 +3017,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->req_obj.req ? NULL : cur_to_user);
 
if (helpers[i].mref == NULL)
continue;
@@ -3028,8 +3044,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);
}
@@ -3302,7 +3322,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->req_obj.req && set, 0);
+   if (!ret && hdl->req_obj.req && 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



[RFCv9 PATCH 10/29] v4l2-ctrls: alloc memory for p_req

2018-03-28 Thread Hans Verkuil
From: Hans Verkuil 

To store request data the handler_new_ref() allocates memory
for it if needed.

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

diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c 
b/drivers/media/v4l2-core/v4l2-ctrls.c
index d09f49530d9e..e8d6dee375ef 100644
--- a/drivers/media/v4l2-core/v4l2-ctrls.c
+++ b/drivers/media/v4l2-core/v4l2-ctrls.c
@@ -1997,6 +1997,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;
@@ -2004,6 +2005,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
@@ -2017,11 +2022,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->req_obj.req)
+   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
@@ -2061,6 +2071,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);
@@ -2202,7 +2214,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;
}
@@ -2395,7 +2407,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;
}
-- 
2.16.1



[RFCv9 PATCH 01/29] v4l2-device.h: always expose mdev

2018-03-28 Thread Hans Verkuil
From: Hans Verkuil 

The mdev field is only present if CONFIG_MEDIA_CONTROLLER is set.
But since we will need to pass the media_device to vb2 snd the
control framework it is very convenient to just make this field
available all the time. If CONFIG_MEDIA_CONTROLLER is not set,
then it will just be NULL.

Signed-off-by: Hans Verkuil 
---
 include/media/v4l2-device.h | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/include/media/v4l2-device.h b/include/media/v4l2-device.h
index 0c9e4da55499..b330e4a08a6b 100644
--- a/include/media/v4l2-device.h
+++ b/include/media/v4l2-device.h
@@ -33,7 +33,7 @@ struct v4l2_ctrl_handler;
  * struct v4l2_device - main struct to for V4L2 device drivers
  *
  * @dev: pointer to struct device.
- * @mdev: pointer to struct media_device
+ * @mdev: pointer to struct media_device, may be NULL.
  * @subdevs: used to keep track of the registered subdevs
  * @lock: lock this struct; can be used by the driver as well
  * if this struct is embedded into a larger struct.
@@ -58,9 +58,7 @@ struct v4l2_ctrl_handler;
  */
 struct v4l2_device {
struct device *dev;
-#if defined(CONFIG_MEDIA_CONTROLLER)
struct media_device *mdev;
-#endif
struct list_head subdevs;
spinlock_t lock;
char name[V4L2_DEVICE_NAME_SIZE];
-- 
2.16.1



[RFCv9 PATCH 09/29] v4l2-ctrls: prepare internal structs for request API

2018-03-28 Thread Hans Verkuil
From: Hans Verkuil 

Embed and initialize a media_request_object in struct v4l2_ctrl_handler.

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   | 7 +++
 2 files changed, 8 insertions(+)

diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c 
b/drivers/media/v4l2-core/v4l2-ctrls.c
index aa1dd2015e84..d09f49530d9e 100644
--- a/drivers/media/v4l2-core/v4l2-ctrls.c
+++ b/drivers/media/v4l2-core/v4l2-ctrls.c
@@ -1880,6 +1880,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;
+   media_request_object_init(>req_obj);
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 f8faa54b5e7e..89a985607126 100644
--- a/include/media/v4l2-ctrls.h
+++ b/include/media/v4l2-ctrls.h
@@ -20,6 +20,7 @@
 #include 
 #include 
 #include 
+#include 
 
 /* forward references */
 struct file;
@@ -249,6 +250,8 @@ struct v4l2_ctrl {
  * ``prepare_ext_ctrls`` function at ``v4l2-ctrl.c``.
  * @from_other_dev: If true, then @ctrl was defined in another
  * device then the  v4l2_ctrl_handler.
+ * @p_req: The request value. Only used if the control handler
+ * is bound to a media request.
  *
  * Each control handler has a list of these refs. The list_head is used to
  * keep a sorted-by-control-ID list of all controls, while the next pointer
@@ -260,6 +263,7 @@ struct v4l2_ctrl_ref {
struct v4l2_ctrl *ctrl;
struct v4l2_ctrl_helper *helper;
bool from_other_dev;
+   union v4l2_ctrl_ptr p_req;
 };
 
 /**
@@ -283,6 +287,8 @@ struct v4l2_ctrl_ref {
  * @notify_priv: Passed as argument to the v4l2_ctrl notify callback.
  * @nr_of_buckets: Total number of buckets in the array.
  * @error: The error code of the first failed control addition.
+ * @req_obj:   The  media_request_object, used to link into a
+ *  media_request.
  */
 struct v4l2_ctrl_handler {
struct mutex _lock;
@@ -295,6 +301,7 @@ struct v4l2_ctrl_handler {
void *notify_priv;
u16 nr_of_buckets;
int error;
+   struct media_request_object req_obj;
 };
 
 /**
-- 
2.16.1



[RFCv9 PATCH 00/29] Request API

2018-03-28 Thread Hans Verkuil
From: Hans Verkuil 

Hi all,

This patch series is an attempt to pick the best parts of
Alexandre's RFCv4:

https://lkml.org/lkml/2018/2/19/872

and Sakari's RFCv2:

https://www.mail-archive.com/linux-media@vger.kernel.org/msg128170.html

and based on the RFCv2 of the Request public API proposal:

https://www.mail-archive.com/linux-media@vger.kernel.org/msg128098.html

together with my own ideas.

I've no idea what version to give this series, so I just went with
v9 since that's the version of my internal git branch.

This has been tested with vim2m and vivid using v4l2-compliance.
The v4l-utils repo supporting requests is here:
https://git.linuxtv.org/hverkuil/v4l-utils.git/log/?h=request

The goal is to use request and request objects as implemented in
Sakari's RFCv2, together with the vb2 and control framework
support as implemented in Alexandre's RFCv4. In addition, I tried
hard to minimize the impact of requests to drivers.

TODO/Remarks:

1) missing prototype documentation in media-requests.c/h. Some
   is documented, but not everything.

2) improve the control handler implementation: currently this just
   clones the driver's control handler when a request object is
   created. And only standard controls can be contained in a request.
   I probably need another day of work to get this done properly by
   chaining control handlers as they are queued.

   The control patches are also a bit messy, so that needs to be
   cleaned up as well. I hope I can spend some time on this next
   week after Easter as this is the main TODO item. I expect I'll
   need 1-2 days of work to finished this.

   That said, the current implementation should be OK for stateless
   codecs.

3) No VIDIOC_REQUEST_ALLOC 'shortcut' ioctl. Sorry, I just ran out
   of time. Alexandre, Tomasz, feel free to add it back (it should
   be quite easy to do) and post a patch. I'll add it to my patch
   series. As mentioned before: whether or not we actually want this
   has not been decided yet.

4) vim2m: the media topology is a bit bogus, this needs to be fixed
   (i.e. a proper HW entity should be added). But for now it is
   good enough for testing.

5) I think this should slide in fairly easy after the fence support
   is merged. I made sure the request API changes in public headers
   did not clash with the changes made by the fence API.

6) I did not verify the Request API documentation patch. I did update
   it with the new buffer flags and 'which' value, but it probably is
   out of date in places.

7) More testing. I think I have fairly good coverage in v4l2-compliance,
   but no doubt I've missed a few test cases.

8) debugfs: it would be really useful to expose the number of request
   and request objects in debugfs to simplify debugging. Esp. to make
   sure everything is freed correctly.

9) Review copyright/authorship lines. I'm not sure if everything is
   correct. Alexandre, Sakari, if you see something that is not
   right in this respect, just let me know!

Everything seemed to slip nicely into place while working on this,
so I hope this is finally an implementation that we can proceed to
upstream and build upon for complex camera pipelines in the future.

This patch series is also available here:

https://git.linuxtv.org/hverkuil/media_tree.git/log/?h=reqv9

Regards,

Hans

Alexandre Courbot (4):
  v4l2-ctrls: do not clone non-standard controls
  videodev2.h: add request_fd field to v4l2_ext_controls
  Documentation: v4l: document request API
  media: vim2m: add media device

Hans Verkuil (25):
  v4l2-device.h: always expose mdev
  uapi/linux/media.h: add request API
  media-request: allocate media requests
  media-request: core request support
  media-request: add request ioctls
  media-request: add media_request_find
  media-request: add media_request_object_find
  v4l2-ctrls: v4l2_ctrl_add_handler: add from_other_dev
  v4l2-ctrls: prepare internal structs for request API
  v4l2-ctrls: alloc memory for p_req
  v4l2-ctrls: use ref in helper instead of ctrl
  v4l2-ctrls: support g/s_ext_ctrls for requests
  v4l2-ctrls: add core request API
  v4l2-ctrls: integrate with requests
  videodev2.h: Add request_fd field to v4l2_buffer
  vb2: store userspace data in vb2_v4l2_buffer
  videobuf2-core: embed media_request_object
  videobuf2-core: integrate with media requests
  videobuf2-v4l2: integrate with media requests
  videobuf2-core: add vb2_core_request_has_buffers
  videobuf2-v4l2: add vb2_request_queue helper
  vim2m: use workqueue
  vim2m: support requests
  vivid: add mc
  vivid: add request support

 Documentation/media/uapi/v4l/buffer.rst|  19 +-
 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  |  22 +-
 .../media/uapi/v4l/vidioc-new-request.rst  |  64 +++
 

Re: [PATCH 04/15] v4l: vsp1: Store pipeline pointer in vsp1_entity

2018-03-28 Thread Kieran Bingham
Hi Laurent,

Thank you for the patch.

On 26/02/18 21:45, Laurent Pinchart wrote:
> Various types of objects subclassing vsp1_entity currently store a
> pointer to the pipeline. Move the pointer to vsp1_entity to simplify the
> code and avoid storing the pipeline in more entity subclasses later.

This certainly seems like a good improvement to make.

> Signed-off-by: Laurent Pinchart 

Some terse diffstat there to get through - but it all looks good in the end.

Reviewed-by: Kieran Bingham 


> ---
>  drivers/media/platform/vsp1/vsp1_drm.c| 20 +--
>  drivers/media/platform/vsp1/vsp1_drv.c|  2 +-
>  drivers/media/platform/vsp1/vsp1_entity.h |  2 ++
>  drivers/media/platform/vsp1/vsp1_histo.c  |  2 +-
>  drivers/media/platform/vsp1/vsp1_histo.h  |  3 ---
>  drivers/media/platform/vsp1/vsp1_pipe.c   | 33 
> +--
>  drivers/media/platform/vsp1/vsp1_rwpf.h   |  2 --
>  drivers/media/platform/vsp1/vsp1_video.c  | 17 +++-
>  8 files changed, 34 insertions(+), 47 deletions(-)
> 
> diff --git a/drivers/media/platform/vsp1/vsp1_drm.c 
> b/drivers/media/platform/vsp1/vsp1_drm.c
> index a267f12f0cc8..a7ad85ab0b08 100644
> --- a/drivers/media/platform/vsp1/vsp1_drm.c
> +++ b/drivers/media/platform/vsp1/vsp1_drm.c
> @@ -120,6 +120,7 @@ int vsp1_du_setup_lif(struct device *dev, unsigned int 
> pipe_index,
>* inputs.
>*/
>   WARN_ON(list_empty(>entity.list_pipe));
> + rpf->entity.pipe = NULL;

Aha - This reads confusingly as a diff ... because first it ensures the entity
is in a pipe with the WARN_ON, but then sets the pipe to NULL. But I'm going to
hazard a guess and say this is the (!cfg) section of the vsp1_du_setup_lif()
call...

/me checks.

Yes, of course it is... so that's fine.


>   list_del_init(>entity.list_pipe);
>   pipe->inputs[i] = NULL;
>  
> @@ -536,8 +537,10 @@ void vsp1_du_atomic_flush(struct device *dev, unsigned 
> int pipe_index)
>   continue;
>   }
>  
> - if (list_empty(>entity.list_pipe))
> + if (list_empty(>entity.list_pipe)) {
> + rpf->entity.pipe = pipe;
>   list_add_tail(>entity.list_pipe, >entities);
> + }
>  
>   bru->inputs[i].rpf = rpf;
>   rpf->bru_input = i;
> @@ -562,6 +565,7 @@ void vsp1_du_atomic_flush(struct device *dev, unsigned 
> int pipe_index)
>   vsp1_dl_list_write(dl, entity->route->reg,
>  VI6_DPR_NODE_UNUSED);
>  
> + entity->pipe = NULL;
>   list_del_init(>list_pipe);
>  
>   continue;
> @@ -625,24 +629,28 @@ int vsp1_drm_init(struct vsp1_device *vsp1)
>  
>   vsp1_pipeline_init(pipe);
>  
> + pipe->frame_end = vsp1_du_pipeline_frame_end;
> +

Aha - just a code move - I was going to ask why this was here. That's fine.


>   /*
>* The DRM pipeline is static, add entities manually. The first
>* pipeline uses the BRU and the second pipeline the BRS.
>*/
>   pipe->bru = i == 0 ? >bru->entity : >brs->entity;
> - pipe->lif = >lif[i]->entity;
>   pipe->output = vsp1->wpf[i];
> - pipe->output->pipe = pipe;
> - pipe->frame_end = vsp1_du_pipeline_frame_end;
> + pipe->lif = >lif[i]->entity;
>  
> + pipe->bru->pipe = pipe;
>   pipe->bru->sink = >output->entity;
>   pipe->bru->sink_pad = 0;
> + list_add_tail(>bru->list_pipe, >entities);
> +
> + pipe->output->entity.pipe = pipe;

Ick ... pipe->bru->pipe, but pipe->output->entity.pipe ...
 BRU is already an entity, whereas output is an RPF.

A bit painful on the eyes for review - but nothing to be done there I don't 
think.




>   pipe->output->entity.sink = pipe->lif;
>   pipe->output->entity.sink_pad = 0;
> + list_add_tail(>output->entity.list_pipe, >entities);
>  
> - list_add_tail(>bru->list_pipe, >entities);
> + pipe->lif->pipe = pipe;
>   list_add_tail(>lif->list_pipe, >entities);
> - list_add_tail(>output->entity.list_pipe, >entities);
>   }
>  
>   /* Disable all RPFs initially. */
> diff --git a/drivers/media/platform/vsp1/vsp1_drv.c 
> b/drivers/media/platform/vsp1/vsp1_drv.c
> index eed9516e25e1..58a7993f2306 100644
> --- a/drivers/media/platform/vsp1/vsp1_drv.c
> +++ b/drivers/media/platform/vsp1/vsp1_drv.c
> @@ -63,7 +63,7 @@ static irqreturn_t vsp1_irq_handler(int irq, void *data)
>   vsp1_write(vsp1, VI6_WPF_IRQ_STA(i), ~status & mask);
>  
>   if (status & VI6_WFP_IRQ_STA_DFE) {

Re: [PATCH 2/8] PCI: Add pci_find_common_upstream_dev()

2018-03-28 Thread Christoph Hellwig
On Sun, Mar 25, 2018 at 12:59:54PM +0200, Christian König wrote:
> From: "wda...@nvidia.com" 
> 
> Add an interface to find the first device which is upstream of both
> devices.

Please work with Logan and base this on top of the outstanding peer
to peer patchset.


Re: [PATCH 1/8] lib/scatterlist: add sg_set_dma_addr() helper

2018-03-28 Thread Christoph Hellwig
On Sun, Mar 25, 2018 at 12:59:53PM +0200, Christian König wrote:
> Use this function to set an sg entry to point to device resources mapped
> using dma_map_resource(). The page pointer is set to NULL and only the DMA
> address, length and offset values are valid.

NAK.  Please provide a higher level primitive.

Btw, you series seems to miss a cover letter.


Re: [PATCH v4] dvb-usb/friio, dvb-usb-v2/gl861: decompose friio and merge with gl861

2018-03-28 Thread Akihiro TSUKADA
Hi,
thanks for the comment.

> You should implement i2c adapter to demod driver and not add such glue
> to that USB-bridge. I mean that "relayed" stuff, i2c communication to
> tuner via demod. I2C-mux may not work I think as there is no gate-style
> multiplexing so you probably need plain i2c adapter. There is few
> examples already on some demod drivers.

I am afraid that the glue is actually necessary.

host - USB -> gl861 - I2C(1) -> tc90522 (addr:X)
  \- I2C(2) -> tua6034 (addr:Y)

To send an i2c read message to tua6034,
one has to issue two transactions:
 1. write via I2C(1) to addr:X, [ reg:0xfe, val: Y ]
 2. read via I2C(1) from addr:X, [ out_data0, out_data1, ]

The problem is that the transaction 1 is (somehow) implemented with
the different USB request than the other i2c transactions on I2C(1).
(this is confirmed by a packet capture on Windows box).

Although tc90522 already creats the i2c adapter for I2C(2),
tc90522 cannot know/control the USB implementation of I2C(1),
only the bridge driver can do this.

regards,
Akihiro


Re: [PATCH 03/15] v4l: vsp1: Remove unused field from vsp1_drm_pipeline structure

2018-03-28 Thread Kieran Bingham
Hi Laurent,

Thanks for the patch,

On 26/02/18 21:45, Laurent Pinchart wrote:
> The vsp1_drm_pipeline enabled field is set but never used. Remove it.
> 

Indeed - not used.

> Signed-off-by: Laurent Pinchart 

Reviewed-by: Kieran Bingham 

> ---
>  drivers/media/platform/vsp1/vsp1_drm.c | 4 
>  drivers/media/platform/vsp1/vsp1_drm.h | 2 --
>  2 files changed, 6 deletions(-)
> 
> diff --git a/drivers/media/platform/vsp1/vsp1_drm.c 
> b/drivers/media/platform/vsp1/vsp1_drm.c
> index a1f2ba044092..a267f12f0cc8 100644
> --- a/drivers/media/platform/vsp1/vsp1_drm.c
> +++ b/drivers/media/platform/vsp1/vsp1_drm.c
> @@ -273,10 +273,6 @@ EXPORT_SYMBOL_GPL(vsp1_du_setup_lif);
>   */
>  void vsp1_du_atomic_begin(struct device *dev, unsigned int pipe_index)
>  {
> - struct vsp1_device *vsp1 = dev_get_drvdata(dev);
> - struct vsp1_drm_pipeline *drm_pipe = >drm->pipe[pipe_index];
> -
> - drm_pipe->enabled = drm_pipe->pipe.num_inputs != 0;
>  }
>  EXPORT_SYMBOL_GPL(vsp1_du_atomic_begin);
>  
> diff --git a/drivers/media/platform/vsp1/vsp1_drm.h 
> b/drivers/media/platform/vsp1/vsp1_drm.h
> index 1cd9db785bf7..9aa19325cbe9 100644
> --- a/drivers/media/platform/vsp1/vsp1_drm.h
> +++ b/drivers/media/platform/vsp1/vsp1_drm.h
> @@ -20,13 +20,11 @@
>  /**
>   * vsp1_drm_pipeline - State for the API exposed to the DRM driver
>   * @pipe: the VSP1 pipeline used for display
> - * @enabled: pipeline state at the beginning of an update
>   * @du_complete: frame completion callback for the DU driver (optional)
>   * @du_private: data to be passed to the du_complete callback
>   */
>  struct vsp1_drm_pipeline {
>   struct vsp1_pipeline pipe;
> - bool enabled;
>  
>   /* Frame synchronisation */
>   void (*du_complete)(void *, bool);
> 


Re: [PATCH 02/15] v4l: vsp1: Remove outdated comment

2018-03-28 Thread Kieran Bingham
Hi Laurent,

Thank you for the patch.

On 26/02/18 21:45, Laurent Pinchart wrote:
> The entities in the pipeline are all started when the LIF is setup.
> Remove the outdated comment that state otherwise.
> 
> Signed-off-by: Laurent Pinchart 

I'll start with the easy ones :-)

Reviewed-by: Kieran Bingham 

> ---
>  drivers/media/platform/vsp1/vsp1_drm.c | 6 +-
>  1 file changed, 1 insertion(+), 5 deletions(-)
> 
> diff --git a/drivers/media/platform/vsp1/vsp1_drm.c 
> b/drivers/media/platform/vsp1/vsp1_drm.c
> index e31fb371eaf9..a1f2ba044092 100644
> --- a/drivers/media/platform/vsp1/vsp1_drm.c
> +++ b/drivers/media/platform/vsp1/vsp1_drm.c
> @@ -221,11 +221,7 @@ int vsp1_du_setup_lif(struct device *dev, unsigned int 
> pipe_index,
>   return -EPIPE;
>   }
>  
> - /*
> -  * Enable the VSP1. We don't start the entities themselves right at this
> -  * point as there's no plane configured yet, so we can't start
> -  * processing buffers.
> -  */
> + /* Enable the VSP1. */
>   ret = vsp1_device_get(vsp1);
>   if (ret < 0)
>   return ret;
> 


[PATCH] media: dvb-core: Check for allocation failure in dvb_module_probe()

2018-03-28 Thread Dan Carpenter
We should check if kzalloc() fails.

Fixes: 8f569c0b4e6b ("media: dvb-core: add helper functions for I2C binding")
Signed-off-by: Dan Carpenter 

diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c
index cf747d753a79..787fe06df217 100644
--- a/drivers/media/dvb-core/dvbdev.c
+++ b/drivers/media/dvb-core/dvbdev.c
@@ -953,6 +953,8 @@ struct i2c_client *dvb_module_probe(const char *module_name,
struct i2c_board_info *board_info;
 
board_info = kzalloc(sizeof(*board_info), GFP_KERNEL);
+   if (!board_info)
+   return NULL;
 
if (name)
strlcpy(board_info->type, name, I2C_NAME_SIZE);


  1   2   >