aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrey Dolnikov <andrey.dolnikov@cogentembedded.com>2018-04-11 17:06:13 +0300
committerAndrey Dolnikov <andrey.dolnikov@cogentembedded.com>2018-04-11 17:06:13 +0300
commit10aa7f1f74b054c2575e7584a02b3738a24d0c7a (patch)
tree69b91d64c92f194d0b3bf9946a70eec36c5f4770
parent3c34681dd3fe562d5d65d83229caa921afc67a1f (diff)
Add IMR UIO support.
V4L2 RCAR IMR driver is now a module. V4L2 driver is loaded by default.
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0127-IMR-UIO-Driver-initial-version.patch875
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0128-rcar_imr-v4l2-driver-Fix-module-support.patch321
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/condor.cfg1
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/eagle.cfg1
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/imr.cfg3
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/salvator-x.cfg1
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/ulcb.cfg1
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/v3hsk.cfg1
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/v3msk.cfg1
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/v3mzf.cfg2
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas_4.9.bbappend9
11 files changed, 1208 insertions, 8 deletions
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0127-IMR-UIO-Driver-initial-version.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0127-IMR-UIO-Driver-initial-version.patch
new file mode 100644
index 0000000..74d6c07
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0127-IMR-UIO-Driver-initial-version.patch
@@ -0,0 +1,875 @@
+From 4a0e94fec7f69a717fc084fa168c2120998f076c Mon Sep 17 00:00:00 2001
+From: Toshiya Tamaki <toshiya.tamaki.ue@renesas.com>
+Date: Thu, 1 Jun 2017 15:43:21 +0900
+Subject: [PATCH 1/2] IMR UIO Driver initial version
+
+Signed-off-by: Toshiya Tamaki <toshiya.tamaki.ue@renesas.com>
+---
+ .../devicetree/bindings/imr/renesas,imr.txt | 55 +++
+ arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi | 24 +-
+ arch/arm64/boot/dts/renesas/r8a7795.dtsi | 24 +-
+ arch/arm64/boot/dts/renesas/r8a7796.dtsi | 16 +
+ arch/arm64/boot/dts/renesas/r8a7797.dtsi | 24 +-
+ arch/arm64/boot/dts/renesas/r8a7798.dtsi | 36 +-
+ drivers/clk/renesas/r8a7796-cpg-mssr.c | 2 +
+ drivers/uio/Kconfig | 8 +
+ drivers/uio/Makefile | 1 +
+ drivers/uio/uio_imr.c | 495 +++++++++++++++++++++
+ 10 files changed, 631 insertions(+), 54 deletions(-)
+ create mode 100644 Documentation/devicetree/bindings/imr/renesas,imr.txt
+ create mode 100644 drivers/uio/uio_imr.c
+
+diff --git a/Documentation/devicetree/bindings/imr/renesas,imr.txt b/Documentation/devicetree/bindings/imr/renesas,imr.txt
+new file mode 100644
+index 0000000..50ce539
+--- /dev/null
++++ b/Documentation/devicetree/bindings/imr/renesas,imr.txt
+@@ -0,0 +1,55 @@
++* Renesas Electronics IMR
++
++This file provides information on what the device node for the IMR
++interface contains.
++
++Required properties:
++- compatible: "renesas,imr-r8a7795" if the device is a part of R8A7795 SoC.
++ "renesas,imr-r8a7796" if the device is a part of R8A7796 SoC.
++ "renesas,imr-r8a7797" if the device is a part of R8A7797 SoC.
++
++ When compatible with the generic version, nodes must list the
++ SoC-specific version corresponding to the platform first
++ followed by the generic version.
++
++- reg: offset and length of (1) the register block and (2) the stream buffer.
++- interrupts: A list of interrupt-specifiers, one for each entry in
++ interrupt-names.
++ If interrupt-names is not present, an interrupt specifier
++ for a single muxed interrupt.
++- clocks: clock phandle and specifier pair.
++- power-domains: must contain a reference to the PM domain.
++
++Example:
++
++ imr0{
++ compatible = "renesas,imr-r8a7797";
++ reg = <0 0xfe860000 0 0x10000>;
++ interrupts = <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 823>;
++ power-domains = <&sysc R8A7797_PD_A3VC>;
++ };
++
++ imr1{
++ compatible = "renesas,imr-r8a7797";
++ reg = <0 0xfe870000 0 0x10000>;
++ interrupts = <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 822>;
++ power-domains = <&sysc R8A7797_PD_A3VC>;
++ };
++
++ imr2{
++ compatible = "renesas,imr-r8a7797";
++ reg = <0 0xfe880000 0 0x10000>;
++ interrupts = <GIC_SPI 194 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 821>;
++ power-domains = <&sysc R8A7797_PD_A3VC>;
++ };
++
++ imr3{
++ compatible = "renesas,imr-r8a7797";
++ reg = <0 0xfe890000 0 0x10000>;
++ interrupts = <GIC_SPI 195 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 820>;
++ power-domains = <&sysc R8A7797_PD_A3VC>;
++ };
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi b/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi
+index 13516e9..745493c 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi
+@@ -2899,33 +2899,33 @@
+ power-domains = <&sysc R8A7795_PD_A3IR>;
+ };
+
+- imrlx4_ch0: imr-lx4@fe860000 {
+- compatible = "renesas,imr-lx4";
+- reg = <0 0xfe860000 0 0x2000>;
++ imrlx4_ch0: imr0@fe860000 {
++ compatible = "renesas,imr-lx4", "renesas,imr-r8a7795";
++ reg = <0 0xfe860000 0 0x10000>;
+ interrupts = <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 823>;
+ power-domains = <&sysc R8A7795_PD_A3VC>;
+ };
+
+- imrlx4_ch1: imr-lx4@fe870000 {
+- compatible = "renesas,imr-lx4";
+- reg = <0 0xfe870000 0 0x2000>;
++ imrlx4_ch1: imr1@fe870000 {
++ compatible = "renesas,imr-lx4", "renesas,imr-r8a7795";
++ reg = <0 0xfe870000 0 0x10000>;
+ interrupts = <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 822>;
+ power-domains = <&sysc R8A7795_PD_A3VC>;
+ };
+
+- imrlx4_ch2: imr-lx4@fe880000 {
+- compatible = "renesas,imr-lx4";
+- reg = <0 0xfe880000 0 0x2000>;
++ imrlx4_ch2: imr2@fe880000 {
++ compatible = "renesas,imr-lx4", "renesas,imr-r8a7795";
++ reg = <0 0xfe880000 0 0x10000>;
+ interrupts = <GIC_SPI 194 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 821>;
+ power-domains = <&sysc R8A7795_PD_A3VC>;
+ };
+
+- imrlx4_ch3: imr-lx4@fe890000 {
+- compatible = "renesas,imr-lx4";
+- reg = <0 0xfe890000 0 0x2000>;
++ imrlx4_ch3: imr3@fe890000 {
++ compatible = "renesas,imr-lx4", "renesas,imr-r8a7795";
++ reg = <0 0xfe890000 0 0x10000>;
+ interrupts = <GIC_SPI 195 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 820>;
+ power-domains = <&sysc R8A7795_PD_A3VC>;
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795.dtsi b/arch/arm64/boot/dts/renesas/r8a7795.dtsi
+index 565beb9..96e182a 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7795.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a7795.dtsi
+@@ -2895,33 +2895,33 @@
+ power-domains = <&sysc R8A7795_PD_A3IR>;
+ };
+
+- imrlx4_ch0: imr-lx4@fe860000 {
+- compatible = "renesas,imr-lx4";
+- reg = <0 0xfe860000 0 0x2000>;
++ imrlx4_ch0: imr0@fe860000 {
++ compatible = "renesas,imr-lx4", "renesas,imr-r8a7795";
++ reg = <0 0xfe860000 0 0x10000>;
+ interrupts = <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 823>;
+ power-domains = <&sysc R8A7795_PD_A3VC>;
+ };
+
+- imrlx4_ch1: imr-lx4@fe870000 {
+- compatible = "renesas,imr-lx4";
+- reg = <0 0xfe870000 0 0x2000>;
++ imrlx4_ch1: imr1@fe870000 {
++ compatible = "renesas,imr-lx4", "renesas,imr-r8a7795";
++ reg = <0 0xfe870000 0 0x10000>;
+ interrupts = <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 822>;
+ power-domains = <&sysc R8A7795_PD_A3VC>;
+ };
+
+- imrlx4_ch2: imr-lx4@fe880000 {
+- compatible = "renesas,imr-lx4";
+- reg = <0 0xfe880000 0 0x2000>;
++ imrlx4_ch2: imr2@fe880000 {
++ compatible = "renesas,imr-lx4", "renesas,imr-r8a7795";
++ reg = <0 0xfe880000 0 0x10000>;
+ interrupts = <GIC_SPI 194 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 821>;
+ power-domains = <&sysc R8A7795_PD_A3VC>;
+ };
+
+- imrlx4_ch3: imr-lx4@fe890000 {
+- compatible = "renesas,imr-lx4";
+- reg = <0 0xfe890000 0 0x2000>;
++ imrlx4_ch3: imr3@fe890000 {
++ compatible = "renesas,imr-lx4", "renesas,imr-r8a7795";
++ reg = <0 0xfe890000 0 0x10000>;
+ interrupts = <GIC_SPI 195 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 820>;
+ power-domains = <&sysc R8A7795_PD_A3VC>;
+diff --git a/arch/arm64/boot/dts/renesas/r8a7796.dtsi b/arch/arm64/boot/dts/renesas/r8a7796.dtsi
+index bf37b8a..b747f0c 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7796.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a7796.dtsi
+@@ -1174,6 +1174,22 @@
+ status = "disabled";
+ };
+
++ imrlx4_ch0: imr0@fe860000 {
++ compatible = "renesas,imr-lx4", "renesas,imr-r8a7796";
++ reg = <0 0xfe860000 0 0x10000>;
++ interrupts = <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 823>;
++ power-domains = <&sysc R8A7796_PD_A3VC>;
++ };
++
++ imrlx4_ch1: imr1@fe870000 {
++ compatible = "renesas,imr-lx4", "renesas,imr-r8a7796";
++ reg = <0 0xfe870000 0 0x10000>;
++ interrupts = <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 822>;
++ power-domains = <&sysc R8A7796_PD_A3VC>;
++ };
++
+ can0: can@e6c30000 {
+ compatible = "renesas,can-r8a7796",
+ "renesas,rcar-gen3-can";
+diff --git a/arch/arm64/boot/dts/renesas/r8a7797.dtsi b/arch/arm64/boot/dts/renesas/r8a7797.dtsi
+index 2beca53..c878467 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7797.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a7797.dtsi
+@@ -1239,33 +1239,33 @@
+ power-domains = <&sysc R8A7797_PD_A3IR>;
+ };
+
+- imrlx4_ch0: imr-lx4@fe860000 {
+- compatible = "renesas,imr-lx4";
+- reg = <0 0xfe860000 0 0x2000>;
++ imrlx4_ch0: imr0@fe860000 {
++ compatible = "renesas,imr-lx4", "renesas,imr-r8a7797";
++ reg = <0 0xfe860000 0 0x10000>;
+ interrupts = <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 823>;
+ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
+ };
+
+- imrlx4_ch1: imr-lx4@fe870000 {
+- compatible = "renesas,imr-lx4";
+- reg = <0 0xfe870000 0 0x2000>;
++ imrlx4_ch1: imr1@fe870000 {
++ compatible = "renesas,imr-lx4", "renesas,imr-r8a7797";
++ reg = <0 0xfe870000 0 0x10000>;
+ interrupts = <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 822>;
+ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
+ };
+
+- imrlx4_ch2: imr-lx4@fe880000 {
+- compatible = "renesas,imr-lx4";
+- reg = <0 0xfe880000 0 0x2000>;
++ imrlx4_ch2: imr2@fe880000 {
++ compatible = "renesas,imr-lx4", "renesas,imr-r8a7797";
++ reg = <0 0xfe880000 0 0x10000>;
+ interrupts = <GIC_SPI 194 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 821>;
+ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
+ };
+
+- imrlx4_ch3: imr-lx4@fe890000 {
+- compatible = "renesas,imr-lx4";
+- reg = <0 0xfe890000 0 0x2000>;
++ imrlx4_ch3: imr3@fe890000 {
++ compatible = "renesas,imr-lx4", "renesas,imr-r8a7797";
++ reg = <0 0xfe890000 0 0x10000>;
+ interrupts = <GIC_SPI 195 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 820>;
+ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
+diff --git a/arch/arm64/boot/dts/renesas/r8a7798.dtsi b/arch/arm64/boot/dts/renesas/r8a7798.dtsi
+index 48ce2af..7bfd0483 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7798.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a7798.dtsi
+@@ -1588,50 +1588,50 @@
+ power-domains = <&sysc R8A7798_PD_A3IR>;
+ };
+
+- imrlx4_ch0: imr-lx4@fe860000 {
+- compatible = "renesas,imr-lx4";
+- reg = <0 0xfe860000 0 0x2000>;
++ imrlx4_ch0: imr0@fe860000 {
++ compatible = "renesas,imr-lx4", "renesas,imr-r8a7798";
++ reg = <0 0xfe860000 0 0x10000>;
+ interrupts = <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 823>;
+ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
+ };
+
+- imrlx4_ch1: imr-lx4@fe870000 {
+- compatible = "renesas,imr-lx4";
+- reg = <0 0xfe870000 0 0x2000>;
++ imrlx4_ch1: imr1@fe870000 {
++ compatible = "renesas,imr-lx4", "renesas,imr-r8a7798";
++ reg = <0 0xfe870000 0 0x10000>;
+ interrupts = <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 822>;
+ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
+ };
+
+- imrlx4_ch2: imr-lx4@fe880000 {
+- compatible = "renesas,imr-lx4";
+- reg = <0 0xfe880000 0 0x2000>;
++ imrlx4_ch2: imr2@fe880000 {
++ compatible = "renesas,imr-lx4", "renesas,imr-r8a7798";
++ reg = <0 0xfe880000 0 0x10000>;
+ interrupts = <GIC_SPI 194 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 821>;
+ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
+ };
+
+- imrlx4_ch3: imr-lx4@fe890000 {
+- compatible = "renesas,imr-lx4";
+- reg = <0 0xfe890000 0 0x2000>;
++ imrlx4_ch3: imr3@fe890000 {
++ compatible = "renesas,imr-lx4", "renesas,imr-r8a7798";
++ reg = <0 0xfe890000 0 0x10000>;
+ interrupts = <GIC_SPI 195 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 820>;
+ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
+ };
+
+- imrlx4_ch4: imr-lx4@fe8a0000 {
+- compatible = "renesas,imr-lx4";
+- reg = <0 0xfe8a0000 0 0x2000>;
++ imrlx4_ch4: imr4@fe8a0000 {
++ compatible = "renesas,imr-lx4", "renesas,imr-r8a7798";
++ reg = <0 0xfe8a0000 0 0x10000>;
+ interrupts = <GIC_SPI 254 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 707>;
+ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
+ rse;
+ };
+
+- imrlx4_ch5: imr-lx4@fe8b0000 {
+- compatible = "renesas,imr-lx4";
+- reg = <0 0xfe8b0000 0 0x2000>;
++ imrlx4_ch5: imr5@fe8b0000 {
++ compatible = "renesas,imr-lx4", "renesas,imr-r8a7798";
++ reg = <0 0xfe8b0000 0 0x10000>;
+ interrupts = <GIC_SPI 255 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 706>;
+ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
+diff --git a/drivers/clk/renesas/r8a7796-cpg-mssr.c b/drivers/clk/renesas/r8a7796-cpg-mssr.c
+index e886d8a..e2ca77c 100644
+--- a/drivers/clk/renesas/r8a7796-cpg-mssr.c
++++ b/drivers/clk/renesas/r8a7796-cpg-mssr.c
+@@ -204,6 +204,8 @@ static const struct mssr_mod_clk r8a7796_mod_clks[] __initconst = {
+ DEF_MOD("vin1", 810, R8A7796_CLK_S0D2),
+ DEF_MOD("vin0", 811, R8A7796_CLK_S0D2),
+ DEF_MOD("etheravb", 812, R8A7796_CLK_S0D6),
++ DEF_MOD("imr1", 822, R8A7796_CLK_S2D1),
++ DEF_MOD("imr0", 823, R8A7796_CLK_S2D1),
+ DEF_MOD("imp", 824, R8A7796_CLK_S1D1),
+ DEF_MOD("gpio7", 905, R8A7796_CLK_S3D4),
+ DEF_MOD("gpio6", 906, R8A7796_CLK_S3D4),
+diff --git a/drivers/uio/Kconfig b/drivers/uio/Kconfig
+index 52c98ce..09d91ac 100644
+--- a/drivers/uio/Kconfig
++++ b/drivers/uio/Kconfig
+@@ -155,4 +155,12 @@ config UIO_MF624
+
+ If you compile this as a module, it will be called uio_mf624.
+
++config UIO_IMR
++ tristate "Renesas IMR support"
++
++ help
++ Renesas IMR device driver.
++ This driver supports the following SoCs:
++ - R8A7795, R8A7796, R8A7797.
++
+ endif
+diff --git a/drivers/uio/Makefile b/drivers/uio/Makefile
+index 8560dad..3d29324 100644
+--- a/drivers/uio/Makefile
++++ b/drivers/uio/Makefile
+@@ -9,3 +9,4 @@ obj-$(CONFIG_UIO_NETX) += uio_netx.o
+ obj-$(CONFIG_UIO_PRUSS) += uio_pruss.o
+ obj-$(CONFIG_UIO_MF624) += uio_mf624.o
+ obj-$(CONFIG_UIO_FSL_ELBC_GPCM) += uio_fsl_elbc_gpcm.o
++obj-$(CONFIG_UIO_IMR) += uio_imr.o
+diff --git a/drivers/uio/uio_imr.c b/drivers/uio/uio_imr.c
+new file mode 100644
+index 0000000..a64c65e
+--- /dev/null
++++ b/drivers/uio/uio_imr.c
+@@ -0,0 +1,495 @@
++/*************************************************************************/ /*
++ IMR
++
++ Copyright (C) 2015-2017 Renesas Electronics Corporation
++
++ License Dual MIT/GPLv2
++
++ The contents of this file are subject to the MIT license as set out below.
++
++ Permission is hereby granted, free of charge, to any person obtaining a copy
++ of this software and associated documentation files (the "Software"), to deal
++ in the Software without restriction, including without limitation the rights
++ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
++ copies of the Software, and to permit persons to whom the Software is
++ furnished to do so, subject to the following conditions:
++
++ The above copyright notice and this permission notice shall be included in
++ all copies or substantial portions of the Software.
++
++ Alternatively, the contents of this file may be used under the terms of
++ the GNU General Public License Version 2 ("GPL") in which case the provisions
++ of GPL are applicable instead of those above.
++
++ If you wish to allow use of your version of this file only under the terms of
++ GPL, and not to allow others to use your version of this file under the terms
++ of the MIT license, indicate your decision by deleting the provisions above
++ and replace them with the notice and other provisions required by GPL as set
++ out in the file called "GPL-COPYING" included in this distribution. If you do
++ not delete the provisions above, a recipient may use your version of this file
++ under the terms of either the MIT license or GPL.
++
++ This License is also included in this distribution in the file called
++ "MIT-COPYING".
++
++ EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
++ PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
++ BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
++ PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
++ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
++ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
++ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
++
++
++ GPLv2:
++ If you wish to use this file under the terms of GPL, following terms are
++ effective.
++
++ 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; version 2 of the License.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ GNU General Public License for more details.
++
++ 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
++*/ /*************************************************************************/
++
++/* PRQA S 292,2212,2214 EOF */
++#include <linux/platform_device.h>
++#include <linux/uio_driver.h>
++#include <linux/interrupt.h>
++#include <linux/pm_runtime.h>
++#include <linux/slab.h>
++#include <linux/clk.h>
++#include <linux/io.h>
++#include <linux/module.h>
++
++#include <linux/of.h>
++#include <linux/of_irq.h>
++
++/* IMR uio driver name */
++#define DRIVER_NAME "uio_imr"
++
++/* IMR register definition */
++#define IMR_REG_IMR_ADDRESS (0x018U)
++#define IMR_REG_IMR_BIT_BASE (0x3U << 3)
++#define IMR_REG_IMR_BIT_INT (0x1U << 2)
++#define IMR_REG_IMR_BIT_IER (0x1U << 1)
++#define IMR_REG_IMR_BIT_TRA (0x1U << 0)
++
++/**
++ * struct uio_platdata - the uio platform data structure
++ * @uioinfo: UIO device capabilities
++ * @lock lock flag for irq.
++ * @flags: flags for request_irq.
++ * @pdev: IMR platform device data.
++ * @base_reg: IMR base register address.
++ * @clk: clock data.
++ *
++ * the uio platform data structure.
++ */
++struct uio_platdata {
++ struct uio_info *uioinfo;
++ spinlock_t lock;
++ unsigned long flags;
++ struct platform_device *pdev;
++ void __iomem *base_reg;
++ struct clk *clock;
++};
++
++static void write_register(struct uio_platdata *priv,
++ u32 reg_offs, u32 data);
++static int uio_imr_open(struct uio_info *info,
++ __attribute__((unused)) struct inode *inode);
++static int uio_imr_release(struct uio_info *info,
++ __attribute__((unused)) struct inode *inode);
++static irqreturn_t uio_imr_handler(__attribute__((unused)) int irq,
++ struct uio_info *dev_info);
++static int uio_imr_irqcontrol(struct uio_info *info, s32 irq_on);
++static int uio_imr_probe(struct platform_device *pdev);
++static int uio_imr_remove(struct platform_device *pdev);
++static int uio_runtime_imr_nop(__attribute__((unused)) struct device *dev);
++
++/**
++ * write_register() - register setting
++ * @priv: uio platform data.
++ * @reg_offs: register offset.
++ * @data: register value.
++ *
++ * register setting.
++ *
++ *
++ * Return: none
++ */
++static void write_register(struct uio_platdata *priv,
++ u32 reg_offs, u32 data)
++{
++ iowrite32(data, (u8 *)priv->base_reg + reg_offs); /* PRQA S 488 */
++}
++
++/**
++ * uio_imr_open() - open imr module
++ * @info: UIO device capabilities.
++ * @inode: inode.
++ *
++ * Open imr module.
++ *
++ *
++ * Return: 0 normal end.
++ */
++/* PRQA S 3206 2 */
++static int uio_imr_open(struct uio_info *info,
++ __attribute__((unused)) struct inode *inode)
++{
++ struct uio_platdata *pdata = info->priv;
++ /* PRQA S 3200 1 */
++ pr_debug("uio_imr_open enter. name=%s\n", pdata->uioinfo->name);
++
++ /* Wait until the Runtime PM code has woken up the device */
++ (void)pm_runtime_get_sync(&pdata->pdev->dev);
++
++ return 0;
++}
++
++/**
++ * uio_imr_release() - close imr module
++ * @info: UIO device capabilities.
++ * @inode: inode.
++ *
++ * Close imr module.
++ *
++ *
++ * Return: 0 normal end.
++ */
++/* PRQA S 3206 2 */
++static int uio_imr_release(struct uio_info *info,
++ __attribute__((unused)) struct inode *inode)
++{
++ struct uio_platdata *pdata = info->priv;
++
++ pr_debug("uio_imr_release enter\n"); /* PRQA S 3200 */
++
++ /* Tell the Runtime PM code that the device has become idle */
++ (void)pm_runtime_put_sync(&pdata->pdev->dev);
++
++ return 0;
++}
++
++/**
++ * uio_imr_handler() - IMR interrupt handler
++ * @irq: irq No.
++ * @dev_info: UIO device capabilities.
++ *
++ * IMR interrupt handler.
++ *
++ *
++ * Return: IRQ_HANDLED normal end.
++ */
++/* PRQA S 3206 1*/
++static irqreturn_t uio_imr_handler(__attribute__((unused))int irq,
++ struct uio_info *dev_info)
++{
++ struct uio_platdata *pdata = dev_info->priv;
++
++
++ pr_debug("uio_imr_handler enter\n"); /* PRQA S 3200 */
++
++ /* Mask interrupt */
++ write_register(pdata, IMR_REG_IMR_ADDRESS,
++ IMR_REG_IMR_BIT_BASE | (IMR_REG_IMR_BIT_INT |
++ IMR_REG_IMR_BIT_IER | IMR_REG_IMR_BIT_TRA));
++
++ return IRQ_HANDLED;
++}
++
++/**
++ * uio_imr_irqcontrol() - IMR irq controller
++ * @info: UIO device capabilities.
++ * @irq_on: irq enable/disable.
++ *
++ * IMR irq controller. Enable and disable the interrupt.
++ *
++ *
++ * Return: 0 normal end.
++ */
++static int uio_imr_irqcontrol(struct uio_info *info, s32 irq_on)
++{
++ struct uio_platdata *pdata = info->priv;
++ u64 flag;
++
++ pr_debug("uio_imr_irqcontrol enter\n"); /* PRQA S 3200 */
++
++ spin_lock_irqsave(&pdata->lock, flag);
++ if (irq_on != 0) {
++ if (test_and_clear_bit(0, &pdata->flags) != 0)
++ enable_irq((u32)info->irq);
++ } else {
++ if (test_and_set_bit(0, &pdata->flags) == 0)
++ disable_irq((u32)info->irq);
++ }
++ spin_unlock_irqrestore(&pdata->lock, flag);
++
++ return 0;
++}
++
++/* PRQA S 1053,1041,605 10 */
++static const struct of_device_id rcar_imr_dt_ids[] = {
++ { .compatible = "renesas,imr-r8a7795", .data = 0 },
++ { .compatible = "renesas,imr-r8a7796", .data = 0 },
++ { .compatible = "renesas,imr-r8a7797", .data = 0 },
++ { .compatible = "renesas,imr-r8a7798", .data = 0 },
++ {},
++};
++MODULE_DEVICE_TABLE(of, rcar_imr_dt_ids); /* PRQA S 605 */
++
++/**
++ * uio_imr_probe() - Initialize IMR module.
++ * @pdev: platform device data.
++ *
++ * Initialize IMR module.
++ *
++ *
++ * Return: 0 normal end.
++ * -EINVAL parameter error.
++ * -ENOMEM memory error.
++ * -ENODEV system error.
++ */
++static int uio_imr_probe(struct platform_device *pdev)
++{
++ struct uio_info *uioinfo_data = NULL;
++ struct uio_platdata *pdata;
++ struct uio_mem *uiomem;
++ int ret = 0;
++ unsigned int i;
++ struct resource *rsc;
++ unsigned int irq_l;
++ unsigned long remap_size;
++
++ if (pdev == NULL) {
++ pr_err("missing pdev\n");
++ ret = -EINVAL;
++ } else {
++ if (pdev->dev.of_node == NULL) {
++ dev_err(&pdev->dev, "missing pdev->dev.of_node\n");
++ ret = -EINVAL;
++ }
++ }
++
++ if (ret == 0) {
++ pr_debug("uio_imr_probe enter name = %s\n", /* PRQA S 3200 */
++ pdev->dev.of_node->name);
++
++ uioinfo_data = devm_kzalloc(&pdev->dev,
++ sizeof(*uioinfo_data),
++ GFP_KERNEL);
++ if (uioinfo_data == NULL)
++ ret = -ENOMEM;
++ }
++
++ if (ret == 0) {
++ uioinfo_data->name = pdev->dev.of_node->name;
++ uioinfo_data->version = "0.1";
++
++ /* get irq number */
++ irq_l = irq_of_parse_and_map(pdev->dev.of_node, 0);
++ if ((int)irq_l == -ENXIO)
++ uioinfo_data->irq = platform_get_irq(pdev, 0);
++ else
++ uioinfo_data->irq = (int)irq_l;
++
++ pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
++ if (pdata == NULL)
++ ret = -ENOMEM;
++ }
++
++ if (ret == 0) {
++ pdata->uioinfo = uioinfo_data;
++ spin_lock_init(&pdata->lock); /* PRQA S 3200 */
++ pdata->flags = 0;
++ pdata->pdev = pdev;
++
++ uiomem = &uioinfo_data->mem[0];
++
++ for (i = 0; i < pdev->num_resources; ++i) {
++ /* PRQA S 491 1 */
++ struct resource *r = &pdev->resource[i];
++
++ if (r->flags == IORESOURCE_IRQ) {
++ uioinfo_data->irq = (long)r->start;
++ } else if (r->flags != IORESOURCE_MEM) {
++ ;
++ } else {
++ if (uiomem >=
++ &uioinfo_data->mem[MAX_UIO_MAPS]) {
++ dev_warn(&pdev->dev,
++ "device has more than "
++ __stringify(MAX_UIO_MAPS)
++ " I/O memory resources.\n");
++ break;
++ }
++
++ uiomem->memtype = UIO_MEM_PHYS;
++ uiomem->addr = r->start;
++ uiomem->size = (r->end - r->start) + 1;
++ ++uiomem; /* PRQA S 489 */
++ }
++ }
++
++ while (uiomem < &uioinfo_data->mem[MAX_UIO_MAPS]) {
++ uiomem->size = 0;
++ ++uiomem; /* PRQA S 489 */
++ }
++
++ uioinfo_data->handler = &uio_imr_handler;
++ uioinfo_data->irqcontrol = &uio_imr_irqcontrol;
++ uioinfo_data->open = &uio_imr_open;
++ uioinfo_data->release = &uio_imr_release;
++ uioinfo_data->priv = pdata;
++
++ pm_runtime_enable(&pdev->dev);
++
++ ret = uio_register_device(&pdev->dev, pdata->uioinfo);
++ if (ret != 0) {
++ pm_runtime_disable(&pdev->dev);
++ dev_err(&pdev->dev, "could not register uio device\n");
++ ret = -ENODEV;
++ }
++ }
++
++ if (ret == 0) {
++ platform_set_drvdata(pdev, pdata);
++ pdata->clock = devm_clk_get(&pdev->dev, NULL);
++ if (IS_ERR(pdata->clock)) {
++ pm_runtime_disable(&pdev->dev);
++ dev_err(&pdev->dev, "could not get clock\n");
++ ret = -ENODEV;
++ } else {
++ /* clock enable */
++ (void)clk_prepare_enable(pdata->clock);
++ }
++ }
++
++ if (ret == 0) {
++ rsc = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ if (rsc == 0) {
++ pm_runtime_disable(&pdev->dev);
++ dev_err(&pdev->dev, "could not platform_get_resource\n");
++ ret = -ENODEV;
++ }
++ }
++
++ if (ret == 0) {
++ remap_size = (rsc->end - rsc->start) + 1;
++ if (!request_mem_region(rsc->start,
++ remap_size,
++ uioinfo_data->name)) {
++ dev_err(&pdev->dev, "could not request IO\n");
++ pm_runtime_disable(&pdev->dev);
++ ret = -ENOMEM;
++ }
++ }
++
++ if (ret == 0) {
++ /* IMR Register Adderss */
++ pdata->base_reg = devm_ioremap_nocache(&pdev->dev,
++ rsc->start,
++ remap_size);
++ if (pdata->base_reg == NULL) {
++ release_mem_region(rsc->start, resource_size(rsc));
++ dev_err(&pdev->dev, "could not remap IMR register\n");
++ pm_runtime_disable(&pdev->dev);
++ ret = -ENOMEM;
++ } else {
++ /* PRQA S 3200 2 */
++ pr_debug("IMR reg_base = %x size = %x\n",
++ (uint32_t)(rsc->start), (uint32_t)remap_size);
++ }
++ }
++
++ return ret;
++}
++
++/**
++ * uio_imr_remove() - release IMR module.
++ * @pdev: platform device data.
++ *
++ * release IMR module.
++ *
++ *
++ * Return: 0 normal end.
++ */
++static int uio_imr_remove(struct platform_device *pdev)
++{
++ struct resource *rsc;
++ struct uio_platdata *pdata = platform_get_drvdata(pdev);
++
++ /* PRQA S 3200 1 */
++ pr_debug("uio_imr_remove enter name = %s\n", pdata->uioinfo->name);
++
++ clk_disable_unprepare(pdata->clock);
++
++ uio_unregister_device(pdata->uioinfo);
++
++ pm_runtime_disable(&pdev->dev);
++
++ irq_dispose_mapping((u32)pdata->uioinfo->irq);
++
++ pdata->uioinfo->handler = NULL;
++ pdata->uioinfo->irqcontrol = NULL;
++
++ platform_set_drvdata(pdev, NULL);
++
++ if (pdata->base_reg != NULL)
++ devm_iounmap(&pdev->dev, pdata->base_reg);
++
++ rsc = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ if (rsc != 0)
++ release_mem_region(rsc->start, resource_size(rsc));
++
++ return 0;
++}
++
++/**
++ * uio_runtime_imr_nop() - Runtime PM callback function.
++ * @dev: device data.
++ *
++ * Runtime PM callback function.
++ *
++ *
++ * Return: 0 normal end.
++ */
++ /* PRQA S 3206 1 */
++static int uio_runtime_imr_nop(__attribute__((unused)) struct device *dev)
++{
++ pr_debug("uio_runtime_imr_nop enter\n"); /* PRQA S 3200 */
++ return 0;
++}
++/* PRQA S 1053 4 */
++static const struct dev_pm_ops uio_dev_pm_imr_ops = {
++ .runtime_suspend = &uio_runtime_imr_nop,
++ .runtime_resume = &uio_runtime_imr_nop,
++};
++
++static struct platform_driver uio_imr_platform_driver = {
++ .probe = &uio_imr_probe,
++ .remove = &uio_imr_remove,
++ .driver = {
++ .name = DRIVER_NAME,
++ .owner = THIS_MODULE,
++ .pm = &uio_dev_pm_imr_ops,
++ .of_match_table = of_match_ptr(rcar_imr_dt_ids),
++ },
++};
++
++module_platform_driver(uio_imr_platform_driver);
++
++
++MODULE_AUTHOR("Renesas Electronics Corporation");
++MODULE_DESCRIPTION("Userspace I/O driver for IMR");
++MODULE_LICENSE("Dual MIT/GPL");
++MODULE_ALIAS("platform:" DRIVER_NAME);
+--
+2.7.4
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0128-rcar_imr-v4l2-driver-Fix-module-support.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0128-rcar_imr-v4l2-driver-Fix-module-support.patch
new file mode 100644
index 0000000..f4ee6e2
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0128-rcar_imr-v4l2-driver-Fix-module-support.patch
@@ -0,0 +1,321 @@
+From 772299b20e32fc3ff86de4a83845e8246d97bcbb Mon Sep 17 00:00:00 2001
+From: Andrey Dolnikov <andrey.dolnikov@cogentembedded.com>
+Date: Mon, 9 Apr 2018 12:50:23 +0300
+Subject: [PATCH 2/2] rcar_imr v4l2 driver: Fix module support.
+
+---
+ arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi | 8 +++++++
+ arch/arm64/boot/dts/renesas/r8a7795.dtsi | 8 +++++++
+ arch/arm64/boot/dts/renesas/r8a7796.dtsi | 6 ++++++
+ arch/arm64/boot/dts/renesas/r8a7797.dtsi | 8 +++++++
+ arch/arm64/boot/dts/renesas/r8a7798.dtsi | 10 +++++++++
+ drivers/media/platform/rcar_imr.c | 32 +++++++++++++++++++++++++---
+ 6 files changed, 69 insertions(+), 3 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi b/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi
+index 745493c..f2769c2 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi
+@@ -2899,12 +2899,17 @@
+ power-domains = <&sysc R8A7795_PD_A3IR>;
+ };
+
++ imr_v4l2_alloc: imr_alloc {
++ dma-coherent;
++ };
++
+ imrlx4_ch0: imr0@fe860000 {
+ compatible = "renesas,imr-lx4", "renesas,imr-r8a7795";
+ reg = <0 0xfe860000 0 0x10000>;
+ interrupts = <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 823>;
+ power-domains = <&sysc R8A7795_PD_A3VC>;
++ alloc-dev = <&imr_v4l2_alloc>;
+ };
+
+ imrlx4_ch1: imr1@fe870000 {
+@@ -2913,6 +2918,7 @@
+ interrupts = <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 822>;
+ power-domains = <&sysc R8A7795_PD_A3VC>;
++ alloc-dev = <&imr_v4l2_alloc>;
+ };
+
+ imrlx4_ch2: imr2@fe880000 {
+@@ -2921,6 +2927,7 @@
+ interrupts = <GIC_SPI 194 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 821>;
+ power-domains = <&sysc R8A7795_PD_A3VC>;
++ alloc-dev = <&imr_v4l2_alloc>;
+ };
+
+ imrlx4_ch3: imr3@fe890000 {
+@@ -2929,6 +2936,7 @@
+ interrupts = <GIC_SPI 195 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 820>;
+ power-domains = <&sysc R8A7795_PD_A3VC>;
++ alloc-dev = <&imr_v4l2_alloc>;
+ };
+ };
+ };
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795.dtsi b/arch/arm64/boot/dts/renesas/r8a7795.dtsi
+index 96e182a..366ee5f 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7795.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a7795.dtsi
+@@ -2895,12 +2895,17 @@
+ power-domains = <&sysc R8A7795_PD_A3IR>;
+ };
+
++ imr_v4l2_alloc: imr_alloc {
++ dma-coherent;
++ };
++
+ imrlx4_ch0: imr0@fe860000 {
+ compatible = "renesas,imr-lx4", "renesas,imr-r8a7795";
+ reg = <0 0xfe860000 0 0x10000>;
+ interrupts = <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 823>;
+ power-domains = <&sysc R8A7795_PD_A3VC>;
++ alloc-dev = <&imr_v4l2_alloc>;
+ };
+
+ imrlx4_ch1: imr1@fe870000 {
+@@ -2909,6 +2914,7 @@
+ interrupts = <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 822>;
+ power-domains = <&sysc R8A7795_PD_A3VC>;
++ alloc-dev = <&imr_v4l2_alloc>;
+ };
+
+ imrlx4_ch2: imr2@fe880000 {
+@@ -2917,6 +2923,7 @@
+ interrupts = <GIC_SPI 194 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 821>;
+ power-domains = <&sysc R8A7795_PD_A3VC>;
++ alloc-dev = <&imr_v4l2_alloc>;
+ };
+
+ imrlx4_ch3: imr3@fe890000 {
+@@ -2925,6 +2932,7 @@
+ interrupts = <GIC_SPI 195 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 820>;
+ power-domains = <&sysc R8A7795_PD_A3VC>;
++ alloc-dev = <&imr_v4l2_alloc>;
+ };
+ };
+ };
+diff --git a/arch/arm64/boot/dts/renesas/r8a7796.dtsi b/arch/arm64/boot/dts/renesas/r8a7796.dtsi
+index b747f0c..442f027 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7796.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a7796.dtsi
+@@ -1174,12 +1174,17 @@
+ status = "disabled";
+ };
+
++ imr_v4l2_alloc: imr_alloc {
++ dma-coherent;
++ };
++
+ imrlx4_ch0: imr0@fe860000 {
+ compatible = "renesas,imr-lx4", "renesas,imr-r8a7796";
+ reg = <0 0xfe860000 0 0x10000>;
+ interrupts = <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 823>;
+ power-domains = <&sysc R8A7796_PD_A3VC>;
++ alloc-dev = <&imr_v4l2_alloc>;
+ };
+
+ imrlx4_ch1: imr1@fe870000 {
+@@ -1188,6 +1193,7 @@
+ interrupts = <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 822>;
+ power-domains = <&sysc R8A7796_PD_A3VC>;
++ alloc-dev = <&imr_v4l2_alloc>;
+ };
+
+ can0: can@e6c30000 {
+diff --git a/arch/arm64/boot/dts/renesas/r8a7797.dtsi b/arch/arm64/boot/dts/renesas/r8a7797.dtsi
+index c878467..16e73b4 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7797.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a7797.dtsi
+@@ -1239,12 +1239,17 @@
+ power-domains = <&sysc R8A7797_PD_A3IR>;
+ };
+
++ imr_v4l2_alloc: imr_alloc {
++ dma-coherent;
++ };
++
+ imrlx4_ch0: imr0@fe860000 {
+ compatible = "renesas,imr-lx4", "renesas,imr-r8a7797";
+ reg = <0 0xfe860000 0 0x10000>;
+ interrupts = <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 823>;
+ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ alloc-dev = <&imr_v4l2_alloc>;
+ };
+
+ imrlx4_ch1: imr1@fe870000 {
+@@ -1253,6 +1258,7 @@
+ interrupts = <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 822>;
+ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ alloc-dev = <&imr_v4l2_alloc>;
+ };
+
+ imrlx4_ch2: imr2@fe880000 {
+@@ -1261,6 +1267,7 @@
+ interrupts = <GIC_SPI 194 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 821>;
+ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ alloc-dev = <&imr_v4l2_alloc>;
+ };
+
+ imrlx4_ch3: imr3@fe890000 {
+@@ -1269,6 +1276,7 @@
+ interrupts = <GIC_SPI 195 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 820>;
+ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ alloc-dev = <&imr_v4l2_alloc>;
+ };
+ };
+ };
+diff --git a/arch/arm64/boot/dts/renesas/r8a7798.dtsi b/arch/arm64/boot/dts/renesas/r8a7798.dtsi
+index 7bfd0483..0742ec0 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7798.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a7798.dtsi
+@@ -1588,12 +1588,17 @@
+ power-domains = <&sysc R8A7798_PD_A3IR>;
+ };
+
++ imr_v4l2_alloc: imr_alloc {
++ dma-coherent;
++ };
++
+ imrlx4_ch0: imr0@fe860000 {
+ compatible = "renesas,imr-lx4", "renesas,imr-r8a7798";
+ reg = <0 0xfe860000 0 0x10000>;
+ interrupts = <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 823>;
+ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
++ alloc-dev = <&imr_v4l2_alloc>;
+ };
+
+ imrlx4_ch1: imr1@fe870000 {
+@@ -1602,6 +1607,7 @@
+ interrupts = <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 822>;
+ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
++ alloc-dev = <&imr_v4l2_alloc>;
+ };
+
+ imrlx4_ch2: imr2@fe880000 {
+@@ -1610,6 +1616,7 @@
+ interrupts = <GIC_SPI 194 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 821>;
+ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
++ alloc-dev = <&imr_v4l2_alloc>;
+ };
+
+ imrlx4_ch3: imr3@fe890000 {
+@@ -1618,6 +1625,7 @@
+ interrupts = <GIC_SPI 195 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 820>;
+ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
++ alloc-dev = <&imr_v4l2_alloc>;
+ };
+
+ imrlx4_ch4: imr4@fe8a0000 {
+@@ -1626,6 +1634,7 @@
+ interrupts = <GIC_SPI 254 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 707>;
+ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
++ alloc-dev = <&imr_v4l2_alloc>;
+ rse;
+ };
+
+@@ -1635,6 +1644,7 @@
+ interrupts = <GIC_SPI 255 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 706>;
+ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
++ alloc-dev = <&imr_v4l2_alloc>;
+ rse;
+ };
+
+diff --git a/drivers/media/platform/rcar_imr.c b/drivers/media/platform/rcar_imr.c
+index 7b16765..3558211 100644
+--- a/drivers/media/platform/rcar_imr.c
++++ b/drivers/media/platform/rcar_imr.c
+@@ -18,6 +18,7 @@
+ #include <linux/delay.h>
+ #include <linux/rcar-imr.h>
+ #include <linux/of.h>
++#include <linux/of_device.h>
+ #include <media/v4l2-device.h>
+ #include <media/v4l2-ctrls.h>
+ #include <media/v4l2-fh.h>
+@@ -1917,6 +1918,8 @@ static int imr_probe(struct platform_device *pdev)
+ struct resource *res;
+ struct device_node *np = pdev->dev.of_node;
+ int ret;
++ phandle *prop;
++ struct device_node *node;
+
+ imr = devm_kzalloc(&pdev->dev, sizeof(*imr), GFP_KERNEL);
+ if (!imr)
+@@ -1989,10 +1992,15 @@ static int imr_probe(struct platform_device *pdev)
+ ret = PTR_ERR(adev);
+ goto m2m_init_rollback;
+ }
++
+ adev->dma_mask = &adev->coherent_dma_mask;
+ adev->coherent_dma_mask = DMA_BIT_MASK(32);
+- arch_setup_dma_ops(adev, 0, DMA_BIT_MASK(32) + 1, NULL, true);
+ imr->alloc_dev = adev;
++ prop = of_get_property(np, "alloc-dev", NULL);
++ if (prop) {
++ node = of_find_node_by_phandle(be32_to_cpup(prop));
++ of_dma_configure(adev, node);
++ }
+
+ strlcpy(imr->video_dev.name, dev_name(&pdev->dev), sizeof(imr->video_dev.name));
+ imr->video_dev.fops = &imr_fops;
+@@ -2032,7 +2040,6 @@ static int imr_remove(struct platform_device *pdev)
+
+ //pm_runtime_disable(imr->v4l2_dev.dev);
+ video_unregister_device(&imr->video_dev);
+- //device_destroy(imr->alloc_dev, MKDEV(0, 0));
+ v4l2_m2m_release(imr->m2m_dev);
+ v4l2_device_unregister(&imr->v4l2_dev);
+
+@@ -2100,7 +2107,26 @@ static struct platform_driver imr_platform_driver = {
+ },
+ };
+
+-module_platform_driver(imr_platform_driver);
++static int __init imr_module_init(void)
++{
++ return platform_driver_register(&imr_platform_driver);
++}
++
++static int imr_device_destroy(struct device *dev, void *data)
++{
++ device_destroy(imr_alloc_class, dev->devt);
++ return 0;
++}
++
++static void __exit imr_module_exit(void)
++{
++ class_for_each_device(imr_alloc_class, NULL, NULL, imr_device_destroy);
++ class_destroy(imr_alloc_class);
++ platform_driver_unregister(&imr_platform_driver);
++}
++
++module_init(imr_module_init);
++module_exit(imr_module_exit);
+
+ MODULE_ALIAS("imr");
+ MODULE_AUTHOR("Cogent Embedded Inc. <sources@cogentembedded.com>");
+--
+2.7.4
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/condor.cfg b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/condor.cfg
index 7322e21..54ab6a7 100644
--- a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/condor.cfg
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/condor.cfg
@@ -20,7 +20,6 @@ CONFIG_SOC_CAMERA_SCALE_CROP=y
CONFIG_SOC_CAMERA_PLATFORM=y
CONFIG_SOC_CAMERA_MAX9286=y
CONFIG_SOC_CAMERA_OV106XX=y
-CONFIG_VIDEO_RENESAS_IMR=y
CONFIG_INPUT_TOUCHSCREEN=y
CONFIG_INPUT_UINPUT=y
CONFIG_TOUCHSCREEN_PROPERTIES=y
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/eagle.cfg b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/eagle.cfg
index ca8cee8..1e84e31 100644
--- a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/eagle.cfg
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/eagle.cfg
@@ -20,7 +20,6 @@ CONFIG_SOC_CAMERA_SCALE_CROP=y
CONFIG_SOC_CAMERA_PLATFORM=y
CONFIG_SOC_CAMERA_MAX9286=y
CONFIG_SOC_CAMERA_OV106XX=y
-CONFIG_VIDEO_RENESAS_IMR=y
CONFIG_INPUT_TOUCHSCREEN=y
CONFIG_INPUT_UINPUT=y
CONFIG_TOUCHSCREEN_PROPERTIES=y
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/imr.cfg b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/imr.cfg
new file mode 100644
index 0000000..cc7f69e
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/imr.cfg
@@ -0,0 +1,3 @@
+CONFIG_VIDEO_RENESAS_IMR=m
+CONFIG_UIO=y
+CONFIG_UIO_IMR=m
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/salvator-x.cfg b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/salvator-x.cfg
index 36c6103..4af8122 100644
--- a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/salvator-x.cfg
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/salvator-x.cfg
@@ -24,7 +24,6 @@ CONFIG_USB_XHCI_PLATFORM=y
CONFIG_USB_XHCI_RCAR=y
CONFIG_MMC_SDHI_PRE_REQ=y
CONFIG_MMC_SDHI_SEQ=y
-CONFIG_VIDEO_RENESAS_IMR=y
CONFIG_INPUT_TOUCHSCREEN=y
CONFIG_TOUCHSCREEN_PROPERTIES=y
CONFIG_HID_MULTITOUCH=y
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/ulcb.cfg b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/ulcb.cfg
index 5442f19..2714452 100644
--- a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/ulcb.cfg
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/ulcb.cfg
@@ -37,7 +37,6 @@ CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_PLATFORM=y
CONFIG_USB_XHCI_RCAR=y
CONFIG_USB_ACM=y
-CONFIG_VIDEO_RENESAS_IMR=y
CONFIG_VIRTIO_RCAR_PCIE=y
CONFIG_BT=y
CONFIG_BT_BNEP=m
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/v3hsk.cfg b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/v3hsk.cfg
index 3713001..b842d14 100644
--- a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/v3hsk.cfg
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/v3hsk.cfg
@@ -24,7 +24,6 @@ CONFIG_SOC_CAMERA_PLATFORM=y
CONFIG_SOC_CAMERA_MAX9286=y
CONFIG_SOC_CAMERA_TI9X4=y
CONFIG_SOC_CAMERA_OV106XX=y
-CONFIG_VIDEO_RENESAS_IMR=y
CONFIG_INPUT_TOUCHSCREEN=y
CONFIG_INPUT_UINPUT=y
CONFIG_TOUCHSCREEN_PROPERTIES=y
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/v3msk.cfg b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/v3msk.cfg
index a3c72d5..e349d80 100644
--- a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/v3msk.cfg
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/v3msk.cfg
@@ -24,7 +24,6 @@ CONFIG_SOC_CAMERA_PLATFORM=y
CONFIG_SOC_CAMERA_MAX9286=y
CONFIG_SOC_CAMERA_TI9X4=y
CONFIG_SOC_CAMERA_OV106XX=y
-CONFIG_VIDEO_RENESAS_IMR=y
CONFIG_INPUT_TOUCHSCREEN=y
CONFIG_INPUT_UINPUT=y
CONFIG_TOUCHSCREEN_PROPERTIES=y
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/v3mzf.cfg b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/v3mzf.cfg
index cd41866..d1b8914 100644
--- a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/v3mzf.cfg
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/v3mzf.cfg
@@ -17,9 +17,7 @@ CONFIG_SOC_CAMERA_SCALE_CROP=y
CONFIG_SOC_CAMERA_PLATFORM=y
CONFIG_SOC_CAMERA_TI9X4=y
CONFIG_SOC_CAMERA_OV106XX=y
-CONFIG_VIDEO_RENESAS_IMR=y
CONFIG_SERIAL_SH_SCI_DMA=y
-CONFIG_UIO=y
CONFIG_SPI_SLAVE=y
CONFIG_SPI_SLAVE_TIME=y
CONFIG_SPI_SLAVE_SYSTEM_CONTROL=y
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas_4.9.bbappend b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas_4.9.bbappend
index 6beaec5..0233afa 100644
--- a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas_4.9.bbappend
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas_4.9.bbappend
@@ -10,6 +10,7 @@ SRC_URI_append = " \
${@bb.utils.contains('MACHINE_FEATURES', 'h3ulcb-had', ' file://hyperflash.cfg', '', d)} \
${@base_conditional("SDHI_SEQ", "1", " file://sdhi_seq.cfg", "", d)} \
file://qspi.cfg \
+ file://imr.cfg \
file://0001-spi-sh-msiof-fixes.patch \
file://0002-spi-spidev-add-spi-gpio-into-spidev.patch \
file://0003-spi-spi-gpio-fix-CPOL-mode.patch \
@@ -105,6 +106,8 @@ SRC_URI_append = " \
file://0124-RPC-Hyperflash-Add-devicetree-support.patch \
file://0125-r8a7797-pinctrl-Add-pin-function-for-hyperflash.patch \
file://0126-r8a7798-pinctrl-Add-pin-function-for-hyperflash.patch \
+ file://0127-IMR-UIO-Driver-initial-version.patch \
+ file://0128-rcar_imr-v4l2-driver-Fix-module-support.patch \
"
SRC_URI_append_h3ulcb = " file://ulcb.cfg"
@@ -178,6 +181,12 @@ KERNEL_DEVICETREE_append_v3hsk = " \
renesas/r8a7798-v3hsk-vbm-v2.dtb \
"
+# Prefer V4L2 rcar_imr driver over UIO uio_imr
+KERNEL_MODULE_AUTOLOAD += "rcar_imr"
+KERNEL_MODULE_PROBECONF += "rcar_imr"
+KERNEL_MODULE_PROBECONF += "uio_imr"
+module_conf_uio_imr = 'blacklist uio_imr'
+
# V3H VIP devices
KERNEL_MODULE_AUTOLOAD_r8a7798 += "uio_pdrv_genirq"
KERNEL_MODULE_PROBECONF_r8a7798 += "uio_pdrv_genirq"