Re: [PATCH v2 5/5] media: atmel-isc: Rework the format list

2017-09-26 Thread Yang, Wenyou

Hi Hans,

Thank  you very much for your review.

On 2017/9/25 21:24, Hans Verkuil wrote:

Hi Wenyou,

On 18/09/17 08:39, Wenyou Yang wrote:

To improve the readability of code, split the format array into two,
one for the format description, other for the register configuration.
Meanwhile, add the flag member to indicate the format can be achieved
from the sensor or be produced by the controller, and rename members
related to the register configuration.

Also add more formats support: GREY, ARGB444, ARGB555 and ARGB32.

Signed-off-by: Wenyou Yang 

This looks better. Just a few comments, see below.


---

Changes in v2:
  - Add the new patch to remove the unnecessary member from
isc_subdev_entity struct.
  - Rebase on the patch set,
 [PATCH 0/6] [media] Atmel: Adjustments for seven function 
implementations
 https://www.mail-archive.com/linux-media@vger.kernel.org/msg118342.html

  drivers/media/platform/atmel/atmel-isc.c | 524 ---
  1 file changed, 405 insertions(+), 119 deletions(-)

diff --git a/drivers/media/platform/atmel/atmel-isc.c 
b/drivers/media/platform/atmel/atmel-isc.c
index 2d876903da71..90bd0b28a975 100644
--- a/drivers/media/platform/atmel/atmel-isc.c
+++ b/drivers/media/platform/atmel/atmel-isc.c
@@ -89,34 +89,56 @@ struct isc_subdev_entity {
struct list_head list;
  };
  
+#define FMT_FLAG_FROM_SENSOR		BIT(0)

+#define FMT_FLAG_FROM_CONTROLLER   BIT(1)

Document the meaning of these flags.

Will add it in next version.



+
  /*
   * struct isc_format - ISC media bus format information
   * @fourcc:   Fourcc code for this format
   * @mbus_code:V4L2 media bus format code.
+ * flags:  Indicate format from sensor or converted by controller
   * @bpp:  Bits per pixel (when stored in memory)
- * @reg_bps:   reg value for bits per sample
   *(when transferred over a bus)
- * @pipeline:  pipeline switch
   * @sd_support:   Subdev supports this format
   * @isc_support:  ISC can convert raw format to this format
   */
+
  struct isc_format {
u32 fourcc;
u32 mbus_code;
+   u32 flags;
u8  bpp;
  
-	u32	reg_bps;

-   u32 reg_bay_cfg;
-   u32 reg_rlp_mode;
-   u32 reg_dcfg_imode;
-   u32 reg_dctrl_dview;
-
-   u32 pipeline;
-
boolsd_support;
boolisc_support;
  };
  
+/* Pipeline bitmap */

+#define WB_ENABLE  BIT(0)
+#define CFA_ENABLE BIT(1)
+#define CC_ENABLE  BIT(2)
+#define GAM_ENABLE BIT(3)
+#define GAM_BENABLEBIT(4)
+#define GAM_GENABLEBIT(5)
+#define GAM_RENABLEBIT(6)
+#define CSC_ENABLE BIT(7)
+#define CBC_ENABLE BIT(8)
+#define SUB422_ENABLE  BIT(9)
+#define SUB420_ENABLE  BIT(10)
+
+#define GAM_ENABLES(GAM_RENABLE | GAM_GENABLE | GAM_BENABLE | GAM_ENABLE)
+
+struct fmt_config {
+   u32 fourcc;
+
+   u32 pfe_cfg0_bps;
+   u32 cfa_baycfg;
+   u32 rlp_cfg_mode;
+   u32 dcfg_imode;
+   u32 dctrl_dview;
+
+   u32 bits_pipeline;
+};
  
  #define HIST_ENTRIES		512

  #define HIST_BAYER(ISC_HIS_CFG_MODE_B + 1)
@@ -181,80 +203,321 @@ struct isc_device {
struct list_headsubdev_entities;
  };
  
-#define RAW_FMT_IND_START0

-#define RAW_FMT_IND_END  11
-#define ISC_FMT_IND_START12
-#define ISC_FMT_IND_END  14
-
-static struct isc_format isc_formats[] = {
-   { V4L2_PIX_FMT_SBGGR8, MEDIA_BUS_FMT_SBGGR8_1X8, 8,
- ISC_PFE_CFG0_BPS_EIGHT, ISC_BAY_CFG_BGBG, ISC_RLP_CFG_MODE_DAT8,
- ISC_DCFG_IMODE_PACKED8, ISC_DCTRL_DVIEW_PACKED, 0x0,
- false, false },
-   { V4L2_PIX_FMT_SGBRG8, MEDIA_BUS_FMT_SGBRG8_1X8, 8,
- ISC_PFE_CFG0_BPS_EIGHT, ISC_BAY_CFG_GBGB, ISC_RLP_CFG_MODE_DAT8,
- ISC_DCFG_IMODE_PACKED8, ISC_DCTRL_DVIEW_PACKED, 0x0,
- false, false },
-   { V4L2_PIX_FMT_SGRBG8, MEDIA_BUS_FMT_SGRBG8_1X8, 8,
- ISC_PFE_CFG0_BPS_EIGHT, ISC_BAY_CFG_GRGR, ISC_RLP_CFG_MODE_DAT8,
- ISC_DCFG_IMODE_PACKED8, ISC_DCTRL_DVIEW_PACKED, 0x0,
- false, false },
-   { V4L2_PIX_FMT_SRGGB8, MEDIA_BUS_FMT_SRGGB8_1X8, 8,
- ISC_PFE_CFG0_BPS_EIGHT, ISC_BAY_CFG_RGRG, ISC_RLP_CFG_MODE_DAT8,
- ISC_DCFG_IMODE_PACKED8, ISC_DCTRL_DVIEW_PACKED, 0x0,
- false, false },
-
-   { V4L2_PIX_FMT_SBGGR10, MEDIA_BUS_FMT_SBGGR10_1X10, 16,
- ISC_PFG_CFG0_BPS_TEN, ISC_BAY_CFG_BGBG, ISC_RLP_CFG_MODE_DAT10,
- ISC_DCFG_IMODE_PACKED16, ISC_DCTRL_DVIEW_PACKED, 0x0,
- false, false },
-   { V4L2_PIX_FMT_SGBRG10, MEDIA_BUS_FMT_SGBRG10_1X10, 16,
- ISC_PFG_CFG0_BPS_TEN, ISC_BAY_CFG_GBGB, ISC_RLP_CFG_MODE_DAT10,
- ISC_DCFG_IMODE_PACKED16, ISC_DCTRL_DVIEW_PACKED, 0x0,
- false, false },
-   { V4L2_PIX_FMT_SGRBG10, MEDIA_BUS_FMT_SGRBG10_1X10, 16,
- 

cron job: media_tree daily build: ERRORS

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

Results of the daily build of media_tree:

date:   Wed Sep 27 05:00:15 CEST 2017
media-tree git hash:d5426f4c2ebac8cf05de43988c3fccddbee13d28
media_build git hash:   b829b621b4c2e6c5cbedbd1ce62b4e958f7d13a4
v4l-utils git hash: 8be65674f9a57e4bc35858f86bb5489f0afd22c1
gcc version:i686-linux-gcc (GCC) 7.1.0
sparse version: v0.5.0
smatch version: v0.5.0-3553-g78b2ea6
host hardware:  x86_64
host os:4.12.0-164

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-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: ERRORS
linux-2.6.37.6-i686: ERRORS
linux-2.6.38.8-i686: ERRORS
linux-2.6.39.4-i686: ERRORS
linux-3.0.60-i686: ERRORS
linux-3.1.10-i686: ERRORS
linux-3.2.37-i686: ERRORS
linux-3.3.8-i686: WARNINGS
linux-3.4.27-i686: WARNINGS
linux-3.5.7-i686: WARNINGS
linux-3.6.11-i686: WARNINGS
linux-3.7.4-i686: WARNINGS
linux-3.8-i686: WARNINGS
linux-3.9.2-i686: WARNINGS
linux-3.10.1-i686: WARNINGS
linux-3.11.1-i686: WARNINGS
linux-3.12.67-i686: WARNINGS
linux-3.13.11-i686: WARNINGS
linux-3.14.9-i686: WARNINGS
linux-3.15.2-i686: WARNINGS
linux-3.16.7-i686: WARNINGS
linux-3.17.8-i686: WARNINGS
linux-3.18.7-i686: WARNINGS
linux-3.19-i686: WARNINGS
linux-4.0.9-i686: WARNINGS
linux-4.1.33-i686: WARNINGS
linux-4.2.8-i686: WARNINGS
linux-4.3.6-i686: WARNINGS
linux-4.4.22-i686: WARNINGS
linux-4.5.7-i686: WARNINGS
linux-4.6.7-i686: WARNINGS
linux-4.7.5-i686: WARNINGS
linux-4.8-i686: OK
linux-4.9.26-i686: OK
linux-4.10.14-i686: OK
linux-4.11-i686: OK
linux-4.12.1-i686: OK
linux-4.13-i686: OK
linux-2.6.36.4-x86_64: ERRORS
linux-2.6.37.6-x86_64: ERRORS
linux-2.6.38.8-x86_64: ERRORS
linux-2.6.39.4-x86_64: ERRORS
linux-3.0.60-x86_64: ERRORS
linux-3.1.10-x86_64: ERRORS
linux-3.2.37-x86_64: ERRORS
linux-3.3.8-x86_64: WARNINGS
linux-3.4.27-x86_64: WARNINGS
linux-3.5.7-x86_64: WARNINGS
linux-3.6.11-x86_64: WARNINGS
linux-3.7.4-x86_64: WARNINGS
linux-3.8-x86_64: WARNINGS
linux-3.9.2-x86_64: WARNINGS
linux-3.10.1-x86_64: WARNINGS
linux-3.11.1-x86_64: WARNINGS
linux-3.12.67-x86_64: WARNINGS
linux-3.13.11-x86_64: WARNINGS
linux-3.14.9-x86_64: WARNINGS
linux-3.15.2-x86_64: WARNINGS
linux-3.16.7-x86_64: WARNINGS
linux-3.17.8-x86_64: WARNINGS
linux-3.18.7-x86_64: WARNINGS
linux-3.19-x86_64: WARNINGS
linux-4.0.9-x86_64: WARNINGS
linux-4.1.33-x86_64: WARNINGS
linux-4.2.8-x86_64: WARNINGS
linux-4.3.6-x86_64: WARNINGS
linux-4.4.22-x86_64: WARNINGS
linux-4.5.7-x86_64: WARNINGS
linux-4.6.7-x86_64: WARNINGS
linux-4.7.5-x86_64: WARNINGS
linux-4.8-x86_64: WARNINGS
linux-4.9.26-x86_64: WARNINGS
linux-4.10.14-x86_64: WARNINGS
linux-4.11-x86_64: WARNINGS
linux-4.12.1-x86_64: WARNINGS
linux-4.13-x86_64: OK
apps: OK
spec-git: OK

Detailed results are available here:

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

Full logs are available here:

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

The Media Infrastructure API from this daily build is here:

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


Re: [PATCH v2] scripts: kernel-doc: fix nexted handling

2017-09-26 Thread kbuild test robot
Hi Mauro,

[auto build test WARNING on linus/master]
[also build test WARNING on v4.14-rc2 next-20170926]
[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/Mauro-Carvalho-Chehab/scripts-kernel-doc-fix-nexted-handling/20170927-091127
reproduce: make htmldocs

All warnings (new ones prefixed by >>):

   WARNING: convert(1) not found, for SVG to PDF conversion install ImageMagick 
(https://www.imagemagick.org)
   kernel/trace/blktrace.c:824: warning: No description found for parameter 
'cgid'
>> include/net/cfg80211.h:2056: warning: Excess struct/union/enum/typedef 
>> member 'band_pref' description in 'cfg80211_bss_selection'
>> include/net/cfg80211.h:2056: warning: Excess struct/union/enum/typedef 
>> member 'adjust' description in 'cfg80211_bss_selection'
>> include/net/cfg80211.h:4115: warning: Excess struct/union/enum/typedef 
>> member 'bssid' description in 'wireless_dev'
>> include/net/cfg80211.h:2056: warning: Excess struct/union/enum/typedef 
>> member 'band_pref' description in 'cfg80211_bss_selection'
>> include/net/cfg80211.h:2056: warning: Excess struct/union/enum/typedef 
>> member 'adjust' description in 'cfg80211_bss_selection'
>> include/net/cfg80211.h:4115: warning: Excess struct/union/enum/typedef 
>> member 'bssid' description in 'wireless_dev'
>> include/net/cfg80211.h:2056: warning: Excess struct/union/enum/typedef 
>> member 'band_pref' description in 'cfg80211_bss_selection'
>> include/net/cfg80211.h:2056: warning: Excess struct/union/enum/typedef 
>> member 'adjust' description in 'cfg80211_bss_selection'
>> include/net/cfg80211.h:4115: warning: Excess struct/union/enum/typedef 
>> member 'bssid' description in 'wireless_dev'
>> include/net/cfg80211.h:2056: warning: Excess struct/union/enum/typedef 
>> member 'band_pref' description in 'cfg80211_bss_selection'
>> include/net/cfg80211.h:2056: warning: Excess struct/union/enum/typedef 
>> member 'adjust' description in 'cfg80211_bss_selection'
>> include/net/cfg80211.h:4115: warning: Excess struct/union/enum/typedef 
>> member 'bssid' description in 'wireless_dev'
>> include/net/cfg80211.h:2056: warning: Excess struct/union/enum/typedef 
>> member 'band_pref' description in 'cfg80211_bss_selection'
>> include/net/cfg80211.h:2056: warning: Excess struct/union/enum/typedef 
>> member 'adjust' description in 'cfg80211_bss_selection'
>> include/net/cfg80211.h:4115: warning: Excess struct/union/enum/typedef 
>> member 'bssid' description in 'wireless_dev'
>> include/net/cfg80211.h:2056: warning: Excess struct/union/enum/typedef 
>> member 'band_pref' description in 'cfg80211_bss_selection'
>> include/net/cfg80211.h:2056: warning: Excess struct/union/enum/typedef 
>> member 'adjust' description in 'cfg80211_bss_selection'
>> include/net/cfg80211.h:4115: warning: Excess struct/union/enum/typedef 
>> member 'bssid' description in 'wireless_dev'
>> include/net/cfg80211.h:2056: warning: Excess struct/union/enum/typedef 
>> member 'band_pref' description in 'cfg80211_bss_selection'
>> include/net/cfg80211.h:2056: warning: Excess struct/union/enum/typedef 
>> member 'adjust' description in 'cfg80211_bss_selection'

vim +2056 include/net/cfg80211.h

04a773ad Johannes Berg2009-04-19  2041  
04a773ad Johannes Berg2009-04-19  2042  /**
38de03d2 Arend van Spriel 2016-03-02  2043   * struct cfg80211_bss_selection - 
connection parameters for BSS selection.
38de03d2 Arend van Spriel 2016-03-02  2044   *
38de03d2 Arend van Spriel 2016-03-02  2045   * @behaviour: requested BSS 
selection behaviour.
38de03d2 Arend van Spriel 2016-03-02  2046   * @param: parameters for 
requestion behaviour.
38de03d2 Arend van Spriel 2016-03-02  2047   * @band_pref: preferred band for 
%NL80211_BSS_SELECT_ATTR_BAND_PREF.
38de03d2 Arend van Spriel 2016-03-02  2048   * @adjust: parameters for 
%NL80211_BSS_SELECT_ATTR_RSSI_ADJUST.
38de03d2 Arend van Spriel 2016-03-02  2049   */
38de03d2 Arend van Spriel 2016-03-02  2050  struct cfg80211_bss_selection {
38de03d2 Arend van Spriel 2016-03-02  2051  enum nl80211_bss_select_attr 
behaviour;
38de03d2 Arend van Spriel 2016-03-02  2052  union {
57fbcce3 Johannes Berg2016-04-12  2053  enum nl80211_band 
band_pref;
38de03d2 Arend van Spriel 2016-03-02  2054  struct 
cfg80211_bss_select_adjust adjust;
38de03d2 Arend van Spriel 2016-03-02  2055  } param;
38de03d2 Arend van Spriel 2016-03-02 @2056  };
38de03d2 Arend van Spriel 2016-03-02  2057  

:: The code at line 2056 was first introduced by commit
:: 38de03d2a28925b489c11546804e2f5418cc17a4 nl80211: add feature for BSS 
selection support

:: TO: Arend van Spriel <ar...@b

Re: [PATCH 07/10] docs: kernel-doc.rst: add documentation about man pages

2017-09-26 Thread Randy Dunlap
On 09/26/17 10:59, Mauro Carvalho Chehab wrote:
> kernel-doc-nano-HOWTO.txt has a chapter about man pages
> production. While we don't have a working  "make manpages"
> target, add it.
> 
> Signed-off-by: Mauro Carvalho Chehab 
> ---
>  Documentation/doc-guide/kernel-doc.rst | 61 
> ++
>  1 file changed, 47 insertions(+), 14 deletions(-)
> 
> diff --git a/Documentation/doc-guide/kernel-doc.rst 
> b/Documentation/doc-guide/kernel-doc.rst
> index 9777aa53e3dd..50473f0db345 100644
> --- a/Documentation/doc-guide/kernel-doc.rst
> +++ b/Documentation/doc-guide/kernel-doc.rst
> @@ -377,7 +377,6 @@ cross-references.
>  For further details, please refer to the `Sphinx C Domain`_ documentation.
>  
>  
> -
>  In-line member documentation comments
>  ~
>  
> @@ -391,19 +390,19 @@ on a line of their own, like all other kernel-doc 
> comments::
> * @foo: The Foo member.
> */
>struct foo {
> -int foo;
> -/**
> - * @bar: The Bar member.
> - */
> -int bar;
> -/**
> - * @baz: The Baz member.
> - *
> - * Here, the member description may contain several paragraphs.
> - */
> -int baz;
> -/** @foobar: Single line description. */
> -int foobar;
> + int foo;
> + /**
> +  * @bar: The Bar member.
> +  */
> + int bar;
> + /**
> +  * @baz: The Baz member.
> +  *
> +  * Here, the member description may contain several paragraphs.
> +  */
> + int baz;
> + /** @foobar: Single line description. */
> + int foobar;
>}

The above doesn't belong in this patch. (??)

>  
> @@ -452,3 +451,37 @@ file.
>  
>  Data structures visible in kernel include files should also be documented 
> using
>  kernel-doc formatted comments.
> +
> +How to use kernel-doc to generate man pages
> +---
> +
> +If you just want to use kernel-doc to generate man pages you can do this
> +from the Kernel git tree::
> +
> +  $ scripts/kernel-doc -man $(git grep -l '/\*\*' |grep -v Documentation/) | 
> ./split-man.pl /tmp/man
> +
> +Using the small ``split-man.pl`` script below::
> +
> +
> +  #!/usr/bin/perl
> +
> +  if ($#ARGV < 0) {
> + die "where do I put the results?\n";
> +  }
> +
> +  mkdir $ARGV[0],0777;
> +  $state = 0;
> +  while () {
> +  if (/^\.TH \"[^\"]*\" 9 \"([^\"]*)\"/) {
> + if ($state == 1) { close OUT }
> + $state = 1;
> + $fn = "$ARGV[0]/$1.9";
> + print STDERR "Creating $fn\n";
> + open OUT, ">$fn" or die "can't open $fn: $!\n";
> + print OUT $_;
> +  } elsif ($state != 0) {
> + print OUT $_;
> +  }
> +  }
> +
> +  close OUT;
> 


-- 
~Randy


Re: [PATCH 02/10] docs: kernel-doc.rst: better describe kernel-doc arguments

2017-09-26 Thread Randy Dunlap
On 09/26/17 10:59, Mauro Carvalho Chehab wrote:
> Add a new section to describe kernel-doc arguments,
> adding examples about how identation should happen, as failing
> to do that causes Sphinx to do the wrong thing.
> 
> Signed-off-by: Mauro Carvalho Chehab 
> ---
>  Documentation/doc-guide/kernel-doc.rst | 44 
> +++---
>  1 file changed, 41 insertions(+), 3 deletions(-)
> 
> diff --git a/Documentation/doc-guide/kernel-doc.rst 
> b/Documentation/doc-guide/kernel-doc.rst
> index b24854b5d6be..7a3f5c710c0b 100644
> --- a/Documentation/doc-guide/kernel-doc.rst
> +++ b/Documentation/doc-guide/kernel-doc.rst
> @@ -112,16 +112,17 @@ Example kernel-doc function comment::
>  
>/**
> * foobar() - Brief description of foobar.
> -   * @arg: Description of argument of foobar.
> +   * @argument1: Description of parameter argument1 of foobar.
> +   * @argument1: Description of parameter argument2 of foobar.

@argument2:

> *
> * Longer description of foobar.
> *
> * Return: Description of return value of foobar.
> */
> -  int foobar(int arg)
> +  int foobar(int argument1, char *argument2)


-- 
~Randy


Re: s5p-mfc - WARNING: possible circular locking dependency detected,[ 4.14.0-rc2

2017-09-26 Thread Shuah Khan
On 09/26/2017 02:10 PM, Shuah Khan wrote:
> When running gstreamer pipeline with s5p-mfc → exynos-gsc→ exynos-drm,
> I am seeing circular locking dependency detected warning in 4.14-rc2.
> This is a regression from 4.13. The pipeline does run to completion
> video streaming works. Are you aware of this problem, or would you
> like it to be bisected.

Okay more on this. It is not a regression from 4.13. CONFIG_PROVE_LOCKING
is enabled in exynos_defconfig in 4.14 and not on 4.13. It is an existing
problem that is now being reported with CONFIG_PROVE_LOCKING enabled.

> 
> gst-launch-1.0 filesrc location=/media/shuah_arm/GH3_MOV_HD.mp4 ! qtdemux ! 
> h264parse ! v4l2video4dec capture-io-mode=dmabuf ! v4l2video7convert 
> output-io-mode=dmabuf-import ! kmssink force-modesetting=true
> 
> [ 2134.994539] ==
> [ 2135.000661] WARNING: possible circular locking dependency detected
> [ 2135.006815] 4.14.0-rc2 #1 Not tainted
> [ 2135.010452] --
> [ 2135.016606] qtdemux0:sink/2700 is trying to acquire lock:
> [ 2135.021978]  (>mfc_mutex){+.+.}, at: [] 
> s5p_mfc_mmap+0x28/0xd4 [s5p_mfc]
> [ 2135.029950]
>but task is already holding lock:
> [ 2135.035755]  (>mmap_sem){}, at: [] 
> vm_mmap_pgoff+0x44/0xb8
> [ 2135.042774]
>which lock already depends on the new lock.
> 
> [ 2135.050920]
>the existing dependency chain (in reverse order) is:
> [ 2135.058372]
>-> #2 (>mmap_sem){}:
> [ 2135.063751]__might_fault+0x80/0xb0
> [ 2135.067822]filldir64+0xc0/0x2f8
> [ 2135.071635]call_filldir+0xb0/0x14c
> [ 2135.075705]ext4_readdir+0x768/0x90c
> [ 2135.079864]iterate_dir+0x74/0x168
> [ 2135.083851]SyS_getdents64+0x7c/0x1a0
> [ 2135.088099]ret_fast_syscall+0x0/0x28
> [ 2135.092340]
>-> #1 (>i_mutex_dir_key#2){}:
> [ 2135.098671]down_read+0x48/0x90
> [ 2135.102395]lookup_slow+0x74/0x178
> [ 2135.106380]walk_component+0x1a4/0x2e4
> [ 2135.110713]link_path_walk+0x174/0x4a0
> [ 2135.115045]path_openat+0x68/0x944
> [ 2135.119031]do_filp_open+0x60/0xc4
> [ 2135.123019]file_open_name+0xe4/0x114
> [ 2135.127263]filp_open+0x28/0x48
> [ 2135.130990]kernel_read_file_from_path+0x30/0x78
> [ 2135.136193]_request_firmware+0x3ec/0x78c
> [ 2135.140782]request_firmware+0x3c/0x54
> [ 2135.145133]s5p_mfc_load_firmware+0x44/0x140 [s5p_mfc]
> [ 2135.150848]s5p_mfc_open+0x2d4/0x4e0 [s5p_mfc]
> [ 2135.155892]v4l2_open+0xa0/0x104 [videodev]
> [ 2135.160627]chrdev_open+0xa4/0x18c
> [ 2135.164612]do_dentry_open+0x208/0x310
> [ 2135.168945]path_openat+0x28c/0x944
> [ 2135.173017]do_filp_open+0x60/0xc4
> [ 2135.177002]do_sys_open+0x118/0x1c8
> [ 2135.181076]ret_fast_syscall+0x0/0x28
> [ 2135.185320]
>-> #0 (>mfc_mutex){+.+.}:
> [ 2135.190871]lock_acquire+0x6c/0x88
> [ 2135.194855]__mutex_lock+0x68/0xa34
> [ 2135.198927]mutex_lock_interruptible_nested+0x1c/0x24
> [ 2135.204575]s5p_mfc_mmap+0x28/0xd4 [s5p_mfc]
> [ 2135.209430]v4l2_mmap+0x54/0x88 [videodev]
> [ 2135.214093]mmap_region+0x3a8/0x638
> [ 2135.218163]do_mmap+0x330/0x3a4
> [ 2135.221890]vm_mmap_pgoff+0x90/0xb8
> [ 2135.225962]SyS_mmap_pgoff+0x90/0xc0
> [ 2135.230122]ret_fast_syscall+0x0/0x28
> [ 2135.234366]
>other info that might help us debug this:
> 
> [ 2135.242339] Chain exists of:
>  >mfc_mutex --> >i_mutex_dir_key#2 --> 
> >mmap_sem
> 
> [ 2135.253690]  Possible unsafe locking scenario:
> 
> [ 2135.259583]CPU0CPU1
> [ 2135.264089]
> [ 2135.268594]   lock(>mmap_sem);
> [ 2135.271974]lock(>i_mutex_dir_key#2);
> [ 2135.278820]lock(>mmap_sem);
> [ 2135.284712]   lock(>mfc_mutex);
> [ 2135.288265]
> *** DEADLOCK ***
> 
> [ 2135.294159] 1 lock held by qtdemux0:sink/2700:
> [ 2135.298577]  #0:  (>mmap_sem){}, at: [] 
> vm_mmap_pgoff+0x44/0xb8
> [ 2135.306029]
>stack backtrace:
> [ 2135.310365] CPU: 7 PID: 2700 Comm: qtdemux0:sink Not tainted 4.14.0-rc2 #1
> [ 2135.317208] Hardware name: SAMSUNG EXYNOS (Flattened Device Tree)
> [ 2135.323282] [] (unwind_backtrace) from [] 
> (show_stack+0x10/0x14)
> [ 2135.330992] [] (show_stack) from [] 
> (dump_stack+0x98/0xc4)
> [ 2135.338184] [] (dump_stack) from [] 
> (print_circular_bug+0x254/0x410)
> [ 2135.346241] [] (print_circular_bug) from [] 
> (check_prev_add+0x468/0x938)
> [ 2135.354647] [] (check_prev_add) from [] 
> (__lock_acquire+0x1314/0x14fc)
> [ 2135.362878] [] (__lock_acquire) from [] 
> (lock_acquire+0x6c/0x88)
> [ 2135.370591] [] (lock_acquire) from [] 
> 

BUG: Hauppauge USB Live2 audio issues

2017-09-26 Thread Biff Eros
I get some errors loading the driver (modprobe cx231xx):

[ 8177.651308] cx231xx 2-3:1.1: New device Hauppauge Hauppauge Device
@ 480 Mbps (2040:c200) with 6 interfaces
[ 8177.651416] cx231xx 2-3:1.1: can't change interface 3 alt no. to 3:
Max. Pkt size = 0
[ 8177.651418] cx231xx 2-3:1.1: Identified as Hauppauge USB Live 2 (card=9)
[ 8177.652390] i2c i2c-10: Added multiplexed i2c bus 12
[ 8177.652525] i2c i2c-10: Added multiplexed i2c bus 13
[ 8177.737412] cx25840 9-0044: cx23102 A/V decoder found @ 0x88 (cx231xx #0-0)
[ 8179.800209] cx25840 9-0044: loaded v4l-cx231xx-avcore-01.fw
firmware (16382 bytes)
[ 8179.834337] cx231xx 2-3:1.1: v4l2 driver version 0.0.3
[ 8179.925757] cx231xx 2-3:1.1: Registered video device video0 [v4l2]
[ 8179.925974] cx231xx 2-3:1.1: Registered VBI device vbi0
[ 8179.925986] cx231xx 2-3:1.1: video EndPoint Addr 0x84, Alternate settings: 5
[ 8179.925991] cx231xx 2-3:1.1: VBI EndPoint Addr 0x85, Alternate settings: 2
[ 8179.925994] cx231xx 2-3:1.1: sliced CC EndPoint Addr 0x86,
Alternate settings: 2
[ 8179.926036] usbcore: registered new interface driver cx231xx
[ 8179.935145] cx231xx 2-3:1.1: audio EndPoint Addr 0x83, Alternate settings: 3
[ 8179.935147] cx231xx 2-3:1.1: Cx231xx Audio Extension initialized
[ 8179.984924] cx231xx 2-3:1.1: cx231xx_send_usb_command: failed with
status --32
[ 8180.031215] cx231xx 2-3:1.1: cx231xx_send_usb_command: failed with
status --22
[ 8180.037242] cx231xx 2-3:1.1: cx231xx_send_usb_command: failed with
status --22
[ 8180.196931] cx231xx 2-3:1.1: cx231xx_send_usb_command: failed with
status --22
[ 8180.197304] cx231xx 2-3:1.1: cx231xx_send_usb_command: failed with
status --22

I also get non-working sound some of the time, however video capture
with ffmpeg works quite well.  I have been testing using the following
capture command:

ffmpeg -thread_queue_size 512 -f alsa -i hw:2,0 -thread_queue_size 512 \
-f v4l2 -standard pal -i /dev/video0 -codec:v huffyuv -aspect 4:3  \
-codec:a pcm_s16le out.mkv

I've tried with 4.4.14, 4.9.45, 4.9.50.
Also tried: 4.13.0-rc4 (with linuxtv/master a couple of days ago).
They all do the same thing.

thanks,
Mark.


[GIT PULL for 4.15] Camera sensor patches

2017-09-26 Thread Sakari Ailus
Hi Mauro,

Here's the first set of camera sensor patches for 4.15.

There's one framework patch included, "media: Check for active and
has_no_links overrun".

Please pull.


The following changes since commit d5426f4c2ebac8cf05de43988c3fccddbee13d28:

  media: staging: atomisp: use clock framework for camera clocks (2017-09-23 
15:09:37 -0400)

are available in the git repository at:

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

for you to fetch changes up to a0b4db3ddd14b6202b2dba9dfa90572d6767b571:

  smiapp: Make clock control optional (2017-09-26 23:58:56 +0300)


Chiranjeevi Rapolu (4):
  media: ov5670: Use recommended black level and output bias
  media: ov5670: Fix not streaming issue after resume.
  media: ov13858: Calculate pixel-rate at runtime, use mode
  media: ov13858: Fix 4224x3136 video flickering at some vblanks

Colin Ian King (1):
  ov2640: make array reset_seq static, reduces object code size

Fabio Estevam (3):
  mt9m111: Propagate the real error on v4l2_clk_get() failure
  ov2640: Propagate the real error on devm_clk_get() failure
  ov2640: Check the return value from clk_prepare_enable()

Markus Elfring (7):
  ov2640: Delete an error message for a failed memory allocation in 
ov2640_probe()
  ov2640: Improve a size determination in ov2640_probe()
  ov6650: Delete an error message for a failed memory allocation in 
ov6650_probe()
  ov9640: Delete an error message for a failed memory allocation in 
ov9640_probe()
  ov9640: Improve a size determination in ov9640_probe()
  ov9740: Delete an error message for a failed memory allocation in 
ov9740_probe()
  ov9740: Improve a size determination in ov9740_probe()

Rajmohan Mani (1):
  dw9714: Set the v4l2 focus ctrl step as 1

Sakari Ailus (6):
  media: Check for active and has_no_links overrun
  ov13858: Use do_div() for dividing a 64-bit number
  smiapp: Fix error handling in power on sequence
  smiapp: Verify clock frequency after setting it, prevent changing it
  smiapp: Get clock rate if it's not available through DT
  smiapp: Make clock control optional

 drivers/media/i2c/dw9714.c |  7 +++-
 drivers/media/i2c/mt9m111.c|  2 +-
 drivers/media/i2c/ov13858.c| 59 +-
 drivers/media/i2c/ov2640.c | 15 -
 drivers/media/i2c/ov5670.c | 35 ++--
 drivers/media/i2c/ov6650.c |  5 +--
 drivers/media/i2c/smiapp/smiapp-core.c | 50 +---
 drivers/media/i2c/soc_camera/ov9640.c  |  7 ++--
 drivers/media/i2c/soc_camera/ov9740.c  |  6 ++--
 drivers/media/media-entity.c   | 13 +---
 10 files changed, 127 insertions(+), 72 deletions(-)


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


[PATCH 1/2] media: dvb-usb-v2: lmedm04: Improve logic checking of warm start.

2017-09-26 Thread Malcolm Priestley
Warm start has no check as whether a genuine device has
connected and proceeds to next execution path.

Check device should read 0x47 at offset of 2 on USB descriptor read
and it is the amount requested of 6 bytes.

Fix for
kasan: CONFIG_KASAN_INLINE enabled
kasan: GPF could be caused by NULL-ptr deref or user memory access as

Reported-by: Andrey Konovalov 
Signed-off-by: Malcolm Priestley 
---
 drivers/media/usb/dvb-usb-v2/lmedm04.c | 26 ++
 1 file changed, 18 insertions(+), 8 deletions(-)

diff --git a/drivers/media/usb/dvb-usb-v2/lmedm04.c 
b/drivers/media/usb/dvb-usb-v2/lmedm04.c
index 5e320fa4a795..992f2011a6ba 100644
--- a/drivers/media/usb/dvb-usb-v2/lmedm04.c
+++ b/drivers/media/usb/dvb-usb-v2/lmedm04.c
@@ -494,18 +494,23 @@ static int lme2510_pid_filter(struct dvb_usb_adapter 
*adap, int index, u16 pid,
 
 static int lme2510_return_status(struct dvb_usb_device *d)
 {
-   int ret = 0;
+   int ret;
u8 *data;
 
-   data = kzalloc(10, GFP_KERNEL);
+   data = kzalloc(6, GFP_KERNEL);
if (!data)
return -ENOMEM;
 
-   ret |= usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0),
-   0x06, 0x80, 0x0302, 0x00, data, 0x0006, 200);
-   info("Firmware Status: %x (%x)", ret , data[2]);
+   ret = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0),
+ 0x06, 0x80, 0x0302, 0x00,
+ data, 0x6, 200);
+   if (ret != 6)
+   ret = -EINVAL;
+   else
+   ret = data[2];
+
+   info("Firmware Status: %6ph", data);
 
-   ret = (ret < 0) ? -ENODEV : data[2];
kfree(data);
return ret;
 }
@@ -1189,6 +1194,7 @@ static int lme2510_get_adapter_count(struct 
dvb_usb_device *d)
 static int lme2510_identify_state(struct dvb_usb_device *d, const char **name)
 {
struct lme2510_state *st = d->priv;
+   int status;
 
usb_reset_configuration(d->udev);
 
@@ -1197,12 +1203,16 @@ static int lme2510_identify_state(struct dvb_usb_device 
*d, const char **name)
 
st->dvb_usb_lme2510_firmware = dvb_usb_lme2510_firmware;
 
-   if (lme2510_return_status(d) == 0x44) {
+   status = lme2510_return_status(d);
+   if (status == 0x44) {
*name = lme_firmware_switch(d, 0);
return COLD;
}
 
-   return 0;
+   if (status != 0x47)
+   return -EINVAL;
+
+   return WARM;
 }
 
 static int lme2510_get_stream_config(struct dvb_frontend *fe, u8 *ts_type,
-- 
2.14.1



[PATCH 2/2] media: dvb-usb-v2: lmedm04: move ts2020 attach to dm04_lme2510_tuner

2017-09-26 Thread Malcolm Priestley
When the tuner was split from m88rs2000 the attach function is in wrong
place.

Move to dm04_lme2510_tuner to trap errors on failure and removing
a call to lme_coldreset.

Prevents driver starting up without any tuner connected.

Fixes to trap for ts2020 fail.
LME2510(C): FE Found M88RS2000
ts2020: probe of 0-0060 failed with error -11
...
LME2510(C): TUN Found RS2000 tuner
kasan: CONFIG_KASAN_INLINE enabled
kasan: GPF could be caused by NULL-ptr deref or user memory access
general protection fault:  [#1] PREEMPT SMP KASAN

Reported-by: Andrey Konovalov 
Signed-off-by: Malcolm Priestley 
---
 drivers/media/usb/dvb-usb-v2/lmedm04.c | 13 ++---
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/drivers/media/usb/dvb-usb-v2/lmedm04.c 
b/drivers/media/usb/dvb-usb-v2/lmedm04.c
index 992f2011a6ba..be26c029546b 100644
--- a/drivers/media/usb/dvb-usb-v2/lmedm04.c
+++ b/drivers/media/usb/dvb-usb-v2/lmedm04.c
@@ -1076,8 +1076,6 @@ static int dm04_lme2510_frontend_attach(struct 
dvb_usb_adapter *adap)
 
if (adap->fe[0]) {
info("FE Found M88RS2000");
-   dvb_attach(ts2020_attach, adap->fe[0], _config,
-   >i2c_adap);
st->i2c_tuner_gate_w = 5;
st->i2c_tuner_gate_r = 5;
st->i2c_tuner_addr = 0x60;
@@ -1143,17 +1141,18 @@ static int dm04_lme2510_tuner(struct dvb_usb_adapter 
*adap)
ret = st->tuner_config;
break;
case TUNER_RS2000:
-   ret = st->tuner_config;
+   if (dvb_attach(ts2020_attach, adap->fe[0],
+  _config, >i2c_adap))
+   ret = st->tuner_config;
break;
default:
break;
}
 
-   if (ret)
+   if (ret) {
info("TUN Found %s tuner", tun_msg[ret]);
-   else {
-   info("TUN No tuner found --- resetting device");
-   lme_coldreset(d);
+   } else {
+   info("TUN No tuner found");
return -ENODEV;
}
 
-- 
2.14.1



Re: [PATCH v13 05/25] v4l: fwnode: Support generic parsing of graph endpoints in a device

2017-09-26 Thread Sakari Ailus
On Tue, Sep 19, 2017 at 03:34:00PM +0300, Laurent Pinchart wrote:
> Hi Sakari,
> 
> On Tuesday, 19 September 2017 15:11:32 EEST Sakari Ailus wrote:
> > On Tue, Sep 19, 2017 at 02:35:01PM +0300, Laurent Pinchart wrote:
> > > On Friday, 15 September 2017 17:17:04 EEST Sakari Ailus wrote:
> > >> Add two functions for parsing devices graph endpoints:
> > >> v4l2_async_notifier_parse_fwnode_endpoints and
> > >> v4l2_async_notifier_parse_fwnode_endpoints_by_port. The former iterates
> > >> over all endpoints whereas the latter only iterates over the endpoints
> > >> in a given port.
> > >> 
> > >> The former is mostly useful for existing drivers that currently
> > >> implement the iteration over all the endpoints themselves whereas the
> > >> latter is especially intended for devices with both sinks and sources:
> > >> async sub-devices for external devices connected to the device's sources
> > >> will have already been set up, or they are part of the master device.
> > > 
> > > Did you mean s/or they/as they/ ?
> > 
> > No. There are two options here: either the sub-devices a sub-device is
> > connected to (through a graph endpoint) is instantiated through the async
> > framework *or* through the master device driver. But not by both of them at
> > the same time.
> 
> The message is then contradicting itself:
> 
> "async sub-devices for external devices connected to the device's sources 
> will 
> have already been set up, or they are part of the master device."
> 
> They refers to "async sub-devices". If they're part of the master device, 
> they're not async sub-devices.

Ah, now I see what you mean. I'll replace "they" with "the external
sub-devices". The paragraph becomes:

The former is mostly useful for existing drivers that currently implement
the iteration over all the endpoints themselves whereas the latter is
especially intended for devices with both sinks and sources: async
sub-devices for external devices connected to the device's sources will
have already been set up, or the external sub-devices are part of the  
master device.

How about that?

-- 
Regards,

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


Re: [PATCH 09/10] scripts: kernel-doc: parse next structs/unions

2017-09-26 Thread Mauro Carvalho Chehab
Em Tue, 26 Sep 2017 14:59:19 -0300
Mauro Carvalho Chehab  escreveu:

> There are several places within the Kernel tree with nested
> structs/unions, like this one:
> 
>   struct ingenic_cgu_clk_info {
> const char *name;
> enum {
>   CGU_CLK_NONE = 0,
>   CGU_CLK_EXT = BIT(0),
>   CGU_CLK_PLL = BIT(1),
>   CGU_CLK_GATE = BIT(2),
>   CGU_CLK_MUX = BIT(3),
>   CGU_CLK_MUX_GLITCHFREE = BIT(4),
>   CGU_CLK_DIV = BIT(5),
>   CGU_CLK_FIXDIV = BIT(6),
>   CGU_CLK_CUSTOM = BIT(7),
> } type;
> int parents[4];
> union {
>   struct ingenic_cgu_pll_info pll;
>   struct {
> struct ingenic_cgu_gate_info gate;
> struct ingenic_cgu_mux_info mux;
> struct ingenic_cgu_div_info div;
> struct ingenic_cgu_fixdiv_info fixdiv;
>   };
>   struct ingenic_cgu_custom_info custom;
> };
>   };
> 
> Currently, such struct is documented as:
> 
>   **Definition**
> 
>   ::
>   struct ingenic_cgu_clk_info {
>   const char * name;
>   };
> 
>   **Members**
> 
>   ``name``
> name of the clock
> 
> With is obvioulsy wrong. It also generates an error:
>   drivers/clk/ingenic/cgu.h:169: warning: No description found for 
> parameter 'enum'
> 
> However, there's nothing wrong with this kernel-doc markup: everything
> is documented there.
> 
> It makes sense to document all fields there. So, add a
> way for the core to parse those structs.
> 
> With this patch, all documented fields will properly generate
> documentation.
> 
> Signed-off-by: Mauro Carvalho Chehab 
> ---
>  Documentation/doc-guide/kernel-doc.rst |  46 +
>  scripts/kernel-doc | 120 
> ++---
>  2 files changed, 112 insertions(+), 54 deletions(-)
> 
> diff --git a/Documentation/doc-guide/kernel-doc.rst 
> b/Documentation/doc-guide/kernel-doc.rst
> index 50473f0db345..3916a28b82b7 100644
> --- a/Documentation/doc-guide/kernel-doc.rst
> +++ b/Documentation/doc-guide/kernel-doc.rst
> @@ -281,6 +281,52 @@ comment block.
>  The kernel-doc data structure comments describe each member of the structure,
>  in order, with the member descriptions.
>  
> +Nested structs/unions
> +~
> +
> +It is possible to document nested structs unions, like::
> +
> +  /**
> +   * struct nested_foobar - a struct with nested unions and structs
> +   * @arg1: - first argument of anonymous union/anonymous struct
> +   * @arg2: - second argument of anonymous union/anonymous struct
> +   * @arg3: - third argument of anonymous union/anonymous struct
> +   * @arg4: - fourth argument of anonymous union/anonymous struct
> +   * @bar.st1.arg1 - first argument of struct st1 on union bar
> +   * @bar.st1.arg2 - second argument of struct st1 on union bar
> +   * @bar.st2.arg1 - first argument of struct st2 on union bar
> +   * @bar.st2.arg2 - second argument of struct st2 on union bar
> +  struct nested_foobar {
> +/* Anonymous union/struct*/
> +union {
> +  struct {
> +int arg1;
> +int arg2;
> +   }
> +  struct {
> +void *arg3;
> +int arg4;
> +   }
> + }
> + union {
> +  struct {
> +int arg1;
> +int arg2;
> +   } st1;
> +  struct {
> +void *arg1;
> +int arg2;
> +   } st2;
> + } bar;
> +  };
> +
> +.. note::
> +
> +   #) When documenting nested structs or unions, if the struct/union ``foo``
> +  is named, the argument ``bar`` inside it should be documented as
> +  ``@foo.bar:``
> +   #) When the nested struct/union is anonymous, the argument ``bar`` on it
> +  should be documented as ``@bar:``
>  
>  Typedef documentation
>  -
> diff --git a/scripts/kernel-doc b/scripts/kernel-doc
> index b6f3f6962897..880a196c7dc7 100755
> --- a/scripts/kernel-doc
> +++ b/scripts/kernel-doc
> @@ -210,7 +210,7 @@ my $anon_struct_union = 0;
>  my $type_constant = '\b``([^\`]+)``\b';
>  my $type_constant2 = '\%([-_\w]+)';
>  my $type_func = '(\w+)\(\)';
> -my $type_param = '\@(\w+(\.\.\.)?)';
> +my $type_param = '\@(\w[\.\w]*(\.\.\.)?)';
>  my $type_fp_param = '\@(\w+)\(\)';  # Special RST handling for func ptr 
> params
>  my $type_env = '(\$\w+)';
>  my $type_enum = '\&(enum\s*([_\w]+))';
> @@ -663,32 +663,12 @@ sub output_struct_man(%) {
>  print ".SH NAME\n";
>  print $args{'type'} . " " . $args{'struct'} . " \\- " . $args{'purpose'} 
> . "\n";
>  
> +my $declaration = $args{'definition'};
> +$declaration =~ s/\t/  /g;
> +$declaration =~ s/\n/"\n.br\n.BI \"/g;
>  print ".SH SYNOPSIS\n";
>  print $args{'type'} . " " . $args{'struct'} . " {\n.br\n";
> -
> -foreach my $parameter (@{$args{'parameterlist'}}) {
> - if ($parameter =~ /^#/) {
> - print ".BI 

[PATCH 03/20] media: rc: auto load encoder if necessary

2017-09-26 Thread Sean Young
When sending scancodes, load the encoder if we need it.

Signed-off-by: Sean Young 
---
 drivers/media/rc/rc-core-priv.h | 1 +
 drivers/media/rc/rc-ir-raw.c| 2 ++
 drivers/media/rc/rc-main.c  | 2 +-
 3 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/media/rc/rc-core-priv.h b/drivers/media/rc/rc-core-priv.h
index 3cf09408df6c..d29b1b1ef4b7 100644
--- a/drivers/media/rc/rc-core-priv.h
+++ b/drivers/media/rc/rc-core-priv.h
@@ -271,6 +271,7 @@ void ir_raw_event_free(struct rc_dev *dev);
 void ir_raw_event_unregister(struct rc_dev *dev);
 int ir_raw_handler_register(struct ir_raw_handler *ir_raw_handler);
 void ir_raw_handler_unregister(struct ir_raw_handler *ir_raw_handler);
+void ir_raw_load_modules(u64 *protocols);
 void ir_raw_init(void);
 
 /*
diff --git a/drivers/media/rc/rc-ir-raw.c b/drivers/media/rc/rc-ir-raw.c
index 0814e08a280b..b84201cb012a 100644
--- a/drivers/media/rc/rc-ir-raw.c
+++ b/drivers/media/rc/rc-ir-raw.c
@@ -457,6 +457,8 @@ int ir_raw_encode_scancode(enum rc_proto protocol, u32 
scancode,
int ret = -EINVAL;
u64 mask = 1ULL << protocol;
 
+   ir_raw_load_modules();
+
mutex_lock(_raw_handler_lock);
list_for_each_entry(handler, _raw_handler_list, list) {
if (handler->protocols & mask && handler->encode) {
diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c
index cb78e5702bef..62102b3ef5aa 100644
--- a/drivers/media/rc/rc-main.c
+++ b/drivers/media/rc/rc-main.c
@@ -1081,7 +1081,7 @@ static int parse_protocol_change(u64 *protocols, const 
char *buf)
return count;
 }
 
-static void ir_raw_load_modules(u64 *protocols)
+void ir_raw_load_modules(u64 *protocols)
 {
u64 available;
int i, ret;
-- 
2.13.5



[PATCH 01/20] media: lirc: implement scancode sending

2017-09-26 Thread Sean Young
This introduces a new lirc mode: scancode. Any device which can send raw IR
can now also send scancodes.

int main()
{
int mode, fd = open("/dev/lirc0", O_RDWR);

mode = LIRC_MODE_SCANCODE;
if (ioctl(fd, LIRC_SET_SEND_MODE, )) {
// kernel too old or lirc does not support transmit
}
struct lirc_scancode scancode = {
.scancode = 0x1e3d,
.rc_proto = RC_TYPE_RC5,
};
write(fd, , sizeof(scancode));
close(fd);
}

The other fields of lirc_scancode must be set to 0.

Note that toggle (rc5, rc6) and repeats (nec) are not implemented. Nor is
there a method for holding down a key for a period.

Signed-off-by: Sean Young 
---
 drivers/media/rc/ir-lirc-codec.c | 72 +--
 drivers/media/rc/rc-core-priv.h  |  2 +-
 include/media/rc-map.h   | 54 +--
 include/uapi/linux/lirc.h| 93 
 4 files changed, 153 insertions(+), 68 deletions(-)

diff --git a/drivers/media/rc/ir-lirc-codec.c b/drivers/media/rc/ir-lirc-codec.c
index bd046c41a53a..770d768824f4 100644
--- a/drivers/media/rc/ir-lirc-codec.c
+++ b/drivers/media/rc/ir-lirc-codec.c
@@ -107,7 +107,8 @@ static ssize_t ir_lirc_transmit_ir(struct file *file, const 
char __user *buf,
 {
struct lirc_codec *lirc;
struct rc_dev *dev;
-   unsigned int *txbuf; /* buffer with values to transmit */
+   unsigned int *txbuf = NULL;
+   struct ir_raw_event *raw = NULL;
ssize_t ret = -EINVAL;
size_t count;
ktime_t start;
@@ -121,16 +122,51 @@ static ssize_t ir_lirc_transmit_ir(struct file *file, 
const char __user *buf,
if (!lirc)
return -EFAULT;
 
-   if (n < sizeof(unsigned) || n % sizeof(unsigned))
-   return -EINVAL;
+   if (lirc->send_mode == LIRC_MODE_SCANCODE) {
+   struct lirc_scancode scan;
 
-   count = n / sizeof(unsigned);
-   if (count > LIRCBUF_SIZE || count % 2 == 0)
-   return -EINVAL;
+   if (n != sizeof(scan))
+   return -EINVAL;
+
+   if (copy_from_user(, buf, sizeof(scan)))
+   return -EFAULT;
+
+   if (scan.flags || scan.source || scan.target || scan.unused ||
+   scan.timestamp)
+   return -EINVAL;
 
-   txbuf = memdup_user(buf, n);
-   if (IS_ERR(txbuf))
-   return PTR_ERR(txbuf);
+   raw = kmalloc_array(LIRCBUF_SIZE, sizeof(*raw), GFP_KERNEL);
+   if (!raw)
+   return -ENOMEM;
+
+   ret = ir_raw_encode_scancode(scan.rc_proto, scan.scancode,
+raw, LIRCBUF_SIZE);
+   if (ret < 0)
+   goto out;
+
+   count = ret;
+
+   txbuf = kmalloc_array(count, sizeof(unsigned int), GFP_KERNEL);
+   if (!txbuf) {
+   ret = -ENOMEM;
+   goto out;
+   }
+
+   for (i = 0; i < count; i++)
+   /* Convert from NS to US */
+   txbuf[i] = DIV_ROUND_UP(raw[i].duration, 1000);
+   } else {
+   if (n < sizeof(unsigned int) || n % sizeof(unsigned int))
+   return -EINVAL;
+
+   count = n / sizeof(unsigned int);
+   if (count > LIRCBUF_SIZE || count % 2 == 0)
+   return -EINVAL;
+
+   txbuf = memdup_user(buf, n);
+   if (IS_ERR(txbuf))
+   return PTR_ERR(txbuf);
+   }
 
dev = lirc->dev;
if (!dev) {
@@ -159,7 +195,10 @@ static ssize_t ir_lirc_transmit_ir(struct file *file, 
const char __user *buf,
for (duration = i = 0; i < ret; i++)
duration += txbuf[i];
 
-   ret *= sizeof(unsigned int);
+   if (lirc->send_mode == LIRC_MODE_SCANCODE)
+   ret = n;
+   else
+   ret *= sizeof(unsigned int);
 
/*
 * The lircd gap calculation expects the write function to
@@ -174,6 +213,7 @@ static ssize_t ir_lirc_transmit_ir(struct file *file, const 
char __user *buf,
 
 out:
kfree(txbuf);
+   kfree(raw);
return ret;
 }
 
@@ -202,20 +242,22 @@ static long ir_lirc_ioctl(struct file *filep, unsigned 
int cmd,
 
switch (cmd) {
 
-   /* legacy support */
+   /* mode support */
case LIRC_GET_SEND_MODE:
if (!dev->tx_ir)
return -ENOTTY;
 
-   val = LIRC_MODE_PULSE;
+   val = lirc->send_mode;
break;
 
case LIRC_SET_SEND_MODE:
if (!dev->tx_ir)
return -ENOTTY;
 
-   if (val != LIRC_MODE_PULSE)
+   if (!(val == LIRC_MODE_PULSE || val == LIRC_MODE_SCANCODE))

[PATCH 2/5] ir-ctl: show scancode lirc features

2017-09-26 Thread Sean Young
Report if a lirc devices can receive or send using scancodes.

Signed-off-by: Sean Young 
---
 utils/ir-ctl/ir-ctl.c | 30 --
 1 file changed, 24 insertions(+), 6 deletions(-)

diff --git a/utils/ir-ctl/ir-ctl.c b/utils/ir-ctl/ir-ctl.c
index 7dcdd983..32d7162f 100644
--- a/utils/ir-ctl/ir-ctl.c
+++ b/utils/ir-ctl/ir-ctl.c
@@ -691,7 +691,12 @@ static void lirc_features(struct arguments *args, int fd, 
unsigned features)
fprintf(stderr, _("warning: %s: unexpected error while 
retrieving resolution: %m\n"), dev);
}
 
+   bool can_receive = false;
printf(_("Receive features %s:\n"), dev);
+   if (features & LIRC_CAN_REC_SCANCODE) {
+   printf(_(" - Device can receive scancodes\n"));
+   can_receive = true;
+   }
if (features & LIRC_CAN_REC_MODE2) {
printf(_(" - Device can receive raw IR\n"));
if (resolution)
@@ -721,13 +726,22 @@ static void lirc_features(struct arguments *args, int fd, 
unsigned features)
if (min_timeout || max_timeout)
printf(_(" - Can set recording timeout min:%u 
microseconds max:%u microseconds\n"), min_timeout, max_timeout);
}
-   } else if (features & LIRC_CAN_REC_LIRCCODE) {
+   can_receive = true;
+   }
+   if (features & LIRC_CAN_REC_LIRCCODE) {
printf(_(" - Device can receive using device dependent LIRCCODE 
mode (not supported)\n"));
-   } else {
-   printf(_(" - Device cannot receive\n"));
+   can_receive = true;
}
 
+   if (!can_receive)
+   printf(_(" - Device cannot receive\n"));
+
+   bool can_send = false;
printf(_("Send features %s:\n"), dev);
+   if (features & LIRC_CAN_SEND_SCANCODE) {
+   printf(_(" - Device can send scancodes\n"));
+   can_send = true;
+   }
if (features & LIRC_CAN_SEND_PULSE) {
printf(_(" - Device can send raw IR\n"));
if (features & LIRC_CAN_SET_SEND_CARRIER)
@@ -744,11 +758,15 @@ static void lirc_features(struct arguments *args, int fd, 
unsigned features)
else
printf(_(" - Set transmitter (%d 
available)\n"), rc);
}
-   } else if (features & LIRC_CAN_SEND_LIRCCODE) {
+   can_send = true;
+   }
+   if (features & LIRC_CAN_SEND_LIRCCODE) {
printf(_(" - Device can send using device dependent LIRCCODE 
mode (not supported)\n"));
-   } else {
-   printf(_(" - Device cannot send\n"));
+   can_send = true;
}
+
+   if (!can_send)
+   printf(_(" - Device cannot send\n"));
 }
 
 static int lirc_send(struct arguments *args, int fd, unsigned features, struct 
file *f)
-- 
2.13.5



[PATCH 4/5] ir-ctl: implement scancode reading

2017-09-26 Thread Sean Young
Signed-off-by: Sean Young 
---
 utils/ir-ctl/ir-ctl.c| 188 +--
 utils/ir-ctl/ir-encode.c |   4 +
 2 files changed, 135 insertions(+), 57 deletions(-)

diff --git a/utils/ir-ctl/ir-ctl.c b/utils/ir-ctl/ir-ctl.c
index f0dcd2a3..f9cf30a3 100644
--- a/utils/ir-ctl/ir-ctl.c
+++ b/utils/ir-ctl/ir-ctl.c
@@ -24,6 +24,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 
@@ -840,24 +841,122 @@ static int lirc_send(struct arguments *args, int fd, 
unsigned features, struct f
return 0;
 }
 
-int lirc_record(struct arguments *args, int fd, unsigned features)
+static bool keep_reading = true;
+static bool leading_space = true;
+
+int lirc_record_mode2(FILE *out, int fd, struct arguments *args)
 {
-   char *dev = args->device;
-   FILE *out = stdout;
-   int rc = EX_IOERR;
int mode = LIRC_MODE_MODE2;
+   unsigned buf[LIRCBUF_SIZE];
+   char *dev = args->device;
+   ssize_t ret;
 
-   if (!(features & LIRC_CAN_REC_MODE2)) {
-   fprintf(stderr, _("%s: device cannot record raw ir\n"), dev);
-   return EX_UNAVAILABLE;
+   // some kernel versions return errors, ignore them
+   ioctl(fd, LIRC_SET_REC_MODE, );
+
+   ret = TEMP_FAILURE_RETRY(read(fd, buf, sizeof(buf)));
+   if (ret < 0) {
+   fprintf(stderr, _("%s: failed read: %m\n"), dev);
+   return EX_IOERR;
}
 
-   // kernel v4.8 and v4.9 return ENOTTY
-   if (ioctl(fd, LIRC_SET_REC_MODE, ) && errno != ENOTTY) {
-   fprintf(stderr, _("%s: failed to set record mode: %m\n"), dev);
+   if (ret == 0 || ret % sizeof(unsigned)) {
+   fprintf(stderr, _("%s: read returned %zd bytes\n"), dev, ret);
+   return EX_IOERR;
+   }
+
+   for (int i=0; ioneshot &&
+   (msg == LIRC_MODE2_TIMEOUT ||
+   (msg == LIRC_MODE2_SPACE && val > 19000))) {
+   keep_reading = false;
+   break;
+   }
+
+   switch (msg) {
+   case LIRC_MODE2_TIMEOUT:
+   fprintf(out, "timeout %u\n", val);
+   leading_space = true;
+   break;
+   case LIRC_MODE2_PULSE:
+   fprintf(out, "pulse %u\n", val);
+   break;
+   case LIRC_MODE2_SPACE:
+   fprintf(out, "space %u\n", val);
+   break;
+   case LIRC_MODE2_FREQUENCY:
+   fprintf(out, "carrier %u\n", val);
+   break;
+   }
+
+   fflush(out);
+   }
+
+   return 0;
+}
+
+int lirc_record_scancode(FILE *out, int fd, const char *dev)
+{
+   struct lirc_scancode sc[32];
+   int mode = LIRC_MODE_SCANCODE;
+   ssize_t ret;
+
+   ret = ioctl(fd, LIRC_SET_REC_MODE, );
+   if (ret < 0) {
+   fprintf(stderr, _("%s: failed set recording mode: %m\n"), dev);
+   return EX_IOERR;
+   }
+
+   ret = TEMP_FAILURE_RETRY(read(fd, sc, sizeof sc));
+   if (ret < 0) {
+   fprintf(stderr, _("%s: failed read: %m\n"), dev);
return EX_IOERR;
}
 
+   if (ret == 0 || ret % sizeof sc[0]) {
+   fprintf(stderr, _("%s: read returned %zd bytes\n"), dev, ret);
+   return EX_IOERR;
+   }
+
+   for (int i=0; idevice;
+   FILE *out = stdout;
+   int rc = 0;
+   ssize_t ret;
+
+   if (!(features & (LIRC_CAN_REC_MODE2 | LIRC_CAN_REC_SCANCODE))) {
+   fprintf(stderr, _("%s: device cannot receive\n"), dev);
+   return EX_UNAVAILABLE;
+   }
+
if (args->savetofile) {
out = fopen(args->savetofile, "w");
if (!out) {
@@ -865,65 +964,40 @@ int lirc_record(struct arguments *args, int fd, unsigned 
features)
return EX_CANTCREAT;
}
}
-   unsigned buf[LIRCBUF_SIZE];
-
-   bool keep_reading = true;
-   bool leading_space = true;
 
while (keep_reading) {
-   ssize_t ret = TEMP_FAILURE_RETRY(read(fd, buf, sizeof(buf)));
-   if (ret < 0) {
-   fprintf(stderr, _("%s: failed read: %m\n"), dev);
-   goto err;
-   }
-
-   if (ret == 0 || ret % sizeof(unsigned)) {
-   fprintf(stderr, _("%s: read returned %zd bytes\n"),
-   dev, ret);
-   goto err;
+   if (features & LIRC_CAN_REC_SCANCODE) {
+   unsigned mode = LIRC_MODE_MODE2 | LIRC_MODE_SCANCODE;
+   if (ioctl(fd, LIRC_SET_POLL_MODE, )) {
+   fprintf(stderr, _("%s: set poll mode failed: 
%m\n"), dev);
+   rc = 

[PATCH 3/5] ir-ctl: use lirc scancode sending

2017-09-26 Thread Sean Young
Signed-off-by: Sean Young 
---
 utils/ir-ctl/ir-ctl.c | 79 +--
 1 file changed, 52 insertions(+), 27 deletions(-)

diff --git a/utils/ir-ctl/ir-ctl.c b/utils/ir-ctl/ir-ctl.c
index 32d7162f..f0dcd2a3 100644
--- a/utils/ir-ctl/ir-ctl.c
+++ b/utils/ir-ctl/ir-ctl.c
@@ -66,9 +66,18 @@ const char *argp_program_bug_address = "Sean Young 
";
 struct file {
struct file *next;
const char *fname;
-   unsigned carrier;
-   unsigned len;
-   unsigned buf[LIRCBUF_SIZE];
+   bool is_scancode;
+   union {
+   struct {
+   unsigned carrier;
+   unsigned len;
+   unsigned buf[LIRCBUF_SIZE];
+   };
+   struct {
+   unsigned scancode;
+   unsigned protocol;
+   };
+   };
 };
 
 struct arguments {
@@ -187,7 +196,7 @@ static unsigned parse_emitters(char *p)
 
 static struct file *read_file(const char *fname)
 {
-   bool expect_pulse = true, seen_scancode = false;
+   bool expect_pulse = true;
int lineno = 0, lastspace = 0;
char line[1024];
int len = 0;
@@ -206,6 +215,7 @@ static struct file *read_file(const char *fname)
fprintf(stderr, _("Failed to allocate memory\n"));
return NULL;
}
+   f->is_scancode = false;
f->carrier = 0;
f->fname = fname;
 
@@ -226,7 +236,7 @@ static struct file *read_file(const char *fname)
 
if (strcmp(keyword, "scancode") == 0) {
enum rc_proto proto;
-   unsigned scancode, carrier;
+   unsigned scancode;
char *scancodestr;
 
if (len) {
@@ -257,19 +267,9 @@ static struct file *read_file(const char *fname)
return NULL;
}
 
-   if (len + protocol_max_size(proto) >= LIRCBUF_SIZE) {
-   fprintf(stderr, _("error: %s:%d: too much IR 
for one transmit\n"), fname, lineno);
-   return NULL;
-   }
-
-   carrier = protocol_carrier(proto);
-   if (f->carrier && f->carrier != carrier)
-   fprintf(stderr, _("error: %s:%d: carrier 
already specified\n"), fname, lineno);
-   else
-   f->carrier = carrier;
-
-   len += protocol_encode(proto, scancode, f->buf);
-   seen_scancode = true;
+   f->is_scancode = true;
+   f->scancode = scancode;
+   f->protocol = proto;
continue;
}
 
@@ -285,7 +285,7 @@ static struct file *read_file(const char *fname)
continue;
}
 
-   if (seen_scancode) {
+   if (f->is_scancode) {
fprintf(stderr, _("error: %s:%d: scancode must be 
appear in file by itself\n"), fname, lineno);
return NULL;
}
@@ -383,9 +383,9 @@ static struct file *read_scancode(const char *name)
return NULL;
}
 
-   f->carrier = protocol_carrier(proto);
-   f->fname = name;
-   f->len = protocol_encode(proto, scancode, f->buf);
+   f->is_scancode = true;
+   f->scancode = scancode;
+   f->protocol = proto;
 
return f;
 }
@@ -772,16 +772,41 @@ static void lirc_features(struct arguments *args, int fd, 
unsigned features)
 static int lirc_send(struct arguments *args, int fd, unsigned features, struct 
file *f)
 {
const char *dev = args->device;
-   int mode = LIRC_MODE_PULSE;
+   int rc, mode;
+   ssize_t ret;
+
+   if (f->is_scancode && (features & LIRC_CAN_SEND_SCANCODE)) {
+   mode = LIRC_MODE_SCANCODE;
+   rc = ioctl(fd, LIRC_SET_SEND_MODE, );
+   if (rc == 0) {
+   struct lirc_scancode sc = {
+   .scancode = f->scancode,
+   .rc_proto = f->protocol,
+   .flags = 0
+   };
+   ret = TEMP_FAILURE_RETRY(write(fd, , sizeof sc));
+   if (ret > 0)
+   return 0;
+   }
+   }
 
if (!(features & LIRC_CAN_SEND_PULSE)) {
fprintf(stderr, _("%s: device cannot send raw ir\n"), dev);
return EX_UNAVAILABLE;
}
 
-   if (ioctl(fd, LIRC_SET_SEND_MODE, )) {
-   fprintf(stderr, _("%s: failed to set send mode: %m\n"), dev);
-   return EX_IOERR;
+   mode = LIRC_MODE_PULSE;
+   rc = ioctl(fd, LIRC_SET_SEND_MODE, );
+   if (rc) {
+

[PATCH 5/5] keytable: show lirc device and make test show lirc scancodes

2017-09-26 Thread Sean Young
Now you can see what protocol any remote is using the following command.

$ ir-keytable -c -p all -t
Old keytable cleared
Protocols changed to lirc rc-5 rc-5-sz jvc sony nec sanyo mce_kbd rc-6 sharp xmp
Testing events. Please, press CTRL-C to abort.
2124.576099: lirc protocol(rc5): scancode = 0x1e11
2124.576143: event type EV_MSC(0x04): scancode = 0x1e11
2124.576143: event type EV_SYN(0x00).
2125.601002: lirc protocol(rc6_mce): scancode = 0x800f0410
2125.601051: event type EV_MSC(0x04): scancode = 0x800f0410
2125.601051: event type EV_SYN(0x00).

Signed-off-by: Sean Young 
---
 utils/keytable/keytable.c | 140 --
 1 file changed, 134 insertions(+), 6 deletions(-)

diff --git a/utils/keytable/keytable.c b/utils/keytable/keytable.c
index 5d12ec31..f0744c6a 100644
--- a/utils/keytable/keytable.c
+++ b/utils/keytable/keytable.c
@@ -18,13 +18,16 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #include "parse.h"
@@ -270,6 +273,7 @@ static int sysfs = 0;
 struct rc_device {
char *sysfs_name;   /* Device sysfs node name */
char *input_name;   /* Input device file name */
+   char *lirc_name;/* Lirc device file name */
char *drv_name; /* Kernel driver that implements it */
char *keytable_name;/* Keycode table name */
 
@@ -1016,15 +1020,33 @@ static int v2_set_protocols(struct rc_device *rc_dev)
 static int get_attribs(struct rc_device *rc_dev, char *sysfs_name)
 {
struct uevents  *uevent;
-   char*input = "input", *event = "event";
+   char*input = "input", *event = "event", *lirc = "lirc";
char*DEV = "/dev/";
-   static struct sysfs_names *input_names, *event_names, *attribs, *cur;
+   static struct sysfs_names *input_names, *event_names, *attribs, *cur, 
*lirc_names;
 
/* Clean the attributes */
memset(rc_dev, 0, sizeof(*rc_dev));
 
rc_dev->sysfs_name = sysfs_name;
 
+   lirc_names = seek_sysfs_dir(rc_dev->sysfs_name, lirc);
+   if (lirc_names) {
+   uevent = read_sysfs_uevents(lirc_names->name);
+   free_names(lirc_names);
+   if (uevent) {
+   while (uevent->next) {
+   if (!strcmp(uevent->key, "DEVNAME")) {
+   rc_dev->lirc_name = 
malloc(strlen(uevent->value) + strlen(DEV) + 1);
+   strcpy(rc_dev->lirc_name, DEV);
+   strcat(rc_dev->lirc_name, 
uevent->value);
+   break;
+   }
+   uevent = uevent->next;
+   }
+   free_uevent(uevent);
+   }
+   }
+
input_names = seek_sysfs_dir(rc_dev->sysfs_name, input);
if (!input_names)
return EINVAL;
@@ -1262,16 +1284,119 @@ static char *get_event_name(struct parse_event *event, 
u_int16_t code)
return "";
 }
 
-static void test_event(int fd)
+static void print_scancodes(const struct lirc_scancode *scancodes, unsigned 
count)
+{
+   unsigned i;
+
+   for (i=0; i< count; i++)  {
+   const char *p;
+   switch (scancodes[i].rc_proto) {
+   case RC_PROTO_UNKNOWN: p = "unknown"; break;
+   case RC_PROTO_OTHER: p = "other"; break;
+   case RC_PROTO_RC5: p = "rc5"; break;
+   case RC_PROTO_RC5X_20: p = "rc5x_20"; break;
+   case RC_PROTO_RC5_SZ: p = "rc5_sz"; break;
+   case RC_PROTO_JVC: p = "jvc"; break;
+   case RC_PROTO_SONY12: p = "sony12"; break;
+   case RC_PROTO_SONY15: p = "sony15"; break;
+   case RC_PROTO_SONY20: p = "sony20"; break;
+   case RC_PROTO_NEC: p = "nec"; break;
+   case RC_PROTO_NECX: p = "necx"; break;
+   case RC_PROTO_NEC32: p = "nec32"; break;
+   case RC_PROTO_SANYO: p = "sanyo"; break;
+   case RC_PROTO_MCIR2_KBD: p = "mcir2_kbd"; break;
+   case RC_PROTO_MCIR2_MSE: p = "mcri2_mse"; break;
+   case RC_PROTO_RC6_0: p = "rc6_0"; break;
+   case RC_PROTO_RC6_6A_20: p = "rc6_6a_20"; break;
+   case RC_PROTO_RC6_6A_24: p = "rc6_6a_24"; break;
+   case RC_PROTO_RC6_6A_32: p = "rc6_6a_32"; break;
+   case RC_PROTO_RC6_MCE: p = "rc6_mce"; break;
+   case RC_PROTO_SHARP: p = "sharp"; break;
+   case RC_PROTO_XMP: p = "xmp"; break;
+   case RC_PROTO_CEC: p = "cec"; break;
+

[PATCH 1/5] ir-ctl: a pulse space file cannot contain scancode and raw IR

2017-09-26 Thread Sean Young
This simplifies dealing with kernel encoders and raw IR, and does
not make much sense anyway.

Signed-off-by: Sean Young 
---
 utils/ir-ctl/ir-ctl.1.in |  7 ++-
 utils/ir-ctl/ir-ctl.c| 12 +---
 2 files changed, 11 insertions(+), 8 deletions(-)

diff --git a/utils/ir-ctl/ir-ctl.1.in b/utils/ir-ctl/ir-ctl.1.in
index 05550fb1..401521da 100644
--- a/utils/ir-ctl/ir-ctl.1.in
+++ b/utils/ir-ctl/ir-ctl.1.in
@@ -168,11 +168,8 @@ carrier. The above can be written as:
 .PP
scancode rc5:0x1e01
 .PP
-Do not specify scancodes with different protocols in one file, as the
-carrier might differ and the transmitter cannot send this. Multiple
-scancodes can be specified in one file but ensure that the rules for the
-protocol are met by inserting an appropriate space between them. Also,
-there are limits to what lirc devices can send in one go.
+If you specify a scancode in a pulse space file, no other pulse, space or
+even carrier may be specified.
 .PP
 .SS Supported Protocols
 A scancode with protocol can be specified on the command line or in the
diff --git a/utils/ir-ctl/ir-ctl.c b/utils/ir-ctl/ir-ctl.c
index d3cce6a6..7dcdd983 100644
--- a/utils/ir-ctl/ir-ctl.c
+++ b/utils/ir-ctl/ir-ctl.c
@@ -187,7 +187,7 @@ static unsigned parse_emitters(char *p)
 
 static struct file *read_file(const char *fname)
 {
-   bool expect_pulse = true;
+   bool expect_pulse = true, seen_scancode = false;
int lineno = 0, lastspace = 0;
char line[1024];
int len = 0;
@@ -229,8 +229,8 @@ static struct file *read_file(const char *fname)
unsigned scancode, carrier;
char *scancodestr;
 
-   if (!expect_pulse) {
-   fprintf(stderr, _("error: %s:%d: space must 
precede scancode\n"), fname, lineno);
+   if (len) {
+   fprintf(stderr, _("error: %s:%d: scancode must 
be appear in file by itself\n"), fname, lineno);
return NULL;
}
 
@@ -269,6 +269,7 @@ static struct file *read_file(const char *fname)
f->carrier = carrier;
 
len += protocol_encode(proto, scancode, f->buf);
+   seen_scancode = true;
continue;
}
 
@@ -284,6 +285,11 @@ static struct file *read_file(const char *fname)
continue;
}
 
+   if (seen_scancode) {
+   fprintf(stderr, _("error: %s:%d: scancode must be 
appear in file by itself\n"), fname, lineno);
+   return NULL;
+   }
+
if (strcmp(keyword, "space") == 0) {
if (expect_pulse) {
if (len == 0) {
-- 
2.13.5



[PATCH 08/20] media: lirc: remove LIRCCODE and LIRC_GET_LENGTH

2017-09-26 Thread Sean Young
LIRCCODE is a lirc mode where a driver produces driver-dependent
codes for record and transmit. No driver use this any more. The
LIRC_GET_LENGTH ioctl was used for this mode only.

Signed-off-by: Sean Young 
---
 Documentation/media/uapi/rc/lirc-dev-intro.rst | 15 
 Documentation/media/uapi/rc/lirc-func.rst  |  1 -
 Documentation/media/uapi/rc/lirc-get-features.rst  |  7 +---
 Documentation/media/uapi/rc/lirc-get-length.rst| 44 --
 Documentation/media/uapi/rc/lirc-get-rec-mode.rst  |  4 +-
 Documentation/media/uapi/rc/lirc-get-send-mode.rst |  3 +-
 drivers/media/rc/ir-lirc-codec.c   |  1 -
 drivers/media/rc/lirc_dev.c| 12 --
 include/media/lirc_dev.h   |  4 --
 9 files changed, 4 insertions(+), 87 deletions(-)
 delete mode 100644 Documentation/media/uapi/rc/lirc-get-length.rst

diff --git a/Documentation/media/uapi/rc/lirc-dev-intro.rst 
b/Documentation/media/uapi/rc/lirc-dev-intro.rst
index d1936eeb9ce0..3cacf9aeac40 100644
--- a/Documentation/media/uapi/rc/lirc-dev-intro.rst
+++ b/Documentation/media/uapi/rc/lirc-dev-intro.rst
@@ -72,21 +72,6 @@ on the following table.
 this packet will be sent, with the number of microseconds with
 no IR.
 
-.. _lirc-mode-lirccode:
-
-``LIRC_MODE_LIRCCODE``
-
-This mode can be used for IR receive and send.
-
-The IR signal is decoded internally by the receiver, or encoded by the
-transmitter. The LIRC interface represents the scancode as byte string,
-which might not be a u32, it can be any length. The value is entirely
-driver dependent. This mode is used by some older lirc drivers.
-
-The length of each code depends on the driver, which can be retrieved
-with :ref:`lirc_get_length`. This length is used both
-for transmitting and receiving IR.
-
 .. _lirc-mode-pulse:
 
 ``LIRC_MODE_PULSE``
diff --git a/Documentation/media/uapi/rc/lirc-func.rst 
b/Documentation/media/uapi/rc/lirc-func.rst
index 9b5a772ec96c..ddb4620de294 100644
--- a/Documentation/media/uapi/rc/lirc-func.rst
+++ b/Documentation/media/uapi/rc/lirc-func.rst
@@ -18,7 +18,6 @@ LIRC Function Reference
 lirc-set-send-duty-cycle
 lirc-get-timeout
 lirc-set-rec-timeout
-lirc-get-length
 lirc-set-rec-carrier
 lirc-set-rec-carrier-range
 lirc-set-send-carrier
diff --git a/Documentation/media/uapi/rc/lirc-get-features.rst 
b/Documentation/media/uapi/rc/lirc-get-features.rst
index 64f89a4f9d9c..50c2c26d8e89 100644
--- a/Documentation/media/uapi/rc/lirc-get-features.rst
+++ b/Documentation/media/uapi/rc/lirc-get-features.rst
@@ -62,8 +62,7 @@ LIRC features
 
 ``LIRC_CAN_REC_LIRCCODE``
 
-The driver is capable of receiving using
-:ref:`LIRC_MODE_LIRCCODE `.
+Unused. Kept just to avoid breaking uAPI.
 
 .. _LIRC-CAN-SET-SEND-CARRIER:
 
@@ -170,9 +169,7 @@ LIRC features
 
 ``LIRC_CAN_SEND_LIRCCODE``
 
-The driver supports sending (also called as IR blasting or IR TX) using
-:ref:`LIRC_MODE_LIRCCODE `.
-
+Unused. Kept just to avoid breaking uAPI.
 
 Return Value
 
diff --git a/Documentation/media/uapi/rc/lirc-get-length.rst 
b/Documentation/media/uapi/rc/lirc-get-length.rst
deleted file mode 100644
index 3990af5de0e9..
--- a/Documentation/media/uapi/rc/lirc-get-length.rst
+++ /dev/null
@@ -1,44 +0,0 @@
-.. -*- coding: utf-8; mode: rst -*-
-
-.. _lirc_get_length:
-
-*
-ioctl LIRC_GET_LENGTH
-*
-
-Name
-
-
-LIRC_GET_LENGTH - Retrieves the code length in bits.
-
-Synopsis
-
-
-.. c:function:: int ioctl( int fd, LIRC_GET_LENGTH, __u32 *length )
-:name: LIRC_GET_LENGTH
-
-Arguments
-=
-
-``fd``
-File descriptor returned by open().
-
-``length``
-length, in bits
-
-
-Description
-===
-
-Retrieves the code length in bits (only for
-:ref:`LIRC_MODE_LIRCCODE `).
-Reads on the device must be done in blocks matching the bit count.
-The bit could should be rounded up so that it matches full bytes.
-
-
-Return Value
-
-
-On success 0 is returned, on error -1 and the ``errno`` variable is set
-appropriately. The generic error codes are described at the
-:ref:`Generic Error Codes ` chapter.
diff --git a/Documentation/media/uapi/rc/lirc-get-rec-mode.rst 
b/Documentation/media/uapi/rc/lirc-get-rec-mode.rst
index a4eb6c0a26e9..b89de9add921 100644
--- a/Documentation/media/uapi/rc/lirc-get-rec-mode.rst
+++ b/Documentation/media/uapi/rc/lirc-get-rec-mode.rst
@@ -34,9 +34,7 @@ Description
 ===
 
 Get/set supported receive modes. Only :ref:`LIRC_MODE_MODE2 `
-and :ref:`LIRC_MODE_LIRCCODE ` are supported for IR
-receive. Use :ref:`lirc_get_features` to find out which modes the driver
-supports.
+is supported for IR receive.
 
 Return Value
 
diff --git a/Documentation/media/uapi/rc/lirc-get-send-mode.rst 
b/Documentation/media/uapi/rc/lirc-get-send-mode.rst
index 

[PATCH 18/20] media: lirc: introduce LIRC_SET_POLL_MODE

2017-09-26 Thread Sean Young
If you want to poll for both decoded scancodes and raw IR, then this
ioctl will help you.

int fd = open("/dev/lirc0", O_RDONLY | O_NONBLOCK);

for (;;) {
unsigned mode = LIRC_MODE_SCANCODE | LIRC_MODE_MODE2;
ioctl(fd, LIRC_SET_POLL_MODE, );
poll(&((struct pollfd){ .fd = fd, .events = POLLIN }), 1, -1);
mode = LIRC_MODE_SCANCODE;
ioctl(fd, LIRC_SET_REC_MODE, );
struct lirc_scancode sc;
if (read(fd, , sizeof(sc)) == sizeof(sc)) {
printf("scancode protocol:%d scancode:%llx\n",
sc.rc_proto, sc.scancode);
}
mode = LIRC_MODE_MODE2;
ioctl(fd, LIRC_SET_REC_MODE, );
unsigned sample;
if (read(fd, , sizeof(sample)) == sizeof(sample)) {
if (LIRC_IS_SPACE(sample))
printf("space %u\n", LIRC_VAL(sample)));
if (LIRC_IS_PULSE(sample))
printf("pulse %u\n", LIRC_VAL(sample)));
}
}

Note that LIRC_SET_REC_MODE will also affect the poll mode, so you
must set it again before calling poll.

Signed-off-by: Sean Young 
---
 Documentation/media/uapi/rc/lirc-func.rst  |  1 +
 Documentation/media/uapi/rc/lirc-set-poll-mode.rst | 44 ++
 drivers/media/rc/ir-lirc-codec.c   | 25 +---
 drivers/media/rc/lirc_dev.c|  1 +
 include/media/rc-core.h|  3 ++
 5 files changed, 68 insertions(+), 6 deletions(-)
 create mode 100644 Documentation/media/uapi/rc/lirc-set-poll-mode.rst

diff --git a/Documentation/media/uapi/rc/lirc-func.rst 
b/Documentation/media/uapi/rc/lirc-func.rst
index ddb4620de294..a09fb03f6722 100644
--- a/Documentation/media/uapi/rc/lirc-func.rst
+++ b/Documentation/media/uapi/rc/lirc-func.rst
@@ -25,3 +25,4 @@ LIRC Function Reference
 lirc-set-rec-timeout-reports
 lirc-set-measure-carrier-mode
 lirc-set-wideband-receiver
+lirc-set-poll-mode
diff --git a/Documentation/media/uapi/rc/lirc-set-poll-mode.rst 
b/Documentation/media/uapi/rc/lirc-set-poll-mode.rst
new file mode 100644
index ..56112bb0dcc9
--- /dev/null
+++ b/Documentation/media/uapi/rc/lirc-set-poll-mode.rst
@@ -0,0 +1,44 @@
+.. -*- coding: utf-8; mode: rst -*-
+
+.. _lirc_set_poll_mode:
+
+**
+ioctls LIRC_SET_POLL_MODE
+**
+
+Name
+
+
+LIRC_SET_POLL_MODE - Set poll modes
+
+Synopsis
+
+
+.. c:function:: int ioctl( int fd, LIRC_SET_POLL_MODE, __u32 modes)
+   :name: LIRC_SET_POLL_MODE
+
+Arguments
+=
+
+``fd``
+File descriptor returned by open().
+
+``modes``
+Bitmask with enabled poll lirc modes
+
+Description
+===
+
+Set lirc modes for which read readiness is reported by poll. Only
+:ref:`LIRC_MODE_MODE2 ` and
+:ref:`LIRC_MODE_SCANCODE ` are supported.
+Use :ref:`lirc_get_features` to find out which modes the driver supports.
+
+Note that using :ref:`lirc-set-rec-mode` resets the poll mode.
+
+Return Value
+
+
+On success 0 is returned, on error -1 and the ``errno`` variable is set
+appropriately. The generic error codes are described at the
+:ref:`Generic Error Codes ` chapter.
diff --git a/drivers/media/rc/ir-lirc-codec.c b/drivers/media/rc/ir-lirc-codec.c
index 43936128e303..46c6e05e85a6 100644
--- a/drivers/media/rc/ir-lirc-codec.c
+++ b/drivers/media/rc/ir-lirc-codec.c
@@ -342,6 +342,17 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int 
cmd,
return -EINVAL;
 
dev->rec_mode = val;
+   dev->poll_mode = val;
+   return 0;
+
+   case LIRC_SET_POLL_MODE:
+   if (dev->driver_type == RC_DRIVER_IR_RAW_TX)
+   return -ENOTTY;
+
+   if (val & ~(LIRC_MODE_MODE2 | LIRC_MODE_SCANCODE))
+   return -EINVAL;
+
+   dev->poll_mode = val;
return 0;
 
case LIRC_GET_SEND_MODE:
@@ -480,12 +491,14 @@ static unsigned int ir_lirc_poll(struct file *file,
 
if (!rcdev->registered) {
events = POLLHUP | POLLERR;
-   } else if (rcdev->rec_mode == LIRC_MODE_SCANCODE) {
-   if (!kfifo_is_empty(>scancodes))
-   events = POLLIN | POLLRDNORM;
-   } else if (rcdev->rec_mode == LIRC_MODE_MODE2) {
-   if (!kfifo_is_empty(>rawir))
-   events = POLLIN | POLLRDNORM;
+   } else {
+   if ((rcdev->poll_mode & LIRC_MODE_SCANCODE) &&
+   !kfifo_is_empty(>scancodes))
+   events |= POLLIN | POLLRDNORM;
+
+   if ((rcdev->poll_mode & LIRC_MODE_MODE2) &&
+   !kfifo_is_empty(>rawir))
+   events |= POLLIN | POLLRDNORM;
}
 
return events;
diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c
index 

[PATCH 12/20] media: lirc: move lirc_dev->attached to rc_dev->registered

2017-09-26 Thread Sean Young
This is done to further remove the lirc kernel api. Ensure that every
fops checks for this.

Signed-off-by: Sean Young 
---
 drivers/media/rc/ir-lirc-codec.c | 16 ++--
 drivers/media/rc/lirc_dev.c  |  4 +---
 drivers/media/rc/rc-main.c   |  8 
 include/media/lirc_dev.h |  2 --
 include/media/rc-core.h  |  3 +++
 5 files changed, 22 insertions(+), 11 deletions(-)

diff --git a/drivers/media/rc/ir-lirc-codec.c b/drivers/media/rc/ir-lirc-codec.c
index 1f4514fc1d8b..b53f8dccdf77 100644
--- a/drivers/media/rc/ir-lirc-codec.c
+++ b/drivers/media/rc/ir-lirc-codec.c
@@ -101,6 +101,9 @@ static ssize_t ir_lirc_transmit_ir(struct file *file, const 
char __user *buf,
unsigned int duration = 0; /* signal duration in us */
int i;
 
+   if (!dev->registered)
+   return -ENODEV;
+
start = ktime_get();
 
if (dev->send_mode == LIRC_MODE_SCANCODE) {
@@ -218,6 +221,9 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int 
cmd,
return ret;
}
 
+   if (!dev->registered)
+   return -ENODEV;
+
switch (cmd) {
case LIRC_GET_FEATURES:
if (dev->driver_type == RC_DRIVER_IR_RAW) {
@@ -400,12 +406,11 @@ static unsigned int ir_lirc_poll(struct file *file,
 struct poll_table_struct *wait)
 {
struct rc_dev *rcdev = file->private_data;
-   struct lirc_dev *d = rcdev->lirc_dev;
unsigned int events = 0;
 
poll_wait(file, >wait_poll, wait);
 
-   if (!d->attached)
+   if (!rcdev->registered)
events = POLLHUP | POLLERR;
else if (!kfifo_is_empty(>rawir))
events = POLLIN | POLLRDNORM;
@@ -417,14 +422,13 @@ static ssize_t ir_lirc_read(struct file *file, char 
__user *buffer,
size_t length, loff_t *ppos)
 {
struct rc_dev *rcdev = file->private_data;
-   struct lirc_dev *d = rcdev->lirc_dev;
unsigned int copied;
int ret;
 
if (length < sizeof(unsigned int) || length % sizeof(unsigned int))
return -EINVAL;
 
-   if (!d->attached)
+   if (!rcdev->registered)
return -ENODEV;
 
do {
@@ -434,12 +438,12 @@ static ssize_t ir_lirc_read(struct file *file, char 
__user *buffer,
 
ret = wait_event_interruptible(rcdev->wait_poll,
!kfifo_is_empty(>rawir) ||
-   !d->attached);
+   !rcdev->registered);
if (ret)
return ret;
}
 
-   if (!d->attached)
+   if (!rcdev->registered)
return -ENODEV;
 
mutex_lock(>lock);
diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c
index 9a0ad8d9a0cb..22171267aa90 100644
--- a/drivers/media/rc/lirc_dev.c
+++ b/drivers/media/rc/lirc_dev.c
@@ -122,7 +122,6 @@ int lirc_register_device(struct lirc_dev *d)
 
cdev_init(>cdev, d->fops);
d->cdev.owner = d->owner;
-   d->attached = true;
 
err = cdev_device_add(>cdev, >dev);
if (err) {
@@ -153,7 +152,6 @@ void lirc_unregister_device(struct lirc_dev *d)
 
mutex_lock(>mutex);
 
-   d->attached = false;
if (d->open) {
dev_dbg(>dev, LOGHEAD "releasing opened driver\n",
d->name, d->minor);
@@ -180,7 +178,7 @@ int lirc_dev_fop_open(struct inode *inode, struct file 
*file)
if (retval)
return retval;
 
-   if (!d->attached) {
+   if (!rcdev->registered) {
retval = -ENODEV;
goto out;
}
diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c
index 970db1d7c8c8..2d7e9f8a15c3 100644
--- a/drivers/media/rc/rc-main.c
+++ b/drivers/media/rc/rc-main.c
@@ -1783,6 +1783,8 @@ int rc_register_device(struct rc_dev *dev)
goto out_lirc;
}
 
+   dev->registered = true;
+
IR_dprintk(1, "Registered rc%u (driver: %s)\n",
   dev->minor,
   dev->driver_name ? dev->driver_name : "unknown");
@@ -1849,6 +1851,12 @@ void rc_unregister_device(struct rc_dev *dev)
 
ida_simple_remove(_ida, dev->minor);
 
+   dev->registered = false;
+
+   /*
+* lirc device should be freed with dev->registered = false, so
+* that userspace polling will get notified.
+*/
if (dev->driver_type != RC_DRIVER_SCANCODE)
ir_lirc_unregister(dev);
 
diff --git a/include/media/lirc_dev.h b/include/media/lirc_dev.h
index 14d3eb36672e..5782add67edd 100644
--- a/include/media/lirc_dev.h
+++ b/include/media/lirc_dev.h
@@ -26,7 +26,6 @@
  * @rdev:   rc_dev associated with the device
  * @fops:   file_operations for the device
  * 

[PATCH 13/20] media: lirc: do not call rc_close() on unregistered devices

2017-09-26 Thread Sean Young
If a lirc chardev is held open after a device is unplugged, rc_close()
will be called after rc_unregister_device(). The driver is not expecting
any calls at this point, and the iguanair driver causes an oops in
this scenario.

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

diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c
index 2d7e9f8a15c3..247f19efc852 100644
--- a/drivers/media/rc/rc-main.c
+++ b/drivers/media/rc/rc-main.c
@@ -858,7 +858,7 @@ void rc_close(struct rc_dev *rdev)
if (rdev) {
mutex_lock(>lock);
 
-   if (!--rdev->users && rdev->close != NULL)
+   if (!--rdev->users && rdev->close && rdev->registered)
rdev->close(rdev);
 
mutex_unlock(>lock);
-- 
2.13.5



[PATCH 19/20] media: lirc: scancode rc devices should have a lirc device too

2017-09-26 Thread Sean Young
Now that the lirc interface supports scancodes, RC scancode devices
can also have a lirc device.

Signed-off-by: Sean Young 
---
 drivers/media/rc/ir-lirc-codec.c | 34 ++
 drivers/media/rc/lirc_dev.c  | 13 ++---
 drivers/media/rc/rc-main.c   | 14 +-
 3 files changed, 41 insertions(+), 20 deletions(-)

diff --git a/drivers/media/rc/ir-lirc-codec.c b/drivers/media/rc/ir-lirc-codec.c
index 46c6e05e85a6..eff4e1e40be9 100644
--- a/drivers/media/rc/ir-lirc-codec.c
+++ b/drivers/media/rc/ir-lirc-codec.c
@@ -292,6 +292,9 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int 
cmd,
 
switch (cmd) {
case LIRC_GET_FEATURES:
+   if (dev->driver_type == RC_DRIVER_SCANCODE)
+   val |= LIRC_CAN_REC_SCANCODE;
+
if (dev->driver_type == RC_DRIVER_IR_RAW) {
val |= LIRC_CAN_REC_MODE2 | LIRC_CAN_REC_SCANCODE;
if (dev->rx_resolution)
@@ -335,22 +338,37 @@ static long ir_lirc_ioctl(struct file *filep, unsigned 
int cmd,
break;
 
case LIRC_SET_REC_MODE:
-   if (dev->driver_type == RC_DRIVER_IR_RAW_TX)
+   switch (dev->driver_type) {
+   case RC_DRIVER_IR_RAW_TX:
return -ENOTTY;
-
-   if (!(val == LIRC_MODE_MODE2 || val == LIRC_MODE_SCANCODE))
-   return -EINVAL;
+   case RC_DRIVER_SCANCODE:
+   if (val != LIRC_MODE_SCANCODE)
+   return -EINVAL;
+   break;
+   case RC_DRIVER_IR_RAW:
+   if (!(val == LIRC_MODE_MODE2 ||
+ val == LIRC_MODE_SCANCODE))
+   return -EINVAL;
+   break;
+   }
 
dev->rec_mode = val;
dev->poll_mode = val;
return 0;
 
case LIRC_SET_POLL_MODE:
-   if (dev->driver_type == RC_DRIVER_IR_RAW_TX)
+   switch (dev->driver_type) {
+   case RC_DRIVER_IR_RAW_TX:
return -ENOTTY;
-
-   if (val & ~(LIRC_MODE_MODE2 | LIRC_MODE_SCANCODE))
-   return -EINVAL;
+   case RC_DRIVER_SCANCODE:
+   if (val != LIRC_MODE_SCANCODE)
+   return -EINVAL;
+   break;
+   case RC_DRIVER_IR_RAW:
+   if (val & ~(LIRC_MODE_MODE2 | LIRC_MODE_SCANCODE))
+   return -EINVAL;
+   break;
+   }
 
dev->poll_mode = val;
return 0;
diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c
index df592240f1e5..06bbf421ca00 100644
--- a/drivers/media/rc/lirc_dev.c
+++ b/drivers/media/rc/lirc_dev.c
@@ -55,9 +55,16 @@ int ir_lirc_register(struct rc_dev *dev)
device_initialize(>lirc_dev);
dev->lirc_dev.class = lirc_class;
dev->lirc_dev.release = lirc_release_device;
-   dev->send_mode = LIRC_MODE_PULSE;
-   dev->rec_mode = LIRC_MODE_MODE2;
-   dev->poll_mode = LIRC_MODE_MODE2;
+
+   if (dev->driver_type == RC_DRIVER_SCANCODE) {
+   dev->send_mode = LIRC_MODE_SCANCODE;
+   dev->rec_mode = LIRC_MODE_SCANCODE;
+   dev->poll_mode = LIRC_MODE_SCANCODE;
+   } else {
+   dev->send_mode = LIRC_MODE_PULSE;
+   dev->rec_mode = LIRC_MODE_MODE2;
+   dev->poll_mode = LIRC_MODE_MODE2;
+   }
 
if (dev->driver_type == RC_DRIVER_IR_RAW) {
if (kfifo_alloc(>rawir, MAX_IR_EVENT_SIZE, GFP_KERNEL))
diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c
index b58ddc8c1abf..94ad08ee9229 100644
--- a/drivers/media/rc/rc-main.c
+++ b/drivers/media/rc/rc-main.c
@@ -1784,11 +1784,9 @@ int rc_register_device(struct rc_dev *dev)
}
 
/* Ensure that the lirc kfifo is setup before we start the thread */
-   if (dev->driver_type != RC_DRIVER_SCANCODE) {
-   rc = ir_lirc_register(dev);
-   if (rc < 0)
-   goto out_rx;
-   }
+   rc = ir_lirc_register(dev);
+   if (rc < 0)
+   goto out_rx;
 
if (dev->driver_type == RC_DRIVER_IR_RAW) {
rc = ir_raw_event_register(dev);
@@ -1805,8 +1803,7 @@ int rc_register_device(struct rc_dev *dev)
return 0;
 
 out_lirc:
-   if (dev->driver_type != RC_DRIVER_SCANCODE)
-   ir_lirc_unregister(dev);
+   ir_lirc_unregister(dev);
 out_rx:
rc_free_rx_device(dev);
 out_dev:
@@ -1870,8 +1867,7 @@ void rc_unregister_device(struct rc_dev *dev)
 * lirc device should be freed with dev->registered = false, so
 * that userspace polling will get notified.
 */
-   if (dev->driver_type != 

[PATCH 20/20] media: lirc: document LIRC_MODE_SCANCODE

2017-09-26 Thread Sean Young
Lirc supports a new mode which requires documentation.

Signed-off-by: Sean Young 
---
 Documentation/media/lirc.h.rst.exceptions  | 49 ++
 Documentation/media/uapi/rc/lirc-dev-intro.rst | 25 +++
 Documentation/media/uapi/rc/lirc-get-features.rst  | 16 +++
 Documentation/media/uapi/rc/lirc-get-rec-mode.rst  |  6 ++-
 Documentation/media/uapi/rc/lirc-get-send-mode.rst |  4 +-
 Documentation/media/uapi/rc/lirc-read.rst  |  6 +++
 Documentation/media/uapi/rc/lirc-write.rst |  8 
 7 files changed, 111 insertions(+), 3 deletions(-)

diff --git a/Documentation/media/lirc.h.rst.exceptions 
b/Documentation/media/lirc.h.rst.exceptions
index c130617a9986..d86f5df12f75 100644
--- a/Documentation/media/lirc.h.rst.exceptions
+++ b/Documentation/media/lirc.h.rst.exceptions
@@ -28,6 +28,55 @@ ignore define LIRC_CAN_SEND_MASK
 ignore define LIRC_CAN_REC_MASK
 ignore define LIRC_CAN_SET_REC_DUTY_CYCLE
 
+# rc protocols
+
+ignore symbol RC_PROTO_UNKNOWN
+ignore symbol RC_PROTO_OTHER
+ignore symbol RC_PROTO_RC5
+ignore symbol RC_PROTO_RC5X_20
+ignore symbol RC_PROTO_RC5_SZ
+ignore symbol RC_PROTO_JVC
+ignore symbol RC_PROTO_SONY12
+ignore symbol RC_PROTO_SONY15
+ignore symbol RC_PROTO_SONY20
+ignore symbol RC_PROTO_NEC
+ignore symbol RC_PROTO_NECX
+ignore symbol RC_PROTO_NEC32
+ignore symbol RC_PROTO_SANYO
+ignore symbol RC_PROTO_MCIR2_KBD
+ignore symbol RC_PROTO_MCIR2_MSE
+ignore symbol RC_PROTO_RC6_0
+ignore symbol RC_PROTO_RC6_6A_20
+ignore symbol RC_PROTO_RC6_6A_24
+ignore symbol RC_PROTO_RC6_6A_32
+ignore symbol RC_PROTO_RC6_MCE
+ignore symbol RC_PROTO_SHARP
+ignore symbol RC_PROTO_XMP
+ignore symbol RC_PROTO_CEC
+ignore symbol RC_PROTO_UNKNOWN
+ignore symbol RC_PROTO_OTHER
+ignore symbol RC_PROTO_RC5
+ignore symbol RC_PROTO_RC5X_20
+ignore symbol RC_PROTO_RC5_SZ
+ignore symbol RC_PROTO_JVC
+ignore symbol RC_PROTO_SONY12
+ignore symbol RC_PROTO_SONY15
+ignore symbol RC_PROTO_SONY20
+ignore symbol RC_PROTO_NEC
+ignore symbol RC_PROTO_NECX
+ignore symbol RC_PROTO_NEC32
+ignore symbol RC_PROTO_SANYO
+ignore symbol RC_PROTO_MCIR2_KBD
+ignore symbol RC_PROTO_MCIR2_MSE
+ignore symbol RC_PROTO_RC6_0
+ignore symbol RC_PROTO_RC6_6A_20
+ignore symbol RC_PROTO_RC6_6A_24
+ignore symbol RC_PROTO_RC6_6A_32
+ignore symbol RC_PROTO_RC6_MCE
+ignore symbol RC_PROTO_SHARP
+ignore symbol RC_PROTO_XMP
+ignore symbol RC_PROTO_CEC
+
 # Undocumented macros
 
 ignore define PULSE_BIT
diff --git a/Documentation/media/uapi/rc/lirc-dev-intro.rst 
b/Documentation/media/uapi/rc/lirc-dev-intro.rst
index a3fa3c1ef169..bf05cf6985df 100644
--- a/Documentation/media/uapi/rc/lirc-dev-intro.rst
+++ b/Documentation/media/uapi/rc/lirc-dev-intro.rst
@@ -36,6 +36,31 @@ LIRC modes
 LIRC supports some modes of receiving and sending IR codes, as shown
 on the following table.
 
+.. _lirc-mode-scancode:
+.. _lirc-scancode-flag-toggle:
+.. _lirc-scancode-flag-repeat:
+
+``LIRC_MODE_SCANCODE``
+
+This mode is for both sending and receiving IR.
+
+For transmitting (aka sending), create a ``struct lirc_scancode`` with
+the desired scancode set in the ``scancode`` member, ``rc_proto`` set
+the IR protocol, and ``flags`` set to 0. Write this to the lirc device.
+
+For receiving, you read ``struct lirc_scancode`` from the lirc device,
+with ``scancode`` set to the received scancode in the IR protocol
+``rc_proto``. The ``flags`` can have ``LIRC_SCANCODE_FLAG_TOGGLE`` set
+if the toggle bit is set in protocols that support it (e.g. rc-5 and rc-6),
+or ``LIRC_SCANCODE_FLAG_REPEAT`` for when a repeat is received for 
protocols
+that support it (e.g. nec).
+
+The ``timestamp`` field is filled with the time nanoseconds
+(in ``CLOCK_MONOTONIC``) when the scancode was decoded.
+
+An ``enum rc_proto`` in the :ref:`lirc_header` lists all the supported
+IR protocols.
+
 .. _lirc-mode-mode2:
 
 ``LIRC_MODE_MODE2``
diff --git a/Documentation/media/uapi/rc/lirc-get-features.rst 
b/Documentation/media/uapi/rc/lirc-get-features.rst
index 50c2c26d8e89..3ee44067de63 100644
--- a/Documentation/media/uapi/rc/lirc-get-features.rst
+++ b/Documentation/media/uapi/rc/lirc-get-features.rst
@@ -64,6 +64,14 @@ LIRC features
 
 Unused. Kept just to avoid breaking uAPI.
 
+.. _LIRC-CAN-REC-SCANCODE:
+
+``LIRC_CAN_REC_SCANCODE``
+
+The driver is capable of receiving using
+:ref:`LIRC_MODE_SCANCODE `.
+
+
 .. _LIRC-CAN-SET-SEND-CARRIER:
 
 ``LIRC_CAN_SET_SEND_CARRIER``
@@ -171,6 +179,14 @@ LIRC features
 
 Unused. Kept just to avoid breaking uAPI.
 
+.. _LIRC-CAN-SEND-SCANCODE:
+
+``LIRC_CAN_SEND_SCANCODE``
+
+The driver supports sending (also called as IR blasting or IR TX) using
+:ref:`LIRC_MODE_SCANCODE `.
+
+
 Return Value
 
 
diff --git a/Documentation/media/uapi/rc/lirc-get-rec-mode.rst 
b/Documentation/media/uapi/rc/lirc-get-rec-mode.rst
index b89de9add921..221f093db125 100644
--- 

[PATCH 05/20] media: lirc_zilog: fix variable types and other ugliness

2017-09-26 Thread Sean Young
Cleans up code and makes checkpatch happy.

Signed-off-by: Sean Young 
---
 drivers/staging/media/lirc/lirc_zilog.c | 160 +++-
 1 file changed, 55 insertions(+), 105 deletions(-)

diff --git a/drivers/staging/media/lirc/lirc_zilog.c 
b/drivers/staging/media/lirc/lirc_zilog.c
index 757b3fc247ac..d3225bd1b3a6 100644
--- a/drivers/staging/media/lirc/lirc_zilog.c
+++ b/drivers/staging/media/lirc/lirc_zilog.c
@@ -32,32 +32,15 @@
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  */
 
+#include 
 #include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
 #include 
-#include 
-#include 
-#include 
 #include 
 #include 
 #include 
 
-#include 
-#include 
-
 #include 
 #include 
 
@@ -70,7 +53,7 @@ struct IR_tx {
struct i2c_client *c;
 
/* TX additional actions needed */
-   int need_boot;
+   bool need_boot;
bool post_tx_ready_poll;
struct lirc_dev *l;
 };
@@ -81,45 +64,39 @@ struct IR_tx {
 /* Hauppauge IR transmitter data */
 struct tx_data_struct {
/* Boot block */
-   unsigned char *boot_data;
+   u8 *boot_data;
 
/* Start of binary data block */
-   unsigned char *datap;
+   u8 *datap;
 
/* End of binary data block */
-   unsigned char *endp;
+   u8 *endp;
 
/* Number of installed codesets */
-   unsigned int num_code_sets;
+   u32 num_code_sets;
 
/* Pointers to codesets */
-   unsigned char **code_sets;
+   u8 **code_sets;
 
/* Global fixed data template */
int fixed[TX_BLOCK_SIZE];
 };
 
 static struct tx_data_struct *tx_data;
-static struct mutex tx_data_lock;
-
-/* module parameters */
-static bool debug; /* debug output */
+static DEFINE_MUTEX(tx_data_lock);
 
 /* safe read of a uint32 (always network byte order) */
-static int read_uint32(unsigned char **data,
-  unsigned char *endp, unsigned int *val)
+static int read_u32(u8 **data, u8 *endp, u32 *val)
 {
if (*data + 4 > endp)
return 0;
-   *val = ((*data)[0] << 24) | ((*data)[1] << 16) |
-  ((*data)[2] << 8) | (*data)[3];
+   *val = get_unaligned_be32(data);
*data += 4;
return 1;
 }
 
 /* safe read of a uint8 */
-static int read_uint8(unsigned char **data,
- unsigned char *endp, unsigned char *val)
+static int read_u8(u8 **data, u8 *endp, u8 *val)
 {
if (*data + 1 > endp)
return 0;
@@ -128,8 +105,8 @@ static int read_uint8(unsigned char **data,
 }
 
 /* safe skipping of N bytes */
-static int skip(unsigned char **data,
-   unsigned char *endp, unsigned int distance)
+static int skip(u8 **data,
+   u8 *endp, unsigned int distance)
 {
if (*data + distance > endp)
return 0;
@@ -138,11 +115,11 @@ static int skip(unsigned char **data,
 }
 
 /* decompress key data into the given buffer */
-static int get_key_data(unsigned char *buf,
+static int get_key_data(u8 *buf,
unsigned int codeset, unsigned int key)
 {
-   unsigned char *data, *endp, *diffs, *key_block;
-   unsigned char keys, ndiffs, id;
+   u8 *data, *endp, *diffs, *key_block;
+   u8 keys, ndiffs, id;
unsigned int base, lim, pos, i;
 
/* Binary search for the codeset */
@@ -150,7 +127,7 @@ static int get_key_data(unsigned char *buf,
pos = base + (lim >> 1);
data = tx_data->code_sets[pos];
 
-   if (!read_uint32(, tx_data->endp, ))
+   if (!read_u32(, tx_data->endp, ))
goto corrupt;
 
if (i == codeset) {
@@ -169,8 +146,8 @@ static int get_key_data(unsigned char *buf,
tx_data->code_sets[pos + 1] : tx_data->endp;
 
/* Read the block header */
-   if (!read_uint8(, endp, ) ||
-   !read_uint8(, endp, ) ||
+   if (!read_u8(, endp, ) ||
+   !read_u8(, endp, ) ||
ndiffs > TX_BLOCK_SIZE || keys == 0)
goto corrupt;
 
@@ -180,16 +157,16 @@ static int get_key_data(unsigned char *buf,
goto corrupt;
 
/* Read the id of the first key */
-   if (!read_uint8(, endp, ))
+   if (!read_u8(, endp, ))
goto corrupt;
 
/* Unpack the first key's data */
for (i = 0; i < TX_BLOCK_SIZE; ++i) {
if (tx_data->fixed[i] == -1) {
-   if (!read_uint8(, endp, [i]))
+   if (!read_u8(, endp, [i]))
goto corrupt;
} else 

[PATCH 10/20] media: lirc: merge lirc_dev_fop_ioctl and ir_lirc_ioctl

2017-09-26 Thread Sean Young
Calculate lirc features when necessary, and add LIRC_{S,G}ET_REC_MODE
cases to ir_lirc_ioctl.

This makes lirc_dev_fop_ioctl() unnecessary since all cases are
already handled by ir_lirc_ioctl().

Signed-off-by: Sean Young 
---
 drivers/media/rc/ir-lirc-codec.c | 85 +++-
 drivers/media/rc/lirc_dev.c  | 62 ++---
 include/media/lirc_dev.h |  4 --
 3 files changed, 53 insertions(+), 98 deletions(-)

diff --git a/drivers/media/rc/ir-lirc-codec.c b/drivers/media/rc/ir-lirc-codec.c
index 0b977c22b9cf..f96f2a2c4eb1 100644
--- a/drivers/media/rc/ir-lirc-codec.c
+++ b/drivers/media/rc/ir-lirc-codec.c
@@ -225,8 +225,57 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int 
cmd,
}
 
switch (cmd) {
+   case LIRC_GET_FEATURES:
+   if (dev->driver_type == RC_DRIVER_IR_RAW) {
+   val |= LIRC_CAN_REC_MODE2;
+   if (dev->rx_resolution)
+   val |= LIRC_CAN_GET_REC_RESOLUTION;
+   }
+
+   if (dev->tx_scancode)
+   val |= LIRC_CAN_SEND_SCANCODE;
+
+   if (dev->tx_ir) {
+   val |= LIRC_CAN_SEND_PULSE | LIRC_CAN_SEND_SCANCODE;
+   if (dev->s_tx_mask)
+   val |= LIRC_CAN_SET_TRANSMITTER_MASK;
+   if (dev->s_tx_carrier)
+   val |= LIRC_CAN_SET_SEND_CARRIER;
+   if (dev->s_tx_duty_cycle)
+   val |= LIRC_CAN_SET_SEND_DUTY_CYCLE;
+   }
+
+   if (dev->s_rx_carrier_range)
+   val |= LIRC_CAN_SET_REC_CARRIER |
+   LIRC_CAN_SET_REC_CARRIER_RANGE;
+
+   if (dev->s_learning_mode)
+   val |= LIRC_CAN_USE_WIDEBAND_RECEIVER;
+
+   if (dev->s_carrier_report)
+   val |= LIRC_CAN_MEASURE_CARRIER;
+
+   if (dev->max_timeout)
+   val |= LIRC_CAN_SET_REC_TIMEOUT;
+
+   break;
 
/* mode support */
+   case LIRC_GET_REC_MODE:
+   if (dev->driver_type == RC_DRIVER_IR_RAW_TX)
+   return -ENOTTY;
+
+   val = LIRC_MODE_MODE2;
+   break;
+
+   case LIRC_SET_REC_MODE:
+   if (dev->driver_type == RC_DRIVER_IR_RAW_TX)
+   return -ENOTTY;
+
+   if (val != LIRC_MODE_MODE2)
+   return -EINVAL;
+   return 0;
+
case LIRC_GET_SEND_MODE:
if (!dev->tx_ir)
return -ENOTTY;
@@ -344,7 +393,7 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int 
cmd,
break;
 
default:
-   return lirc_dev_fop_ioctl(filep, cmd, arg);
+   return -ENOTTY;
}
 
if (_IOC_DIR(cmd) & _IOC_READ)
@@ -371,47 +420,13 @@ int ir_lirc_register(struct rc_dev *dev)
 {
struct lirc_dev *ldev;
int rc = -ENOMEM;
-   unsigned long features = 0;
 
ldev = lirc_allocate_device();
if (!ldev)
return rc;
 
-   if (dev->driver_type != RC_DRIVER_IR_RAW_TX) {
-   features |= LIRC_CAN_REC_MODE2;
-   if (dev->rx_resolution)
-   features |= LIRC_CAN_GET_REC_RESOLUTION;
-   }
-
-   if (dev->tx_scancode)
-   features |= LIRC_CAN_SEND_SCANCODE;
-
-   if (dev->tx_ir) {
-   features |= LIRC_CAN_SEND_PULSE | LIRC_CAN_SEND_SCANCODE;
-   if (dev->s_tx_mask)
-   features |= LIRC_CAN_SET_TRANSMITTER_MASK;
-   if (dev->s_tx_carrier)
-   features |= LIRC_CAN_SET_SEND_CARRIER;
-   if (dev->s_tx_duty_cycle)
-   features |= LIRC_CAN_SET_SEND_DUTY_CYCLE;
-   }
-
-   if (dev->s_rx_carrier_range)
-   features |= LIRC_CAN_SET_REC_CARRIER |
-   LIRC_CAN_SET_REC_CARRIER_RANGE;
-
-   if (dev->s_learning_mode)
-   features |= LIRC_CAN_USE_WIDEBAND_RECEIVER;
-
-   if (dev->s_carrier_report)
-   features |= LIRC_CAN_MEASURE_CARRIER;
-
-   if (dev->max_timeout)
-   features |= LIRC_CAN_SET_REC_TIMEOUT;
-
snprintf(ldev->name, sizeof(ldev->name), "ir-lirc-codec (%s)",
 dev->driver_name);
-   ldev->features = features;
ldev->buf = NULL;
ldev->chunk_size = sizeof(int);
ldev->buffer_size = LIRCBUF_SIZE;
diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c
index 884923cbee9d..f149fbf382ca 100644
--- a/drivers/media/rc/lirc_dev.c
+++ b/drivers/media/rc/lirc_dev.c
@@ -109,6 +109,7 @@ EXPORT_SYMBOL(lirc_free_device);
 
 int lirc_register_device(struct lirc_dev *d)
 {
+   struct rc_dev *rcdev = d->rdev;
int minor;
 

[PATCH 14/20] media: lirc: create rc-core open and close lirc functions

2017-09-26 Thread Sean Young
Replace the generic kernel lirc api with ones which use rc-core, further
reducing the lirc_dev members.

Signed-off-by: Sean Young 
---
 drivers/media/rc/ir-lirc-codec.c | 59 --
 drivers/media/rc/lirc_dev.c  | 68 ++--
 include/media/lirc_dev.h | 11 ---
 include/media/rc-core.h  |  2 ++
 4 files changed, 62 insertions(+), 78 deletions(-)

diff --git a/drivers/media/rc/ir-lirc-codec.c b/drivers/media/rc/ir-lirc-codec.c
index b53f8dccdf77..0b956ff09740 100644
--- a/drivers/media/rc/ir-lirc-codec.c
+++ b/drivers/media/rc/ir-lirc-codec.c
@@ -88,6 +88,61 @@ void ir_lirc_raw_event(struct rc_dev *dev, struct 
ir_raw_event ev)
wake_up_poll(>wait_poll, POLLIN | POLLRDNORM);
 }
 
+static int ir_lirc_open(struct inode *inode, struct file *file)
+{
+   struct lirc_dev *d = container_of(inode->i_cdev, struct lirc_dev, cdev);
+   struct rc_dev *dev = d->rdev;
+   int retval;
+
+   retval = rc_open(dev);
+   if (retval)
+   return retval;
+
+   retval = mutex_lock_interruptible(>lock);
+   if (retval)
+   goto out_rc;
+
+   if (!dev->registered) {
+   retval = -ENODEV;
+   goto out_unlock;
+   }
+
+   if (dev->lirc_open) {
+   retval = -EBUSY;
+   goto out_unlock;
+   }
+
+   if (dev->driver_type == RC_DRIVER_IR_RAW)
+   kfifo_reset_out(>rawir);
+
+   dev->lirc_open++;
+   file->private_data = dev;
+
+   nonseekable_open(inode, file);
+   mutex_unlock(>lock);
+
+   return 0;
+
+out_unlock:
+   mutex_unlock(>lock);
+out_rc:
+   rc_close(dev);
+   return retval;
+}
+
+static int ir_lirc_close(struct inode *inode, struct file *file)
+{
+   struct rc_dev *dev = file->private_data;
+
+   mutex_lock(>lock);
+   dev->lirc_open--;
+   mutex_unlock(>lock);
+
+   rc_close(dev);
+
+   return 0;
+}
+
 static ssize_t ir_lirc_transmit_ir(struct file *file, const char __user *buf,
   size_t n, loff_t *ppos)
 {
@@ -465,8 +520,8 @@ static const struct file_operations lirc_fops = {
 #endif
.read   = ir_lirc_read,
.poll   = ir_lirc_poll,
-   .open   = lirc_dev_fop_open,
-   .release= lirc_dev_fop_close,
+   .open   = ir_lirc_open,
+   .release= ir_lirc_close,
.llseek = no_llseek,
 };
 
diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c
index 22171267aa90..32124fb5c88e 100644
--- a/drivers/media/rc/lirc_dev.c
+++ b/drivers/media/rc/lirc_dev.c
@@ -61,7 +61,6 @@ lirc_allocate_device(void)
 
d = kzalloc(sizeof(*d), GFP_KERNEL);
if (d) {
-   mutex_init(>mutex);
device_initialize(>dev);
d->dev.class = lirc_class;
d->dev.release = lirc_release_device;
@@ -150,15 +149,15 @@ void lirc_unregister_device(struct lirc_dev *d)
dev_dbg(>dev, "lirc_dev: driver %s unregistered from minor = %d\n",
d->name, d->minor);
 
-   mutex_lock(>mutex);
+   mutex_lock(>lock);
 
-   if (d->open) {
+   if (rcdev->lirc_open) {
dev_dbg(>dev, LOGHEAD "releasing opened driver\n",
d->name, d->minor);
wake_up_poll(>wait_poll, POLLHUP);
}
 
-   mutex_unlock(>mutex);
+   mutex_unlock(>lock);
 
cdev_device_del(>cdev, >dev);
ida_simple_remove(_ida, d->minor);
@@ -166,67 +165,6 @@ void lirc_unregister_device(struct lirc_dev *d)
 }
 EXPORT_SYMBOL(lirc_unregister_device);
 
-int lirc_dev_fop_open(struct inode *inode, struct file *file)
-{
-   struct lirc_dev *d = container_of(inode->i_cdev, struct lirc_dev, cdev);
-   struct rc_dev *rcdev = d->rdev;
-   int retval;
-
-   dev_dbg(>dev, LOGHEAD "open called\n", d->name, d->minor);
-
-   retval = mutex_lock_interruptible(>mutex);
-   if (retval)
-   return retval;
-
-   if (!rcdev->registered) {
-   retval = -ENODEV;
-   goto out;
-   }
-
-   if (d->open) {
-   retval = -EBUSY;
-   goto out;
-   }
-
-   if (d->rdev) {
-   retval = rc_open(d->rdev);
-   if (retval)
-   goto out;
-   }
-
-   if (rcdev->driver_type == RC_DRIVER_IR_RAW)
-   kfifo_reset_out(>rawir);
-
-   d->open++;
-
-   file->private_data = d->rdev;
-   nonseekable_open(inode, file);
-   mutex_unlock(>mutex);
-
-   return 0;
-
-out:
-   mutex_unlock(>mutex);
-   return retval;
-}
-EXPORT_SYMBOL(lirc_dev_fop_open);
-
-int lirc_dev_fop_close(struct inode *inode, struct file *file)
-{
-   struct rc_dev *rcdev = file->private_data;
-   struct lirc_dev *d = rcdev->lirc_dev;
-
-   mutex_lock(>mutex);
-
-   rc_close(rcdev);
-

[PATCH 02/20] media: lirc: use the correct carrier for scancode transmit

2017-09-26 Thread Sean Young
If the lirc device supports it, set the carrier for the protocol.

Signed-off-by: Sean Young 
---
 drivers/media/rc/ir-jvc-decoder.c |  1 +
 drivers/media/rc/ir-lirc-codec.c  |  7 +++
 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/rc-core-priv.h   |  1 +
 drivers/media/rc/rc-ir-raw.c  | 30 ++
 include/media/rc-core.h   |  1 +
 12 files changed, 47 insertions(+)

diff --git a/drivers/media/rc/ir-jvc-decoder.c 
b/drivers/media/rc/ir-jvc-decoder.c
index e2bd68c42edf..2ae20dfc0e61 100644
--- a/drivers/media/rc/ir-jvc-decoder.c
+++ b/drivers/media/rc/ir-jvc-decoder.c
@@ -212,6 +212,7 @@ static struct ir_raw_handler jvc_handler = {
.protocols  = RC_PROTO_BIT_JVC,
.decode = ir_jvc_decode,
.encode = ir_jvc_encode,
+   .carrier= 38000,
 };
 
 static int __init ir_jvc_decode_init(void)
diff --git a/drivers/media/rc/ir-lirc-codec.c b/drivers/media/rc/ir-lirc-codec.c
index 770d768824f4..ff7c46cc201c 100644
--- a/drivers/media/rc/ir-lirc-codec.c
+++ b/drivers/media/rc/ir-lirc-codec.c
@@ -155,6 +155,13 @@ static ssize_t ir_lirc_transmit_ir(struct file *file, 
const char __user *buf,
for (i = 0; i < count; i++)
/* Convert from NS to US */
txbuf[i] = DIV_ROUND_UP(raw[i].duration, 1000);
+
+   if (dev->s_tx_carrier) {
+   int carrier = ir_raw_encode_carrier(scan.rc_proto);
+
+   if (carrier > 0)
+   dev->s_tx_carrier(dev, carrier);
+   }
} else {
if (n < sizeof(unsigned int) || n % sizeof(unsigned int))
return -EINVAL;
diff --git a/drivers/media/rc/ir-mce_kbd-decoder.c 
b/drivers/media/rc/ir-mce_kbd-decoder.c
index 7c572a643656..efa3b735dcc4 100644
--- a/drivers/media/rc/ir-mce_kbd-decoder.c
+++ b/drivers/media/rc/ir-mce_kbd-decoder.c
@@ -474,6 +474,7 @@ static struct ir_raw_handler mce_kbd_handler = {
.encode = ir_mce_kbd_encode,
.raw_register   = ir_mce_kbd_register,
.raw_unregister = ir_mce_kbd_unregister,
+   .carrier= 36000,
 };
 
 static int __init ir_mce_kbd_decode_init(void)
diff --git a/drivers/media/rc/ir-nec-decoder.c 
b/drivers/media/rc/ir-nec-decoder.c
index 817c18f2ddd1..5380a9b23c07 100644
--- a/drivers/media/rc/ir-nec-decoder.c
+++ b/drivers/media/rc/ir-nec-decoder.c
@@ -259,6 +259,7 @@ static struct ir_raw_handler nec_handler = {
RC_PROTO_BIT_NEC32,
.decode = ir_nec_decode,
.encode = ir_nec_encode,
+   .carrier= 38000,
 };
 
 static int __init ir_nec_decode_init(void)
diff --git a/drivers/media/rc/ir-rc5-decoder.c 
b/drivers/media/rc/ir-rc5-decoder.c
index 1292f534de43..cd1c4ee5fcd4 100644
--- a/drivers/media/rc/ir-rc5-decoder.c
+++ b/drivers/media/rc/ir-rc5-decoder.c
@@ -282,6 +282,7 @@ static struct ir_raw_handler rc5_handler = {
RC_PROTO_BIT_RC5_SZ,
.decode = ir_rc5_decode,
.encode = ir_rc5_encode,
+   .carrier= 36000,
 };
 
 static int __init ir_rc5_decode_init(void)
diff --git a/drivers/media/rc/ir-rc6-decoder.c 
b/drivers/media/rc/ir-rc6-decoder.c
index 5d0d2fe3b7a7..665025303c28 100644
--- a/drivers/media/rc/ir-rc6-decoder.c
+++ b/drivers/media/rc/ir-rc6-decoder.c
@@ -408,6 +408,7 @@ static struct ir_raw_handler rc6_handler = {
  RC_PROTO_BIT_RC6_MCE,
.decode = ir_rc6_decode,
.encode = ir_rc6_encode,
+   .carrier= 36000,
 };
 
 static int __init ir_rc6_decode_init(void)
diff --git a/drivers/media/rc/ir-sanyo-decoder.c 
b/drivers/media/rc/ir-sanyo-decoder.c
index 758c60956850..723e7d75a593 100644
--- a/drivers/media/rc/ir-sanyo-decoder.c
+++ b/drivers/media/rc/ir-sanyo-decoder.c
@@ -218,6 +218,7 @@ static struct ir_raw_handler sanyo_handler = {
.protocols  = RC_PROTO_BIT_SANYO,
.decode = ir_sanyo_decode,
.encode = ir_sanyo_encode,
+   .carrier= 38000,
 };
 
 static int __init ir_sanyo_decode_init(void)
diff --git a/drivers/media/rc/ir-sharp-decoder.c 
b/drivers/media/rc/ir-sharp-decoder.c
index ed43a4212479..73174081e843 100644
--- a/drivers/media/rc/ir-sharp-decoder.c
+++ b/drivers/media/rc/ir-sharp-decoder.c
@@ -226,6 +226,7 @@ static struct ir_raw_handler sharp_handler = {
.protocols  = RC_PROTO_BIT_SHARP,
.decode = ir_sharp_decode,
.encode = ir_sharp_encode,
+   

[PATCH 09/20] media: lirc: lirc interface should not be a raw decoder

2017-09-26 Thread Sean Young
The lirc user interface exists as a raw decoder, which does not make
much sense for transmit-only devices.

In addition, we want to have lirc char devices for devices which do not
use raw IR, i.e. scancode only devices.

Note that rc-code, lirc_dev, ir-lirc-codec are now calling functions of
each other, so they've been merged into one module rc-core to avoid
circular dependencies.

Since ir-lirc-codec no longer exists as separate codec module, there is no
need for RC_DRIVER_IR_RAW_TX type drivers to call ir_raw_event_register().

Signed-off-by: Sean Young 
---
 drivers/media/rc/Kconfig |  29 +++--
 drivers/media/rc/Makefile|   4 +-
 drivers/media/rc/ir-lirc-codec.c | 134 +++
 drivers/media/rc/lirc_dev.c  |  47 --
 drivers/media/rc/rc-core-priv.h  |  45 +
 drivers/media/rc/rc-ir-raw.c |  24 ++-
 drivers/media/rc/rc-main.c   |  49 +++---
 include/media/lirc_dev.h |  10 ---
 include/media/rc-core.h  |  33 ++
 9 files changed, 144 insertions(+), 231 deletions(-)

diff --git a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig
index e8f7570fc501..c145914cd806 100644
--- a/drivers/media/rc/Kconfig
+++ b/drivers/media/rc/Kconfig
@@ -16,34 +16,21 @@ menuconfig RC_CORE
 if RC_CORE
 source "drivers/media/rc/keymaps/Kconfig"
 
-menuconfig RC_DECODERS
-bool "Remote controller decoders"
-   depends on RC_CORE
-   default y
-
-if RC_DECODERS
 config LIRC
-   tristate "LIRC interface driver"
+   bool "LIRC user interface"
depends on RC_CORE
-
---help---
-  Enable this option to build the Linux Infrared Remote
-  Control (LIRC) core device interface driver. The LIRC
-  interface passes raw IR to and from userspace, where the
-  LIRC daemon handles protocol decoding for IR reception and
-  encoding for IR transmitting (aka "blasting").
+  Enable this option to enable the Linux Infrared Remote
+  Control user interface (e.g. /dev/lirc*). This interface
+  passes raw IR to and from userspace, which is needed for
+  IR transmitting (aka "blasting") and for the lirc daemon.
 
-config IR_LIRC_CODEC
-   tristate "Enable IR to LIRC bridge"
+menuconfig RC_DECODERS
+bool "Remote controller decoders"
depends on RC_CORE
-   depends on LIRC
default y
 
-   ---help---
-  Enable this option to pass raw IR to and from userspace via
-  the LIRC interface.
-
-
+if RC_DECODERS
 config IR_NEC_DECODER
tristate "Enable IR raw decoder for the NEC protocol"
depends on RC_CORE
diff --git a/drivers/media/rc/Makefile b/drivers/media/rc/Makefile
index efdcf2318448..8eef9a48e594 100644
--- a/drivers/media/rc/Makefile
+++ b/drivers/media/rc/Makefile
@@ -1,8 +1,9 @@
-rc-core-objs   := rc-main.o rc-ir-raw.o
 
 obj-y += keymaps/
 
 obj-$(CONFIG_RC_CORE) += rc-core.o
+rc-core-y := rc-main.o rc-ir-raw.o
+rc-core-$(CONFIG_LIRC) += lirc_dev.o ir-lirc-codec.o
 obj-$(CONFIG_LIRC) += lirc_dev.o
 obj-$(CONFIG_IR_NEC_DECODER) += ir-nec-decoder.o
 obj-$(CONFIG_IR_RC5_DECODER) += ir-rc5-decoder.o
@@ -12,7 +13,6 @@ obj-$(CONFIG_IR_SONY_DECODER) += ir-sony-decoder.o
 obj-$(CONFIG_IR_SANYO_DECODER) += ir-sanyo-decoder.o
 obj-$(CONFIG_IR_SHARP_DECODER) += ir-sharp-decoder.o
 obj-$(CONFIG_IR_MCE_KBD_DECODER) += ir-mce_kbd-decoder.o
-obj-$(CONFIG_IR_LIRC_CODEC) += ir-lirc-codec.o
 obj-$(CONFIG_IR_XMP_DECODER) += ir-xmp-decoder.o
 
 # stand-alone IR receivers/transmitters
diff --git a/drivers/media/rc/ir-lirc-codec.c b/drivers/media/rc/ir-lirc-codec.c
index 79bf178bbaac..0b977c22b9cf 100644
--- a/drivers/media/rc/ir-lirc-codec.c
+++ b/drivers/media/rc/ir-lirc-codec.c
@@ -14,7 +14,6 @@
 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -23,21 +22,15 @@
 #define LIRCBUF_SIZE 256
 
 /**
- * ir_lirc_decode() - Send raw IR data to lirc_dev to be relayed to the
- *   lircd userspace daemon for decoding.
- * @input_dev: the struct rc_dev descriptor of the device
- * @duration:  the struct ir_raw_event descriptor of the pulse/space
+ * ir_lirc_raw_event() - Send raw IR data to lirc to be relayed to userspace
  *
- * This function returns -EINVAL if the lirc interfaces aren't wired up.
+ * @dev:   the struct rc_dev descriptor of the device
+ * @ev:the struct ir_raw_event descriptor of the pulse/space
  */
-static int ir_lirc_decode(struct rc_dev *dev, struct ir_raw_event ev)
+void ir_lirc_raw_event(struct rc_dev *dev, struct ir_raw_event ev)
 {
-   struct lirc_codec *lirc = >raw->lirc;
int sample;
 
-   if (!dev->raw->lirc.ldev || !dev->raw->lirc.ldev->buf)
-   return -EINVAL;
-
/* Packet start */
if (ev.reset) {
/* Userspace expects a long space event before the start of
@@ -56,15 +49,15 @@ static int ir_lirc_decode(struct rc_dev *dev, struct 

[PATCH 17/20] media: lirc: implement reading scancode

2017-09-26 Thread Sean Young
This implements LIRC_MODE_SCANCODE reading from the lirc device. The
scancode can be read from the input device too, but with this interface
you get the rc protocol, toggle and repeat status in addition too just
the scancode.

int main()
{
int fd, mode, rc;
fd = open("/dev/lirc0", O_RDWR);

mode = LIRC_MODE_SCANCODE;
if (ioctl(fd, LIRC_SET_REC_MODE, )) {
// kernel too old or lirc does not support transmit
}
struct lirc_scancode scancode;
while (read(fd, , sizeof(scancode)) == sizeof(scancode)) {
printf("protocol:%d scancode:0x%x toggle:%d repeat:%d\n",
scancode.rc_proto, scancode.scancode,
!!(scancode.flags & LIRC_SCANCODE_FLAG_TOGGLE),
!!(scancode.flags & LIRC_SCANCODE_FLAG_REPEAT));
}
close(fd);
}

Note that the translated KEY_* is not included, that information is
published to the input device.

Signed-off-by: Sean Young 
---
 drivers/media/rc/ir-lirc-codec.c  | 87 ++-
 drivers/media/rc/ir-mce_kbd-decoder.c |  6 +++
 drivers/media/rc/lirc_dev.c   | 12 +
 drivers/media/rc/rc-core-priv.h   |  3 ++
 drivers/media/rc/rc-main.c| 14 ++
 include/media/rc-core.h   |  5 ++
 6 files changed, 116 insertions(+), 11 deletions(-)

diff --git a/drivers/media/rc/ir-lirc-codec.c b/drivers/media/rc/ir-lirc-codec.c
index fb5df6c8208f..43936128e303 100644
--- a/drivers/media/rc/ir-lirc-codec.c
+++ b/drivers/media/rc/ir-lirc-codec.c
@@ -88,6 +88,15 @@ void ir_lirc_raw_event(struct rc_dev *dev, struct 
ir_raw_event ev)
wake_up_poll(>wait_poll, POLLIN | POLLRDNORM);
 }
 
+void ir_lirc_scancode_event(struct rc_dev *dev, struct lirc_scancode *lsc)
+{
+   lsc->timestamp = ktime_get_ns();
+
+   if (kfifo_put(>scancodes, *lsc))
+   wake_up_poll(>wait_poll, POLLIN | POLLRDNORM);
+}
+EXPORT_SYMBOL_GPL(ir_lirc_scancode_event);
+
 static int ir_lirc_open(struct inode *inode, struct file *file)
 {
struct rc_dev *dev = container_of(inode->i_cdev, struct rc_dev,
@@ -114,6 +123,8 @@ static int ir_lirc_open(struct inode *inode, struct file 
*file)
 
if (dev->driver_type == RC_DRIVER_IR_RAW)
kfifo_reset_out(>rawir);
+   if (dev->driver_type != RC_DRIVER_IR_RAW_TX)
+   kfifo_reset_out(>scancodes);
 
dev->lirc_open++;
file->private_data = dev;
@@ -282,7 +293,7 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int 
cmd,
switch (cmd) {
case LIRC_GET_FEATURES:
if (dev->driver_type == RC_DRIVER_IR_RAW) {
-   val |= LIRC_CAN_REC_MODE2;
+   val |= LIRC_CAN_REC_MODE2 | LIRC_CAN_REC_SCANCODE;
if (dev->rx_resolution)
val |= LIRC_CAN_GET_REC_RESOLUTION;
}
@@ -320,15 +331,17 @@ static long ir_lirc_ioctl(struct file *filep, unsigned 
int cmd,
if (dev->driver_type == RC_DRIVER_IR_RAW_TX)
return -ENOTTY;
 
-   val = LIRC_MODE_MODE2;
+   val = dev->rec_mode;
break;
 
case LIRC_SET_REC_MODE:
if (dev->driver_type == RC_DRIVER_IR_RAW_TX)
return -ENOTTY;
 
-   if (val != LIRC_MODE_MODE2)
+   if (!(val == LIRC_MODE_MODE2 || val == LIRC_MODE_SCANCODE))
return -EINVAL;
+
+   dev->rec_mode = val;
return 0;
 
case LIRC_GET_SEND_MODE:
@@ -465,16 +478,21 @@ static unsigned int ir_lirc_poll(struct file *file,
 
poll_wait(file, >wait_poll, wait);
 
-   if (!rcdev->registered)
+   if (!rcdev->registered) {
events = POLLHUP | POLLERR;
-   else if (!kfifo_is_empty(>rawir))
-   events = POLLIN | POLLRDNORM;
+   } else if (rcdev->rec_mode == LIRC_MODE_SCANCODE) {
+   if (!kfifo_is_empty(>scancodes))
+   events = POLLIN | POLLRDNORM;
+   } else if (rcdev->rec_mode == LIRC_MODE_MODE2) {
+   if (!kfifo_is_empty(>rawir))
+   events = POLLIN | POLLRDNORM;
+   }
 
return events;
 }
 
-static ssize_t ir_lirc_read(struct file *file, char __user *buffer,
-   size_t length, loff_t *ppos)
+static ssize_t ir_lirc_read_mode2(struct file *file, char __user *buffer,
+ size_t length)
 {
struct rc_dev *rcdev = file->private_data;
unsigned int copied;
@@ -483,9 +501,6 @@ static ssize_t ir_lirc_read(struct file *file, char __user 
*buffer,
if (length < sizeof(unsigned int) || length % sizeof(unsigned int))
return -EINVAL;
 
-   if (!rcdev->registered)
-   return -ENODEV;
-
do {
if (kfifo_is_empty(>rawir)) {
  

[PATCH 07/20] media: promote lirc_zilog out of staging

2017-09-26 Thread Sean Young
Rename to zilog_ir in the process.

Signed-off-by: Sean Young 
---
 drivers/media/rc/Kconfig   | 12 
 drivers/media/rc/Makefile  |  1 +
 .../lirc/lirc_zilog.c => media/rc/zilog_ir.c}  |  0
 drivers/staging/media/Kconfig  |  3 --
 drivers/staging/media/Makefile |  1 -
 drivers/staging/media/lirc/Kconfig | 21 -
 drivers/staging/media/lirc/Makefile|  6 
 drivers/staging/media/lirc/TODO| 36 --
 8 files changed, 13 insertions(+), 67 deletions(-)
 rename drivers/{staging/media/lirc/lirc_zilog.c => media/rc/zilog_ir.c} (100%)
 delete mode 100644 drivers/staging/media/lirc/Kconfig
 delete mode 100644 drivers/staging/media/lirc/Makefile
 delete mode 100644 drivers/staging/media/lirc/TODO

diff --git a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig
index 467cf2bdbd42..e8f7570fc501 100644
--- a/drivers/media/rc/Kconfig
+++ b/drivers/media/rc/Kconfig
@@ -468,6 +468,18 @@ config IR_SIR
   To compile this driver as a module, choose M here: the module will
   be called sir-ir.
 
+config IR_ZILOG
+   tristate "Zilog/Hauppauge IR Transmitter"
+   depends on RC_CORE
+   depends on LIRC
+   depends on I2C
+   ---help---
+  Driver for the Zilog/Hauppauge IR Transmitter, found on
+  PVR-150/500, HVR-1200/1250/1700/1800, HD-PVR and other cards
+
+  To compile this driver as a module, choose M here: the
+  module will be called zilog_ir.
+
 config IR_ZX
tristate "ZTE ZX IR remote control"
depends on RC_CORE
diff --git a/drivers/media/rc/Makefile b/drivers/media/rc/Makefile
index 9bc6a3980ed0..efdcf2318448 100644
--- a/drivers/media/rc/Makefile
+++ b/drivers/media/rc/Makefile
@@ -43,4 +43,5 @@ obj-$(CONFIG_IR_IMG) += img-ir/
 obj-$(CONFIG_IR_SERIAL) += serial_ir.o
 obj-$(CONFIG_IR_SIR) += sir_ir.o
 obj-$(CONFIG_IR_MTK) += mtk-cir.o
+obj-$(CONFIG_IR_ZILOG) += zilog_ir.o
 obj-$(CONFIG_IR_ZX) += zx-irdec.o
diff --git a/drivers/staging/media/lirc/lirc_zilog.c 
b/drivers/media/rc/zilog_ir.c
similarity index 100%
rename from drivers/staging/media/lirc/lirc_zilog.c
rename to drivers/media/rc/zilog_ir.c
diff --git a/drivers/staging/media/Kconfig b/drivers/staging/media/Kconfig
index f8c25ee082ef..3a09140700e6 100644
--- a/drivers/staging/media/Kconfig
+++ b/drivers/staging/media/Kconfig
@@ -31,7 +31,4 @@ source "drivers/staging/media/imx/Kconfig"
 
 source "drivers/staging/media/omap4iss/Kconfig"
 
-# Keep LIRC at the end, as it has sub-menus
-source "drivers/staging/media/lirc/Kconfig"
-
 endif
diff --git a/drivers/staging/media/Makefile b/drivers/staging/media/Makefile
index ac090c5fce30..9c057126d61f 100644
--- a/drivers/staging/media/Makefile
+++ b/drivers/staging/media/Makefile
@@ -1,7 +1,6 @@
 obj-$(CONFIG_I2C_BCM2048)  += bcm2048/
 obj-$(CONFIG_DVB_CXD2099)  += cxd2099/
 obj-$(CONFIG_VIDEO_IMX_MEDIA)  += imx/
-obj-$(CONFIG_LIRC_STAGING) += lirc/
 obj-$(CONFIG_VIDEO_DM365_VPFE) += davinci_vpfe/
 obj-$(CONFIG_VIDEO_OMAP4)  += omap4iss/
 obj-$(CONFIG_INTEL_ATOMISP) += atomisp/
diff --git a/drivers/staging/media/lirc/Kconfig 
b/drivers/staging/media/lirc/Kconfig
deleted file mode 100644
index 3e350a9922de..
--- a/drivers/staging/media/lirc/Kconfig
+++ /dev/null
@@ -1,21 +0,0 @@
-#
-# LIRC driver(s) configuration
-#
-menuconfig LIRC_STAGING
-   bool "Linux Infrared Remote Control IR receiver/transmitter drivers"
-   depends on LIRC
-   help
- Say Y here, and all supported Linux Infrared Remote Control IR and
- RF receiver and transmitter drivers will be displayed. When paired
- with a remote control and the lirc daemon, the receiver drivers
- allow control of your Linux system via remote control.
-
-if LIRC_STAGING
-
-config LIRC_ZILOG
-   tristate "Zilog/Hauppauge IR Transmitter"
-   depends on LIRC && I2C
-   help
- Driver for the Zilog/Hauppauge IR Transmitter, found on
- PVR-150/500, HVR-1200/1250/1700/1800, HD-PVR and other cards
-endif
diff --git a/drivers/staging/media/lirc/Makefile 
b/drivers/staging/media/lirc/Makefile
deleted file mode 100644
index 665562436e30..
--- a/drivers/staging/media/lirc/Makefile
+++ /dev/null
@@ -1,6 +0,0 @@
-# Makefile for the lirc drivers.
-#
-
-# Each configuration option enables a list of files.
-
-obj-$(CONFIG_LIRC_ZILOG)   += lirc_zilog.o
diff --git a/drivers/staging/media/lirc/TODO b/drivers/staging/media/lirc/TODO
deleted file mode 100644
index a97800a8e127..
--- a/drivers/staging/media/lirc/TODO
+++ /dev/null
@@ -1,36 +0,0 @@
-1. Both ir-kbd-i2c and lirc_zilog provide support for RX events for
-the chips supported by lirc_zilog.  Before moving lirc_zilog out of staging:
-
-a. ir-kbd-i2c needs a module parameter added to allow the user to tell
-   ir-kbd-i2c to ignore Z8 IR 

[PATCH 15/20] media: lirc: remove name from lirc_dev

2017-09-26 Thread Sean Young
This is a duplicate of rcdev->driver_name.

Signed-off-by: Sean Young 
---
 Documentation/media/uapi/rc/lirc-dev-intro.rst | 2 +-
 drivers/media/rc/ir-lirc-codec.c   | 2 --
 drivers/media/rc/lirc_dev.c| 9 +++--
 include/media/lirc_dev.h   | 2 --
 4 files changed, 4 insertions(+), 11 deletions(-)

diff --git a/Documentation/media/uapi/rc/lirc-dev-intro.rst 
b/Documentation/media/uapi/rc/lirc-dev-intro.rst
index 3cacf9aeac40..a3fa3c1ef169 100644
--- a/Documentation/media/uapi/rc/lirc-dev-intro.rst
+++ b/Documentation/media/uapi/rc/lirc-dev-intro.rst
@@ -18,7 +18,7 @@ Example dmesg output upon a driver registering w/LIRC:
 
 $ dmesg |grep lirc_dev
 lirc_dev: IR Remote Control driver registered, major 248
-rc rc0: lirc_dev: driver ir-lirc-codec (mceusb) registered at minor = 0
+rc rc0: lirc_dev: driver mceusb registered at minor = 0
 
 What you should see for a chardev:
 
diff --git a/drivers/media/rc/ir-lirc-codec.c b/drivers/media/rc/ir-lirc-codec.c
index 0b956ff09740..b6e20ddcd915 100644
--- a/drivers/media/rc/ir-lirc-codec.c
+++ b/drivers/media/rc/ir-lirc-codec.c
@@ -534,8 +534,6 @@ int ir_lirc_register(struct rc_dev *dev)
if (!ldev)
return rc;
 
-   snprintf(ldev->name, sizeof(ldev->name), "ir-lirc-codec (%s)",
-dev->driver_name);
ldev->fops = _fops;
ldev->dev.parent = >dev;
ldev->rdev = dev;
diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c
index 32124fb5c88e..4ac74fd86fd4 100644
--- a/drivers/media/rc/lirc_dev.c
+++ b/drivers/media/rc/lirc_dev.c
@@ -101,9 +101,6 @@ int lirc_register_device(struct lirc_dev *d)
return -EINVAL;
}
 
-   /* some safety check 8-) */
-   d->name[sizeof(d->name) - 1] = '\0';
-
if (rcdev->driver_type == RC_DRIVER_IR_RAW) {
if (kfifo_alloc(>rawir, MAX_IR_EVENT_SIZE, GFP_KERNEL))
return -ENOMEM;
@@ -131,7 +128,7 @@ int lirc_register_device(struct lirc_dev *d)
get_device(d->dev.parent);
 
dev_info(>dev, "lirc_dev: driver %s registered at minor = %d\n",
-d->name, d->minor);
+rcdev->driver_name, d->minor);
 
return 0;
 }
@@ -147,13 +144,13 @@ void lirc_unregister_device(struct lirc_dev *d)
rcdev = d->rdev;
 
dev_dbg(>dev, "lirc_dev: driver %s unregistered from minor = %d\n",
-   d->name, d->minor);
+   rcdev->driver_name, d->minor);
 
mutex_lock(>lock);
 
if (rcdev->lirc_open) {
dev_dbg(>dev, LOGHEAD "releasing opened driver\n",
-   d->name, d->minor);
+   rcdev->driver_name, d->minor);
wake_up_poll(>wait_poll, POLLHUP);
}
 
diff --git a/include/media/lirc_dev.h b/include/media/lirc_dev.h
index b45af81b4633..d12e1d1c3d67 100644
--- a/include/media/lirc_dev.h
+++ b/include/media/lirc_dev.h
@@ -21,7 +21,6 @@
 /**
  * struct lirc_dev - represents a LIRC device
  *
- * @name:  used for logging
  * @minor: the minor device (/dev/lircX) number for the device
  * @rdev:   rc_dev associated with the device
  * @fops:   file_operations for the device
@@ -30,7 +29,6 @@
  * @cdev:   cdev assigned to the device
  */
 struct lirc_dev {
-   char name[40];
unsigned int minor;
 
struct rc_dev *rdev;
-- 
2.13.5



[PATCH 16/20] media: lirc: be gone, lirc kernel api!

2017-09-26 Thread Sean Young
The lirc kernel api sneaked its way in along with the lirc drivers; it
was terrible, but now the last step can be done to banish it forever.

All future drivers should use the rc-core api.

Signed-off-by: Sean Young 
---
 Documentation/media/kapi/rc-core.rst |   5 --
 drivers/media/rc/ir-lirc-codec.c |  42 +-
 drivers/media/rc/lirc_dev.c  | 145 ---
 drivers/media/rc/rc-core-priv.h  |   3 +
 drivers/media/rc/rc-main.c   |   1 -
 include/media/lirc_dev.h |  50 
 include/media/rc-core.h  |   8 +-
 7 files changed, 60 insertions(+), 194 deletions(-)
 delete mode 100644 include/media/lirc_dev.h

diff --git a/Documentation/media/kapi/rc-core.rst 
b/Documentation/media/kapi/rc-core.rst
index a45895886257..41c2256dbf6a 100644
--- a/Documentation/media/kapi/rc-core.rst
+++ b/Documentation/media/kapi/rc-core.rst
@@ -7,8 +7,3 @@ Remote Controller core
 .. kernel-doc:: include/media/rc-core.h
 
 .. kernel-doc:: include/media/rc-map.h
-
-LIRC
-
-
-.. kernel-doc:: include/media/lirc_dev.h
diff --git a/drivers/media/rc/ir-lirc-codec.c b/drivers/media/rc/ir-lirc-codec.c
index b6e20ddcd915..fb5df6c8208f 100644
--- a/drivers/media/rc/ir-lirc-codec.c
+++ b/drivers/media/rc/ir-lirc-codec.c
@@ -12,10 +12,10 @@
  *  GNU General Public License for more details.
  */
 
+#include 
 #include 
 #include 
 #include 
-#include 
 #include 
 #include "rc-core-priv.h"
 
@@ -90,8 +90,8 @@ void ir_lirc_raw_event(struct rc_dev *dev, struct 
ir_raw_event ev)
 
 static int ir_lirc_open(struct inode *inode, struct file *file)
 {
-   struct lirc_dev *d = container_of(inode->i_cdev, struct lirc_dev, cdev);
-   struct rc_dev *dev = d->rdev;
+   struct rc_dev *dev = container_of(inode->i_cdev, struct rc_dev,
+ lirc_cdev);
int retval;
 
retval = rc_open(dev);
@@ -511,7 +511,7 @@ static ssize_t ir_lirc_read(struct file *file, char __user 
*buffer,
return copied;
 }
 
-static const struct file_operations lirc_fops = {
+const struct file_operations lirc_fops = {
.owner  = THIS_MODULE,
.write  = ir_lirc_transmit_ir,
.unlocked_ioctl = ir_lirc_ioctl,
@@ -524,37 +524,3 @@ static const struct file_operations lirc_fops = {
.release= ir_lirc_close,
.llseek = no_llseek,
 };
-
-int ir_lirc_register(struct rc_dev *dev)
-{
-   struct lirc_dev *ldev;
-   int rc = -ENOMEM;
-
-   ldev = lirc_allocate_device();
-   if (!ldev)
-   return rc;
-
-   ldev->fops = _fops;
-   ldev->dev.parent = >dev;
-   ldev->rdev = dev;
-   ldev->owner = THIS_MODULE;
-
-   rc = lirc_register_device(ldev);
-   if (rc < 0)
-   goto out;
-
-   dev->send_mode = LIRC_MODE_PULSE;
-
-   dev->lirc_dev = ldev;
-   return 0;
-
-out:
-   lirc_free_device(ldev);
-   return rc;
-}
-
-void ir_lirc_unregister(struct rc_dev *dev)
-{
-   lirc_unregister_device(dev->lirc_dev);
-   dev->lirc_dev = NULL;
-}
diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c
index 4ac74fd86fd4..155a4de249a0 100644
--- a/drivers/media/rc/lirc_dev.c
+++ b/drivers/media/rc/lirc_dev.c
@@ -18,24 +18,19 @@
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include 
-#include 
-#include 
-#include 
 #include 
 #include 
-#include 
 #include 
+#include 
 
 #include "rc-core-priv.h"
 #include 
-#include 
 
 #define LOGHEAD"lirc_dev (%s[%d]): "
 
 static dev_t lirc_base_dev;
 
 /* Used to keep track of allocated lirc devices */
-#define LIRC_MAX_DEVICES 256
 static DEFINE_IDA(lirc_ida);
 
 /* Only used for sysfs but defined to void otherwise */
@@ -43,124 +38,80 @@ static struct class *lirc_class;
 
 static void lirc_release_device(struct device *ld)
 {
-   struct lirc_dev *d = container_of(ld, struct lirc_dev, dev);
-   struct rc_dev *rcdev = d->rdev;
+   struct rc_dev *rcdev = container_of(ld, struct rc_dev, lirc_dev);
 
if (rcdev->driver_type == RC_DRIVER_IR_RAW)
kfifo_free(>rawir);
 
-   kfree(d);
-   module_put(THIS_MODULE);
-   put_device(d->dev.parent);
-}
-
-struct lirc_dev *
-lirc_allocate_device(void)
-{
-   struct lirc_dev *d;
-
-   d = kzalloc(sizeof(*d), GFP_KERNEL);
-   if (d) {
-   device_initialize(>dev);
-   d->dev.class = lirc_class;
-   d->dev.release = lirc_release_device;
-   __module_get(THIS_MODULE);
-   }
-
-   return d;
-}
-EXPORT_SYMBOL(lirc_allocate_device);
-
-void lirc_free_device(struct lirc_dev *d)
-{
-   if (!d)
-   return;
-
-   put_device(>dev);
+   put_device(>dev);
 }
-EXPORT_SYMBOL(lirc_free_device);
 
-int lirc_register_device(struct lirc_dev *d)
+int ir_lirc_register(struct rc_dev *dev)
 {
-   struct rc_dev *rcdev = d->rdev;
-   int minor;
-   int err;
+   

[PATCH 04/20] media: lirc_zilog: remove receiver

2017-09-26 Thread Sean Young
The ir-kbd-i2c module already handles this very well.

Signed-off-by: Sean Young 
---
 drivers/staging/media/lirc/lirc_zilog.c | 901 +++-
 1 file changed, 76 insertions(+), 825 deletions(-)

diff --git a/drivers/staging/media/lirc/lirc_zilog.c 
b/drivers/staging/media/lirc/lirc_zilog.c
index 6bd0717bf76e..757b3fc247ac 100644
--- a/drivers/staging/media/lirc/lirc_zilog.c
+++ b/drivers/staging/media/lirc/lirc_zilog.c
@@ -64,28 +64,7 @@
 /* Max transfer size done by I2C transfer functions */
 #define MAX_XFER_SIZE  64
 
-struct IR;
-
-struct IR_rx {
-   struct kref ref;
-   struct IR *ir;
-
-   /* RX device */
-   struct mutex client_lock;
-   struct i2c_client *c;
-
-   /* RX polling thread data */
-   struct task_struct *task;
-
-   /* RX read data */
-   unsigned char b[3];
-   bool hdpvr_data_fmt;
-};
-
 struct IR_tx {
-   struct kref ref;
-   struct IR *ir;
-
/* TX device */
struct mutex client_lock;
struct i2c_client *c;
@@ -93,39 +72,9 @@ struct IR_tx {
/* TX additional actions needed */
int need_boot;
bool post_tx_ready_poll;
-};
-
-struct IR {
-   struct kref ref;
-   struct list_head list;
-
-   /* FIXME spinlock access to l->features */
struct lirc_dev *l;
-   struct lirc_buffer rbuf;
-
-   struct mutex ir_lock;
-   atomic_t open_count;
-
-   struct device *dev;
-   struct i2c_adapter *adapter;
-
-   spinlock_t rx_ref_lock; /* struct IR_rx kref get()/put() */
-   struct IR_rx *rx;
-
-   spinlock_t tx_ref_lock; /* struct IR_tx kref get()/put() */
-   struct IR_tx *tx;
 };
 
-/* IR transceiver instance object list */
-/*
- * This lock is used for the following:
- * a. ir_devices_list access, insertions, deletions
- * b. struct IR kref get()s and put()s
- * c. serialization of ir_probe() for the two i2c_clients for a Z8
- */
-static DEFINE_MUTEX(ir_devices_lock);
-static LIST_HEAD(ir_devices_list);
-
 /* Block size for IR transmitter */
 #define TX_BLOCK_SIZE  99
 
@@ -153,348 +102,8 @@ struct tx_data_struct {
 static struct tx_data_struct *tx_data;
 static struct mutex tx_data_lock;
 
-
 /* module parameters */
 static bool debug; /* debug output */
-static bool tx_only;   /* only handle the IR Tx function */
-
-
-/* struct IR reference counting */
-static struct IR *get_ir_device(struct IR *ir, bool ir_devices_lock_held)
-{
-   if (ir_devices_lock_held) {
-   kref_get(>ref);
-   } else {
-   mutex_lock(_devices_lock);
-   kref_get(>ref);
-   mutex_unlock(_devices_lock);
-   }
-   return ir;
-}
-
-static void release_ir_device(struct kref *ref)
-{
-   struct IR *ir = container_of(ref, struct IR, ref);
-
-   /*
-* Things should be in this state by now:
-* ir->rx set to NULL and deallocated - happens before ir->rx->ir put()
-* ir->rx->task kthread stopped - happens before ir->rx->ir put()
-* ir->tx set to NULL and deallocated - happens before ir->tx->ir put()
-* ir->open_count ==  0 - happens on final close()
-* ir_lock, tx_ref_lock, rx_ref_lock, all released
-*/
-   if (ir->l)
-   lirc_unregister_device(ir->l);
-
-   if (kfifo_initialized(>rbuf.fifo))
-   lirc_buffer_free(>rbuf);
-   list_del(>list);
-   kfree(ir);
-}
-
-static int put_ir_device(struct IR *ir, bool ir_devices_lock_held)
-{
-   int released;
-
-   if (ir_devices_lock_held)
-   return kref_put(>ref, release_ir_device);
-
-   mutex_lock(_devices_lock);
-   released = kref_put(>ref, release_ir_device);
-   mutex_unlock(_devices_lock);
-
-   return released;
-}
-
-/* struct IR_rx reference counting */
-static struct IR_rx *get_ir_rx(struct IR *ir)
-{
-   struct IR_rx *rx;
-
-   spin_lock(>rx_ref_lock);
-   rx = ir->rx;
-   if (rx)
-   kref_get(>ref);
-   spin_unlock(>rx_ref_lock);
-   return rx;
-}
-
-static void destroy_rx_kthread(struct IR_rx *rx, bool ir_devices_lock_held)
-{
-   /* end up polling thread */
-   if (!IS_ERR_OR_NULL(rx->task)) {
-   kthread_stop(rx->task);
-   rx->task = NULL;
-   /* Put the ir ptr that ir_probe() gave to the rx poll thread */
-   put_ir_device(rx->ir, ir_devices_lock_held);
-   }
-}
-
-static void release_ir_rx(struct kref *ref)
-{
-   struct IR_rx *rx = container_of(ref, struct IR_rx, ref);
-   struct IR *ir = rx->ir;
-
-   /*
-* This release function can't do all the work, as we want
-* to keep the rx_ref_lock a spinlock, and killing the poll thread
-* and releasing the ir reference can cause a sleep.  That work is
-* performed by put_ir_rx()
-*/
-   ir->l->features &= ~LIRC_CAN_REC_LIRCCODE;
-   /* Don't put_ir_device(rx->ir) here; lock can't be freed 

[PATCH 06/20] media: lirc_zilog: port to rc-core using scancode tx interface

2017-09-26 Thread Sean Young
Now that rc-core can send a scancode by rc protocol and scancode, port
the lirc_zilog to this interface. The firmware file needs updating
to contain the protocol and scancode, so we have haup-ir-blaster-v2.bin
for this.

The LIRC_MODE_LIRCCODE is no longer supported, and transmit can only
be done using the new LIRC_MODE_SCANCODE interface.

Signed-off-by: Sean Young 
---
 drivers/media/rc/ir-lirc-codec.c|  18 +-
 drivers/staging/media/lirc/lirc_zilog.c | 419 
 include/media/rc-core.h |   2 +
 3 files changed, 166 insertions(+), 273 deletions(-)

diff --git a/drivers/media/rc/ir-lirc-codec.c b/drivers/media/rc/ir-lirc-codec.c
index ff7c46cc201c..6fd19b816d92 100644
--- a/drivers/media/rc/ir-lirc-codec.c
+++ b/drivers/media/rc/ir-lirc-codec.c
@@ -122,6 +122,10 @@ static ssize_t ir_lirc_transmit_ir(struct file *file, 
const char __user *buf,
if (!lirc)
return -EFAULT;
 
+   dev = lirc->dev;
+   if (!dev)
+   return -EFAULT;
+
if (lirc->send_mode == LIRC_MODE_SCANCODE) {
struct lirc_scancode scan;
 
@@ -135,6 +139,11 @@ static ssize_t ir_lirc_transmit_ir(struct file *file, 
const char __user *buf,
scan.timestamp)
return -EINVAL;
 
+   if (dev->tx_scancode) {
+   ret = dev->tx_scancode(dev, );
+   return ret < 0 ? ret : n;
+   }
+
raw = kmalloc_array(LIRCBUF_SIZE, sizeof(*raw), GFP_KERNEL);
if (!raw)
return -ENOMEM;
@@ -175,12 +184,6 @@ static ssize_t ir_lirc_transmit_ir(struct file *file, 
const char __user *buf,
return PTR_ERR(txbuf);
}
 
-   dev = lirc->dev;
-   if (!dev) {
-   ret = -EFAULT;
-   goto out;
-   }
-
if (!dev->tx_ir) {
ret = -EINVAL;
goto out;
@@ -406,6 +409,9 @@ static int ir_lirc_register(struct rc_dev *dev)
features |= LIRC_CAN_GET_REC_RESOLUTION;
}
 
+   if (dev->tx_scancode)
+   features |= LIRC_CAN_SEND_SCANCODE;
+
if (dev->tx_ir) {
features |= LIRC_CAN_SEND_PULSE | LIRC_CAN_SEND_SCANCODE;
if (dev->s_tx_mask)
diff --git a/drivers/staging/media/lirc/lirc_zilog.c 
b/drivers/staging/media/lirc/lirc_zilog.c
index d3225bd1b3a6..c7f1636abf38 100644
--- a/drivers/staging/media/lirc/lirc_zilog.c
+++ b/drivers/staging/media/lirc/lirc_zilog.c
@@ -41,11 +41,11 @@
 #include 
 #include 
 
-#include 
-#include 
+#include 
 
+#define DEVICE_NAME"Zilog/Hauppauge i2c IR TX"
 /* Max transfer size done by I2C transfer functions */
-#define MAX_XFER_SIZE  64
+#define MAX_XFER_SIZE  64
 
 struct IR_tx {
/* TX device */
@@ -55,7 +55,8 @@ struct IR_tx {
/* TX additional actions needed */
bool need_boot;
bool post_tx_ready_poll;
-   struct lirc_dev *l;
+   struct rc_dev *rc;
+   char phys[32];
 };
 
 /* Block size for IR transmitter */
@@ -115,102 +116,99 @@ static int skip(u8 **data,
 }
 
 /* decompress key data into the given buffer */
-static int get_key_data(u8 *buf,
-   unsigned int codeset, unsigned int key)
+static int get_key_data(u8 *buf, enum rc_proto proto, u32 scancode)
 {
u8 *data, *endp, *diffs, *key_block;
-   u8 keys, ndiffs, id;
-   unsigned int base, lim, pos, i;
+   unsigned int lim, i, k, codeset;
+   u8 keys, ndiffs, p;
+   u32 protocols, s;
 
/* Binary search for the codeset */
-   for (base = 0, lim = tx_data->num_code_sets; lim; lim >>= 1) {
-   pos = base + (lim >> 1);
-   data = tx_data->code_sets[pos];
+   for (codeset = 0; codeset < tx_data->num_code_sets; codeset++) {
+   data = tx_data->code_sets[codeset];
 
-   if (!read_u32(, tx_data->endp, ))
+   /* bitset protocols contained in this codeset */
+   if (!read_u32(, tx_data->endp, ))
goto corrupt;
 
-   if (i == codeset) {
-   break;
-   } else if (codeset > i) {
-   base = pos + 1;
-   --lim;
-   }
-   }
-   /* Not found? */
-   if (!lim)
-   return -EPROTO;
-
-   /* Set end of data block */
-   endp = pos < tx_data->num_code_sets - 1 ?
-   tx_data->code_sets[pos + 1] : tx_data->endp;
-
-   /* Read the block header */
-   if (!read_u8(, endp, ) ||
-   !read_u8(, endp, ) ||
-   ndiffs > TX_BLOCK_SIZE || keys == 0)
-   goto corrupt;
+   if (!(BIT(proto) & protocols))
+   continue;
 
-   /* Save diffs & skip */
-   diffs = data;
-   if (!skip(, endp, ndiffs))
-   goto corrupt;
+   /* Set end of data 

[PATCH 11/20] media: lirc: use kfifo rather than lirc_buffer for raw IR

2017-09-26 Thread Sean Young
Since the only mode lirc devices can handle is raw IR, handle this
in a plain kfifo.

Remove lirc_buffer since this is no longer needed.

Signed-off-by: Sean Young 
---
 drivers/media/rc/ir-lirc-codec.c |  75 ---
 drivers/media/rc/lirc_dev.c  | 191 ---
 include/media/lirc_dev.h | 109 --
 include/media/rc-core.h  |   4 +
 4 files changed, 81 insertions(+), 298 deletions(-)

diff --git a/drivers/media/rc/ir-lirc-codec.c b/drivers/media/rc/ir-lirc-codec.c
index f96f2a2c4eb1..1f4514fc1d8b 100644
--- a/drivers/media/rc/ir-lirc-codec.c
+++ b/drivers/media/rc/ir-lirc-codec.c
@@ -66,8 +66,6 @@ void ir_lirc_raw_event(struct rc_dev *dev, struct 
ir_raw_event ev)
} else {
 
if (dev->gap) {
-   int gap_sample;
-
dev->gap_duration += ktime_to_ns(ktime_sub(ktime_get(),
 dev->gap_start));
 
@@ -76,9 +74,7 @@ void ir_lirc_raw_event(struct rc_dev *dev, struct 
ir_raw_event ev)
dev->gap_duration = min_t(u64, dev->gap_duration,
  LIRC_VALUE_MASK);
 
-   gap_sample = LIRC_SPACE(dev->gap_duration);
-   lirc_buffer_write(dev->lirc_dev->buf,
- (unsigned char *)_sample);
+   kfifo_put(>rawir, LIRC_SPACE(dev->gap_duration));
dev->gap = false;
}
 
@@ -88,10 +84,8 @@ void ir_lirc_raw_event(struct rc_dev *dev, struct 
ir_raw_event ev)
   TO_US(ev.duration), TO_STR(ev.pulse));
}
 
-   lirc_buffer_write(dev->lirc_dev->buf,
- (unsigned char *) );
-
-   wake_up(>lirc_dev->buf->wait_poll);
+   kfifo_put(>rawir, sample);
+   wake_up_poll(>wait_poll, POLLIN | POLLRDNORM);
 }
 
 static ssize_t ir_lirc_transmit_ir(struct file *file, const char __user *buf,
@@ -402,6 +396,62 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int 
cmd,
return ret;
 }
 
+static unsigned int ir_lirc_poll(struct file *file,
+struct poll_table_struct *wait)
+{
+   struct rc_dev *rcdev = file->private_data;
+   struct lirc_dev *d = rcdev->lirc_dev;
+   unsigned int events = 0;
+
+   poll_wait(file, >wait_poll, wait);
+
+   if (!d->attached)
+   events = POLLHUP | POLLERR;
+   else if (!kfifo_is_empty(>rawir))
+   events = POLLIN | POLLRDNORM;
+
+   return events;
+}
+
+static ssize_t ir_lirc_read(struct file *file, char __user *buffer,
+   size_t length, loff_t *ppos)
+{
+   struct rc_dev *rcdev = file->private_data;
+   struct lirc_dev *d = rcdev->lirc_dev;
+   unsigned int copied;
+   int ret;
+
+   if (length < sizeof(unsigned int) || length % sizeof(unsigned int))
+   return -EINVAL;
+
+   if (!d->attached)
+   return -ENODEV;
+
+   do {
+   if (kfifo_is_empty(>rawir)) {
+   if (file->f_flags & O_NONBLOCK)
+   return -EAGAIN;
+
+   ret = wait_event_interruptible(rcdev->wait_poll,
+   !kfifo_is_empty(>rawir) ||
+   !d->attached);
+   if (ret)
+   return ret;
+   }
+
+   if (!d->attached)
+   return -ENODEV;
+
+   mutex_lock(>lock);
+   ret = kfifo_to_user(>rawir, buffer, length, );
+   mutex_unlock(>lock);
+   if (ret)
+   return ret;
+   } while (copied == 0);
+
+   return copied;
+}
+
 static const struct file_operations lirc_fops = {
.owner  = THIS_MODULE,
.write  = ir_lirc_transmit_ir,
@@ -409,8 +459,8 @@ static const struct file_operations lirc_fops = {
 #ifdef CONFIG_COMPAT
.compat_ioctl   = ir_lirc_ioctl,
 #endif
-   .read   = lirc_dev_fop_read,
-   .poll   = lirc_dev_fop_poll,
+   .read   = ir_lirc_read,
+   .poll   = ir_lirc_poll,
.open   = lirc_dev_fop_open,
.release= lirc_dev_fop_close,
.llseek = no_llseek,
@@ -427,9 +477,6 @@ int ir_lirc_register(struct rc_dev *dev)
 
snprintf(ldev->name, sizeof(ldev->name), "ir-lirc-codec (%s)",
 dev->driver_name);
-   ldev->buf = NULL;
-   ldev->chunk_size = sizeof(int);
-   ldev->buffer_size = LIRCBUF_SIZE;
ldev->fops = _fops;
ldev->dev.parent = >dev;
ldev->rdev = dev;
diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c
index f149fbf382ca..9a0ad8d9a0cb 100644
--- a/drivers/media/rc/lirc_dev.c
+++ 

[PATCH 00/20] lirc scancode interface, and more

2017-09-26 Thread Sean Young
Introduce lirc scancode mode, use that to port lirc_zilog to rc-core
using that interface, and then remove the lirc kernel api.

In summary:
 - This removes the lirc staging directory.
 - lirc IR TX can use in-kernel encoders for scancode encoding
 - lirc_zilog uses the same interface
 - lirc kapi (not uapi!) is gone
 - The reading lirc scancode gives more information (e.g. protocol,
   toggle, repeat). So you can determine what protocol variant a remotes uses
 - Line count is actually down and code cleaner (imo)
 - The scancode interface can be used for cec keycode transmit.

On the cec keycode transmit I am hoping for feedback. Also I am ensure what
to do with the new firmware file for the zilog_ir.

Sean Young (20):
  media: lirc: implement scancode sending
  media: lirc: use the correct carrier for scancode transmit
  media: rc: auto load encoder if necessary
  media: lirc_zilog: remove receiver
  media: lirc_zilog: fix variable types and other ugliness
  media: lirc_zilog: port to rc-core using scancode tx interface
  media: promote lirc_zilog out of staging
  media: lirc: remove LIRCCODE and LIRC_GET_LENGTH
  media: lirc: lirc interface should not be a raw decoder
  media: lirc: merge lirc_dev_fop_ioctl and ir_lirc_ioctl
  media: lirc: use kfifo rather than lirc_buffer for raw IR
  media: lirc: move lirc_dev->attached to rc_dev->registered
  media: lirc: do not call rc_close() on unregistered devices
  media: lirc: create rc-core open and close lirc functions
  media: lirc: remove name from lirc_dev
  media: lirc: be gone, lirc kernel api!
  media: lirc: implement reading scancode
  media: lirc: introduce LIRC_SET_POLL_MODE
  media: lirc: scancode rc devices should have a lirc device too
  media: lirc: document LIRC_MODE_SCANCODE

 Documentation/media/kapi/rc-core.rst   |5 -
 Documentation/media/lirc.h.rst.exceptions  |   49 +
 Documentation/media/uapi/rc/lirc-dev-intro.rst |   42 +-
 Documentation/media/uapi/rc/lirc-func.rst  |2 +-
 Documentation/media/uapi/rc/lirc-get-features.rst  |   17 +-
 Documentation/media/uapi/rc/lirc-get-length.rst|   44 -
 Documentation/media/uapi/rc/lirc-get-rec-mode.rst  |8 +-
 Documentation/media/uapi/rc/lirc-get-send-mode.rst |5 +-
 Documentation/media/uapi/rc/lirc-read.rst  |6 +
 Documentation/media/uapi/rc/lirc-set-poll-mode.rst |   44 +
 Documentation/media/uapi/rc/lirc-write.rst |8 +
 drivers/media/rc/Kconfig   |   41 +-
 drivers/media/rc/Makefile  |5 +-
 drivers/media/rc/ir-jvc-decoder.c  |1 +
 drivers/media/rc/ir-lirc-codec.c   |  513 --
 drivers/media/rc/ir-mce_kbd-decoder.c  |7 +
 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/lirc_dev.c|  480 +-
 drivers/media/rc/rc-core-priv.h|   53 +-
 drivers/media/rc/rc-ir-raw.c   |   56 +-
 drivers/media/rc/rc-main.c |   72 +-
 drivers/media/rc/zilog_ir.c|  739 +
 drivers/staging/media/Kconfig  |3 -
 drivers/staging/media/Makefile |1 -
 drivers/staging/media/lirc/Kconfig |   21 -
 drivers/staging/media/lirc/Makefile|6 -
 drivers/staging/media/lirc/TODO|   36 -
 drivers/staging/media/lirc/lirc_zilog.c| 1653 
 include/media/lirc_dev.h   |  192 ---
 include/media/rc-core.h|   55 +-
 include/media/rc-map.h |   54 +-
 include/uapi/linux/lirc.h  |   93 ++
 37 files changed, 1605 insertions(+), 2712 deletions(-)
 delete mode 100644 Documentation/media/uapi/rc/lirc-get-length.rst
 create mode 100644 Documentation/media/uapi/rc/lirc-set-poll-mode.rst
 create mode 100644 drivers/media/rc/zilog_ir.c
 delete mode 100644 drivers/staging/media/lirc/Kconfig
 delete mode 100644 drivers/staging/media/lirc/Makefile
 delete mode 100644 drivers/staging/media/lirc/TODO
 delete mode 100644 drivers/staging/media/lirc/lirc_zilog.c
 delete mode 100644 include/media/lirc_dev.h

-- 
2.13.5



s5p-mfc - WARNING: possible circular locking dependency detected,[ 4.14.0-rc2

2017-09-26 Thread Shuah Khan
When running gstreamer pipeline with s5p-mfc → exynos-gsc→ exynos-drm,
I am seeing circular locking dependency detected warning in 4.14-rc2.
This is a regression from 4.13. The pipeline does run to completion
video streaming works. Are you aware of this problem, or would you
like it to be bisected.

gst-launch-1.0 filesrc location=/media/shuah_arm/GH3_MOV_HD.mp4 ! qtdemux ! 
h264parse ! v4l2video4dec capture-io-mode=dmabuf ! v4l2video7convert 
output-io-mode=dmabuf-import ! kmssink force-modesetting=true

[ 2134.994539] ==
[ 2135.000661] WARNING: possible circular locking dependency detected
[ 2135.006815] 4.14.0-rc2 #1 Not tainted
[ 2135.010452] --
[ 2135.016606] qtdemux0:sink/2700 is trying to acquire lock:
[ 2135.021978]  (>mfc_mutex){+.+.}, at: [] 
s5p_mfc_mmap+0x28/0xd4 [s5p_mfc]
[ 2135.029950]
   but task is already holding lock:
[ 2135.035755]  (>mmap_sem){}, at: [] vm_mmap_pgoff+0x44/0xb8
[ 2135.042774]
   which lock already depends on the new lock.

[ 2135.050920]
   the existing dependency chain (in reverse order) is:
[ 2135.058372]
   -> #2 (>mmap_sem){}:
[ 2135.063751]__might_fault+0x80/0xb0
[ 2135.067822]filldir64+0xc0/0x2f8
[ 2135.071635]call_filldir+0xb0/0x14c
[ 2135.075705]ext4_readdir+0x768/0x90c
[ 2135.079864]iterate_dir+0x74/0x168
[ 2135.083851]SyS_getdents64+0x7c/0x1a0
[ 2135.088099]ret_fast_syscall+0x0/0x28
[ 2135.092340]
   -> #1 (>i_mutex_dir_key#2){}:
[ 2135.098671]down_read+0x48/0x90
[ 2135.102395]lookup_slow+0x74/0x178
[ 2135.106380]walk_component+0x1a4/0x2e4
[ 2135.110713]link_path_walk+0x174/0x4a0
[ 2135.115045]path_openat+0x68/0x944
[ 2135.119031]do_filp_open+0x60/0xc4
[ 2135.123019]file_open_name+0xe4/0x114
[ 2135.127263]filp_open+0x28/0x48
[ 2135.130990]kernel_read_file_from_path+0x30/0x78
[ 2135.136193]_request_firmware+0x3ec/0x78c
[ 2135.140782]request_firmware+0x3c/0x54
[ 2135.145133]s5p_mfc_load_firmware+0x44/0x140 [s5p_mfc]
[ 2135.150848]s5p_mfc_open+0x2d4/0x4e0 [s5p_mfc]
[ 2135.155892]v4l2_open+0xa0/0x104 [videodev]
[ 2135.160627]chrdev_open+0xa4/0x18c
[ 2135.164612]do_dentry_open+0x208/0x310
[ 2135.168945]path_openat+0x28c/0x944
[ 2135.173017]do_filp_open+0x60/0xc4
[ 2135.177002]do_sys_open+0x118/0x1c8
[ 2135.181076]ret_fast_syscall+0x0/0x28
[ 2135.185320]
   -> #0 (>mfc_mutex){+.+.}:
[ 2135.190871]lock_acquire+0x6c/0x88
[ 2135.194855]__mutex_lock+0x68/0xa34
[ 2135.198927]mutex_lock_interruptible_nested+0x1c/0x24
[ 2135.204575]s5p_mfc_mmap+0x28/0xd4 [s5p_mfc]
[ 2135.209430]v4l2_mmap+0x54/0x88 [videodev]
[ 2135.214093]mmap_region+0x3a8/0x638
[ 2135.218163]do_mmap+0x330/0x3a4
[ 2135.221890]vm_mmap_pgoff+0x90/0xb8
[ 2135.225962]SyS_mmap_pgoff+0x90/0xc0
[ 2135.230122]ret_fast_syscall+0x0/0x28
[ 2135.234366]
   other info that might help us debug this:

[ 2135.242339] Chain exists of:
 >mfc_mutex --> >i_mutex_dir_key#2 --> >mmap_sem

[ 2135.253690]  Possible unsafe locking scenario:

[ 2135.259583]CPU0CPU1
[ 2135.264089]
[ 2135.268594]   lock(>mmap_sem);
[ 2135.271974]lock(>i_mutex_dir_key#2);
[ 2135.278820]lock(>mmap_sem);
[ 2135.284712]   lock(>mfc_mutex);
[ 2135.288265]
*** DEADLOCK ***

[ 2135.294159] 1 lock held by qtdemux0:sink/2700:
[ 2135.298577]  #0:  (>mmap_sem){}, at: [] 
vm_mmap_pgoff+0x44/0xb8
[ 2135.306029]
   stack backtrace:
[ 2135.310365] CPU: 7 PID: 2700 Comm: qtdemux0:sink Not tainted 4.14.0-rc2 #1
[ 2135.317208] Hardware name: SAMSUNG EXYNOS (Flattened Device Tree)
[ 2135.323282] [] (unwind_backtrace) from [] 
(show_stack+0x10/0x14)
[ 2135.330992] [] (show_stack) from [] 
(dump_stack+0x98/0xc4)
[ 2135.338184] [] (dump_stack) from [] 
(print_circular_bug+0x254/0x410)
[ 2135.346241] [] (print_circular_bug) from [] 
(check_prev_add+0x468/0x938)
[ 2135.354647] [] (check_prev_add) from [] 
(__lock_acquire+0x1314/0x14fc)
[ 2135.362878] [] (__lock_acquire) from [] 
(lock_acquire+0x6c/0x88)
[ 2135.370591] [] (lock_acquire) from [] 
(__mutex_lock+0x68/0xa34)
[ 2135.378217] [] (__mutex_lock) from [] 
(mutex_lock_interruptible_nested+0x1c/0x24)
[ 2135.387419] [] (mutex_lock_interruptible_nested) from [] 
(s5p_mfc_mmap+0x28/0xd4 [s5p_mfc])
[ 2135.397489] [] (s5p_mfc_mmap [s5p_mfc]) from [] 
(v4l2_mmap+0x54/0x88 [videodev])
[ 2135.406571] [] (v4l2_mmap [videodev]) from [] 
(mmap_region+0x3a8/0x638)
[ 2135.414870] [] (mmap_region) from [] 
(do_mmap+0x330/0x3a4)
[ 2135.422063] [] (do_mmap) from [] 

Re: [PATCH v4 9/9] kasan: rework Kconfig settings

2017-09-26 Thread Andrey Ryabinin
On 09/23/2017 12:29 AM, Arnd Bergmann wrote:
> We get a lot of very large stack frames using gcc-7.0.1 with the default
> -fsanitize-address-use-after-scope --param asan-stack=1 options, which
> can easily cause an overflow of the kernel stack, e.g.
> 
> drivers/gpu/drm/i915/gvt/handlers.c:2407:1: error: the frame size of 31216 
> bytes is larger than 2048 bytes
> drivers/net/wireless/ralink/rt2x00/rt2800lib.c:5650:1: error: the frame size 
> of 23632 bytes is larger than 2048 bytes
> drivers/scsi/fnic/fnic_trace.c:451:1: error: the frame size of 5152 bytes is 
> larger than 2048 bytes
> fs/btrfs/relocation.c:1202:1: error: the frame size of 4256 bytes is larger 
> than 2048 bytes
> fs/fscache/stats.c:287:1: error: the frame size of 6552 bytes is larger than 
> 2048 bytes
> lib/atomic64_test.c:250:1: error: the frame size of 12616 bytes is larger 
> than 2048 bytes
> mm/vmscan.c:1367:1: error: the frame size of 5080 bytes is larger than 2048 
> bytes
> net/wireless/nl80211.c:1905:1: error: the frame size of 4232 bytes is larger 
> than 2048 bytes
> 
> To reduce this risk, -fsanitize-address-use-after-scope is now split
> out into a separate CONFIG_KASAN_EXTRA Kconfig option, leading to stack
> frames that are smaller than 2 kilobytes most of the time on x86_64. An
> earlier version of this patch also prevented combining KASAN_EXTRA with
> KASAN_INLINE, but that is no longer necessary with gcc-7.0.1.
> 
> A lot of warnings with KASAN_EXTRA go away if we disable KMEMCHECK,
> as -fsanitize-address-use-after-scope seems to understand the builtin
> memcpy, but adds checking code around an extern memcpy call. I had to work
> around a circular dependency, as DEBUG_SLAB/SLUB depended on !KMEMCHECK,
> while KASAN did it the other way round. Now we handle both the same way
> and make KASAN and KMEMCHECK mutually exclusive.
> 
> All patches to get the frame size below 2048 bytes with CONFIG_KASAN=y
> and CONFIG_KASAN_EXTRA=n have been submitted along with this patch, so
> we can bring back that default now. KASAN_EXTRA=y still causes lots of
> warnings but now defaults to !COMPILE_TEST to disable it in allmodconfig,
> and it remains disabled in all other defconfigs since it is a new option.
> I arbitrarily raise the warning limit for KASAN_EXTRA to 3072 to reduce
> the noise, but an allmodconfig kernel still has around 50 warnings
> on gcc-7.
> 
> I experimented a bit more with smaller stack frames and have another
> follow-up series that reduces the warning limit for 64-bit architectures
> to 1280 bytes (without CONFIG_KASAN).
> 
> With earlier versions of this patch series, I also had patches to
> address the warnings we get with KASAN and/or KASAN_EXTRA, using a
> "noinline_if_stackbloat" annotation. That annotation now got replaced with
> a gcc-8 bugfix (see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81715)
> and a workaround for older compilers, which means that KASAN_EXTRA is
> now just as bad as before and will lead to an instant stack overflow in
> a few extreme cases.
> 
> This reverts parts of commit commit 3f181b4 ("lib/Kconfig.debug: disable
> -Wframe-larger-than warnings with KASAN=y").
> 
> Signed-off-by: Arnd Bergmann 

Acked-by: Andrey Ryabinin 


Re: [PATCH] scripts: kernel-doc: parse next structs/unions

2017-09-26 Thread Mauro Carvalho Chehab
Em Tue, 26 Sep 2017 18:56:10 +0200
Markus Heiser  escreveu:

> > Am 25.09.2017 um 20:22 schrieb Mauro Carvalho Chehab 
> > :
> > 
> > Jon,
> > 
> > Please let me know what you think about this approach. IMHO, it is a way
> > better than what we do right now. This is more a proof of concept, as the
> > patch is not complete. 
> > 
> > With it, we can now document both anonymous and named unions/structs.
> > 
> > For named structs, the name of the fields should be in the format:
> > foo.bar
> > 
> > What's missing on this PoC:
> > 
> > 1) I didn't check if @foo.bar: would work, though.  Probably the parser
> >   for it should be added to allow this new syntax.  
> 
> Below you will find my  with a "@sys_clk.rate: lorem ipsum".
> With I expected a output in the **Members** section for sys_clk.rate but
> I got none :o

The parser line for @foo.bar: was not working, as I was expecting. The
version I posted today handles it well:

``sys_clk.rate``
  lorem ipsum

It didn't handled - nor warned - about the lack of documentation for
this one:
const struct omap_vfsm_instance *vfsm;

but this is unrelated.

> Anyway your concept is good and so I applied it to my py-version. If you
> are interested in follow the patches titled ...
> 
> kernel-doc: fix nested & sub-nested handling (continued
> 
> at  https://github.com/return42/linuxdoc/commits/master
> 
> I also added some comments from my (py-) experience to your perl
> implementation below.
> 
> Here are some links which illustrate how your concept could work:
> 
> documentation with example: 
>   
> https://return42.github.io/linuxdoc/linuxdoc-howto/kernel-doc-syntax.html#structs-unions
> 
> how the example is rendered:
>   
> https://return42.github.io/linuxdoc/linuxdoc-howto/all-in-a-tumble.html#example-my-struct

> > 
> > +   my $declaration = $members;
> > +
> > +   # Split nested struct/union elements as newer ones
> > +   my $cont = 1;
> > +   while ($cont) {
> > +   $cont = 0;  
> 
> Is the outer loop needed ..
> 
> > +   while ($members =~ 
> > m/(struct|union)([^{};]+){([^{}]*)}([^{}\;]*)\;/) {  
> 
> this (inner) loop seems enough to me.
> 
> > +   my $newmember = "$1 $4;";
> > +   my $id = $4;  
> 
> This won't work if  you have e.g.
> 
>union car {int foo;} bar1, bar2, *bbar3;
> 
> where $id will be "bar1, bar2, *bbar3", you need to split
> this string and iterate over the id's.

That's true, if we have cases like that. I hope not!

Seriously, in the above case, the developer should very likely declare
the union outside the main struct and have its own kernel-doc markup.

My personal taste would be to not explicitly support the above. If it
hits some code, try to argue with the developer first, before patching
kernel-doc to such weird stuff.

> > +   my $content = $3;
> > +   $id =~ s/[:\[].*//;
> > +   foreach my $arg (split /;/, $content) {
> > +   next if ($arg =~ m/^\s*$/);
> > +   my $type = $arg;
> > +   my $name = $arg;
> > +   $type =~ s/\s\S+$//;
> > +   $name =~ s/.*\s//;
> > +   next if (($name =~ m/^\s*$/));
> > +   if ($id =~ m/^\s*$/) {
> > +   # anonymous struct/union
> > +   $newmember .= "$type $name;";
> > +   } else {
> > +   $newmember .= "$type $id.$name;";
> > +   }
> > +   }
> > +   $members =~ 
> > s/(struct|union)([^{};]+){([^{}]*)}([^{}\;]*)\;/$newmember/;  
> 
> I'am not so familiar with Perl regexpr, does this replace only the
> first matching occurrence with $newmember or all?

Just the first match. if we wanted to apply it multiple times, we need
to add a "g" at the end, e. g.:

$members =~ 
s/(struct|union)([^{};]+){([^{}]*)}([^{}\;]*)\;/$newmember/g;


> 
> > +   $cont = 1;
> > +   };
> > +   };
> > +
> > +   # Ignore other nested elements, like enums
> > +   $members =~ s/({[^\{\}]*})//g;
> > +   $nested = $decl_type;
> > +   $nested =~ s/\/\*.*?\*\///gos;
> > +
> > create_parameterlist($members, ';', $file);
> > check_sections($file, $declaration_name, "struct", $sectcheck, 
> > $struct_actual, $nested);
> > 
> > +   # Adjust declaration for better display
> > +   $declaration =~ s/([{,;])/$1\n/g;
> > +   $declaration =~ s/}\s+;/};/g;
> > +   my @def_args = split /\n/, $declaration;
> > +   my $level = 2;
> > +   $declaration = "";
> > +   foreach my $clause (@def_args) {
> > +   $clause =~ s/^\s+//;
> > +   $clause =~ s/\s+$//;
> > +   $clause =~ s/\s+/ /;
> > +   $level-- if ($clause =~ m/}/ && $level > 2);
> > +   $declaration .= "\t" 

Re: [PATCH v2] scripts: kernel-doc: fix nexted handling

2017-09-26 Thread Mauro Carvalho Chehab
Em Tue, 26 Sep 2017 14:45:08 +0200
Markus Heiser  escreveu:

> > Am 25.09.2017 um 20:41 schrieb Mauro Carvalho Chehab 
> > :  
> 
> >>> + $cont = 1;
> >>> + };
> >>> + };
> >>> + # Ignore other nested elements, like enums
> >>> + $members =~ s/({[^\{\}]*})//g;
> >>> + $nested = $decl_type;
> >> 
> >> What is the latter good for? I guess the 'nested' trick to suppress
> >> such 'excess' warnings from nested types is no longer needed .. right?  
> > 
> > For things like:
> > 
> > enum { foo, bar } type;
> > 
> > Granted, a good documentation should also describe "foo" and "bar",
> > but that could be easily done by moving enums out of the struct, or
> > by add descriptions for "foo" and "bar" at @type: markup.  
> 
> 
> Hm .. I suppose you are misunderstanding me. I didn't asked about 
> $members, I asked about $nested. There is only one place where
> $nested is used, and this is in the check_sections function ...
> 
> @@ -2531,9 +2527,7 @@ sub check_sections($$) {
>   } else {
> - if ($nested !~ m/\Q$sects[$sx]\E/) {
> - print STDERR "${file}:$.: warning: " .
> - "Excess struct/union/enum/typedef 
> member " .
> - "'$sects[$sx]' " .
> - "description in '$decl_name'\n";
> - ++$warnings;
> - }
> +print STDERR "${file}:$.: warning: " .
> +"Excess struct/union/enum/typedef member " .
> +"'$sects[$sx]' " .
> +"description in '$decl_name'\n";
> +++$warnings;
>   }
> 
> Since this is the only place where $nested is use, we can drop all
> the occurrence of $nested in the kernel-doc script .. or I'am
> totally wrong?

Ah, now I understood you! Yeah, this can be removed. I'll put it into
a separate cleanup patch.

See below.

Regards,
Mauro


[PATCH] scripts: kernel-doc: get rid of $nested parameter

The check_sections() function has a $nested parameter, meant
to identify when a nested struct is present. As we now have
a logic that handles it, get rid of such parameter.

Signed-off-by: Mauro Carvalho Chehab 

diff --git a/scripts/kernel-doc b/scripts/kernel-doc
index 880a196c7dc7..cff66ee91f2c 100755
--- a/scripts/kernel-doc
+++ b/scripts/kernel-doc
@@ -979,7 +979,6 @@ sub dump_union($$) {
 sub dump_struct($$) {
 my $x = shift;
 my $file = shift;
-my $nested;
 
 if ($x =~ /(struct|union)\s+(\w+)\s*{(.*)}/) {
my $decl_type = $1;
@@ -1034,11 +1033,9 @@ sub dump_struct($$) {
 
# Ignore other nested elements, like enums
$members =~ s/({[^\{\}]*})//g;
-   $nested = $decl_type;
-   $nested =~ s/\/\*.*?\*\///gos;
 
create_parameterlist($members, ';', $file);
-   check_sections($file, $declaration_name, "struct", $sectcheck, 
$struct_actual, $nested);
+   check_sections($file, $declaration_name, "struct", $sectcheck, 
$struct_actual);
 
# Adjust declaration for better display
$declaration =~ s/([{;])/$1\n/g;
@@ -1334,8 +1331,8 @@ sub push_parameter($$$) {
$parametertypes{$param} = $type;
 }
 
-sub check_sections($$) {
-   my ($file, $decl_name, $decl_type, $sectcheck, $prmscheck, $nested) = 
@_;
+sub check_sections($) {
+   my ($file, $decl_name, $decl_type, $sectcheck, $prmscheck) = @_;
my @sects = split ' ', $sectcheck;
my @prms = split ' ', $prmscheck;
my $err;
@@ -1369,14 +1366,6 @@ sub check_sections($$) {
"'$sects[$sx]' " .
"description in '$decl_name'\n";
++$warnings;
-   } else {
-   if ($nested !~ m/\Q$sects[$sx]\E/) {
-   print STDERR "${file}:$.: warning: " .
-   "Excess struct/union/enum/typedef 
member " .
-   "'$sects[$sx]' " .
-   "description in '$decl_name'\n";
-   ++$warnings;
-   }
}
}
}
@@ -1487,7 +1476,7 @@ sub dump_function($$) {
 }
 
my $prms = join " ", @parameterlist;
-   check_sections($file, $declaration_name, "function", $sectcheck, $prms, 
"");
+   check_sections($file, $declaration_name, "function", $sectcheck, $prms);
 
 # This check emits a lot of warnings at the moment, because many
 # functions don't have a 'Return' doc section. So until the number


Thanks,
Mauro


[PATCH 05/10] docs: kernel-doc.rst: improve structs chapter

2017-09-26 Thread Mauro Carvalho Chehab
There is a mess on this chapter: it suggests that even
enums and unions should be documented with "struct". That's
not the way it should be ;-)

Fix it and move it to happen earlier.


Signed-off-by: Mauro Carvalho Chehab 

Signed-off-by: Mauro Carvalho Chehab 
---
 Documentation/doc-guide/kernel-doc.rst | 48 +-
 1 file changed, 24 insertions(+), 24 deletions(-)

diff --git a/Documentation/doc-guide/kernel-doc.rst 
b/Documentation/doc-guide/kernel-doc.rst
index 9b69dfe928d8..68cb1b496c73 100644
--- a/Documentation/doc-guide/kernel-doc.rst
+++ b/Documentation/doc-guide/kernel-doc.rst
@@ -258,6 +258,30 @@ named ``Return``.
  as a new section heading, with probably won't produce the desired
  effect.
 
+Structure, union, and enumeration documentation
+---
+
+The general format of a struct, union, and enum kernel-doc comment is::
+
+  /**
+   * struct struct_name - Brief description.
+   * @argument: Description of member member_name.
+   *
+   * Description of the structure.
+   */
+
+On the above, ``struct`` is used to mean structs. You can also use ``union``
+and ``enum``  to describe unions and enums. ``argument`` is used
+to mean struct and union member names as well as enumerations in an enum.
+
+The brief description following the structure name may span multiple lines, and
+ends with a member description, a blank comment line, or the end of the
+comment block.
+
+The kernel-doc data structure comments describe each member of the structure,
+in order, with the member descriptions.
+
+
 
 Highlights and cross-references
 ---
@@ -331,30 +355,6 @@ cross-references.
 For further details, please refer to the `Sphinx C Domain`_ documentation.
 
 
-Structure, union, and enumeration documentation

-
-The general format of a struct, union, and enum kernel-doc comment is::
-
-  /**
-   * struct struct_name - Brief description.
-   * @member_name: Description of member member_name.
-   *
-   * Description of the structure.
-   */
-
-Below, "struct" is used to mean structs, unions and enums, and "member" is used
-to mean struct and union members as well as enumerations in an enum.
-
-The brief description following the structure name may span multiple lines, and
-ends with a ``@member:`` description, a blank comment line, or the end of the
-comment block.
-
-The kernel-doc data structure comments describe each member of the structure, 
in
-order, with the ``@member:`` descriptions. The ``@member:`` descriptions must
-begin on the very next line following the opening brief function description
-line, with no intervening blank comment lines. The ``@member:`` descriptions 
may
-span multiple lines. The continuation lines may contain indentation.
 
 In-line member documentation comments
 ~
-- 
2.13.5



[PATCH 09/10] scripts: kernel-doc: parse next structs/unions

2017-09-26 Thread Mauro Carvalho Chehab
There are several places within the Kernel tree with nested
structs/unions, like this one:

  struct ingenic_cgu_clk_info {
const char *name;
enum {
  CGU_CLK_NONE = 0,
  CGU_CLK_EXT = BIT(0),
  CGU_CLK_PLL = BIT(1),
  CGU_CLK_GATE = BIT(2),
  CGU_CLK_MUX = BIT(3),
  CGU_CLK_MUX_GLITCHFREE = BIT(4),
  CGU_CLK_DIV = BIT(5),
  CGU_CLK_FIXDIV = BIT(6),
  CGU_CLK_CUSTOM = BIT(7),
} type;
int parents[4];
union {
  struct ingenic_cgu_pll_info pll;
  struct {
struct ingenic_cgu_gate_info gate;
struct ingenic_cgu_mux_info mux;
struct ingenic_cgu_div_info div;
struct ingenic_cgu_fixdiv_info fixdiv;
  };
  struct ingenic_cgu_custom_info custom;
};
  };

Currently, such struct is documented as:

**Definition**

::
struct ingenic_cgu_clk_info {
const char * name;
};

**Members**

``name``
  name of the clock

With is obvioulsy wrong. It also generates an error:
drivers/clk/ingenic/cgu.h:169: warning: No description found for 
parameter 'enum'

However, there's nothing wrong with this kernel-doc markup: everything
is documented there.

It makes sense to document all fields there. So, add a
way for the core to parse those structs.

With this patch, all documented fields will properly generate
documentation.

Signed-off-by: Mauro Carvalho Chehab 
---
 Documentation/doc-guide/kernel-doc.rst |  46 +
 scripts/kernel-doc | 120 ++---
 2 files changed, 112 insertions(+), 54 deletions(-)

diff --git a/Documentation/doc-guide/kernel-doc.rst 
b/Documentation/doc-guide/kernel-doc.rst
index 50473f0db345..3916a28b82b7 100644
--- a/Documentation/doc-guide/kernel-doc.rst
+++ b/Documentation/doc-guide/kernel-doc.rst
@@ -281,6 +281,52 @@ comment block.
 The kernel-doc data structure comments describe each member of the structure,
 in order, with the member descriptions.
 
+Nested structs/unions
+~
+
+It is possible to document nested structs unions, like::
+
+  /**
+   * struct nested_foobar - a struct with nested unions and structs
+   * @arg1: - first argument of anonymous union/anonymous struct
+   * @arg2: - second argument of anonymous union/anonymous struct
+   * @arg3: - third argument of anonymous union/anonymous struct
+   * @arg4: - fourth argument of anonymous union/anonymous struct
+   * @bar.st1.arg1 - first argument of struct st1 on union bar
+   * @bar.st1.arg2 - second argument of struct st1 on union bar
+   * @bar.st2.arg1 - first argument of struct st2 on union bar
+   * @bar.st2.arg2 - second argument of struct st2 on union bar
+  struct nested_foobar {
+/* Anonymous union/struct*/
+union {
+  struct {
+int arg1;
+int arg2;
+ }
+  struct {
+void *arg3;
+int arg4;
+ }
+   }
+   union {
+  struct {
+int arg1;
+int arg2;
+ } st1;
+  struct {
+void *arg1;
+int arg2;
+ } st2;
+   } bar;
+  };
+
+.. note::
+
+   #) When documenting nested structs or unions, if the struct/union ``foo``
+  is named, the argument ``bar`` inside it should be documented as
+  ``@foo.bar:``
+   #) When the nested struct/union is anonymous, the argument ``bar`` on it
+  should be documented as ``@bar:``
 
 Typedef documentation
 -
diff --git a/scripts/kernel-doc b/scripts/kernel-doc
index b6f3f6962897..880a196c7dc7 100755
--- a/scripts/kernel-doc
+++ b/scripts/kernel-doc
@@ -210,7 +210,7 @@ my $anon_struct_union = 0;
 my $type_constant = '\b``([^\`]+)``\b';
 my $type_constant2 = '\%([-_\w]+)';
 my $type_func = '(\w+)\(\)';
-my $type_param = '\@(\w+(\.\.\.)?)';
+my $type_param = '\@(\w[\.\w]*(\.\.\.)?)';
 my $type_fp_param = '\@(\w+)\(\)';  # Special RST handling for func ptr params
 my $type_env = '(\$\w+)';
 my $type_enum = '\&(enum\s*([_\w]+))';
@@ -663,32 +663,12 @@ sub output_struct_man(%) {
 print ".SH NAME\n";
 print $args{'type'} . " " . $args{'struct'} . " \\- " . $args{'purpose'} . 
"\n";
 
+my $declaration = $args{'definition'};
+$declaration =~ s/\t/  /g;
+$declaration =~ s/\n/"\n.br\n.BI \"/g;
 print ".SH SYNOPSIS\n";
 print $args{'type'} . " " . $args{'struct'} . " {\n.br\n";
-
-foreach my $parameter (@{$args{'parameterlist'}}) {
-   if ($parameter =~ /^#/) {
-   print ".BI \"$parameter\"\n.br\n";
-   next;
-   }
-   my $parameter_name = $parameter;
-   $parameter_name =~ s/\[.*//;
-
-   ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
-   $type = $args{'parametertypes'}{$parameter};
-   if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
-   # pointer-to-function
-   print 

[PATCH 10/10] [RFC] w1_netlink.h: add support for nested structs

2017-09-26 Thread Mauro Carvalho Chehab
Describe nested struct/union fields

NOTE: This is a pure test patch, meant to validate if the
parsing logic for nested structs is working properly.

I've no idea if the random text I added there is correct!

Signed-off-by: Mauro Carvalho Chehab 
---
 drivers/w1/w1_netlink.h | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/w1/w1_netlink.h b/drivers/w1/w1_netlink.h
index a36661cd1f05..e781d1109cd7 100644
--- a/drivers/w1/w1_netlink.h
+++ b/drivers/w1/w1_netlink.h
@@ -60,6 +60,10 @@ enum w1_netlink_message_types {
  * @status: kernel feedback for success 0 or errno failure value
  * @len: length of data following w1_netlink_msg
  * @id: union holding master bus id (msg.id) and slave device id (id[8]).
+ * @id.id: Slave ID (8 bytes)
+ * @id.mst: master bus identification
+ * @id.mst.id: master bus ID
+ * @id.mst.res: master bus reserved
  * @data: start address of any following data
  *
  * The base message structure for w1 messages over netlink.
-- 
2.13.5



[PATCH 07/10] docs: kernel-doc.rst: add documentation about man pages

2017-09-26 Thread Mauro Carvalho Chehab
kernel-doc-nano-HOWTO.txt has a chapter about man pages
production. While we don't have a working  "make manpages"
target, add it.

Signed-off-by: Mauro Carvalho Chehab 
---
 Documentation/doc-guide/kernel-doc.rst | 61 ++
 1 file changed, 47 insertions(+), 14 deletions(-)

diff --git a/Documentation/doc-guide/kernel-doc.rst 
b/Documentation/doc-guide/kernel-doc.rst
index 9777aa53e3dd..50473f0db345 100644
--- a/Documentation/doc-guide/kernel-doc.rst
+++ b/Documentation/doc-guide/kernel-doc.rst
@@ -377,7 +377,6 @@ cross-references.
 For further details, please refer to the `Sphinx C Domain`_ documentation.
 
 
-
 In-line member documentation comments
 ~
 
@@ -391,19 +390,19 @@ on a line of their own, like all other kernel-doc 
comments::
* @foo: The Foo member.
*/
   struct foo {
-int foo;
-/**
- * @bar: The Bar member.
- */
-int bar;
-/**
- * @baz: The Baz member.
- *
- * Here, the member description may contain several paragraphs.
- */
-int baz;
-/** @foobar: Single line description. */
-int foobar;
+   int foo;
+   /**
+* @bar: The Bar member.
+*/
+   int bar;
+   /**
+* @baz: The Baz member.
+*
+* Here, the member description may contain several paragraphs.
+*/
+   int baz;
+   /** @foobar: Single line description. */
+   int foobar;
   }
 
 
@@ -452,3 +451,37 @@ file.
 
 Data structures visible in kernel include files should also be documented using
 kernel-doc formatted comments.
+
+How to use kernel-doc to generate man pages
+---
+
+If you just want to use kernel-doc to generate man pages you can do this
+from the Kernel git tree::
+
+  $ scripts/kernel-doc -man $(git grep -l '/\*\*' |grep -v Documentation/) | 
./split-man.pl /tmp/man
+
+Using the small ``split-man.pl`` script below::
+
+
+  #!/usr/bin/perl
+
+  if ($#ARGV < 0) {
+ die "where do I put the results?\n";
+  }
+
+  mkdir $ARGV[0],0777;
+  $state = 0;
+  while () {
+  if (/^\.TH \"[^\"]*\" 9 \"([^\"]*)\"/) {
+   if ($state == 1) { close OUT }
+   $state = 1;
+   $fn = "$ARGV[0]/$1.9";
+   print STDERR "Creating $fn\n";
+   open OUT, ">$fn" or die "can't open $fn: $!\n";
+   print OUT $_;
+  } elsif ($state != 0) {
+   print OUT $_;
+  }
+  }
+
+  close OUT;
-- 
2.13.5



[PATCH 01/10] scripts: kernel-doc: get rid of unused output formats

2017-09-26 Thread Mauro Carvalho Chehab
Since there isn't any docbook code anymore upstream,
we can get rid of several output formats:

- docbook/xml, html, html5 and list formats were used by
  the old build system;
- As ReST is text, there's not much sense on outputting
  on a different text format.

After this patch, only man and rst output formats are
supported.

Signed-off-by: Mauro Carvalho Chehab 
---
 scripts/kernel-doc | 1182 +---
 1 file changed, 4 insertions(+), 1178 deletions(-)

diff --git a/scripts/kernel-doc b/scripts/kernel-doc
index 9d3eafea58f0..69757ee9db4c 100755
--- a/scripts/kernel-doc
+++ b/scripts/kernel-doc
@@ -51,13 +51,8 @@ The documentation comments are identified by "/**" opening 
comment mark. See
 Documentation/kernel-doc-nano-HOWTO.txt for the documentation comment syntax.
 
 Output format selection (mutually exclusive):
-  -docbook Output DocBook format.
-  -htmlOutput HTML format.
-  -html5   Output HTML5 format.
-  -listOutput symbol list format. This is for use by 
docproc.
   -man Output troff manual page format. This is the default.
   -rst Output reStructuredText format.
-  -textOutput plain text format.
 
 Output selection (mutually exclusive):
   -export  Only output documentation for symbols that have been
@@ -224,84 +219,11 @@ my $type_typedef = '\&(typedef\s*([_\w]+))';
 my $type_union = '\&(union\s*([_\w]+))';
 my $type_member = '\&([_\w]+)(\.|->)([_\w]+)';
 my $type_fallback = '\&([_\w]+)';
-my $type_enum_xml = '\(enum\s*([_\w]+))';
-my $type_struct_xml = '\(struct\s*([_\w]+))';
-my $type_typedef_xml = '\(typedef\s*([_\w]+))';
-my $type_union_xml = '\(union\s*([_\w]+))';
-my $type_member_xml = '\([_\w]+)(\.|-\)([_\w]+)';
-my $type_fallback_xml = '\([_\w]+)';
 my $type_member_func = $type_member . '\(\)';
 
 # Output conversion substitutions.
 #  One for each output format
 
-# these work fairly well
-my @highlights_html = (
-   [$type_constant, "\$1"],
-   [$type_constant2, "\$1"],
-   [$type_func, "\$1"],
-   [$type_enum_xml, "\$1"],
-   [$type_struct_xml, "\$1"],
-   [$type_typedef_xml, "\$1"],
-   [$type_union_xml, "\$1"],
-   [$type_env, "\$1"],
-   [$type_param, "\$1"],
-   [$type_member_xml, "\$1\$2\$3"],
-   [$type_fallback_xml, "\$1"]
-  );
-my $local_lt = "lt:";
-my $local_gt = "gt:";
-my $blankline_html = $local_lt . "p" . $local_gt;  # was ""
-
-# html version 5
-my @highlights_html5 = (
-[$type_constant, "\$1"],
-[$type_constant2, "\$1"],
-[$type_func, "\$1"],
-[$type_enum_xml, "\$1"],
-[$type_struct_xml, "\$1"],
-[$type_typedef_xml, "\$1"],
-[$type_union_xml, "\$1"],
-[$type_env, "\$1"],
-[$type_param, "\$1]"],
-[$type_member_xml, "\$1\$2\$3"],
-[$type_fallback_xml, "\$1"]
-  );
-my $blankline_html5 = $local_lt . "br /" . $local_gt;
-
-# XML, docbook format
-my @highlights_xml = (
-  ["([^=])\\\"([^\\\"<]+)\\\"", "\$1\$2"],
-  [$type_constant, "\$1"],
-  [$type_constant2, "\$1"],
-  [$type_enum_xml, "\$1"],
-  [$type_struct_xml, "\$1"],
-  [$type_typedef_xml, "\$1"],
-  [$type_union_xml, "\$1"],
-  [$type_param, "\$1"],
-  [$type_func, "\$1"],
-  [$type_env, "\$1"],
-  [$type_member_xml, 
"\$1\$2\$3"],
-  [$type_fallback_xml, "\$1"]
-);
-my $blankline_xml = $local_lt . "/para" . $local_gt . $local_lt . "para" . 
$local_gt . "\n";
-
-# gnome, docbook format
-my @highlights_gnome = (
-[$type_constant, "\$1"],
-[$type_constant2, "\$1"],
-[$type_func, "\$1"],
-[$type_enum, "\$1"],
-[$type_struct, "\$1"],
-[$type_typedef, "\$1"],
-[$type_union, "\$1"],
-[$type_env, "\$1"],
-[$type_param, "\$1" ],
-[$type_member, 
"\$1\$2\$3"],
-[$type_fallback, "\$1"]
-  );
-my $blankline_gnome = "\n";
-
 # these are pretty rough
 my @highlights_man = (
   [$type_constant, "\$1"],
@@ -317,21 +239,6 @@ my 

[PATCH 00/10] kernel-doc: add supported to document nested structs/unions

2017-09-26 Thread Mauro Carvalho Chehab
Right now, it is not possible to document nested struct and nested unions.
kernel-doc simply ignore them.

Add support to document them.

This series starts with a patch getting rid of the now unused output formats
for kernel-doc: since we got rid of all DocBook stuff, we should not need
them anymore. The reason for dropping it (despite cleaning up), is that
it doesn't make sense to invest time on adding new features for formats
that aren't used anymore.

The next 8 patches on this series improve kernel-doc documentation and
finally get rid of its old documentation (kernel-doc-nano-HOWTO.txt).

Patch 9/10 is the most interesting one in this series: it adds support for
nested structures and unions.

Patch 10/10 is just an example from a random header with kernel-doc
markups. There's no special reason for selecting this file, and the
comments there are likely wrong. So, please use it only as a way to test
the new parser logic from patch 9/10.

Mauro Carvalho Chehab (10):
  scripts: kernel-doc: get rid of unused output formats
  docs: kernel-doc.rst: better describe kernel-doc arguments
  docs: kernel-doc.rst: improve private members description
  docs: kernel-doc.rst: improve function documentation section
  docs: kernel-doc.rst: improve structs chapter
  docs: kernel-doc: improve typedef documentation
  docs: kernel-doc.rst: add documentation about man pages
  docs: get rid of kernel-doc-nano-HOWTO.txt
  scripts: kernel-doc: parse next structs/unions
  [RFC] w1_netlink.h: add support for nested structs

---

Before this series, I send a few PoC patches. They were all
replaced by patch 9/10.

 Documentation/00-INDEX  |2 -
 Documentation/doc-guide/kernel-doc.rst  |  387 ++---
 Documentation/kernel-doc-nano-HOWTO.txt |  322 
 drivers/w1/w1_netlink.h |4 +
 scripts/kernel-doc  | 1304 ++-
 5 files changed, 346 insertions(+), 1673 deletions(-)
 delete mode 100644 Documentation/kernel-doc-nano-HOWTO.txt

-- 
2.13.5




[PATCH 08/10] docs: get rid of kernel-doc-nano-HOWTO.txt

2017-09-26 Thread Mauro Carvalho Chehab
Everything there is already described at
Documentation/doc-guide/kernel-doc.rst. So, there's no reason why
to keep it anymore.

Signed-off-by: Mauro Carvalho Chehab 
---
 Documentation/00-INDEX  |   2 -
 Documentation/kernel-doc-nano-HOWTO.txt | 322 
 scripts/kernel-doc  |   2 +-
 3 files changed, 1 insertion(+), 325 deletions(-)
 delete mode 100644 Documentation/kernel-doc-nano-HOWTO.txt

diff --git a/Documentation/00-INDEX b/Documentation/00-INDEX
index 3bec49c33bbb..aca4f00ec69b 100644
--- a/Documentation/00-INDEX
+++ b/Documentation/00-INDEX
@@ -228,8 +228,6 @@ isdn/
- directory with info on the Linux ISDN support, and supported cards.
 kbuild/
- directory with info about the kernel build process.
-kernel-doc-nano-HOWTO.txt
-   - outdated info about kernel-doc documentation.
 kdump/
- directory with mini HowTo on getting the crash dump code to work.
 doc-guide/
diff --git a/Documentation/kernel-doc-nano-HOWTO.txt 
b/Documentation/kernel-doc-nano-HOWTO.txt
deleted file mode 100644
index c23e2c5ab80d..
--- a/Documentation/kernel-doc-nano-HOWTO.txt
+++ /dev/null
@@ -1,322 +0,0 @@
-NOTE: this document is outdated and will eventually be removed.  See
-Documentation/doc-guide/ for current information.
-
-kernel-doc nano-HOWTO
-=
-
-How to format kernel-doc comments
--
-
-In order to provide embedded, 'C' friendly, easy to maintain,
-but consistent and extractable documentation of the functions and
-data structures in the Linux kernel, the Linux kernel has adopted
-a consistent style for documenting functions and their parameters,
-and structures and their members.
-
-The format for this documentation is called the kernel-doc format.
-It is documented in this Documentation/kernel-doc-nano-HOWTO.txt file.
-
-This style embeds the documentation within the source files, using
-a few simple conventions.  The scripts/kernel-doc perl script, the
-Documentation/sphinx/kerneldoc.py Sphinx extension and other tools understand
-these conventions, and are used to extract this embedded documentation
-into various documents.
-
-In order to provide good documentation of kernel functions and data
-structures, please use the following conventions to format your
-kernel-doc comments in Linux kernel source.
-
-We definitely need kernel-doc formatted documentation for functions
-that are exported to loadable modules using EXPORT_SYMBOL.
-
-We also look to provide kernel-doc formatted documentation for
-functions externally visible to other kernel files (not marked
-"static").
-
-We also recommend providing kernel-doc formatted documentation
-for private (file "static") routines, for consistency of kernel
-source code layout.  But this is lower priority and at the
-discretion of the MAINTAINER of that kernel source file.
-
-Data structures visible in kernel include files should also be
-documented using kernel-doc formatted comments.
-
-The opening comment mark "/**" is reserved for kernel-doc comments.
-Only comments so marked will be considered by the kernel-doc scripts,
-and any comment so marked must be in kernel-doc format.  Do not use
-"/**" to be begin a comment block unless the comment block contains
-kernel-doc formatted comments.  The closing comment marker for
-kernel-doc comments can be either "*/" or "**/", but "*/" is
-preferred in the Linux kernel tree.
-
-Kernel-doc comments should be placed just before the function
-or data structure being described.
-
-Example kernel-doc function comment:
-
-/**
- * foobar() - short function description of foobar
- * @arg1:  Describe the first argument to foobar.
- * @arg2:  Describe the second argument to foobar.
- * One can provide multiple line descriptions
- * for arguments.
- *
- * A longer description, with more discussion of the function foobar()
- * that might be useful to those using or modifying it.  Begins with
- * empty comment line, and may include additional embedded empty
- * comment lines.
- *
- * The longer description can have multiple paragraphs.
- *
- * Return: Describe the return value of foobar.
- */
-
-The short description following the subject can span multiple lines
-and ends with an @argument description, an empty line or the end of
-the comment block.
-
-The @argument descriptions must begin on the very next line following
-this opening short function description line, with no intervening
-empty comment lines.
-
-If a function parameter is "..." (varargs), it should be listed in
-kernel-doc notation as:
- * @...: description
-
-The return value, if any, should be described in a dedicated section
-named "Return".
-
-Example kernel-doc data structure comment.
-
-/**
- * struct blah - the basic blah structure
- * @mem1:  describe the first member of struct blah
- * @mem2:  describe the second member of struct blah,
- * 

[PATCH 06/10] docs: kernel-doc: improve typedef documentation

2017-09-26 Thread Mauro Carvalho Chehab
Add documentation about typedefs for function prototypes and
move it to happen earlier.

Signed-off-by: Mauro Carvalho Chehab 
---
 Documentation/doc-guide/kernel-doc.rst | 32 ++--
 1 file changed, 22 insertions(+), 10 deletions(-)

diff --git a/Documentation/doc-guide/kernel-doc.rst 
b/Documentation/doc-guide/kernel-doc.rst
index 68cb1b496c73..9777aa53e3dd 100644
--- a/Documentation/doc-guide/kernel-doc.rst
+++ b/Documentation/doc-guide/kernel-doc.rst
@@ -282,6 +282,28 @@ The kernel-doc data structure comments describe each 
member of the structure,
 in order, with the member descriptions.
 
 
+Typedef documentation
+-
+
+The general format of a typedef kernel-doc comment is::
+
+  /**
+   * typedef type_name - Brief description.
+   *
+   * Description of the type.
+   */
+
+Typedefs with function prototypes can also be documented::
+
+  /**
+   * typedef type_name - Brief description.
+   * @arg1: description of arg1
+   * @arg2: description of arg2
+   *
+   * Description of the type.
+   */
+   typedef void (*type_name)(struct v4l2_ctrl *arg1, void *arg2);
+
 
 Highlights and cross-references
 ---
@@ -384,16 +406,6 @@ on a line of their own, like all other kernel-doc 
comments::
 int foobar;
   }
 
-Typedef documentation
--
-
-The general format of a typedef kernel-doc comment is::
-
-  /**
-   * typedef type_name - Brief description.
-   *
-   * Description of the type.
-   */
 
 Overview documentation comments
 ---
-- 
2.13.5



[PATCH 04/10] docs: kernel-doc.rst: improve function documentation section

2017-09-26 Thread Mauro Carvalho Chehab
Move its contents to happen earlier and improve the description
of return values, adding a subsection to it. Most of the contents
there came from kernel-doc-nano-HOWTO.txt.

Signed-off-by: Mauro Carvalho Chehab 
---
 Documentation/doc-guide/kernel-doc.rst | 100 -
 1 file changed, 61 insertions(+), 39 deletions(-)

diff --git a/Documentation/doc-guide/kernel-doc.rst 
b/Documentation/doc-guide/kernel-doc.rst
index f1eb00899084..9b69dfe928d8 100644
--- a/Documentation/doc-guide/kernel-doc.rst
+++ b/Documentation/doc-guide/kernel-doc.rst
@@ -197,6 +197,67 @@ Example::
   int d;
   };
 
+Function documentation
+--
+
+The general format of a function and function-like macro kernel-doc comment 
is::
+
+  /**
+   * function_name() - Brief description of function.
+   * @arg1: Describe the first argument.
+   * @arg2: Describe the second argument.
+   *One can provide multiple line descriptions
+   *for arguments.
+   *
+   * A longer description, with more discussion of the function function_name()
+   * that might be useful to those using or modifying it. Begins with an
+   * empty comment line, and may include additional embedded empty
+   * comment lines.
+   *
+   * The longer description may have multiple paragraphs.
+   *
+   * Return: Describe the return value of foobar.
+   *
+   * The return value description can also have multiple paragraphs, and should
+   * be placed at the end of the comment block.
+   */
+
+The brief description following the function name may span multiple lines, and
+ends with an argument description, a blank comment line, or the end of the
+comment block.
+
+Return values
+~
+
+The return value, if any, should be described in a dedicated section
+named ``Return``.
+
+.. note::
+
+  #) The multi-line descriptive text you provide does *not* recognize
+ line breaks, so if you try to format some text nicely, as in::
+
+   * Return:
+   * 0 - OK
+   * -EINVAL - invalid argument
+   * -ENOMEM - out of memory
+
+ this will all run together and produce::
+
+   Return: 0 - OK -EINVAL - invalid argument -ENOMEM - out of memory
+
+ So, in order to produce the desired line breaks, you need to use a
+ ReST list, e. g.::
+
+  * Return:
+  * * 0- OK to runtime suspend the device
+  * * -EBUSY   - Device should not be runtime suspended
+
+  #) If the descriptive text you provide has lines that begin with
+ some phrase followed by a colon, each of those phrases will be taken
+ as a new section heading, with probably won't produce the desired
+ effect.
+
 
 Highlights and cross-references
 ---
@@ -269,45 +330,6 @@ cross-references.
 
 For further details, please refer to the `Sphinx C Domain`_ documentation.
 
-Function documentation
---
-
-The general format of a function and function-like macro kernel-doc comment 
is::
-
-  /**
-   * function_name() - Brief description of function.
-   * @arg1: Describe the first argument.
-   * @arg2: Describe the second argument.
-   *One can provide multiple line descriptions
-   *for arguments.
-   *
-   * A longer description, with more discussion of the function function_name()
-   * that might be useful to those using or modifying it. Begins with an
-   * empty comment line, and may include additional embedded empty
-   * comment lines.
-   *
-   * The longer description may have multiple paragraphs.
-   *
-   * Return: Describe the return value of foobar.
-   *
-   * The return value description can also have multiple paragraphs, and should
-   * be placed at the end of the comment block.
-   */
-
-The brief description following the function name may span multiple lines, and
-ends with an ``@argument:`` description, a blank comment line, or the end of 
the
-comment block.
-
-The kernel-doc function comments describe each parameter to the function, in
-order, with the ``@argument:`` descriptions. The ``@argument:`` descriptions
-must begin on the very next line following the opening brief function
-description line, with no intervening blank comment lines. The ``@argument:``
-descriptions may span multiple lines. The continuation lines may contain
-indentation. If a function parameter is ``...`` (varargs), it should be listed
-in kernel-doc notation as: ``@...:``.
-
-The return value, if any, should be described in a dedicated section at the end
-of the comment starting with "Return:".
 
 Structure, union, and enumeration documentation
 ---
-- 
2.13.5



[PATCH 03/10] docs: kernel-doc.rst: improve private members description

2017-09-26 Thread Mauro Carvalho Chehab
The private members section can now be moved to be together
with the arguments section. Move it there and add an example
about the usage of public:

Signed-off-by: Mauro Carvalho Chehab 
---
 Documentation/doc-guide/kernel-doc.rst | 56 ++
 1 file changed, 30 insertions(+), 26 deletions(-)

diff --git a/Documentation/doc-guide/kernel-doc.rst 
b/Documentation/doc-guide/kernel-doc.rst
index 7a3f5c710c0b..f1eb00899084 100644
--- a/Documentation/doc-guide/kernel-doc.rst
+++ b/Documentation/doc-guide/kernel-doc.rst
@@ -167,6 +167,36 @@ notation as::
 
   * @...: description
 
+Private members
+~~~
+
+Inside a struct or union description, you can use the ``private:`` and
+``public:`` comment tags. Structure fields that are inside a ``private:``
+area are not listed in the generated output documentation.
+
+The ``private:`` and ``public:`` tags must begin immediately following a
+``/*`` comment marker.  They may optionally include comments between the
+``:`` and the ending ``*/`` marker.
+
+Example::
+
+  /**
+   * struct my_struct - short description
+   * @a: first member
+   * @b: second member
+   * @d: fourth member
+   *
+   * Longer description
+   */
+  struct my_struct {
+  int a;
+  int b;
+  /* private: internal use only */
+  int c;
+  /* public: the next one is public */
+  int d;
+  };
+
 
 Highlights and cross-references
 ---
@@ -332,32 +362,6 @@ on a line of their own, like all other kernel-doc 
comments::
 int foobar;
   }
 
-Private members
-~~~
-
-Inside a struct description, you can use the "private:" and "public:" comment
-tags. Structure fields that are inside a "private:" area are not listed in the
-generated output documentation.  The "private:" and "public:" tags must begin
-immediately following a ``/*`` comment marker.  They may optionally include
-comments between the ``:`` and the ending ``*/`` marker.
-
-Example::
-
-  /**
-   * struct my_struct - short description
-   * @a: first member
-   * @b: second member
-   *
-   * Longer description
-   */
-  struct my_struct {
-  int a;
-  int b;
-  /* private: internal use only */
-  int c;
-  };
-
-
 Typedef documentation
 -
 
-- 
2.13.5



[PATCH 02/10] docs: kernel-doc.rst: better describe kernel-doc arguments

2017-09-26 Thread Mauro Carvalho Chehab
Add a new section to describe kernel-doc arguments,
adding examples about how identation should happen, as failing
to do that causes Sphinx to do the wrong thing.

Signed-off-by: Mauro Carvalho Chehab 
---
 Documentation/doc-guide/kernel-doc.rst | 44 +++---
 1 file changed, 41 insertions(+), 3 deletions(-)

diff --git a/Documentation/doc-guide/kernel-doc.rst 
b/Documentation/doc-guide/kernel-doc.rst
index b24854b5d6be..7a3f5c710c0b 100644
--- a/Documentation/doc-guide/kernel-doc.rst
+++ b/Documentation/doc-guide/kernel-doc.rst
@@ -112,16 +112,17 @@ Example kernel-doc function comment::
 
   /**
* foobar() - Brief description of foobar.
-   * @arg: Description of argument of foobar.
+   * @argument1: Description of parameter argument1 of foobar.
+   * @argument1: Description of parameter argument2 of foobar.
*
* Longer description of foobar.
*
* Return: Description of return value of foobar.
*/
-  int foobar(int arg)
+  int foobar(int argument1, char *argument2)
 
 The format is similar for documentation for structures, enums, paragraphs,
-etc. See the sections below for details.
+etc. See the sections below for specific details of each type.
 
 The kernel-doc structure is extracted from the comments, and proper `Sphinx C
 Domain`_ function and type descriptions with anchors are generated for them. 
The
@@ -130,6 +131,43 @@ cross-references. See below for details.
 
 .. _Sphinx C Domain: http://www.sphinx-doc.org/en/stable/domains.html
 
+
+Parameters and member arguments
+---
+
+The kernel-doc function comments describe each parameter to the function and
+function typedefs or each member of struct/union, in order, with the
+``@argument:`` descriptions. For each non-private member argument, one
+``@argument`` definition is needed.
+
+The ``@argument:`` descriptions begin on the very next line following
+the opening brief function description line, with no intervening blank
+comment lines.
+
+The ``@argument:`` descriptions may span multiple lines.
+
+.. note::
+
+   If the ``@argument`` description has multiple lines, the continuation
+   of the description should be starting exactly at the same column as
+   the previous line, e. g.::
+
+  * @argument: some long description
+  *   that continues on next lines
+
+   or::
+
+  * @argument:
+  *some long description
+  *that continues on next lines
+
+If a function or typedef parameter argument is ``...`` (e. g. a variable
+number of arguments), its description should be listed in kernel-doc
+notation as::
+
+  * @...: description
+
+
 Highlights and cross-references
 ---
 
-- 
2.13.5



Re: [PATCH] scripts: kernel-doc: parse next structs/unions

2017-09-26 Thread Markus Heiser

> Am 25.09.2017 um 20:22 schrieb Mauro Carvalho Chehab 
> :
> 
> Jon,
> 
> Please let me know what you think about this approach. IMHO, it is a way
> better than what we do right now. This is more a proof of concept, as the
> patch is not complete. 
> 
> With it, we can now document both anonymous and named unions/structs.
> 
> For named structs, the name of the fields should be in the format:
>   foo.bar
> 
> What's missing on this PoC:
> 
> 1) I didn't check if @foo.bar: would work, though.  Probably the parser
>   for it should be added to allow this new syntax.

Below you will find my  with a "@sys_clk.rate: lorem ipsum".
With I expected a output in the **Members** section for sys_clk.rate but
I got none :o

Anyway your concept is good and so I applied it to my py-version. If you
are interested in follow the patches titled ...

kernel-doc: fix nested & sub-nested handling (continued

at  https://github.com/return42/linuxdoc/commits/master

I also added some comments from my (py-) experience to your perl
implementation below.

Here are some links which illustrate how your concept could work:

documentation with example: 
  
https://return42.github.io/linuxdoc/linuxdoc-howto/kernel-doc-syntax.html#structs-unions

how the example is rendered:
  
https://return42.github.io/linuxdoc/linuxdoc-howto/all-in-a-tumble.html#example-my-struct


> 
> 2) I only changed the ReST output to preserve the struct format with
>   nested fields. 
> 
> For (2), I'm thinking is we should still have all those output formats for
> kernel-doc. IMHO, I would keep just RST (and perhaps man - while we don't
> have a "make man" targed working.
> 
> Depending on your comments, I'll proceed addressing (1) and (2)
> and doing more tests with it.
> 
> 
> 
> scripts/kernel-doc | 83 +++---
> 1 file changed, 54 insertions(+), 29 deletions(-)
> 
> diff --git a/scripts/kernel-doc b/scripts/kernel-doc
> index 9d3eafea58f0..5ca81b879088 100755
> --- a/scripts/kernel-doc
> +++ b/scripts/kernel-doc
> @@ -2035,29 +2035,9 @@ sub output_struct_rst(%) {
> 
> print "**Definition**\n\n";
> print "::\n\n";
> -print "  " . $args{'type'} . " " . $args{'struct'} . " {\n";
> -foreach $parameter (@{$args{'parameterlist'}}) {
> - if ($parameter =~ /^#/) {
> - print "  " . "$parameter\n";
> - next;
> - }
> -
> - my $parameter_name = $parameter;
> - $parameter_name =~ s/\[.*//;
> -
> - ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
> - $type = $args{'parametertypes'}{$parameter};
> - if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
> - # pointer-to-function
> - print "$1 $parameter) ($2);\n";
> - } elsif ($type =~ m/^(.*?)\s*(:.*)/) {
> - # bitfield
> - print "$1 $parameter$2;\n";
> - } else {
> - print "" . $type . " " . $parameter . ";\n";
> - }
> -}
> -print "  };\n\n";
> +my $declaration = $args{'definition'};
> +$declaration =~ s/\t/  /g;
> +print "  " . $args{'type'} . " " . $args{'struct'} . " {\n$declaration  
> };\n\n";
> 
> print "**Members**\n\n";
> $lineprefix = "  ";
> @@ -2168,20 +2148,15 @@ sub dump_struct($$) {
> my $nested;
> 
> if ($x =~ /(struct|union)\s+(\w+)\s*{(.*)}/) {
> - #my $decl_type = $1;
> + my $decl_type = $1;
>   $declaration_name = $2;
>   my $members = $3;
> 
> - # ignore embedded structs or unions
> - $members =~ s/({.*})//g;
> - $nested = $1;
> -
>   # ignore members marked private:
>   $members =~ s/\/\*\s*private:.*?\/\*\s*public:.*?\*\///gosi;
>   $members =~ s/\/\*\s*private:.*//gosi;
>   # strip comments:
>   $members =~ s/\/\*.*?\*\///gos;
> - $nested =~ s/\/\*.*?\*\///gos;
>   # strip kmemcheck_bitfield_{begin,end}.*;
>   $members =~ s/kmemcheck_bitfield_.*?;//gos;
>   # strip attributes
> @@ -2193,13 +2168,63 @@ sub dump_struct($$) {
>   # replace DECLARE_HASHTABLE
>   $members =~ s/DECLARE_HASHTABLE\s*\(([^,)]+), ([^,)]+)\)/unsigned long 
> $1\[1 << (($2) - 1)\]/gos;
> 
> + my $declaration = $members;
> +
> + # Split nested struct/union elements as newer ones
> + my $cont = 1;
> + while ($cont) {
> + $cont = 0;

Is the outer loop needed ..

> + while ($members =~ 
> m/(struct|union)([^{};]+){([^{}]*)}([^{}\;]*)\;/) {

this (inner) loop seems enough to me.

> + my $newmember = "$1 $4;";
> + my $id = $4;

This won't work if  you have e.g.

   union car {int foo;} bar1, bar2, *bbar3;

where $id will be "bar1, bar2, *bbar3", you need to split
this string and iterate over the id's.

> + my $content = $3;
> + $id =~ s/[:\[].*//;
> + foreach my $arg (split /;/, $content) {
> + next if ($arg =~ m/^\s*$/);
> +   

Re: [PATCH 1/6] [media] tda8261: Use common error handling code in tda8261_set_params()

2017-09-26 Thread SF Markus Elfring
>> @@ -129,18 +129,18 @@ static int tda8261_set_params(struct dvb_frontend *fe)
>>  
>>  /* Set params */
>>  err = tda8261_write(state, buf);
>> -if (err < 0) {
>> -pr_err("%s: I/O Error\n", __func__);
>> -return err;
>> -}
>> +err = tda8261_get_status(fe, );
>> +if (err < 0)
>> +goto report_failure;
>> +
> 
> Is this change really correct? Doesn't it query the status once more
> often than before?

Thanks for your inquiry.

Unfortunately, I made a copy mistake at this source code place.
When should I send a corrected suggestion for this update step
in the patch series?

Regards,
Markus


Re: [PATCH v4 4/9] em28xx: fix em28xx_dvb_init for KASAN

2017-09-26 Thread Andrey Ryabinin


On 09/26/2017 09:47 AM, Arnd Bergmann wrote:
> On Mon, Sep 25, 2017 at 11:32 PM, Arnd Bergmann  wrote:
>> On Mon, Sep 25, 2017 at 7:41 AM, David Laight  
>> wrote:
>>> From: Arnd Bergmann
 Sent: 22 September 2017 22:29
>>> ...
 It seems that this is triggered in part by using strlcpy(), which the
 compiler doesn't recognize as copying at most 'len' bytes, since strlcpy
 is not part of the C standard.
>>>
>>> Neither is strncpy().
>>>
>>> It'll almost certainly be a marker in a header file somewhere,
>>> so it should be possibly to teach it about other functions.
>>
>> I'm currently travelling and haven't investigated in detail, but from
>> taking a closer look here, I found that the hardened 'strlcpy()'
>> in include/linux/string.h triggers it. There is also a hardened
>> (much shorted) 'strncpy()' that doesn't trigger it in the same file,
>> and having only the extern declaration of strncpy also doesn't.
> 
> And a little more experimenting leads to this simple patch that fixes
> the problem:
> 
> --- a/include/linux/string.h
> +++ b/include/linux/string.h
> @@ -254,7 +254,7 @@ __FORTIFY_INLINE size_t strlcpy(char *p, const
> char *q, size_t size)
> size_t q_size = __builtin_object_size(q, 0);
> if (p_size == (size_t)-1 && q_size == (size_t)-1)
> return __real_strlcpy(p, q, size);
> -   ret = strlen(q);
> +   ret = __builtin_strlen(q);


I think this is not correct. Fortified strlen called here on purpose. If sizeof 
q is known at compile time
and 'q' contains not-null fortified strlen() will panic.


> if (size) {
> size_t len = (ret >= size) ? size - 1 : ret;
> if (__builtin_constant_p(len) && len >= p_size)
> 
> The problem is apparently that the fortified strlcpy calls the fortified 
> strlen,
> which in turn calls strnlen and that ends up calling the extern 
> '__real_strnlen'
> that gcc cannot reduce to a constant expression for a constant input.


Per my observation, it's the code like this:
if () 
fortify_panic(__func__);


somehow prevent gcc to merge several "struct i2c_board_info info;" into one 
stack slot.
With the hack bellow, stack usage reduced to ~1,6K:

---
 include/linux/string.h | 4 
 1 file changed, 4 deletions(-)

diff --git a/include/linux/string.h b/include/linux/string.h
index 54d21783e18d..9a96ff3ebf94 100644
--- a/include/linux/string.h
+++ b/include/linux/string.h
@@ -261,8 +261,6 @@ __FORTIFY_INLINE __kernel_size_t strlen(const char *p)
if (p_size == (size_t)-1)
return __builtin_strlen(p);
ret = strnlen(p, p_size);
-   if (p_size <= ret)
-   fortify_panic(__func__);
return ret;
 }
 
@@ -271,8 +269,6 @@ __FORTIFY_INLINE __kernel_size_t strnlen(const char *p, 
__kernel_size_t maxlen)
 {
size_t p_size = __builtin_object_size(p, 0);
__kernel_size_t ret = __real_strnlen(p, maxlen < p_size ? maxlen : 
p_size);
-   if (p_size <= ret && maxlen != ret)
-   fortify_panic(__func__);
return ret;
 }




> Not sure if that change is the best fix, but it seems to address the problem 
> in
> this driver and probably leads to better code in other places as well.
> 

Probably it would be better to solve this on the strlcpy side, but I haven't 
found the way to do this right.
Alternative solutions:

 - use memcpy() instead of strlcpy(). All source strings are smaller than 
I2C_NAME_SIZE, so we could
   do something like this - memcpy(info.type, "si2168", sizeof("si2168"));
   Also this should be faster.

 - Move code under different "case:" in the switch(dev->model) to the separate 
function should help as well.
   But it might be harder to backport into stables.





[PATCH 2/3] edid-decode: detailed_block: fix maybe uninitialized warning

2017-09-26 Thread Baruch Siach
Fix the following warnings:

edid-decode.c: In function ‘detailed_block’:
edid-decode.c:394:2: warning: ‘width’ may be used uninitialized in this 
function [-Wmaybe-uninitialized]
edid-decode.c:394:2: warning: ‘ratio’ may be used uninitialized in this 
function [-Wmaybe-uninitialized]

Signed-off-by: Baruch Siach 
---
 edid-decode.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/edid-decode.c b/edid-decode.c
index 3df35ec6d07f..4abd79333d61 100644
--- a/edid-decode.c
+++ b/edid-decode.c
@@ -348,6 +348,10 @@ detailed_cvt_descriptor(unsigned char *x, int first)
width = 8 * (((height * 15) / 9) / 8);
ratio = "15:9";
break;
+default:
+   width = 0;
+   ratio = "unknown";
+   break;
 }
 
 if (x[1] & 0x03)
-- 
2.14.1



[PATCH 1/3] edid-decode: parse_cta: fix maybe uninitialized warning

2017-09-26 Thread Baruch Siach
Fix the following warning:

edid-decode.c: In function ‘parse_cta’:
edid-decode.c:142:5: warning: ‘v’ may be used uninitialized in this function 
[-Wmaybe-uninitialized]

Signed-off-by: Baruch Siach 
---
 edid-decode.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/edid-decode.c b/edid-decode.c
index 5592227d1db5..3df35ec6d07f 100644
--- a/edid-decode.c
+++ b/edid-decode.c
@@ -124,7 +124,7 @@ struct field {
 static void
 decode_value(struct field *field, int val, const char *prefix)
 {
-struct value *v;
+struct value *v = NULL;
 int i;
 
 for (i = 0; i < field->n_values; i++) {
@@ -139,7 +139,8 @@ decode_value(struct field *field, int val, const char 
*prefix)
return;
 }
 
-printf("%s%s: %s (%d)\n", prefix, field->name, v->description, val);
+printf("%s%s: %s (%d)\n", prefix, field->name,
+ v ? v->description : "unknown", val);
 }
 
 static void
-- 
2.14.1



[PATCH 3/3] edid-decode: parse_extension: fix maybe uninitialized warning

2017-09-26 Thread Baruch Siach
Fix the following warning:

edid-decode.c: In function ‘main’:
edid-decode.c:2962:26: warning: ‘conformant_extension’ may be used 
uninitialized in this function [-Wmaybe-uninitialized]

Signed-off-by: Baruch Siach 
---
 edid-decode.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/edid-decode.c b/edid-decode.c
index 4abd79333d61..d3aafa926900 100644
--- a/edid-decode.c
+++ b/edid-decode.c
@@ -2397,7 +2397,7 @@ extension_version(unsigned char *x)
 static int
 parse_extension(unsigned char *x)
 {
-int conformant_extension;
+int conformant_extension = 0;
 printf("\n");
 
 switch(x[0]) {
-- 
2.14.1



Re: [PATCH v6 2/2] media: rc: Add driver for tango HW IR decoder

2017-09-26 Thread Måns Rullgård
Marc Gonzalez  writes:

> On 26/09/2017 15:02, Måns Rullgård wrote:
>
>> I could continue nit-picking, but I think this is good enough.
>> Thanks for being patient.
>> 
>> Signed-off-by: Mans Rullgard 
>
> Smirk.
>
> If you feel like making a final round of changes on top of this patch,
> then go for it. It's your code, after all.
>
> (Too bad there is no devm variant of clk_prepare_enable.)
>
> Does it make sense to submit a keymap for the Sigma remote control
> used with Vantage boards? And define that as the default keymap?

Maybe.  The real product I have with a tango3 chip uses a remote control
that is quite similar the Sigma one.  Having something that works out of
the box with the dev board is also nice.

-- 
Måns Rullgård


Re: usb/media/uvc: warning in uvc_scan_chain_forward/__list_add

2017-09-26 Thread Andrey Konovalov
On Tue, Sep 26, 2017 at 2:50 PM, Laurent Pinchart
 wrote:
> Hi Andrey,
>
> On Tuesday, 26 September 2017 15:41:45 EEST Andrey Konovalov wrote:
>> On Tue, Sep 26, 2017 at 10:43 AM, Laurent Pinchart wrote:
>> > On Monday, 25 September 2017 15:40:13 EEST Andrey Konovalov wrote:
>> >> Hi!
>> >>
>> >> I've got the following report while fuzzing the kernel with syzkaller.
>> >
>> > Thank you for the report.
>> >
>> >> On commit e19b205be43d11bff638cad4487008c48d21c103 (4.14-rc2).
>> >>
>> >> list_add double add: new=880069084010, prev=880069084010,
>> >> next=880067d22298.
>> >> [ cut here ]
>> >> WARNING: CPU: 1 PID: 1846 at lib/list_debug.c:31
>> >> __list_add_valid+0xbd/0xf0
>> >> Modules linked in:
>> >> CPU: 1 PID: 1846 Comm: kworker/1:2 Not tainted
>> >> 4.14.0-rc2-42613-g1488251d1a98 #238
>> >> Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs
>> >> 01/01/2011 Workqueue: usb_hub_wq hub_event
>> >> task: 88006b01ca40 task.stack: 880064358000
>> >> RIP: 0010:__list_add_valid+0xbd/0xf0 lib/list_debug.c:29
>> >> RSP: 0018:88006435ddd0 EFLAGS: 00010286
>> >> RAX: 0058 RBX: 880067d22298 RCX: 
>> >> RDX: 0058 RSI: 85a58800 RDI: ed000c86bbac
>> >> RBP: 88006435dde8 R08: 11000c86ba52 R09: 
>> >> R10: 0002 R11:  R12: 880069084010
>> >> R13: 880067d22298 R14: 880069084010 R15: 880067d222a0
>> >> FS:  () GS:88006c90()
>> >> knlGS: CS:  0010 DS:  ES:  CR0: 80050033
>> >> CR2: 20004ff2 CR3: 6b447000 CR4: 06e0
>> >>
>> >> Call Trace:
>> >>  __list_add ./include/linux/list.h:59
>> >>  list_add_tail+0x8c/0x1b0 ./include/linux/list.h:92
>> >>  uvc_scan_chain_forward.isra.8+0x373/0x416
>> >>
>> >> drivers/media/usb/uvc/uvc_driver.c:1471
>> >>
>> >>  uvc_scan_chain drivers/media/usb/uvc/uvc_driver.c:1585
>> >>  uvc_scan_device drivers/media/usb/uvc/uvc_driver.c:1769
>> >>  uvc_probe+0x77f2/0x8f00 drivers/media/usb/uvc/uvc_driver.c:2104
>> >
>> > So the issue happens at probe time, before the driver registers the V4L2
>> > device nodes that allow userspace access to the device. I wonder how
>> > fuzzing caused this. Do you have a more detailed log ?
>> >
>> > Could you also tell me what webcam you're using to test this out ? The
>> > output of lsusb -v would be useful.
>>
>> Hi Laurent,
>>
>> I fuzz the USB stack externally by emulating random USB devices via
>> dummy_hcd and gadgetfs.
>
> Ah that makes more sense indeed.
>
>> lsusb -v doesn't show anything, since the USB device doesn't finish
>> initialization.
>>
>> Since I'm able to reproduce this, I can collect debug traces for you.
>
> Could you send me the descriptors that your gadget driver returns to the host
> ? If that's difficult, as an alternative, could you enable tracing in the
> uvcvideo driver (uvcvideo.trace=0x on the kernel commmand line for
> instance) and send me the kernel log ?

The log with uvcvideo.trace=0x is below.

Also attaching usbmon trace.

gadgetfs: bound to dummy_udc driver
usb 1-1: new full-speed USB device number 2 using dummy_hcd
gadgetfs: connected
gadgetfs: disconnected
gadgetfs: connected
usb 1-1: config 3 has an invalid interface number: 3 but max is 0
usb 1-1: config 3 contains an unexpected descriptor of type 0x1, skipping
usb 1-1: config 3 has an invalid descriptor of length 208, skipping
remainder of the config
usb 1-1: config 3 has no interface number 0
usb 1-1: New USB device found, idVendor=07f5, idProduct=03ff
usb 1-1: New USB device strings: Mfr=83, Product=255, SerialNumber=5
usb 1-1: Product: a
usb 1-1: Manufacturer: a
usb 1-1: SerialNumber: a
gadgetfs: configuration #3
uvcvideo: Probing generic UVC device 1
uvcvideo: Found UVC 0.00 device a (07f5:03ff)
uvcvideo: Scanning UVC chain: OT 0
list_add double add: new=880061ca3a90, prev=880061ca3a90,
next=88006b3f48d8.
[ cut here ]
...
---[ end trace e2bce247826f5cdb ]---
 (-> OT 0)
uvcvideo: Found a valid video chain ( -> 0).
uvcvideo 1-1:3.3: Entity type for entity a was not initialized!
uvcvideo: UVC device initialized.
gadgetfs: disconnected
usb 1-1: USB disconnect, device number 2

>
>> Here's a part of the log around the warning report:
>>
>> gadgetfs: bound to dummy_udc driver
>> usb 1-1: new full-speed USB device number 2 using dummy_hcd
>> gadgetfs: connected
>> gadgetfs: disconnected
>> gadgetfs: connected
>> usb 1-1: config 3 has an invalid interface number: 3 but max is 0
>> usb 1-1: config 3 contains an unexpected descriptor of type 0x1, skipping
>> usb 1-1: config 3 has an invalid descriptor of length 208, skipping
>> remainder of the config
>> usb 1-1: config 3 has no interface number 0
>> usb 1-1: New USB device found, idVendor=07f5, idProduct=03ff
>> usb 1-1: New USB device strings: Mfr=83, Product=255, 

Re: [PATCH v6 2/2] media: rc: Add driver for tango HW IR decoder

2017-09-26 Thread Marc Gonzalez
On 26/09/2017 15:02, Måns Rullgård wrote:

> I could continue nit-picking, but I think this is good enough.
> Thanks for being patient.
> 
> Signed-off-by: Mans Rullgard 

Smirk.

If you feel like making a final round of changes on top of this patch,
then go for it. It's your code, after all.

(Too bad there is no devm variant of clk_prepare_enable.)

Does it make sense to submit a keymap for the Sigma remote control
used with Vantage boards? And define that as the default keymap?

Regards.



[PATCH 2/2] [media] dmxdev: Improve a size determination in dvb_dmxdev_add_pid()

2017-09-26 Thread SF Markus Elfring
From: Markus Elfring 
Date: Tue, 26 Sep 2017 15:22:57 +0200

Replace the specification of a data structure by a pointer dereference
as the parameter for the operator "sizeof" to make the corresponding size
determination a bit safer according to the Linux coding style convention.

This issue was detected by using the Coccinelle software.

Signed-off-by: Markus Elfring 
---
 drivers/media/dvb-core/dmxdev.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/dvb-core/dmxdev.c b/drivers/media/dvb-core/dmxdev.c
index f8bf7459d5ca..8e0f91775fe4 100644
--- a/drivers/media/dvb-core/dmxdev.c
+++ b/drivers/media/dvb-core/dmxdev.c
@@ -809,7 +809,7 @@ static int dvb_dmxdev_add_pid(struct dmxdev *dmxdev,
(!list_empty(>feed.ts)))
return -EINVAL;
 
-   feed = kzalloc(sizeof(struct dmxdev_feed), GFP_KERNEL);
+   feed = kzalloc(sizeof(*feed), GFP_KERNEL);
if (feed == NULL)
return -ENOMEM;
 
-- 
2.14.1



[PATCH 0/2] [media] dmxdev: Fine-tuning for two function implementations

2017-09-26 Thread SF Markus Elfring
From: Markus Elfring 
Date: Tue, 26 Sep 2017 15:30:03 +0200

Two update suggestions were taken into account
from static source code analysis.

Markus Elfring (2):
  Use common error handling code in dvb_dmxdev_start_feed()
  Improve a size determination in dvb_dmxdev_add_pid()

 drivers/media/dvb-core/dmxdev.c | 18 +-
 1 file changed, 9 insertions(+), 9 deletions(-)

-- 
2.14.1



[PATCH 1/2] [media] dmxdev: Use common error handling code in dvb_dmxdev_start_feed()

2017-09-26 Thread SF Markus Elfring
From: Markus Elfring 
Date: Tue, 26 Sep 2017 15:12:47 +0200

Add a jump target so that a bit of exception handling can be better reused
at the end of this function.

This issue was detected by using the Coccinelle software.

Signed-off-by: Markus Elfring 
---
 drivers/media/dvb-core/dmxdev.c | 16 
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/media/dvb-core/dmxdev.c b/drivers/media/dvb-core/dmxdev.c
index 45e91add73ba..f8bf7459d5ca 100644
--- a/drivers/media/dvb-core/dmxdev.c
+++ b/drivers/media/dvb-core/dmxdev.c
@@ -594,18 +594,18 @@ static int dvb_dmxdev_start_feed(struct dmxdev *dmxdev,
tsfeed->priv = filter;
 
ret = tsfeed->set(tsfeed, feed->pid, ts_type, ts_pes, timeout);
-   if (ret < 0) {
-   dmxdev->demux->release_ts_feed(dmxdev->demux, tsfeed);
-   return ret;
-   }
+   if (ret < 0)
+   goto release_feed;
 
ret = tsfeed->start_filtering(tsfeed);
-   if (ret < 0) {
-   dmxdev->demux->release_ts_feed(dmxdev->demux, tsfeed);
-   return ret;
-   }
+   if (ret < 0)
+   goto release_feed;
 
return 0;
+
+release_feed:
+   dmxdev->demux->release_ts_feed(dmxdev->demux, tsfeed);
+   return ret;
 }
 
 static int dvb_dmxdev_filter_start(struct dmxdev_filter *filter)
-- 
2.14.1



Re: [progress]: dvb_usb_rtl28xxu not tuning "Leadtek Winfast DTV2000 DS PLUS TV"

2017-09-26 Thread Eyal Lebedinsky

On 26/09/17 22:45, Vincent McIntyre wrote:

On Tue, Sep 26, 2017 at 02:32:26PM +1000, Eyal Lebedinsky wrote:


While the problem persists, I managed to find a way around it for now.

I changed the antenna input.

Originally I used a powered splitter to feed all the tuners, and it worked
well with the out-of-kernel driver. This driver does not build or work with
a more modern kernel so I shifted to using dvb_usb_rtl28xxu which fails to
tune.

The new wiring splits (passive) the antenna in two, feeds one side directly
to the two "Leadtek Winfast DTV2000 DS PLUS TV" cards (through another passive
2-way) and the other side goes to the old powered splitter that feeds a few
USB tuners.

Now all tuners are happy. It seems that the "Leadtek Winfast DTV2000 DS PLUS TV"
cannot handle the amplified input while the USB tuners require it.

I hope that there is a way to set a profile in dvb_usb_rtl28xxu to attenuate
the input to an acceptable level thus unravelling the antenna cables rat-nest.


Glad you had some success.

I did some more rummaging in v4l-utils. It may help you to know about
dvb-fe-tool, which gives information about the frontend device
(eg /dev/dvb/adapter0/frontend0). In particular you can monitor the
s/n as you make changes:

  # dvb-fe-tool --femon -a 0  #here doing adapter0/frontend0

It displays info about the signal quality and the carrier/noise (C/N) ratio,
which might help any investigation of where the driver fails to cope as
you change what you are feeding it.

I noticed your dvbv5-scan showed C/N around 20dB but the manpage shows
'good signal' with C/N of 36dB which suggests the device should be
expected to deal with higher signal levels.

Once you figured out the signal level, did a dvbv5-scan work with no
errors? In the example you showed I saw the channels getting 'lock'
but then some kind of error occurred.


I had very good reception and scandvb tuned to all channels. I did not test
dvbv5-scan again but I expect it would work too (will try in the morning).


Regards
Vince


--
Eyal Lebedinsky (e...@eyal.emu.id.au)


Re: [PATCH v6 2/2] media: rc: Add driver for tango HW IR decoder

2017-09-26 Thread Måns Rullgård
Marc Gonzalez  writes:

> From: Mans Rullgard 
>
> The tango HW IR decoder supports NEC, RC-5, RC-6 protocols.
>
> Signed-off-by: Marc Gonzalez 

I could continue nit-picking, but I think this is good enough.  Thanks
for being patient.

Signed-off-by: Mans Rullgard 

> ---
> Changes between v5 and v6
> * Move "register fields" macros to top of file
> * Restore IRQ pending writes
> ---
>  drivers/media/rc/Kconfig|  10 ++
>  drivers/media/rc/Makefile   |   1 +
>  drivers/media/rc/tango-ir.c | 279 
> 
>  3 files changed, 290 insertions(+)
>  create mode 100644 drivers/media/rc/tango-ir.c
>
> diff --git a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig
> index d9ce8ff55d0c..e80d4362e769 100644
> --- a/drivers/media/rc/Kconfig
> +++ b/drivers/media/rc/Kconfig
> @@ -469,6 +469,16 @@ config IR_SIR
>  To compile this driver as a module, choose M here: the module will
>  be called sir-ir.
>
> +config IR_TANGO
> + tristate "Sigma Designs SMP86xx IR decoder"
> + depends on RC_CORE
> + depends on ARCH_TANGO || COMPILE_TEST
> + ---help---
> +Adds support for the HW IR decoder embedded on Sigma Designs
> +Tango-based systems (SMP86xx, SMP87xx).
> +The HW decoder supports NEC, RC-5, RC-6 IR protocols.
> +When compiled as a module, look for tango-ir.
> +
>  config IR_ZX
>   tristate "ZTE ZX IR remote control"
>   depends on RC_CORE
> diff --git a/drivers/media/rc/Makefile b/drivers/media/rc/Makefile
> index 9bc6a3980ed0..643797dc971b 100644
> --- a/drivers/media/rc/Makefile
> +++ b/drivers/media/rc/Makefile
> @@ -44,3 +44,4 @@ obj-$(CONFIG_IR_SERIAL) += serial_ir.o
>  obj-$(CONFIG_IR_SIR) += sir_ir.o
>  obj-$(CONFIG_IR_MTK) += mtk-cir.o
>  obj-$(CONFIG_IR_ZX) += zx-irdec.o
> +obj-$(CONFIG_IR_TANGO) += tango-ir.o
> diff --git a/drivers/media/rc/tango-ir.c b/drivers/media/rc/tango-ir.c
> new file mode 100644
> index ..1bd4e3412a29
> --- /dev/null
> +++ b/drivers/media/rc/tango-ir.c
> @@ -0,0 +1,279 @@
> +/*
> + * Copyright (C) 2015 Mans Rullgard 
> + *
> + * This program is free software; you can redistribute  it and/or modify it
> + * under  the terms of  the GNU General  Public License as published by the
> + * Free Software Foundation;  either version 2 of the  License, or (at your
> + * option) any later version.
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#define DRIVER_NAME "tango-ir"
> +
> +#define IR_NEC_CTRL  0x00
> +#define IR_NEC_DATA  0x04
> +#define IR_CTRL  0x08
> +#define IR_RC5_CLK_DIV   0x0c
> +#define IR_RC5_DATA  0x10
> +#define IR_INT   0x14
> +
> +#define NEC_TIME_BASE560
> +#define RC5_TIME_BASE1778
> +
> +#define RC6_CTRL 0x00
> +#define RC6_CLKDIV   0x04
> +#define RC6_DATA00x08
> +#define RC6_DATA10x0c
> +#define RC6_DATA20x10
> +#define RC6_DATA30x14
> +#define RC6_DATA40x18
> +
> +#define RC6_CARRIER  36000
> +#define RC6_TIME_BASE16
> +
> +#define NEC_CAP(n)   ((n) << 24)
> +#define GPIO_SEL(n)  ((n) << 16)
> +#define DISABLE_NEC  (BIT(4) | BIT(8))
> +#define ENABLE_RC5   (BIT(0) | BIT(9))
> +#define ENABLE_RC6   (BIT(0) | BIT(7))
> +#define ACK_IR_INT   (BIT(0) | BIT(1))
> +#define ACK_RC6_INT  (BIT(31))
> +
> +struct tango_ir {
> + void __iomem *rc5_base;
> + void __iomem *rc6_base;
> + struct rc_dev *rc;
> + struct clk *clk;
> +};
> +
> +static void tango_ir_handle_nec(struct tango_ir *ir)
> +{
> + u32 v, code;
> + enum rc_proto proto;
> +
> + v = readl_relaxed(ir->rc5_base + IR_NEC_DATA);
> + if (!v) {
> + rc_repeat(ir->rc);
> + return;
> + }
> +
> + code = ir_nec_bytes_to_scancode(v, v >> 8, v >> 16, v >> 24, );
> + rc_keydown(ir->rc, proto, code, 0);
> +}
> +
> +static void tango_ir_handle_rc5(struct tango_ir *ir)
> +{
> + u32 data, field, toggle, addr, cmd, code;
> +
> + data = readl_relaxed(ir->rc5_base + IR_RC5_DATA);
> + if (data & BIT(31))
> + return;
> +
> + field = data >> 12 & 1;
> + toggle = data >> 11 & 1;
> + addr = data >> 6 & 0x1f;
> + cmd = (data & 0x3f) | (field ^ 1) << 6;
> +
> + code = RC_SCANCODE_RC5(addr, cmd);
> + rc_keydown(ir->rc, RC_PROTO_RC5, code, toggle);
> +}
> +
> +static void tango_ir_handle_rc6(struct tango_ir *ir)
> +{
> + u32 data0, data1, toggle, mode, addr, cmd, code;
> +
> + data0 = readl_relaxed(ir->rc6_base + RC6_DATA0);
> + data1 = readl_relaxed(ir->rc6_base + RC6_DATA1);
> +
> + mode = data0 >> 1 & 7;
> + if (mode != 0)
> + return;
> +
> + toggle = data0 & 1;
> + addr = data0 >> 16;
> + cmd = data1;
> +
> + code = RC_SCANCODE_RC6_0(addr, cmd);
> + rc_keydown(ir->rc, RC_PROTO_RC6_0, code, 

Re: usb/media/uvc: warning in uvc_scan_chain_forward/__list_add

2017-09-26 Thread Laurent Pinchart
Hi Andrey,

On Tuesday, 26 September 2017 15:41:45 EEST Andrey Konovalov wrote:
> On Tue, Sep 26, 2017 at 10:43 AM, Laurent Pinchart wrote:
> > On Monday, 25 September 2017 15:40:13 EEST Andrey Konovalov wrote:
> >> Hi!
> >> 
> >> I've got the following report while fuzzing the kernel with syzkaller.
> > 
> > Thank you for the report.
> > 
> >> On commit e19b205be43d11bff638cad4487008c48d21c103 (4.14-rc2).
> >> 
> >> list_add double add: new=880069084010, prev=880069084010,
> >> next=880067d22298.
> >> [ cut here ]
> >> WARNING: CPU: 1 PID: 1846 at lib/list_debug.c:31
> >> __list_add_valid+0xbd/0xf0
> >> Modules linked in:
> >> CPU: 1 PID: 1846 Comm: kworker/1:2 Not tainted
> >> 4.14.0-rc2-42613-g1488251d1a98 #238
> >> Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs
> >> 01/01/2011 Workqueue: usb_hub_wq hub_event
> >> task: 88006b01ca40 task.stack: 880064358000
> >> RIP: 0010:__list_add_valid+0xbd/0xf0 lib/list_debug.c:29
> >> RSP: 0018:88006435ddd0 EFLAGS: 00010286
> >> RAX: 0058 RBX: 880067d22298 RCX: 
> >> RDX: 0058 RSI: 85a58800 RDI: ed000c86bbac
> >> RBP: 88006435dde8 R08: 11000c86ba52 R09: 
> >> R10: 0002 R11:  R12: 880069084010
> >> R13: 880067d22298 R14: 880069084010 R15: 880067d222a0
> >> FS:  () GS:88006c90()
> >> knlGS: CS:  0010 DS:  ES:  CR0: 80050033
> >> CR2: 20004ff2 CR3: 6b447000 CR4: 06e0
> >> 
> >> Call Trace:
> >>  __list_add ./include/linux/list.h:59
> >>  list_add_tail+0x8c/0x1b0 ./include/linux/list.h:92
> >>  uvc_scan_chain_forward.isra.8+0x373/0x416
> >> 
> >> drivers/media/usb/uvc/uvc_driver.c:1471
> >> 
> >>  uvc_scan_chain drivers/media/usb/uvc/uvc_driver.c:1585
> >>  uvc_scan_device drivers/media/usb/uvc/uvc_driver.c:1769
> >>  uvc_probe+0x77f2/0x8f00 drivers/media/usb/uvc/uvc_driver.c:2104
> > 
> > So the issue happens at probe time, before the driver registers the V4L2
> > device nodes that allow userspace access to the device. I wonder how
> > fuzzing caused this. Do you have a more detailed log ?
> > 
> > Could you also tell me what webcam you're using to test this out ? The
> > output of lsusb -v would be useful.
> 
> Hi Laurent,
> 
> I fuzz the USB stack externally by emulating random USB devices via
> dummy_hcd and gadgetfs.

Ah that makes more sense indeed.

> lsusb -v doesn't show anything, since the USB device doesn't finish
> initialization.
> 
> Since I'm able to reproduce this, I can collect debug traces for you.

Could you send me the descriptors that your gadget driver returns to the host 
? If that's difficult, as an alternative, could you enable tracing in the 
uvcvideo driver (uvcvideo.trace=0x on the kernel commmand line for 
instance) and send me the kernel log ?

> Here's a part of the log around the warning report:
> 
> gadgetfs: bound to dummy_udc driver
> usb 1-1: new full-speed USB device number 2 using dummy_hcd
> gadgetfs: connected
> gadgetfs: disconnected
> gadgetfs: connected
> usb 1-1: config 3 has an invalid interface number: 3 but max is 0
> usb 1-1: config 3 contains an unexpected descriptor of type 0x1, skipping
> usb 1-1: config 3 has an invalid descriptor of length 208, skipping
> remainder of the config
> usb 1-1: config 3 has no interface number 0
> usb 1-1: New USB device found, idVendor=07f5, idProduct=03ff
> usb 1-1: New USB device strings: Mfr=83, Product=255, SerialNumber=5
> usb 1-1: Product: a
> usb 1-1: Manufacturer: a
> usb 1-1: SerialNumber: a
> gadgetfs: configuration #3
> uvcvideo: Found UVC 0.00 device a (07f5:03ff)
> list_add double add: new=880069a64910, prev=880069a64910,
> next=8800698468d8.
> [ cut here ]
> WARNING: CPU: 1 PID: 1846 at lib/list_debug.c:31 __list_add_valid+0xbd/0xf0
> ...
> ---[ end trace ea45186b02846d5a ]---
> uvcvideo 1-1:3.3: Entity type for entity a was not initialized!
> gadgetfs: disconnected
> usb 1-1: USB disconnect, device number 2
> 
> Thanks!
> 
> >>  usb_probe_interface+0x35d/0x8e0 drivers/usb/core/driver.c:361
> >>  really_probe drivers/base/dd.c:413
> >>  driver_probe_device+0x610/0xa00 drivers/base/dd.c:557
> >>  __device_attach_driver+0x230/0x290 drivers/base/dd.c:653
> >>  bus_for_each_drv+0x161/0x210 drivers/base/bus.c:463
> >>  __device_attach+0x26e/0x3d0 drivers/base/dd.c:710
> >>  device_initial_probe+0x1f/0x30 drivers/base/dd.c:757
> >>  bus_probe_device+0x1eb/0x290 drivers/base/bus.c:523
> >>  device_add+0xd0b/0x1660 drivers/base/core.c:1835
> >>  usb_set_configuration+0x104e/0x1870 drivers/usb/core/message.c:1932
> >>  generic_probe+0x73/0xe0 drivers/usb/core/generic.c:174
> >>  usb_probe_device+0xaf/0xe0 drivers/usb/core/driver.c:266
> >>  really_probe drivers/base/dd.c:413
> >>  driver_probe_device+0x610/0xa00 drivers/base/dd.c:557
> >>  

Re: [PATCH v2] scripts: kernel-doc: fix nexted handling

2017-09-26 Thread Markus Heiser

> Am 25.09.2017 um 20:41 schrieb Mauro Carvalho Chehab 
> :

>>> +   $cont = 1;
>>> +   };
>>> +   };
>>> +   # Ignore other nested elements, like enums
>>> +   $members =~ s/({[^\{\}]*})//g;
>>> +   $nested = $decl_type;  
>> 
>> What is the latter good for? I guess the 'nested' trick to suppress
>> such 'excess' warnings from nested types is no longer needed .. right?
> 
> For things like:
> 
>   enum { foo, bar } type;
> 
> Granted, a good documentation should also describe "foo" and "bar",
> but that could be easily done by moving enums out of the struct, or
> by add descriptions for "foo" and "bar" at @type: markup.


Hm .. I suppose you are misunderstanding me. I didn't asked about 
$members, I asked about $nested. There is only one place where
$nested is used, and this is in the check_sections function ...

@@ -2531,9 +2527,7 @@ sub check_sections($$) {
} else {
-   if ($nested !~ m/\Q$sects[$sx]\E/) {
-   print STDERR "${file}:$.: warning: " .
-   "Excess struct/union/enum/typedef 
member " .
-   "'$sects[$sx]' " .
-   "description in '$decl_name'\n";
-   ++$warnings;
-   }
+print STDERR "${file}:$.: warning: " .
+"Excess struct/union/enum/typedef member " .
+"'$sects[$sx]' " .
+"description in '$decl_name'\n";
+++$warnings;
}

Since this is the only place where $nested is use, we can drop all
the occurrence of $nested in the kernel-doc script .. or I'am
totally wrong?

  -- Markus --


Re: [progress]: dvb_usb_rtl28xxu not tuning "Leadtek Winfast DTV2000 DS PLUS TV"

2017-09-26 Thread Vincent McIntyre
On Tue, Sep 26, 2017 at 02:32:26PM +1000, Eyal Lebedinsky wrote:
> 
> While the problem persists, I managed to find a way around it for now.
> 
> I changed the antenna input.
> 
> Originally I used a powered splitter to feed all the tuners, and it worked
> well with the out-of-kernel driver. This driver does not build or work with
> a more modern kernel so I shifted to using dvb_usb_rtl28xxu which fails to
> tune.
> 
> The new wiring splits (passive) the antenna in two, feeds one side directly
> to the two "Leadtek Winfast DTV2000 DS PLUS TV" cards (through another passive
> 2-way) and the other side goes to the old powered splitter that feeds a few
> USB tuners.
> 
> Now all tuners are happy. It seems that the "Leadtek Winfast DTV2000 DS PLUS 
> TV"
> cannot handle the amplified input while the USB tuners require it.
> 
> I hope that there is a way to set a profile in dvb_usb_rtl28xxu to attenuate
> the input to an acceptable level thus unravelling the antenna cables rat-nest.

Glad you had some success.

I did some more rummaging in v4l-utils. It may help you to know about
dvb-fe-tool, which gives information about the frontend device
(eg /dev/dvb/adapter0/frontend0). In particular you can monitor the
s/n as you make changes:

 # dvb-fe-tool --femon -a 0  #here doing adapter0/frontend0

It displays info about the signal quality and the carrier/noise (C/N) ratio,
which might help any investigation of where the driver fails to cope as
you change what you are feeding it.

I noticed your dvbv5-scan showed C/N around 20dB but the manpage shows
'good signal' with C/N of 36dB which suggests the device should be
expected to deal with higher signal levels.

Once you figured out the signal level, did a dvbv5-scan work with no
errors? In the example you showed I saw the channels getting 'lock'
but then some kind of error occurred.

Regards
Vince



Re: usb/media/uvc: warning in uvc_scan_chain_forward/__list_add

2017-09-26 Thread Andrey Konovalov
On Tue, Sep 26, 2017 at 10:43 AM, Laurent Pinchart
 wrote:
> Hi Andrey,
>
> On Monday, 25 September 2017 15:40:13 EEST Andrey Konovalov wrote:
>> Hi!
>>
>> I've got the following report while fuzzing the kernel with syzkaller.
>
> Thank you for the report.
>
>> On commit e19b205be43d11bff638cad4487008c48d21c103 (4.14-rc2).
>>
>> list_add double add: new=880069084010, prev=880069084010,
>> next=880067d22298.
>> [ cut here ]
>> WARNING: CPU: 1 PID: 1846 at lib/list_debug.c:31 __list_add_valid+0xbd/0xf0
>> Modules linked in:
>> CPU: 1 PID: 1846 Comm: kworker/1:2 Not tainted
>> 4.14.0-rc2-42613-g1488251d1a98 #238
>> Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
>> Workqueue: usb_hub_wq hub_event
>> task: 88006b01ca40 task.stack: 880064358000
>> RIP: 0010:__list_add_valid+0xbd/0xf0 lib/list_debug.c:29
>> RSP: 0018:88006435ddd0 EFLAGS: 00010286
>> RAX: 0058 RBX: 880067d22298 RCX: 
>> RDX: 0058 RSI: 85a58800 RDI: ed000c86bbac
>> RBP: 88006435dde8 R08: 11000c86ba52 R09: 
>> R10: 0002 R11:  R12: 880069084010
>> R13: 880067d22298 R14: 880069084010 R15: 880067d222a0
>> FS:  () GS:88006c90() knlGS:
>> CS:  0010 DS:  ES:  CR0: 80050033
>> CR2: 20004ff2 CR3: 6b447000 CR4: 06e0
>> Call Trace:
>>  __list_add ./include/linux/list.h:59
>>  list_add_tail+0x8c/0x1b0 ./include/linux/list.h:92
>>  uvc_scan_chain_forward.isra.8+0x373/0x416
>> drivers/media/usb/uvc/uvc_driver.c:1471
>>  uvc_scan_chain drivers/media/usb/uvc/uvc_driver.c:1585
>>  uvc_scan_device drivers/media/usb/uvc/uvc_driver.c:1769
>>  uvc_probe+0x77f2/0x8f00 drivers/media/usb/uvc/uvc_driver.c:2104
>
> So the issue happens at probe time, before the driver registers the V4L2
> device nodes that allow userspace access to the device. I wonder how fuzzing
> caused this. Do you have a more detailed log ?
>
> Could you also tell me what webcam you're using to test this out ? The output
> of lsusb -v would be useful.

Hi Laurent,

I fuzz the USB stack externally by emulating random USB devices via
dummy_hcd and gadgetfs.

lsusb -v doesn't show anything, since the USB device doesn't finish
initialization.

Since I'm able to reproduce this, I can collect debug traces for you.

Here's a part of the log around the warning report:

gadgetfs: bound to dummy_udc driver
usb 1-1: new full-speed USB device number 2 using dummy_hcd
gadgetfs: connected
gadgetfs: disconnected
gadgetfs: connected
usb 1-1: config 3 has an invalid interface number: 3 but max is 0
usb 1-1: config 3 contains an unexpected descriptor of type 0x1, skipping
usb 1-1: config 3 has an invalid descriptor of length 208, skipping
remainder of the config
usb 1-1: config 3 has no interface number 0
usb 1-1: New USB device found, idVendor=07f5, idProduct=03ff
usb 1-1: New USB device strings: Mfr=83, Product=255, SerialNumber=5
usb 1-1: Product: a
usb 1-1: Manufacturer: a
usb 1-1: SerialNumber: a
gadgetfs: configuration #3
uvcvideo: Found UVC 0.00 device a (07f5:03ff)
list_add double add: new=880069a64910, prev=880069a64910,
next=8800698468d8.
[ cut here ]
WARNING: CPU: 1 PID: 1846 at lib/list_debug.c:31 __list_add_valid+0xbd/0xf0
...
---[ end trace ea45186b02846d5a ]---
uvcvideo 1-1:3.3: Entity type for entity a was not initialized!
gadgetfs: disconnected
usb 1-1: USB disconnect, device number 2

Thanks!

>
>>  usb_probe_interface+0x35d/0x8e0 drivers/usb/core/driver.c:361
>>  really_probe drivers/base/dd.c:413
>>  driver_probe_device+0x610/0xa00 drivers/base/dd.c:557
>>  __device_attach_driver+0x230/0x290 drivers/base/dd.c:653
>>  bus_for_each_drv+0x161/0x210 drivers/base/bus.c:463
>>  __device_attach+0x26e/0x3d0 drivers/base/dd.c:710
>>  device_initial_probe+0x1f/0x30 drivers/base/dd.c:757
>>  bus_probe_device+0x1eb/0x290 drivers/base/bus.c:523
>>  device_add+0xd0b/0x1660 drivers/base/core.c:1835
>>  usb_set_configuration+0x104e/0x1870 drivers/usb/core/message.c:1932
>>  generic_probe+0x73/0xe0 drivers/usb/core/generic.c:174
>>  usb_probe_device+0xaf/0xe0 drivers/usb/core/driver.c:266
>>  really_probe drivers/base/dd.c:413
>>  driver_probe_device+0x610/0xa00 drivers/base/dd.c:557
>>  __device_attach_driver+0x230/0x290 drivers/base/dd.c:653
>>  bus_for_each_drv+0x161/0x210 drivers/base/bus.c:463
>>  __device_attach+0x26e/0x3d0 drivers/base/dd.c:710
>>  device_initial_probe+0x1f/0x30 drivers/base/dd.c:757
>>  bus_probe_device+0x1eb/0x290 drivers/base/bus.c:523
>>  device_add+0xd0b/0x1660 drivers/base/core.c:1835
>>  usb_new_device+0x7b8/0x1020 drivers/usb/core/hub.c:2457
>>  hub_port_connect drivers/usb/core/hub.c:4903
>>  hub_port_connect_change drivers/usb/core/hub.c:5009
>>  port_event drivers/usb/core/hub.c:5115
>>  hub_event+0x194d/0x3740 

Re: [progress]: dvb_usb_rtl28xxu not tuning "Leadtek Winfast DTV2000 DS PLUS TV"

2017-09-26 Thread Eyal Lebedinsky

On 26/09/17 14:32, Eyal Lebedinsky wrote:

On 18/09/17 14:26, Eyal Lebedinsky wrote:

I have just upgraded to f24. I am now using the standard dvb_usb_rtl28xxu fe
which logs messages suggesting all is well (I get the /dev/dvb/adapter? etc.)
but I get no channels tuned when I run mythfrontend or scandvb.

Is anyone using this combination?
Is this the correct way to use this tuner?

BTW:

Until f22 I was using the out of kernel driver from
 https://github.com/jaredquinn/DVB-Realtek-RTL2832U.git
but I now get a compile error.

TIA


This is an FYI in case anyone else stumbles on this thread.

While the problem persists, I managed to find a way around it for now.

I changed the antenna input.

Originally I used a powered splitter to feed all the tuners, and it worked
well with the out-of-kernel driver. This driver does not build or work with
a more modern kernel so I shifted to using dvb_usb_rtl28xxu which fails to
tune.

The new wiring splits (passive) the antenna in two, feeds one side directly
to the two "Leadtek Winfast DTV2000 DS PLUS TV" cards (through another passive
2-way) and the other side goes to the old powered splitter that feeds a few
USB tuners.

Now all tuners are happy. It seems that the "Leadtek Winfast DTV2000 DS PLUS TV"
cannot handle the amplified input while the USB tuners require it.

I hope that there is a way to set a profile in dvb_usb_rtl28xxu to attenuate
the input to an acceptable level thus unravelling the antenna cables rat-nest.


Looking further, I think that it is the fc0013 tuner that should manage the lna
but does not. Compare it to the module in here

https://github.com/jaredquinn/DVB-Realtek-RTL2832U/blob/master/src/tuner_fc0013.c
which I was using successfully (unfortunately this repo does not build or work
with current linux kernels).

Is this possible? If so, can it be fixed?

cheers


cheers


--
Eyal Lebedinsky (e...@eyal.emu.id.au)


usb/media/b2c2: GPF in flexcop_usb_transfer_init

2017-09-26 Thread Andrey Konovalov
Hi!

I've got the following report while fuzzing the kernel with syzkaller.

On commit e19b205be43d11bff638cad4487008c48d21c103 (4.14-rc2).

It seems that there's no check on the actual number of endpoints.

usb 1-1: New USB device strings: Mfr=212, Product=0, SerialNumber=6
usb 1-1: Manufacturer: a
usb 1-1: SerialNumber: a
gadgetfs: configuration #3
flexcop_usb: running at FULL speed.
gadgetfs: disconnected
flexcop_usb: error while reading dword from 161 (516).
flexcop_usb: error while writing dword from 33 (516).
flexcop_usb: error while writing dword from 33 (516).
flexcop_usb: error while reading dword from 161 (516).
flexcop_usb: error while reading dword from 247 (1820).
flexcop_usb: error while writing dword from 119 (1820).
flexcop_usb: error while reading dword from 176 (768).
flexcop_usb: error while reading dword from 162 (520).
flexcop_usb: error while writing dword from 48 (768).
flexcop_usb: error while writing dword from 34 (520).
flexcop_usb: error while reading dword from 176 (768).
flexcop_usb: error while reading dword from 162 (520).
flexcop_usb: error while writing dword from 48 (768).
flexcop_usb: error while writing dword from 34 (520).
flexcop_usb: error while reading dword from 177 (772).
flexcop_usb: error while reading dword from 162 (520).
flexcop_usb: error while writing dword from 49 (772).
flexcop_usb: error while writing dword from 34 (520).
flexcop_usb: error while reading dword from 177 (772).
flexcop_usb: error while reading dword from 162 (520).
flexcop_usb: error while writing dword from 49 (772).
flexcop_usb: error while writing dword from 34 (520).
flexcop_usb: error while reading dword from 178 (776).
flexcop_usb: error while reading dword from 162 (520).
flexcop_usb: error while writing dword from 50 (776).
flexcop_usb: error while writing dword from 34 (520).
flexcop_usb: error while reading dword from 178 (776).
flexcop_usb: error while reading dword from 162 (520).
flexcop_usb: error while writing dword from 50 (776).
flexcop_usb: error while writing dword from 34 (520).
flexcop_usb: error while writing dword from 51 (780).
flexcop_usb: error while reading dword from 162 (520).
flexcop_usb: error while writing dword from 34 (520).
flexcop_usb: error while reading dword from 178 (776).
flexcop_usb: error while writing dword from 50 (776).
flexcop_usb: error while reading dword from 162 (520).
flexcop_usb: error while writing dword from 34 (520).
flexcop_usb: error while reading dword from 162 (520).
flexcop_usb: error while writing dword from 34 (520).
dvbdev: DVB: registering new adapter (FlexCop Digital TV device)
b2c2-flexcop: reading of MAC address failed.

CX24123: wrong demod revision: 0
nxt200x: Unknown/Unsupported NXT chip: 00 00 00 00 00
tuner-simple 0-0061: creating new instance
tuner-simple 0-0061: type set to 64 (LG TDVS-H06xF)
b2c2-flexcop: found 'LG Electronics LGDT3303 VSB/QAM Frontend' .
usb 1-1: DVB: registering adapter 0 frontend 0 (LG Electronics
LGDT3303 VSB/QAM Frontend)...
b2c2-flexcop: initialization of 'Air2PC/AirStar 2 ATSC 3rd generation
(HD5000)' at the 'USB' bus controlled by a 'FlexCopIII' complete
kasan: CONFIG_KASAN_INLINE enabled
kasan: GPF could be caused by NULL-ptr deref or user memory access
general protection fault:  [#1] PREEMPT SMP KASAN
Modules linked in:
CPU: 0 PID: 24 Comm: kworker/0:1 Not tainted 4.14.0-rc2-42613-g1488251d1a98 #254
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
Workqueue: usb_hub_wq hub_event
task: 88006befe300 task.stack: 88006bf78000
RIP: 0010:flexcop_usb_transfer_init drivers/media/usb/b2c2/flexcop-usb.c:429
RIP: 0010:flexcop_usb_probe+0x4c9/0xc00 drivers/media/usb/b2c2/flexcop-usb.c:574
RSP: 0018:88006bf7e570 EFLAGS: 00010247
RAX: dc00 RBX: 88006944 RCX: 
RDX:  RSI: 88006befeca8 RDI: 0004
RBP: 88006bf7e5e8 R08: 11000d7efb34 R09: 
R10: 88006bf7e4d0 R11:  R12: 88006bafa200
R13:  R14:  R15: 880062b51198
FS:  () GS:88006c80() knlGS:
CS:  0010 DS:  ES:  CR0: 80050033
CR2: 2fb4 CR3: 674bb000 CR4: 06f0
Call Trace:
 usb_probe_interface+0x35d/0x8e0 drivers/usb/core/driver.c:361
 really_probe drivers/base/dd.c:413
 driver_probe_device+0x610/0xa00 drivers/base/dd.c:557
 __device_attach_driver+0x230/0x290 drivers/base/dd.c:653
 bus_for_each_drv+0x161/0x210 drivers/base/bus.c:463
 __device_attach+0x26e/0x3d0 drivers/base/dd.c:710
 device_initial_probe+0x1f/0x30 drivers/base/dd.c:757
 bus_probe_device+0x1eb/0x290 drivers/base/bus.c:523
 device_add+0xd0b/0x1660 drivers/base/core.c:1835
 usb_set_configuration+0x104e/0x1870 drivers/usb/core/message.c:1932
 generic_probe+0x73/0xe0 drivers/usb/core/generic.c:174
 usb_probe_device+0xaf/0xe0 drivers/usb/core/driver.c:266
 really_probe drivers/base/dd.c:413
 

Re: [PATCH 1/6] [media] tda8261: Use common error handling code in tda8261_set_params()

2017-09-26 Thread Christoph Böhmwalder
On 26.09.2017 13:27, SF Markus Elfring wrote:
> From: Markus Elfring 
> Date: Tue, 26 Sep 2017 11:01:44 +0200
> 
> * Add a jump target so that a bit of exception handling can be better
>   reused at the end of this function.
> 
>   This issue was detected by using the Coccinelle software.
> 
> * The script "checkpatch.pl" pointed information out like the following.
> 
>   ERROR: do not use assignment in if condition
> 
>   Thus fix an affected source code place.
> 
> Signed-off-by: Markus Elfring 
> ---
>  drivers/media/dvb-frontends/tda8261.c | 20 
>  1 file changed, 12 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/media/dvb-frontends/tda8261.c 
> b/drivers/media/dvb-frontends/tda8261.c
> index 4eb294f330bc..5a8a9b6b8107 100644
> --- a/drivers/media/dvb-frontends/tda8261.c
> +++ b/drivers/media/dvb-frontends/tda8261.c
> @@ -129,18 +129,18 @@ static int tda8261_set_params(struct dvb_frontend *fe)
>  
>   /* Set params */
>   err = tda8261_write(state, buf);
> - if (err < 0) {
> - pr_err("%s: I/O Error\n", __func__);
> - return err;
> - }
> + err = tda8261_get_status(fe, );
> + if (err < 0)
> + goto report_failure;
> +

Is this change really correct? Doesn't it query the status once more
often than before?

>   /* sleep for some time */
>   pr_debug("%s: Waiting to Phase LOCK\n", __func__);
>   msleep(20);
>   /* check status */
> - if ((err = tda8261_get_status(fe, )) < 0) {
> - pr_err("%s: I/O Error\n", __func__);
> - return err;
> - }
> + err = tda8261_get_status(fe, );
> + if (err < 0)
> + goto report_failure;
> +
>   if (status == 1) {
>   pr_debug("%s: Tuner Phase locked: status=%d\n", __func__,
>status);
> @@ -150,6 +150,10 @@ static int tda8261_set_params(struct dvb_frontend *fe)
>   }
>  
>   return 0;
> +
> +report_failure:
> + pr_err("%s: I/O Error\n", __func__);
> + return err;
>  }
>  
>  static void tda8261_release(struct dvb_frontend *fe)
> 


-- 
Regards,
Christoph



signature.asc
Description: OpenPGP digital signature


[PATCH 6/6] [media] tda8261: Delete an unnecessary variable initialisation in three functions

2017-09-26 Thread SF Markus Elfring
From: Markus Elfring 
Date: Tue, 26 Sep 2017 12:55:16 +0200

The local variable "err" is reassigned by a statement at the beginning.
Thus omit the explicit initialisation in these functions.

Signed-off-by: Markus Elfring 
---
 drivers/media/dvb-frontends/tda8261.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/media/dvb-frontends/tda8261.c 
b/drivers/media/dvb-frontends/tda8261.c
index 20185ee8f253..33144a34e337 100644
--- a/drivers/media/dvb-frontends/tda8261.c
+++ b/drivers/media/dvb-frontends/tda8261.c
@@ -39,7 +39,7 @@ struct tda8261_state {
 static int tda8261_read(struct tda8261_state *state, u8 *buf)
 {
const struct tda8261_config *config = state->config;
-   int err = 0;
+   int err;
struct i2c_msg msg = { .addr= config->addr, .flags = I2C_M_RD,.buf 
= buf,  .len = 1 };
 
err = i2c_transfer(state->i2c, , 1);
@@ -52,7 +52,7 @@ static int tda8261_read(struct tda8261_state *state, u8 *buf)
 static int tda8261_write(struct tda8261_state *state, u8 *buf)
 {
const struct tda8261_config *config = state->config;
-   int err = 0;
+   int err;
struct i2c_msg msg = { .addr = config->addr, .flags = 0, .buf = buf, 
.len = 4 };
 
err = i2c_transfer(state->i2c, , 1);
@@ -66,7 +66,7 @@ static int tda8261_get_status(struct dvb_frontend *fe, u32 
*status)
 {
struct tda8261_state *state = fe->tuner_priv;
u8 result = 0;
-   int err = 0;
+   int err;
 
*status = 0;
err = tda8261_read(state, );
-- 
2.14.1



[PATCH 4/6] [media] tda8261: Delete an unnecessary variable initialisation in tda8261_attach()

2017-09-26 Thread SF Markus Elfring
From: Markus Elfring 
Date: Tue, 26 Sep 2017 12:24:57 +0200

The local variable "state" is reassigned by a statement at the beginning.
Thus omit the explicit initialisation.

Signed-off-by: Markus Elfring 
---
 drivers/media/dvb-frontends/tda8261.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/dvb-frontends/tda8261.c 
b/drivers/media/dvb-frontends/tda8261.c
index e3b4183d00c2..492d8c03a5fa 100644
--- a/drivers/media/dvb-frontends/tda8261.c
+++ b/drivers/media/dvb-frontends/tda8261.c
@@ -183,7 +183,7 @@ struct dvb_frontend *tda8261_attach(struct dvb_frontend *fe,
const struct tda8261_config *config,
struct i2c_adapter *i2c)
 {
-   struct tda8261_state *state = NULL;
+   struct tda8261_state *state;
 
state = kzalloc(sizeof(*state), GFP_KERNEL);
if (!state)
-- 
2.14.1



[PATCH 5/6] [media] tda8261: Adjust three function calls together with a variable assignment

2017-09-26 Thread SF Markus Elfring
From: Markus Elfring 
Date: Tue, 26 Sep 2017 12:52:24 +0200

The script "checkpatch.pl" pointed information out like the following.

ERROR: do not use assignment in if condition

Thus fix the affected source code places.

Signed-off-by: Markus Elfring 
---
 drivers/media/dvb-frontends/tda8261.c | 10 ++
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/media/dvb-frontends/tda8261.c 
b/drivers/media/dvb-frontends/tda8261.c
index 492d8c03a5fa..20185ee8f253 100644
--- a/drivers/media/dvb-frontends/tda8261.c
+++ b/drivers/media/dvb-frontends/tda8261.c
@@ -42,7 +42,8 @@ static int tda8261_read(struct tda8261_state *state, u8 *buf)
int err = 0;
struct i2c_msg msg = { .addr= config->addr, .flags = I2C_M_RD,.buf 
= buf,  .len = 1 };
 
-   if ((err = i2c_transfer(state->i2c, , 1)) != 1)
+   err = i2c_transfer(state->i2c, , 1);
+   if (err != 1)
pr_err("%s: read error, err=%d\n", __func__, err);
 
return err;
@@ -54,7 +55,8 @@ static int tda8261_write(struct tda8261_state *state, u8 *buf)
int err = 0;
struct i2c_msg msg = { .addr = config->addr, .flags = 0, .buf = buf, 
.len = 4 };
 
-   if ((err = i2c_transfer(state->i2c, , 1)) != 1)
+   err = i2c_transfer(state->i2c, , 1);
+   if (err != 1)
pr_err("%s: write error, err=%d\n", __func__, err);
 
return err;
@@ -67,8 +69,8 @@ static int tda8261_get_status(struct dvb_frontend *fe, u32 
*status)
int err = 0;
 
*status = 0;
-
-   if ((err = tda8261_read(state, )) < 0) {
+   err = tda8261_read(state, );
+   if (err < 0) {
pr_err("%s: I/O Error\n", __func__);
return err;
}
-- 
2.14.1



[PATCH 3/6] [media] tda8261: Return directly after a failed kzalloc() in tda8261_attach()

2017-09-26 Thread SF Markus Elfring
From: Markus Elfring 
Date: Tue, 26 Sep 2017 12:20:33 +0200

* Return directly after a call of the function "kzalloc" failed
  at the beginning.

* Delete a call of the function "kfree" and the jump target "exit"
  which became unnecessary with this refactoring.

Signed-off-by: Markus Elfring 
---
 drivers/media/dvb-frontends/tda8261.c | 6 +-
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/drivers/media/dvb-frontends/tda8261.c 
b/drivers/media/dvb-frontends/tda8261.c
index 5269a170c84e..e3b4183d00c2 100644
--- a/drivers/media/dvb-frontends/tda8261.c
+++ b/drivers/media/dvb-frontends/tda8261.c
@@ -187,7 +187,7 @@ struct dvb_frontend *tda8261_attach(struct dvb_frontend *fe,
 
state = kzalloc(sizeof(*state), GFP_KERNEL);
if (!state)
-   goto exit;
+   return NULL;
 
state->config   = config;
state->i2c  = i2c;
@@ -200,10 +200,6 @@ struct dvb_frontend *tda8261_attach(struct dvb_frontend 
*fe,
pr_info("%s: Attaching TDA8261 8PSK/QPSK tuner\n", __func__);
 
return fe;
-
-exit:
-   kfree(state);
-   return NULL;
 }
 
 EXPORT_SYMBOL(tda8261_attach);
-- 
2.14.1



Re: [PATCH v14 20/28] v4l: fwnode: Add a helper function to obtain device / integer references

2017-09-26 Thread Sakari Ailus
Hi Hans,

Thanks for the review.

On Tue, Sep 26, 2017 at 10:47:40AM +0200, Hans Verkuil wrote:
> On 26/09/17 00:25, Sakari Ailus wrote:
> > v4l2_fwnode_reference_parse_int_prop() will find an fwnode such that under
> > the device's own fwnode, it will follow child fwnodes with the given
> > property-value pair and return the resulting fwnode.
> > 
> > Signed-off-by: Sakari Ailus 
> > ---
> >  drivers/media/v4l2-core/v4l2-fwnode.c | 201 
> > ++
> >  1 file changed, 201 insertions(+)
> > 
> > diff --git a/drivers/media/v4l2-core/v4l2-fwnode.c 
> > b/drivers/media/v4l2-core/v4l2-fwnode.c
> > index f739dfd16cf7..f93049c361e4 100644
> > --- a/drivers/media/v4l2-core/v4l2-fwnode.c
> > +++ b/drivers/media/v4l2-core/v4l2-fwnode.c
> > @@ -578,6 +578,207 @@ static int v4l2_fwnode_reference_parse(
> > return ret;
> >  }
> >  
> > +/*
> > + * v4l2_fwnode_reference_get_int_prop - parse a reference with integer
> > + * arguments
> > + * @dev: struct device pointer
> > + * @notifier: notifier for @dev
> > + * @prop: the name of the property
> > + * @index: the index of the reference to get
> > + * @props: the array of integer property names
> > + * @nprops: the number of integer property names in @nprops
> > + *
> > + * Find fwnodes referred to by a property @prop, then under that
> > + * iteratively, @nprops times, follow each child node which has a
> > + * property in @props array at a given child index the value of which
> > + * matches the integer argument at an index.
> 
> "at an index". Still makes no sense to me. Which index?

How about this:

First find an fwnode referred to by the reference at @index in @prop.

Then under that fwnode, @nprops times, for each property in @props,
iteratively follow child nodes starting from fwnode such that they have the
property in @props array at the index of the child node distance from the
root node and the value of that property matching with the integer argument of
the reference, at the same index.

> 
> > + *
> > + * For example, if this function was called with arguments and values
> > + * @dev corresponding to device "SEN", @prop == "flash-leds", @index
> > + * == 1, @props == { "led" }, @nprops == 1, with the ASL snippet below
> > + * it would return the node marked with THISONE. The @dev argument in
> > + * the ASL below.
> 
> I know I asked for this before, but can you change the example to one where
> nprops = 2? I think that will help understanding this.

I could do that but then the example no longer corresponds to any actual
case that exists at the moment. LED nodes will use a single integer
argument and lens-focus nodes none.

> 
> > + *
> > + * Device (LED)
> > + * {
> > + * Name (_DSD, Package () {
> > + * ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"),
> > + * Package () {
> > + * Package () { "led0", "LED0" },
> > + * Package () { "led1", "LED1" },
> > + * }
> > + * })
> > + * Name (LED0, Package () {
> > + * ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> > + * Package () {
> > + * Package () { "led", 0 },
> > + * }
> > + * })
> > + * Name (LED1, Package () {
> > + * // THISONE
> > + * ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> > + * Package () {
> > + * Package () { "led", 1 },
> > + * }
> > + * })
> > + * }
> > + *
> > + * Device (SEN)
> > + * {
> > + * Name (_DSD, Package () {
> > + * ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> > + * Package () {
> > + * Package () {
> > + * "flash-leds",
> > + * Package () { ^LED, 0, ^LED, 1 },
> > + * }
> > + * }
> > + * })
> > + * }
> > + *
> > + * where
> > + *
> > + * LED LED driver device
> > + * LED0First LED
> > + * LED1Second LED
> > + * SEN Camera sensor device (or another device the LED is
> > + * related to)
> > + *
> > + * Return: 0 on success
> > + *-ENOENT if no entries (or the property itself) were found
> > + *-EINVAL if property parsing otherwise failed
> > + *-ENOMEM if memory allocation failed
> > + */
> > +static struct fwnode_handle *v4l2_fwnode_reference_get_int_prop(
> > +   struct fwnode_handle *fwnode, const char *prop, unsigned int index,
> > +   const char **props, unsigned int nprops)
> > +{
> > +   struct fwnode_reference_args fwnode_args;
> > +   unsigned int *args = fwnode_args.args;
> > +   struct fwnode_handle *child;
> > +   int ret;
> > +
> > +   /*
> > +* Obtain remote fwnode as well as the integer arguments.
> > +*
> > +* Note that right now both -ENODATA 

[PATCH 2/6] [media] tda8261: Improve a size determination in tda8261_attach()

2017-09-26 Thread SF Markus Elfring
From: Markus Elfring 
Date: Tue, 26 Sep 2017 12:06:19 +0200

* The script "checkpatch.pl" pointed information out like the following.

  ERROR: do not use assignment in if condition

  Thus fix an affected source code place.

* Replace the specification of a data structure by a pointer dereference
  as the parameter for the operator "sizeof" to make the corresponding size
  determination a bit safer according to the Linux coding style convention.

Signed-off-by: Markus Elfring 
---
 drivers/media/dvb-frontends/tda8261.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/media/dvb-frontends/tda8261.c 
b/drivers/media/dvb-frontends/tda8261.c
index 5a8a9b6b8107..5269a170c84e 100644
--- a/drivers/media/dvb-frontends/tda8261.c
+++ b/drivers/media/dvb-frontends/tda8261.c
@@ -185,7 +185,8 @@ struct dvb_frontend *tda8261_attach(struct dvb_frontend *fe,
 {
struct tda8261_state *state = NULL;
 
-   if ((state = kzalloc(sizeof (struct tda8261_state), GFP_KERNEL)) == 
NULL)
+   state = kzalloc(sizeof(*state), GFP_KERNEL);
+   if (!state)
goto exit;
 
state->config   = config;
-- 
2.14.1



[PATCH 1/6] [media] tda8261: Use common error handling code in tda8261_set_params()

2017-09-26 Thread SF Markus Elfring
From: Markus Elfring 
Date: Tue, 26 Sep 2017 11:01:44 +0200

* Add a jump target so that a bit of exception handling can be better
  reused at the end of this function.

  This issue was detected by using the Coccinelle software.

* The script "checkpatch.pl" pointed information out like the following.

  ERROR: do not use assignment in if condition

  Thus fix an affected source code place.

Signed-off-by: Markus Elfring 
---
 drivers/media/dvb-frontends/tda8261.c | 20 
 1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/drivers/media/dvb-frontends/tda8261.c 
b/drivers/media/dvb-frontends/tda8261.c
index 4eb294f330bc..5a8a9b6b8107 100644
--- a/drivers/media/dvb-frontends/tda8261.c
+++ b/drivers/media/dvb-frontends/tda8261.c
@@ -129,18 +129,18 @@ static int tda8261_set_params(struct dvb_frontend *fe)
 
/* Set params */
err = tda8261_write(state, buf);
-   if (err < 0) {
-   pr_err("%s: I/O Error\n", __func__);
-   return err;
-   }
+   err = tda8261_get_status(fe, );
+   if (err < 0)
+   goto report_failure;
+
/* sleep for some time */
pr_debug("%s: Waiting to Phase LOCK\n", __func__);
msleep(20);
/* check status */
-   if ((err = tda8261_get_status(fe, )) < 0) {
-   pr_err("%s: I/O Error\n", __func__);
-   return err;
-   }
+   err = tda8261_get_status(fe, );
+   if (err < 0)
+   goto report_failure;
+
if (status == 1) {
pr_debug("%s: Tuner Phase locked: status=%d\n", __func__,
 status);
@@ -150,6 +150,10 @@ static int tda8261_set_params(struct dvb_frontend *fe)
}
 
return 0;
+
+report_failure:
+   pr_err("%s: I/O Error\n", __func__);
+   return err;
 }
 
 static void tda8261_release(struct dvb_frontend *fe)
-- 
2.14.1



[PATCH 0/6] [media] TDA8261: Fine-tuning for five function implementations

2017-09-26 Thread SF Markus Elfring
From: Markus Elfring 
Date: Tue, 26 Sep 2017 13:20:12 +0200

A few update suggestions were taken into account
from static source code analysis.

Markus Elfring (6):
  Use common error handling code in tda8261_set_params()
  Improve a size determination in tda8261_attach()
  Return directly after a failed kzalloc() in tda8261_attach()
  Delete an unnecessary variable initialisation in tda8261_attach()
  Adjust three function calls together with a variable assignment
  Delete an unnecessary variable initialisation in three functions

 drivers/media/dvb-frontends/tda8261.c | 47 +++
 1 file changed, 25 insertions(+), 22 deletions(-)

-- 
2.14.1



Re: usb/media/lmedm04: GPF in lme2510_int_read/usb_pipe_endpoint

2017-09-26 Thread Andrey Konovalov
On Mon, Sep 25, 2017 at 3:30 PM, Malcolm Priestley  wrote:
>
>
> On 25/09/17 13:39, Andrey Konovalov wrote:
>>
>> Hi!
>>
>> I've got the following report while fuzzing the kernel with syzkaller.
>>
>> On commit e19b205be43d11bff638cad4487008c48d21c103 (4.14-rc2).
>>
>> usb 1-1: new full-speed USB device number 2 using dummy_hcd
>> gadgetfs: connected
>> gadgetfs: disconnected
>> gadgetfs: connected
>> usb 1-1: config 63 interface 0 altsetting 32 endpoint 0x7 has invalid
>> maxpacket 476, setting to 64
>> usb 1-1: config 63 interface 0 altsetting 32 has an invalid endpoint
>> with address 0x0, skipping
>> usb 1-1: config 63 interface 0 altsetting 32 has an invalid endpoint
>> with address 0xE7, skipping
>> usb 1-1: config 63 interface 0 altsetting 32 has an invalid endpoint
>> with address 0x7F, skipping
>> usb 1-1: config 63 interface 0 has no altsetting 0
>> usb 1-1: New USB device found, idVendor=3344, idProduct=22f0
>> usb 1-1: New USB device strings: Mfr=255, Product=0, SerialNumber=8
>> usb 1-1: Manufacturer: a
>> usb 1-1: SerialNumber: a
>> gadgetfs: configuration #63
>> gadgetfs: configuration #63
>> usb 1-1: selecting invalid altsetting 1
>> LME2510(C): Firmware Status: 4 (61)
>> usb 1-1: dvb_usb_v2: found a 'DM04_LME2510C_DVB-S RS2000' in warm state
>> usb 1-1: dvb_usb_v2: will use the device's hardware PID filter (table
>> count: 15)
>> dvbdev: DVB: registering new adapter (DM04_LME2510C_DVB-S RS2000)
>> usb 1-1: media controller created
>> dvbdev: dvb_create_media_entity: media entity 'dvb-demux' registered.
>> LME2510(C): FE Found M88RS2000
>> ts2020: probe of 0-0060 failed with error -11
>> usb 1-1: DVB: registering adapter 0 frontend 0 (DM04_LME2510C_DVB-S
>> RS2000 RS2000)...
>> dvbdev: dvb_create_media_entity: media entity 'DM04_LME2510C_DVB-S
>> RS2000 RS2000' registered.
>> LME2510(C): TUN Found RS2000 tuner
>> kasan: CONFIG_KASAN_INLINE enabled
>> kasan: GPF could be caused by NULL-ptr deref or user memory access
>> general protection fault:  [#1] PREEMPT SMP KASAN
>
>
> Neither it it null or user memory and it is always present regardless of
> tuner state when _real_ hardware is connected.

Hi Malcolm,

An attacker may connect a malicious USB device having physical access
to a machine. In this case such device would only cause a kernel
crash, which might not be considered that critical, but other bugs
might be exploitable and allow to execute arbitrary code or leak data.
It would be nice to get this fixed to allow further testing of this
driver.

Thanks!

>
> --
> You received this message because you are subscribed to the Google Groups
> "syzkaller" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to syzkaller+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.


[PATCH v6 2/2] media: rc: Add driver for tango HW IR decoder

2017-09-26 Thread Marc Gonzalez
From: Mans Rullgard 

The tango HW IR decoder supports NEC, RC-5, RC-6 protocols.

Signed-off-by: Marc Gonzalez 
---
Changes between v5 and v6
* Move "register fields" macros to top of file
* Restore IRQ pending writes
---
 drivers/media/rc/Kconfig|  10 ++
 drivers/media/rc/Makefile   |   1 +
 drivers/media/rc/tango-ir.c | 279 
 3 files changed, 290 insertions(+)
 create mode 100644 drivers/media/rc/tango-ir.c

diff --git a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig
index d9ce8ff55d0c..e80d4362e769 100644
--- a/drivers/media/rc/Kconfig
+++ b/drivers/media/rc/Kconfig
@@ -469,6 +469,16 @@ config IR_SIR
   To compile this driver as a module, choose M here: the module will
   be called sir-ir.
 
+config IR_TANGO
+   tristate "Sigma Designs SMP86xx IR decoder"
+   depends on RC_CORE
+   depends on ARCH_TANGO || COMPILE_TEST
+   ---help---
+  Adds support for the HW IR decoder embedded on Sigma Designs
+  Tango-based systems (SMP86xx, SMP87xx).
+  The HW decoder supports NEC, RC-5, RC-6 IR protocols.
+  When compiled as a module, look for tango-ir.
+
 config IR_ZX
tristate "ZTE ZX IR remote control"
depends on RC_CORE
diff --git a/drivers/media/rc/Makefile b/drivers/media/rc/Makefile
index 9bc6a3980ed0..643797dc971b 100644
--- a/drivers/media/rc/Makefile
+++ b/drivers/media/rc/Makefile
@@ -44,3 +44,4 @@ obj-$(CONFIG_IR_SERIAL) += serial_ir.o
 obj-$(CONFIG_IR_SIR) += sir_ir.o
 obj-$(CONFIG_IR_MTK) += mtk-cir.o
 obj-$(CONFIG_IR_ZX) += zx-irdec.o
+obj-$(CONFIG_IR_TANGO) += tango-ir.o
diff --git a/drivers/media/rc/tango-ir.c b/drivers/media/rc/tango-ir.c
new file mode 100644
index ..1bd4e3412a29
--- /dev/null
+++ b/drivers/media/rc/tango-ir.c
@@ -0,0 +1,279 @@
+/*
+ * Copyright (C) 2015 Mans Rullgard 
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define DRIVER_NAME "tango-ir"
+
+#define IR_NEC_CTRL0x00
+#define IR_NEC_DATA0x04
+#define IR_CTRL0x08
+#define IR_RC5_CLK_DIV 0x0c
+#define IR_RC5_DATA0x10
+#define IR_INT 0x14
+
+#define NEC_TIME_BASE  560
+#define RC5_TIME_BASE  1778
+
+#define RC6_CTRL   0x00
+#define RC6_CLKDIV 0x04
+#define RC6_DATA0  0x08
+#define RC6_DATA1  0x0c
+#define RC6_DATA2  0x10
+#define RC6_DATA3  0x14
+#define RC6_DATA4  0x18
+
+#define RC6_CARRIER36000
+#define RC6_TIME_BASE  16
+
+#define NEC_CAP(n) ((n) << 24)
+#define GPIO_SEL(n)((n) << 16)
+#define DISABLE_NEC(BIT(4) | BIT(8))
+#define ENABLE_RC5 (BIT(0) | BIT(9))
+#define ENABLE_RC6 (BIT(0) | BIT(7))
+#define ACK_IR_INT (BIT(0) | BIT(1))
+#define ACK_RC6_INT(BIT(31))
+
+struct tango_ir {
+   void __iomem *rc5_base;
+   void __iomem *rc6_base;
+   struct rc_dev *rc;
+   struct clk *clk;
+};
+
+static void tango_ir_handle_nec(struct tango_ir *ir)
+{
+   u32 v, code;
+   enum rc_proto proto;
+
+   v = readl_relaxed(ir->rc5_base + IR_NEC_DATA);
+   if (!v) {
+   rc_repeat(ir->rc);
+   return;
+   }
+
+   code = ir_nec_bytes_to_scancode(v, v >> 8, v >> 16, v >> 24, );
+   rc_keydown(ir->rc, proto, code, 0);
+}
+
+static void tango_ir_handle_rc5(struct tango_ir *ir)
+{
+   u32 data, field, toggle, addr, cmd, code;
+
+   data = readl_relaxed(ir->rc5_base + IR_RC5_DATA);
+   if (data & BIT(31))
+   return;
+
+   field = data >> 12 & 1;
+   toggle = data >> 11 & 1;
+   addr = data >> 6 & 0x1f;
+   cmd = (data & 0x3f) | (field ^ 1) << 6;
+
+   code = RC_SCANCODE_RC5(addr, cmd);
+   rc_keydown(ir->rc, RC_PROTO_RC5, code, toggle);
+}
+
+static void tango_ir_handle_rc6(struct tango_ir *ir)
+{
+   u32 data0, data1, toggle, mode, addr, cmd, code;
+
+   data0 = readl_relaxed(ir->rc6_base + RC6_DATA0);
+   data1 = readl_relaxed(ir->rc6_base + RC6_DATA1);
+
+   mode = data0 >> 1 & 7;
+   if (mode != 0)
+   return;
+
+   toggle = data0 & 1;
+   addr = data0 >> 16;
+   cmd = data1;
+
+   code = RC_SCANCODE_RC6_0(addr, cmd);
+   rc_keydown(ir->rc, RC_PROTO_RC6_0, code, toggle);
+}
+
+static irqreturn_t tango_ir_irq(int irq, void *dev_id)
+{
+   struct tango_ir *ir = dev_id;
+   unsigned int rc5_stat;
+   unsigned int rc6_stat;
+
+   rc5_stat = readl_relaxed(ir->rc5_base + IR_INT);
+   writel_relaxed(rc5_stat, ir->rc5_base + IR_INT);
+
+   rc6_stat = readl_relaxed(ir->rc6_base + RC6_CTRL);
+   writel_relaxed(rc6_stat, ir->rc6_base + RC6_CTRL);
+

Re: [PATCH v14 20/28] v4l: fwnode: Add a helper function to obtain device / integer references

2017-09-26 Thread Hans Verkuil
On 26/09/17 00:25, Sakari Ailus wrote:
> v4l2_fwnode_reference_parse_int_prop() will find an fwnode such that under
> the device's own fwnode, it will follow child fwnodes with the given
> property-value pair and return the resulting fwnode.
> 
> Signed-off-by: Sakari Ailus 
> ---
>  drivers/media/v4l2-core/v4l2-fwnode.c | 201 
> ++
>  1 file changed, 201 insertions(+)
> 
> diff --git a/drivers/media/v4l2-core/v4l2-fwnode.c 
> b/drivers/media/v4l2-core/v4l2-fwnode.c
> index f739dfd16cf7..f93049c361e4 100644
> --- a/drivers/media/v4l2-core/v4l2-fwnode.c
> +++ b/drivers/media/v4l2-core/v4l2-fwnode.c
> @@ -578,6 +578,207 @@ static int v4l2_fwnode_reference_parse(
>   return ret;
>  }
>  
> +/*
> + * v4l2_fwnode_reference_get_int_prop - parse a reference with integer
> + *   arguments
> + * @dev: struct device pointer
> + * @notifier: notifier for @dev
> + * @prop: the name of the property
> + * @index: the index of the reference to get
> + * @props: the array of integer property names
> + * @nprops: the number of integer property names in @nprops
> + *
> + * Find fwnodes referred to by a property @prop, then under that
> + * iteratively, @nprops times, follow each child node which has a
> + * property in @props array at a given child index the value of which
> + * matches the integer argument at an index.

"at an index". Still makes no sense to me. Which index?

> + *
> + * For example, if this function was called with arguments and values
> + * @dev corresponding to device "SEN", @prop == "flash-leds", @index
> + * == 1, @props == { "led" }, @nprops == 1, with the ASL snippet below
> + * it would return the node marked with THISONE. The @dev argument in
> + * the ASL below.

I know I asked for this before, but can you change the example to one where
nprops = 2? I think that will help understanding this.

> + *
> + *   Device (LED)
> + *   {
> + *   Name (_DSD, Package () {
> + *   ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"),
> + *   Package () {
> + *   Package () { "led0", "LED0" },
> + *   Package () { "led1", "LED1" },
> + *   }
> + *   })
> + *   Name (LED0, Package () {
> + *   ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> + *   Package () {
> + *   Package () { "led", 0 },
> + *   }
> + *   })
> + *   Name (LED1, Package () {
> + *   // THISONE
> + *   ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> + *   Package () {
> + *   Package () { "led", 1 },
> + *   }
> + *   })
> + *   }
> + *
> + *   Device (SEN)
> + *   {
> + *   Name (_DSD, Package () {
> + *   ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> + *   Package () {
> + *   Package () {
> + *   "flash-leds",
> + *   Package () { ^LED, 0, ^LED, 1 },
> + *   }
> + *   }
> + *   })
> + *   }
> + *
> + * where
> + *
> + *   LED LED driver device
> + *   LED0First LED
> + *   LED1Second LED
> + *   SEN Camera sensor device (or another device the LED is
> + *   related to)
> + *
> + * Return: 0 on success
> + *  -ENOENT if no entries (or the property itself) were found
> + *  -EINVAL if property parsing otherwise failed
> + *  -ENOMEM if memory allocation failed
> + */
> +static struct fwnode_handle *v4l2_fwnode_reference_get_int_prop(
> + struct fwnode_handle *fwnode, const char *prop, unsigned int index,
> + const char **props, unsigned int nprops)
> +{
> + struct fwnode_reference_args fwnode_args;
> + unsigned int *args = fwnode_args.args;
> + struct fwnode_handle *child;
> + int ret;
> +
> + /*
> +  * Obtain remote fwnode as well as the integer arguments.
> +  *
> +  * Note that right now both -ENODATA and -ENOENT may signal
> +  * out-of-bounds access. Return -ENOENT in that case.
> +  */
> + ret = fwnode_property_get_reference_args(fwnode, prop, NULL, nprops,
> +  index, _args);
> + if (ret)
> + return ERR_PTR(ret == -ENODATA ? -ENOENT : ret);
> +
> + /*
> +  * Find a node in the tree under the referred fwnode corresponding the

corresponding -> corresponding to

> +  * integer arguments.
> +  */
> + fwnode = fwnode_args.fwnode;
> + while (nprops--) {
> + u32 val;
> +
> + /* Loop over all child nodes under fwnode. */
> + fwnode_for_each_child_node(fwnode, child) {
> + if (fwnode_property_read_u32(child, *props, ))
> +   

Re: usb/media/uvc: warning in uvc_scan_chain_forward/__list_add

2017-09-26 Thread Laurent Pinchart
Hi Andrey,

On Monday, 25 September 2017 15:40:13 EEST Andrey Konovalov wrote:
> Hi!
> 
> I've got the following report while fuzzing the kernel with syzkaller.

Thank you for the report.

> On commit e19b205be43d11bff638cad4487008c48d21c103 (4.14-rc2).
> 
> list_add double add: new=880069084010, prev=880069084010,
> next=880067d22298.
> [ cut here ]
> WARNING: CPU: 1 PID: 1846 at lib/list_debug.c:31 __list_add_valid+0xbd/0xf0
> Modules linked in:
> CPU: 1 PID: 1846 Comm: kworker/1:2 Not tainted
> 4.14.0-rc2-42613-g1488251d1a98 #238
> Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
> Workqueue: usb_hub_wq hub_event
> task: 88006b01ca40 task.stack: 880064358000
> RIP: 0010:__list_add_valid+0xbd/0xf0 lib/list_debug.c:29
> RSP: 0018:88006435ddd0 EFLAGS: 00010286
> RAX: 0058 RBX: 880067d22298 RCX: 
> RDX: 0058 RSI: 85a58800 RDI: ed000c86bbac
> RBP: 88006435dde8 R08: 11000c86ba52 R09: 
> R10: 0002 R11:  R12: 880069084010
> R13: 880067d22298 R14: 880069084010 R15: 880067d222a0
> FS:  () GS:88006c90() knlGS:
> CS:  0010 DS:  ES:  CR0: 80050033
> CR2: 20004ff2 CR3: 6b447000 CR4: 06e0
> Call Trace:
>  __list_add ./include/linux/list.h:59
>  list_add_tail+0x8c/0x1b0 ./include/linux/list.h:92
>  uvc_scan_chain_forward.isra.8+0x373/0x416
> drivers/media/usb/uvc/uvc_driver.c:1471
>  uvc_scan_chain drivers/media/usb/uvc/uvc_driver.c:1585
>  uvc_scan_device drivers/media/usb/uvc/uvc_driver.c:1769
>  uvc_probe+0x77f2/0x8f00 drivers/media/usb/uvc/uvc_driver.c:2104

So the issue happens at probe time, before the driver registers the V4L2 
device nodes that allow userspace access to the device. I wonder how fuzzing 
caused this. Do you have a more detailed log ?

Could you also tell me what webcam you're using to test this out ? The output 
of lsusb -v would be useful.

>  usb_probe_interface+0x35d/0x8e0 drivers/usb/core/driver.c:361
>  really_probe drivers/base/dd.c:413
>  driver_probe_device+0x610/0xa00 drivers/base/dd.c:557
>  __device_attach_driver+0x230/0x290 drivers/base/dd.c:653
>  bus_for_each_drv+0x161/0x210 drivers/base/bus.c:463
>  __device_attach+0x26e/0x3d0 drivers/base/dd.c:710
>  device_initial_probe+0x1f/0x30 drivers/base/dd.c:757
>  bus_probe_device+0x1eb/0x290 drivers/base/bus.c:523
>  device_add+0xd0b/0x1660 drivers/base/core.c:1835
>  usb_set_configuration+0x104e/0x1870 drivers/usb/core/message.c:1932
>  generic_probe+0x73/0xe0 drivers/usb/core/generic.c:174
>  usb_probe_device+0xaf/0xe0 drivers/usb/core/driver.c:266
>  really_probe drivers/base/dd.c:413
>  driver_probe_device+0x610/0xa00 drivers/base/dd.c:557
>  __device_attach_driver+0x230/0x290 drivers/base/dd.c:653
>  bus_for_each_drv+0x161/0x210 drivers/base/bus.c:463
>  __device_attach+0x26e/0x3d0 drivers/base/dd.c:710
>  device_initial_probe+0x1f/0x30 drivers/base/dd.c:757
>  bus_probe_device+0x1eb/0x290 drivers/base/bus.c:523
>  device_add+0xd0b/0x1660 drivers/base/core.c:1835
>  usb_new_device+0x7b8/0x1020 drivers/usb/core/hub.c:2457
>  hub_port_connect drivers/usb/core/hub.c:4903
>  hub_port_connect_change drivers/usb/core/hub.c:5009
>  port_event drivers/usb/core/hub.c:5115
>  hub_event+0x194d/0x3740 drivers/usb/core/hub.c:5195
>  process_one_work+0xc7f/0x1db0 kernel/workqueue.c:2119
>  worker_thread+0x221/0x1850 kernel/workqueue.c:2253
>  kthread+0x3a1/0x470 kernel/kthread.c:231
>  ret_from_fork+0x2a/0x40 arch/x86/entry/entry_64.S:431
> Code: f1 48 c7 c7 c0 89 a5 85 48 89 de e8 38 34 e1 fe 0f ff 31 c0 eb
> c3 48 89 f2 48 89 d9 4c 89 e6 48 c7 c7 40 8a a5 85 e8 1d 34 e1 fe <0f>
> ff 31 c0 eb a8 48 89 75 e8 e8 e4 b3 2a ff 48 8b 75 e8 e9 5b
> ---[ end trace 23181469b7a6915e ]---

-- 
Regards,

Laurent Pinchart



Re: [PATCH v14 22/28] v4l: fwnode: Add a convenience function for registering sensors

2017-09-26 Thread Sakari Ailus
On Tue, Sep 26, 2017 at 10:26:35AM +0200, Hans Verkuil wrote:
> On 26/09/17 00:25, Sakari Ailus wrote:
> > Add a convenience function for parsing firmware for information on related
> > devices using v4l2_async_notifier_parse_fwnode_sensor_common() registering
> > the notifier and finally the async sub-device itself.
> > 
> > This should be useful for sensor drivers that do not have device specific
> > requirements related to firmware information parsing or the async
> > framework.
> 
> I'm confused. This is a second patch 22/28 that appears to be identical to the
> previous one.
> 
> I'm ignoring this one, I assume something went wrong when you mailed this 
> series.

Yes. I changed the subject but accidentally used the same directory for the
patches. The patch is the same.

The intended subject prefix is "v4l: fwnode".

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


[iMX6] HDMI as V4L Video Output Interface?

2017-09-26 Thread David Müller
Hello

Is it possible to use the HDMI output as a V4L Video Output Interface or
Video Output Overlay Interface using mainline kernels?

Dave


Re: [PATCH v14 27/28] ov13858: Add support for flash and lens devices

2017-09-26 Thread Hans Verkuil
On 26/09/17 00:25, Sakari Ailus wrote:
> Parse async sub-devices related to the sensor by switching the async
> sub-device registration function.
> 
> Signed-off-by: Sakari Ailus 

Acked-by: Hans Verkuil 

> ---
>  drivers/media/i2c/ov13858.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/media/i2c/ov13858.c b/drivers/media/i2c/ov13858.c
> index af7af0d14c69..c86525982e17 100644
> --- a/drivers/media/i2c/ov13858.c
> +++ b/drivers/media/i2c/ov13858.c
> @@ -1746,7 +1746,7 @@ static int ov13858_probe(struct i2c_client *client,
>   goto error_handler_free;
>   }
>  
> - ret = v4l2_async_register_subdev(>sd);
> + ret = v4l2_async_register_subdev_sensor_common(>sd);
>   if (ret < 0)
>   goto error_media_entity;
>  
> 






Re: [PATCH v14 24/28] smiapp: Add support for flash and lens devices

2017-09-26 Thread Hans Verkuil
On 26/09/17 00:25, Sakari Ailus wrote:
> Parse async sub-devices related to the sensor by switching the async
> sub-device registration function.
> 
> These types devices aren't directly related to the sensor, but are
> nevertheless handled by the smiapp driver due to the relationship of these
> component to the main part of the camera module --- the sensor.
> 
> This does not yet address providing the user space with information on how
> to associate the sensor or lens devices but the kernel now has the
> necessary information to do that.
> 
> Signed-off-by: Sakari Ailus 

Acked-by: Hans Verkuil 

> ---
>  drivers/media/i2c/smiapp/smiapp-core.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/media/i2c/smiapp/smiapp-core.c 
> b/drivers/media/i2c/smiapp/smiapp-core.c
> index 700f433261d0..3d9a251ca825 100644
> --- a/drivers/media/i2c/smiapp/smiapp-core.c
> +++ b/drivers/media/i2c/smiapp/smiapp-core.c
> @@ -3092,7 +3092,7 @@ static int smiapp_probe(struct i2c_client *client,
>   if (rval < 0)
>   goto out_media_entity_cleanup;
>  
> - rval = v4l2_async_register_subdev(>src->sd);
> + rval = v4l2_async_register_subdev_sensor_common(>src->sd);
>   if (rval < 0)
>   goto out_media_entity_cleanup;
>  
> 



Re: [PATCH v14 26/28] ov5670: Add support for flash and lens devices

2017-09-26 Thread Hans Verkuil
On 26/09/17 00:25, Sakari Ailus wrote:
> Parse async sub-devices related to the sensor by switching the async
> sub-device registration function.
> 
> Signed-off-by: Sakari Ailus 

Acked-by: Hans Verkuil 

> ---
>  drivers/media/i2c/ov5670.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/media/i2c/ov5670.c b/drivers/media/i2c/ov5670.c
> index 6f7a1d6d2200..0a1723f5a66c 100644
> --- a/drivers/media/i2c/ov5670.c
> +++ b/drivers/media/i2c/ov5670.c
> @@ -2514,7 +2514,7 @@ static int ov5670_probe(struct i2c_client *client)
>   }
>  
>   /* Async register for subdev */
> - ret = v4l2_async_register_subdev(>sd);
> + ret = v4l2_async_register_subdev_sensor_common(>sd);
>   if (ret < 0) {
>   err_msg = "v4l2_async_register_subdev() error";
>   goto error_entity_cleanup;
> 



Re: [PATCH v14 25/28] et8ek8: Add support for flash and lens devices

2017-09-26 Thread Hans Verkuil
On 26/09/17 00:25, Sakari Ailus wrote:
> Parse async sub-devices related to the sensor by switching the async
> sub-device registration function.
> 
> Signed-off-by: Sakari Ailus 

Acked-by: Hans Verkuil 

> ---
>  drivers/media/i2c/et8ek8/et8ek8_driver.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/media/i2c/et8ek8/et8ek8_driver.c 
> b/drivers/media/i2c/et8ek8/et8ek8_driver.c
> index c14f0fd6ded3..e9eff9039ef5 100644
> --- a/drivers/media/i2c/et8ek8/et8ek8_driver.c
> +++ b/drivers/media/i2c/et8ek8/et8ek8_driver.c
> @@ -1453,7 +1453,7 @@ static int et8ek8_probe(struct i2c_client *client,
>   goto err_mutex;
>   }
>  
> - ret = v4l2_async_register_subdev(>subdev);
> + ret = v4l2_async_register_subdev_sensor_common(>subdev);
>   if (ret < 0)
>   goto err_entity;
>  
> 



Re: [PATCH v14 22/28] v4l: fwnode: Add a convenience function for registering sensors

2017-09-26 Thread Hans Verkuil
On 26/09/17 00:25, Sakari Ailus wrote:
> Add a convenience function for parsing firmware for information on related
> devices using v4l2_async_notifier_parse_fwnode_sensor_common() registering
> the notifier and finally the async sub-device itself.
> 
> This should be useful for sensor drivers that do not have device specific
> requirements related to firmware information parsing or the async
> framework.

I'm confused. This is a second patch 22/28 that appears to be identical to the
previous one.

I'm ignoring this one, I assume something went wrong when you mailed this 
series.

Regards,

Hans

> 
> Signed-off-by: Sakari Ailus 
> ---
>  drivers/media/v4l2-core/v4l2-async.c  |  5 +
>  drivers/media/v4l2-core/v4l2-fwnode.c | 41 
> +++
>  include/media/v4l2-async.h| 22 +++
>  include/media/v4l2-subdev.h   |  3 +++
>  4 files changed, 71 insertions(+)
> 
> diff --git a/drivers/media/v4l2-core/v4l2-async.c 
> b/drivers/media/v4l2-core/v4l2-async.c
> index 470607da96b2..f388892f43ec 100644
> --- a/drivers/media/v4l2-core/v4l2-async.c
> +++ b/drivers/media/v4l2-core/v4l2-async.c
> @@ -570,6 +570,11 @@ void v4l2_async_unregister_subdev(struct v4l2_subdev *sd)
>  {
>   struct v4l2_async_notifier *notifier = sd->notifier;
>  
> + if (sd->subdev_notifier)
> + v4l2_async_notifier_unregister(sd->subdev_notifier);
> + v4l2_async_notifier_cleanup(sd->subdev_notifier);
> + kfree(sd->subdev_notifier);
> +
>   if (!sd->asd) {
>   if (!list_empty(>async_list))
>   v4l2_async_cleanup(sd);
> diff --git a/drivers/media/v4l2-core/v4l2-fwnode.c 
> b/drivers/media/v4l2-core/v4l2-fwnode.c
> index 4976096a1d83..622bdcc2df2d 100644
> --- a/drivers/media/v4l2-core/v4l2-fwnode.c
> +++ b/drivers/media/v4l2-core/v4l2-fwnode.c
> @@ -29,6 +29,7 @@
>  
>  #include 
>  #include 
> +#include 
>  
>  enum v4l2_fwnode_bus_type {
>   V4L2_FWNODE_BUS_TYPE_GUESS = 0,
> @@ -814,6 +815,46 @@ int v4l2_async_notifier_parse_fwnode_sensor_common(
>  }
>  EXPORT_SYMBOL_GPL(v4l2_async_notifier_parse_fwnode_sensor_common);
>  
> +int v4l2_async_register_subdev_sensor_common(struct v4l2_subdev *sd)
> +{
> + struct v4l2_async_notifier *notifier;
> + int ret;
> +
> + if (WARN_ON(!sd->dev))
> + return -ENODEV;
> +
> + notifier = kzalloc(sizeof(*notifier), GFP_KERNEL);
> + if (!notifier)
> + return -ENOMEM;
> +
> + ret = v4l2_async_notifier_parse_fwnode_sensor_common(sd->dev,
> +  notifier);
> + if (ret < 0)
> + goto out_cleanup;
> +
> + ret = v4l2_async_subdev_notifier_register(sd, notifier);
> + if (ret < 0)
> + goto out_cleanup;
> +
> + ret = v4l2_async_register_subdev(sd);
> + if (ret < 0)
> + goto out_unregister;
> +
> + sd->subdev_notifier = notifier;
> +
> + return 0;
> +
> +out_unregister:
> + v4l2_async_notifier_unregister(notifier);
> +
> +out_cleanup:
> + v4l2_async_notifier_cleanup(notifier);
> + kfree(notifier);
> +
> + return ret;
> +}
> +EXPORT_SYMBOL_GPL(v4l2_async_register_subdev_sensor_common);
> +
>  MODULE_LICENSE("GPL");
>  MODULE_AUTHOR("Sakari Ailus ");
>  MODULE_AUTHOR("Sylwester Nawrocki ");
> diff --git a/include/media/v4l2-async.h b/include/media/v4l2-async.h
> index 479c317fab2f..74f2ea27d117 100644
> --- a/include/media/v4l2-async.h
> +++ b/include/media/v4l2-async.h
> @@ -173,6 +173,28 @@ void v4l2_async_notifier_cleanup(struct 
> v4l2_async_notifier *notifier);
>  int v4l2_async_register_subdev(struct v4l2_subdev *sd);
>  
>  /**
> + * v4l2_async_register_subdev_sensor_common - registers a sensor sub-device 
> to
> + * the asynchronous sub-device
> + * framework and parse set up common
> + * sensor related devices
> + *
> + * @sd: pointer to struct _subdev
> + *
> + * This function is just like v4l2_async_register_subdev() with the exception
> + * that calling it will also parse firmware interfaces for remote references
> + * using v4l2_async_notifier_parse_fwnode_sensor_common() and registers the
> + * async sub-devices. The sub-device is similarly unregistered by calling
> + * v4l2_async_unregister_subdev().
> + *
> + * While registered, the subdev module is marked as in-use.
> + *
> + * An error is returned if the module is no longer loaded on any attempts
> + * to register it.
> + */
> +int __must_check v4l2_async_register_subdev_sensor_common(
> + struct v4l2_subdev *sd);
> +
> +/**
>   * v4l2_async_unregister_subdev - unregisters a sub-device to the 
> asynchronous
>   *   subdevice framework
>   *
> diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h
> index 

Re: [PATCH v14 22/28] v4l: async: Add a convenience function for registering sensors

2017-09-26 Thread Hans Verkuil
On 26/09/17 00:25, Sakari Ailus wrote:
> Add a convenience function for parsing firmware for information on related
> devices using v4l2_async_notifier_parse_fwnode_sensor_common() registering
> the notifier and finally the async sub-device itself.
> 
> This should be useful for sensor drivers that do not have device specific
> requirements related to firmware information parsing or the async
> framework.
> 
> Signed-off-by: Sakari Ailus 

Nice, makes sense.

Acked-by: Hans Verkuil 

Regards,

Hans

> ---
>  drivers/media/v4l2-core/v4l2-async.c  |  5 +
>  drivers/media/v4l2-core/v4l2-fwnode.c | 41 
> +++
>  include/media/v4l2-async.h| 22 +++
>  include/media/v4l2-subdev.h   |  3 +++
>  4 files changed, 71 insertions(+)
> 
> diff --git a/drivers/media/v4l2-core/v4l2-async.c 
> b/drivers/media/v4l2-core/v4l2-async.c
> index fe383c5d1215..f2c82f5a9747 100644
> --- a/drivers/media/v4l2-core/v4l2-async.c
> +++ b/drivers/media/v4l2-core/v4l2-async.c
> @@ -580,6 +580,11 @@ void v4l2_async_unregister_subdev(struct v4l2_subdev *sd)
>  {
>   struct v4l2_async_notifier *notifier = sd->notifier;
>  
> + if (sd->subdev_notifier)
> + v4l2_async_notifier_unregister(sd->subdev_notifier);
> + v4l2_async_notifier_cleanup(sd->subdev_notifier);
> + kfree(sd->subdev_notifier);
> +
>   if (!sd->asd) {
>   if (!list_empty(>async_list))
>   v4l2_async_cleanup(sd);
> diff --git a/drivers/media/v4l2-core/v4l2-fwnode.c 
> b/drivers/media/v4l2-core/v4l2-fwnode.c
> index 4976096a1d83..622bdcc2df2d 100644
> --- a/drivers/media/v4l2-core/v4l2-fwnode.c
> +++ b/drivers/media/v4l2-core/v4l2-fwnode.c
> @@ -29,6 +29,7 @@
>  
>  #include 
>  #include 
> +#include 
>  
>  enum v4l2_fwnode_bus_type {
>   V4L2_FWNODE_BUS_TYPE_GUESS = 0,
> @@ -814,6 +815,46 @@ int v4l2_async_notifier_parse_fwnode_sensor_common(
>  }
>  EXPORT_SYMBOL_GPL(v4l2_async_notifier_parse_fwnode_sensor_common);
>  
> +int v4l2_async_register_subdev_sensor_common(struct v4l2_subdev *sd)
> +{
> + struct v4l2_async_notifier *notifier;
> + int ret;
> +
> + if (WARN_ON(!sd->dev))
> + return -ENODEV;
> +
> + notifier = kzalloc(sizeof(*notifier), GFP_KERNEL);
> + if (!notifier)
> + return -ENOMEM;
> +
> + ret = v4l2_async_notifier_parse_fwnode_sensor_common(sd->dev,
> +  notifier);
> + if (ret < 0)
> + goto out_cleanup;
> +
> + ret = v4l2_async_subdev_notifier_register(sd, notifier);
> + if (ret < 0)
> + goto out_cleanup;
> +
> + ret = v4l2_async_register_subdev(sd);
> + if (ret < 0)
> + goto out_unregister;
> +
> + sd->subdev_notifier = notifier;
> +
> + return 0;
> +
> +out_unregister:
> + v4l2_async_notifier_unregister(notifier);
> +
> +out_cleanup:
> + v4l2_async_notifier_cleanup(notifier);
> + kfree(notifier);
> +
> + return ret;
> +}
> +EXPORT_SYMBOL_GPL(v4l2_async_register_subdev_sensor_common);
> +
>  MODULE_LICENSE("GPL");
>  MODULE_AUTHOR("Sakari Ailus ");
>  MODULE_AUTHOR("Sylwester Nawrocki ");
> diff --git a/include/media/v4l2-async.h b/include/media/v4l2-async.h
> index 479c317fab2f..74f2ea27d117 100644
> --- a/include/media/v4l2-async.h
> +++ b/include/media/v4l2-async.h
> @@ -173,6 +173,28 @@ void v4l2_async_notifier_cleanup(struct 
> v4l2_async_notifier *notifier);
>  int v4l2_async_register_subdev(struct v4l2_subdev *sd);
>  
>  /**
> + * v4l2_async_register_subdev_sensor_common - registers a sensor sub-device 
> to
> + * the asynchronous sub-device
> + * framework and parse set up common
> + * sensor related devices
> + *
> + * @sd: pointer to struct _subdev
> + *
> + * This function is just like v4l2_async_register_subdev() with the exception
> + * that calling it will also parse firmware interfaces for remote references
> + * using v4l2_async_notifier_parse_fwnode_sensor_common() and registers the
> + * async sub-devices. The sub-device is similarly unregistered by calling
> + * v4l2_async_unregister_subdev().
> + *
> + * While registered, the subdev module is marked as in-use.
> + *
> + * An error is returned if the module is no longer loaded on any attempts
> + * to register it.
> + */
> +int __must_check v4l2_async_register_subdev_sensor_common(
> + struct v4l2_subdev *sd);
> +
> +/**
>   * v4l2_async_unregister_subdev - unregisters a sub-device to the 
> asynchronous
>   *   subdevice framework
>   *
> diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h
> index e83872078376..ec399c770301 100644
> --- a/include/media/v4l2-subdev.h
> +++ b/include/media/v4l2-subdev.h
> @@ -793,6 

Re: [PATCH v14 16/28] v4l: async: Ensure only unique fwnodes are registered to notifiers

2017-09-26 Thread Hans Verkuil
On 26/09/17 00:25, Sakari Ailus wrote:
> While registering a notifier, check that each newly added fwnode is
> unique, and return an error if it is not. Also check that a newly added
> notifier does not have the same fwnodes twice.
> 
> Signed-off-by: Sakari Ailus 

Acked-by: Hans Verkuil 

> ---
>  drivers/media/v4l2-core/v4l2-async.c | 88 
> 
>  1 file changed, 79 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/media/v4l2-core/v4l2-async.c 
> b/drivers/media/v4l2-core/v4l2-async.c
> index 735f72f81740..470607da96b2 100644
> --- a/drivers/media/v4l2-core/v4l2-async.c
> +++ b/drivers/media/v4l2-core/v4l2-async.c
> @@ -307,8 +307,71 @@ static void v4l2_async_cleanup(struct v4l2_subdev *sd)
>   sd->dev = NULL;
>  }
>  
> +/* See if an fwnode can be found in a notifier's lists. */
> +static bool __v4l2_async_notifier_fwnode_has_async_subdev(
> + struct v4l2_async_notifier *notifier, struct fwnode_handle *fwnode)
> +{
> + struct v4l2_async_subdev *asd;
> + struct v4l2_subdev *sd;
> +
> + list_for_each_entry(asd, >waiting, list) {
> + if (asd->match_type != V4L2_ASYNC_MATCH_FWNODE)
> + continue;
> +
> + if (asd->match.fwnode.fwnode == fwnode)
> + return true;
> + }
> +
> + list_for_each_entry(sd, >done, async_list) {
> + if (WARN_ON(!sd->asd))
> + continue;
> +
> + if (sd->asd->match_type != V4L2_ASYNC_MATCH_FWNODE)
> + continue;
> +
> + if (sd->asd->match.fwnode.fwnode == fwnode)
> + return true;
> + }
> +
> + return false;
> +}
> +
> +/*
> + * Find out whether an async sub-device was set up for an fwnode already or
> + * whether it exists in a given notifier before @this_index.
> + */
> +static bool v4l2_async_notifier_fwnode_has_async_subdev(
> + struct v4l2_async_notifier *notifier, struct fwnode_handle *fwnode,
> + unsigned int this_index)
> +{
> + unsigned int j;
> +
> + lockdep_assert_held(_lock);
> +
> + /* Check that an fwnode is not being added more than once. */
> + for (j = 0; j < this_index; j++) {
> + struct v4l2_async_subdev *asd = notifier->subdevs[this_index];
> + struct v4l2_async_subdev *other_asd = notifier->subdevs[j];
> +
> + if (other_asd->match_type == V4L2_ASYNC_MATCH_FWNODE &&
> + asd->match.fwnode.fwnode ==
> + other_asd->match.fwnode.fwnode)
> + return true;
> + }
> +
> + /* Check than an fwnode did not exist in other notifiers. */
> + list_for_each_entry(notifier, _list, list)
> + if (__v4l2_async_notifier_fwnode_has_async_subdev(
> + notifier, fwnode))
> + return true;
> +
> + return false;
> +}
> +
>  static int __v4l2_async_notifier_register(struct v4l2_async_notifier 
> *notifier)
>  {
> + struct device *dev =
> + notifier->v4l2_dev ? notifier->v4l2_dev->dev : NULL;
>   struct v4l2_async_subdev *asd;
>   int ret;
>   int i;
> @@ -319,6 +382,8 @@ static int __v4l2_async_notifier_register(struct 
> v4l2_async_notifier *notifier)
>   INIT_LIST_HEAD(>waiting);
>   INIT_LIST_HEAD(>done);
>  
> + mutex_lock(_lock);
> +
>   for (i = 0; i < notifier->num_subdevs; i++) {
>   asd = notifier->subdevs[i];
>  
> @@ -326,30 +391,35 @@ static int __v4l2_async_notifier_register(struct 
> v4l2_async_notifier *notifier)
>   case V4L2_ASYNC_MATCH_CUSTOM:
>   case V4L2_ASYNC_MATCH_DEVNAME:
>   case V4L2_ASYNC_MATCH_I2C:
> + break;
>   case V4L2_ASYNC_MATCH_FWNODE:
> + if (v4l2_async_notifier_fwnode_has_async_subdev(
> + notifier, asd->match.fwnode.fwnode, i)) {
> + dev_err(dev,
> + "fwnode has already been registered or 
> in notifier's subdev list\n");
> + ret = -EEXIST;
> + goto out_unlock;
> + }
>   break;
>   default:
> - dev_err(notifier->v4l2_dev ? notifier->v4l2_dev->dev : 
> NULL,
> - "Invalid match type %u on %p\n",
> + dev_err(dev, "Invalid match type %u on %p\n",
>   asd->match_type, asd);
> - return -EINVAL;
> + ret = -EINVAL;
> + goto out_unlock;
>   }
>   list_add_tail(>list, >waiting);
>   }
>  
> - mutex_lock(_lock);
> -
>   ret = v4l2_async_notifier_try_all_subdevs(notifier);
> - if (ret) {
> - mutex_unlock(_lock);
> - return ret;
> - }
> + if 

Re: [PATCH v14 15/28] v4l: async: Allow binding notifiers to sub-devices

2017-09-26 Thread Sakari Ailus
On Tue, Sep 26, 2017 at 01:25:26AM +0300, Sakari Ailus wrote:
> Registering a notifier has required the knowledge of struct v4l2_device
> for the reason that sub-devices generally are registered to the
> v4l2_device (as well as the media device, also available through
> v4l2_device).
> 
> This information is not available for sub-device drivers at probe time.
> 
> What this patch does is that it allows registering notifiers without
> having v4l2_device around. Instead the sub-device pointer is stored in the
> notifier. Once the sub-device of the driver that registered the notifier
> is registered, the notifier will gain the knowledge of the v4l2_device,
> and the binding of async sub-devices from the sub-device driver's notifier
> may proceed.
> 
> The root notifier's complete callback is only called when all sub-device
> notifiers are completed.

This paragraph is actually no longer true. I changed it to:

The complete callbacks will be called only when the v4l2_device is
available and no notifier has pending sub-devices to bind.

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


Re: [PATCH v14 14/28] v4l: async: Prepare for async sub-device notifiers

2017-09-26 Thread Hans Verkuil
On 26/09/17 10:17, Sakari Ailus wrote:
> Hi Hans,
> 
> On Tue, Sep 26, 2017 at 10:12:50AM +0200, Hans Verkuil wrote:
>> On 26/09/17 00:25, Sakari Ailus wrote:
>>> Refactor the V4L2 async framework a little in preparation for async
>>> sub-device notifiers.
>>
>> Perhaps extend this a bit to also state the reason for these changes?
> 
> Well, the true reason is that Laurent felt the following patch was doing
> too much, but most of the changes in it are actually tightly
> interconnected.
> 
> How about adding:
> 
> This avoids making some structural changes in the patch actually
> implementing sub-device notifiers, making that patch easier to review.

That will do.

I preferred the original version, that way I could see WHY things were done,
even though the patch was larger.

Regards,

Hans

> 
>>
>>>
>>> Signed-off-by: Sakari Ailus 
>>
>> Anyway,
>>
>> Acked-by: Hans Verkuil 
> 
> Thanks!
> 
>>
>>> ---
>>>  drivers/media/v4l2-core/v4l2-async.c | 66 
>>> +---
>>>  1 file changed, 47 insertions(+), 19 deletions(-)
>>>
>>> diff --git a/drivers/media/v4l2-core/v4l2-async.c 
>>> b/drivers/media/v4l2-core/v4l2-async.c
>>> index 77b9f851bfa9..1d4132305243 100644
>>> --- a/drivers/media/v4l2-core/v4l2-async.c
>>> +++ b/drivers/media/v4l2-core/v4l2-async.c
>>> @@ -125,12 +125,13 @@ static struct v4l2_async_subdev 
>>> *v4l2_async_find_match(
>>>  }
>>>  
>>>  static int v4l2_async_match_notify(struct v4l2_async_notifier *notifier,
>>> +  struct v4l2_device *v4l2_dev,
>>>struct v4l2_subdev *sd,
>>>struct v4l2_async_subdev *asd)
>>>  {
>>> int ret;
>>>  
>>> -   ret = v4l2_device_register_subdev(notifier->v4l2_dev, sd);
>>> +   ret = v4l2_device_register_subdev(v4l2_dev, sd);
>>> if (ret < 0)
>>> return ret;
>>>  
>>> @@ -154,6 +155,31 @@ static int v4l2_async_match_notify(struct 
>>> v4l2_async_notifier *notifier,
>>> return 0;
>>>  }
>>>  
>>> +/* Test all async sub-devices in a notifier for a match. */
>>> +static int v4l2_async_notifier_try_all_subdevs(
>>> +   struct v4l2_async_notifier *notifier)
>>> +{
>>> +   struct v4l2_device *v4l2_dev = notifier->v4l2_dev;
>>> +   struct v4l2_subdev *sd, *tmp;
>>> +
>>> +   list_for_each_entry_safe(sd, tmp, _list, async_list) {
>>> +   struct v4l2_async_subdev *asd;
>>> +   int ret;
>>> +
>>> +   asd = v4l2_async_find_match(notifier, sd);
>>> +   if (!asd)
>>> +   continue;
>>> +
>>> +   ret = v4l2_async_match_notify(notifier, v4l2_dev, sd, asd);
>>> +   if (ret < 0) {
>>> +   mutex_unlock(_lock);
>>> +   return ret;
>>> +   }
>>> +   }
>>> +
>>> +   return 0;
>>> +}
>>> +
>>>  static void v4l2_async_cleanup(struct v4l2_subdev *sd)
>>>  {
>>> v4l2_device_unregister_subdev(sd);
>>> @@ -163,17 +189,15 @@ static void v4l2_async_cleanup(struct v4l2_subdev *sd)
>>> sd->dev = NULL;
>>>  }
>>>  
>>> -int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev,
>>> -struct v4l2_async_notifier *notifier)
>>> +static int __v4l2_async_notifier_register(struct v4l2_async_notifier 
>>> *notifier)
>>>  {
>>> -   struct v4l2_subdev *sd, *tmp;
>>> struct v4l2_async_subdev *asd;
>>> +   int ret;
>>> int i;
>>>  
>>> -   if (!v4l2_dev || notifier->num_subdevs > V4L2_MAX_SUBDEVS)
>>> +   if (notifier->num_subdevs > V4L2_MAX_SUBDEVS)
>>> return -EINVAL;
>>>  
>>> -   notifier->v4l2_dev = v4l2_dev;
>>> INIT_LIST_HEAD(>waiting);
>>> INIT_LIST_HEAD(>done);
>>>  
>>> @@ -206,18 +230,10 @@ int v4l2_async_notifier_register(struct v4l2_device 
>>> *v4l2_dev,
>>>  
>>> mutex_lock(_lock);
>>>  
>>> -   list_for_each_entry_safe(sd, tmp, _list, async_list) {
>>> -   int ret;
>>> -
>>> -   asd = v4l2_async_find_match(notifier, sd);
>>> -   if (!asd)
>>> -   continue;
>>> -
>>> -   ret = v4l2_async_match_notify(notifier, sd, asd);
>>> -   if (ret < 0) {
>>> -   mutex_unlock(_lock);
>>> -   return ret;
>>> -   }
>>> +   ret = v4l2_async_notifier_try_all_subdevs(notifier);
>>> +   if (ret) {
>>> +   mutex_unlock(_lock);
>>> +   return ret;
>>> }
>>>  
>>> /* Keep also completed notifiers on the list */
>>> @@ -227,6 +243,17 @@ int v4l2_async_notifier_register(struct v4l2_device 
>>> *v4l2_dev,
>>>  
>>> return 0;
>>>  }
>>> +
>>> +int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev,
>>> +struct v4l2_async_notifier *notifier)
>>> +{
>>> +   if (WARN_ON(!v4l2_dev))
>>> +   return -EINVAL;
>>> +
>>> +   notifier->v4l2_dev = v4l2_dev;
>>> +
>>> +   return __v4l2_async_notifier_register(notifier);
>>> +}
>>>  EXPORT_SYMBOL(v4l2_async_notifier_register);
>>>  
>>>  

Re: [PATCH v14 14/28] v4l: async: Prepare for async sub-device notifiers

2017-09-26 Thread Sakari Ailus
Hi Hans,

On Tue, Sep 26, 2017 at 10:12:50AM +0200, Hans Verkuil wrote:
> On 26/09/17 00:25, Sakari Ailus wrote:
> > Refactor the V4L2 async framework a little in preparation for async
> > sub-device notifiers.
> 
> Perhaps extend this a bit to also state the reason for these changes?

Well, the true reason is that Laurent felt the following patch was doing
too much, but most of the changes in it are actually tightly
interconnected.

How about adding:

This avoids making some structural changes in the patch actually
implementing sub-device notifiers, making that patch easier to review.

> 
> > 
> > Signed-off-by: Sakari Ailus 
> 
> Anyway,
> 
> Acked-by: Hans Verkuil 

Thanks!

> 
> > ---
> >  drivers/media/v4l2-core/v4l2-async.c | 66 
> > +---
> >  1 file changed, 47 insertions(+), 19 deletions(-)
> > 
> > diff --git a/drivers/media/v4l2-core/v4l2-async.c 
> > b/drivers/media/v4l2-core/v4l2-async.c
> > index 77b9f851bfa9..1d4132305243 100644
> > --- a/drivers/media/v4l2-core/v4l2-async.c
> > +++ b/drivers/media/v4l2-core/v4l2-async.c
> > @@ -125,12 +125,13 @@ static struct v4l2_async_subdev 
> > *v4l2_async_find_match(
> >  }
> >  
> >  static int v4l2_async_match_notify(struct v4l2_async_notifier *notifier,
> > +  struct v4l2_device *v4l2_dev,
> >struct v4l2_subdev *sd,
> >struct v4l2_async_subdev *asd)
> >  {
> > int ret;
> >  
> > -   ret = v4l2_device_register_subdev(notifier->v4l2_dev, sd);
> > +   ret = v4l2_device_register_subdev(v4l2_dev, sd);
> > if (ret < 0)
> > return ret;
> >  
> > @@ -154,6 +155,31 @@ static int v4l2_async_match_notify(struct 
> > v4l2_async_notifier *notifier,
> > return 0;
> >  }
> >  
> > +/* Test all async sub-devices in a notifier for a match. */
> > +static int v4l2_async_notifier_try_all_subdevs(
> > +   struct v4l2_async_notifier *notifier)
> > +{
> > +   struct v4l2_device *v4l2_dev = notifier->v4l2_dev;
> > +   struct v4l2_subdev *sd, *tmp;
> > +
> > +   list_for_each_entry_safe(sd, tmp, _list, async_list) {
> > +   struct v4l2_async_subdev *asd;
> > +   int ret;
> > +
> > +   asd = v4l2_async_find_match(notifier, sd);
> > +   if (!asd)
> > +   continue;
> > +
> > +   ret = v4l2_async_match_notify(notifier, v4l2_dev, sd, asd);
> > +   if (ret < 0) {
> > +   mutex_unlock(_lock);
> > +   return ret;
> > +   }
> > +   }
> > +
> > +   return 0;
> > +}
> > +
> >  static void v4l2_async_cleanup(struct v4l2_subdev *sd)
> >  {
> > v4l2_device_unregister_subdev(sd);
> > @@ -163,17 +189,15 @@ static void v4l2_async_cleanup(struct v4l2_subdev *sd)
> > sd->dev = NULL;
> >  }
> >  
> > -int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev,
> > -struct v4l2_async_notifier *notifier)
> > +static int __v4l2_async_notifier_register(struct v4l2_async_notifier 
> > *notifier)
> >  {
> > -   struct v4l2_subdev *sd, *tmp;
> > struct v4l2_async_subdev *asd;
> > +   int ret;
> > int i;
> >  
> > -   if (!v4l2_dev || notifier->num_subdevs > V4L2_MAX_SUBDEVS)
> > +   if (notifier->num_subdevs > V4L2_MAX_SUBDEVS)
> > return -EINVAL;
> >  
> > -   notifier->v4l2_dev = v4l2_dev;
> > INIT_LIST_HEAD(>waiting);
> > INIT_LIST_HEAD(>done);
> >  
> > @@ -206,18 +230,10 @@ int v4l2_async_notifier_register(struct v4l2_device 
> > *v4l2_dev,
> >  
> > mutex_lock(_lock);
> >  
> > -   list_for_each_entry_safe(sd, tmp, _list, async_list) {
> > -   int ret;
> > -
> > -   asd = v4l2_async_find_match(notifier, sd);
> > -   if (!asd)
> > -   continue;
> > -
> > -   ret = v4l2_async_match_notify(notifier, sd, asd);
> > -   if (ret < 0) {
> > -   mutex_unlock(_lock);
> > -   return ret;
> > -   }
> > +   ret = v4l2_async_notifier_try_all_subdevs(notifier);
> > +   if (ret) {
> > +   mutex_unlock(_lock);
> > +   return ret;
> > }
> >  
> > /* Keep also completed notifiers on the list */
> > @@ -227,6 +243,17 @@ int v4l2_async_notifier_register(struct v4l2_device 
> > *v4l2_dev,
> >  
> > return 0;
> >  }
> > +
> > +int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev,
> > +struct v4l2_async_notifier *notifier)
> > +{
> > +   if (WARN_ON(!v4l2_dev))
> > +   return -EINVAL;
> > +
> > +   notifier->v4l2_dev = v4l2_dev;
> > +
> > +   return __v4l2_async_notifier_register(notifier);
> > +}
> >  EXPORT_SYMBOL(v4l2_async_notifier_register);
> >  
> >  void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier)
> > @@ -303,7 +330,8 @@ int v4l2_async_register_subdev(struct v4l2_subdev *sd)
> > struct v4l2_async_subdev *asd = 

Re: [PATCH v14 15/28] v4l: async: Allow binding notifiers to sub-devices

2017-09-26 Thread Hans Verkuil
On 26/09/17 00:25, Sakari Ailus wrote:
> Registering a notifier has required the knowledge of struct v4l2_device
> for the reason that sub-devices generally are registered to the
> v4l2_device (as well as the media device, also available through
> v4l2_device).
> 
> This information is not available for sub-device drivers at probe time.
> 
> What this patch does is that it allows registering notifiers without
> having v4l2_device around. Instead the sub-device pointer is stored in the
> notifier. Once the sub-device of the driver that registered the notifier
> is registered, the notifier will gain the knowledge of the v4l2_device,
> and the binding of async sub-devices from the sub-device driver's notifier
> may proceed.
> 
> The root notifier's complete callback is only called when all sub-device
> notifiers are completed.
> 
> Signed-off-by: Sakari Ailus 

Acked-by: Hans Verkuil 

> ---
>  drivers/media/v4l2-core/v4l2-async.c | 218 
> +--
>  include/media/v4l2-async.h   |  16 ++-
>  2 files changed, 199 insertions(+), 35 deletions(-)
> 
> diff --git a/drivers/media/v4l2-core/v4l2-async.c 
> b/drivers/media/v4l2-core/v4l2-async.c
> index 1d4132305243..735f72f81740 100644
> --- a/drivers/media/v4l2-core/v4l2-async.c
> +++ b/drivers/media/v4l2-core/v4l2-async.c
> @@ -124,11 +124,109 @@ static struct v4l2_async_subdev *v4l2_async_find_match(
>   return NULL;
>  }
>  
> +/* Find the sub-device notifier registered by a sub-device driver. */
> +static struct v4l2_async_notifier *v4l2_async_find_subdev_notifier(
> + struct v4l2_subdev *sd)
> +{
> + struct v4l2_async_notifier *n;
> +
> + list_for_each_entry(n, _list, list)
> + if (n->sd == sd)
> + return n;
> +
> + return NULL;
> +}
> +
> +/* Get v4l2_device related to the notifier if one can be found. */
> +static struct v4l2_device *v4l2_async_notifier_find_v4l2_dev(
> + struct v4l2_async_notifier *notifier)
> +{
> + while (notifier->parent)
> + notifier = notifier->parent;
> +
> + return notifier->v4l2_dev;
> +}
> +
> +/*
> + * Return true if all child sub-device notifiers are complete, false 
> otherwise.
> + */
> +static bool v4l2_async_notifier_can_complete(
> + struct v4l2_async_notifier *notifier)
> +{
> + struct v4l2_subdev *sd;
> +
> + if (!list_empty(>waiting))
> + return false;
> +
> + list_for_each_entry(sd, >done, async_list) {
> + struct v4l2_async_notifier *subdev_notifier =
> + v4l2_async_find_subdev_notifier(sd);
> +
> + if (subdev_notifier &&
> + !v4l2_async_notifier_can_complete(subdev_notifier))
> + return false;
> + }
> +
> + return true;
> +}
> +
> +/* Complete all notifiers. Call on the root notifier. */
> +static int v4l2_async_notifier_complete(
> + struct v4l2_async_notifier *notifier)
> +{
> + struct v4l2_subdev *sd;
> +
> + list_for_each_entry(sd, >done, async_list) {
> + struct v4l2_async_notifier *subdev_notifier =
> + v4l2_async_find_subdev_notifier(sd);
> + int ret;
> +
> + if (!subdev_notifier)
> + continue;
> +
> + ret = v4l2_async_notifier_complete(subdev_notifier);
> + if (ret)
> + return ret;
> + }
> +
> + return v4l2_async_notifier_call_complete(notifier);
> +}
> +
> +/*
> + * Complete notifiers if possible. This is done when all async sub-devices 
> have
> + * been bound; v4l2_device is also available then.
> + */
> +static int v4l2_async_notifier_try_complete(
> + struct v4l2_async_notifier *notifier)
> +{
> + /* Quick check whether there are still more sub-devices here. */
> + if (!list_empty(>waiting))
> + return 0;
> +
> + /* Check the entire notifier tree; find the root notifier first. */
> + while (notifier->parent)
> + notifier = notifier->parent;
> +
> + /* This is root if it has v4l2_dev. */
> + if (!notifier->v4l2_dev)
> + return 0;
> +
> + /* Is everything ready? */
> + if (!v4l2_async_notifier_can_complete(notifier))
> + return 0;
> +
> + return v4l2_async_notifier_complete(notifier);
> +}
> +
> +static int v4l2_async_notifier_try_all_subdevs(
> + struct v4l2_async_notifier *notifier);
> +
>  static int v4l2_async_match_notify(struct v4l2_async_notifier *notifier,
>  struct v4l2_device *v4l2_dev,
>  struct v4l2_subdev *sd,
>  struct v4l2_async_subdev *asd)
>  {
> + struct v4l2_async_notifier *subdev_notifier;
>   int ret;
>  
>   ret = v4l2_device_register_subdev(v4l2_dev, sd);
> @@ -149,8 +247,17 @@ static int v4l2_async_match_notify(struct 
> v4l2_async_notifier *notifier,
>   /* Move from 

Re: [PATCH v14 14/28] v4l: async: Prepare for async sub-device notifiers

2017-09-26 Thread Hans Verkuil
On 26/09/17 00:25, Sakari Ailus wrote:
> Refactor the V4L2 async framework a little in preparation for async
> sub-device notifiers.

Perhaps extend this a bit to also state the reason for these changes?

> 
> Signed-off-by: Sakari Ailus 

Anyway,

Acked-by: Hans Verkuil 

> ---
>  drivers/media/v4l2-core/v4l2-async.c | 66 
> +---
>  1 file changed, 47 insertions(+), 19 deletions(-)
> 
> diff --git a/drivers/media/v4l2-core/v4l2-async.c 
> b/drivers/media/v4l2-core/v4l2-async.c
> index 77b9f851bfa9..1d4132305243 100644
> --- a/drivers/media/v4l2-core/v4l2-async.c
> +++ b/drivers/media/v4l2-core/v4l2-async.c
> @@ -125,12 +125,13 @@ static struct v4l2_async_subdev *v4l2_async_find_match(
>  }
>  
>  static int v4l2_async_match_notify(struct v4l2_async_notifier *notifier,
> +struct v4l2_device *v4l2_dev,
>  struct v4l2_subdev *sd,
>  struct v4l2_async_subdev *asd)
>  {
>   int ret;
>  
> - ret = v4l2_device_register_subdev(notifier->v4l2_dev, sd);
> + ret = v4l2_device_register_subdev(v4l2_dev, sd);
>   if (ret < 0)
>   return ret;
>  
> @@ -154,6 +155,31 @@ static int v4l2_async_match_notify(struct 
> v4l2_async_notifier *notifier,
>   return 0;
>  }
>  
> +/* Test all async sub-devices in a notifier for a match. */
> +static int v4l2_async_notifier_try_all_subdevs(
> + struct v4l2_async_notifier *notifier)
> +{
> + struct v4l2_device *v4l2_dev = notifier->v4l2_dev;
> + struct v4l2_subdev *sd, *tmp;
> +
> + list_for_each_entry_safe(sd, tmp, _list, async_list) {
> + struct v4l2_async_subdev *asd;
> + int ret;
> +
> + asd = v4l2_async_find_match(notifier, sd);
> + if (!asd)
> + continue;
> +
> + ret = v4l2_async_match_notify(notifier, v4l2_dev, sd, asd);
> + if (ret < 0) {
> + mutex_unlock(_lock);
> + return ret;
> + }
> + }
> +
> + return 0;
> +}
> +
>  static void v4l2_async_cleanup(struct v4l2_subdev *sd)
>  {
>   v4l2_device_unregister_subdev(sd);
> @@ -163,17 +189,15 @@ static void v4l2_async_cleanup(struct v4l2_subdev *sd)
>   sd->dev = NULL;
>  }
>  
> -int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev,
> -  struct v4l2_async_notifier *notifier)
> +static int __v4l2_async_notifier_register(struct v4l2_async_notifier 
> *notifier)
>  {
> - struct v4l2_subdev *sd, *tmp;
>   struct v4l2_async_subdev *asd;
> + int ret;
>   int i;
>  
> - if (!v4l2_dev || notifier->num_subdevs > V4L2_MAX_SUBDEVS)
> + if (notifier->num_subdevs > V4L2_MAX_SUBDEVS)
>   return -EINVAL;
>  
> - notifier->v4l2_dev = v4l2_dev;
>   INIT_LIST_HEAD(>waiting);
>   INIT_LIST_HEAD(>done);
>  
> @@ -206,18 +230,10 @@ int v4l2_async_notifier_register(struct v4l2_device 
> *v4l2_dev,
>  
>   mutex_lock(_lock);
>  
> - list_for_each_entry_safe(sd, tmp, _list, async_list) {
> - int ret;
> -
> - asd = v4l2_async_find_match(notifier, sd);
> - if (!asd)
> - continue;
> -
> - ret = v4l2_async_match_notify(notifier, sd, asd);
> - if (ret < 0) {
> - mutex_unlock(_lock);
> - return ret;
> - }
> + ret = v4l2_async_notifier_try_all_subdevs(notifier);
> + if (ret) {
> + mutex_unlock(_lock);
> + return ret;
>   }
>  
>   /* Keep also completed notifiers on the list */
> @@ -227,6 +243,17 @@ int v4l2_async_notifier_register(struct v4l2_device 
> *v4l2_dev,
>  
>   return 0;
>  }
> +
> +int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev,
> +  struct v4l2_async_notifier *notifier)
> +{
> + if (WARN_ON(!v4l2_dev))
> + return -EINVAL;
> +
> + notifier->v4l2_dev = v4l2_dev;
> +
> + return __v4l2_async_notifier_register(notifier);
> +}
>  EXPORT_SYMBOL(v4l2_async_notifier_register);
>  
>  void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier)
> @@ -303,7 +330,8 @@ int v4l2_async_register_subdev(struct v4l2_subdev *sd)
>   struct v4l2_async_subdev *asd = v4l2_async_find_match(notifier,
> sd);
>   if (asd) {
> - int ret = v4l2_async_match_notify(notifier, sd, asd);
> + int ret = v4l2_async_match_notify(
> + notifier, notifier->v4l2_dev, sd, asd);
>   mutex_unlock(_lock);
>   return ret;
>   }
> 



  1   2   >