diff options
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" |