[PATCH] r8a77965 CMT test setup using UIO

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Magnus Damm <damm+renesas@xxxxxxxxxxxxx>

This patch contains kernel modificatons to allow some basic testing from
user space of the CMT0 device included on the r8a77965 SoC.

Not suitable for upstream merge. No attempt has been made to turn this into
somewhat clean code, so consider this a rough hack. The patch is a combination
of the following:
 - Device Tree modifications to expose CMT0 via UIO
 - code to add UIO driver debug code
 - adjustment for the compat string matching in MODULE_DEVICE_TABLE()

As Geert kindly pointed out there might be better ways to do this.

For the kernel, simply apply the kernel patch (including a few debug printouts)
and make sure to extend your kernel config with CONFIG_UIO_PDRV_GENIRQ=y.

The code in this patch is similar to earlier posted series but has been
ported from r8a77965 to r8a77961.

[PATCH 0/2] r8a77961 CMT test setup using UIO
[PATCH 1/2] r8a77961 CMT0 device exposed via UIO
[PATCH 2/2] UIO CMT test program

The most tricky challenge was to trim down the kernel size to be able to
boot with the old boot loader. The user space UIO test app remains the same
as for r8a77961 and can be located in the mailing list archives.

The following log shows how to execute the test program once on the target:

# ./uio-cmt-test
found matching UIO device at /sys/class/uio/uio0/
CLKE
CMCSR
CMCOR
[  227.228333] irqhandler 24
waiting 10sUIO write
CLKE
UIO read
got CMT IRQ
CLKE

Please note that only a few registers of a single channel of the CMT0 device
has been exercised. The kernel debug printout and /proc/interrupts may be
used to verify that at least one interrupt has been delivered.

One limitation with the current setup is that the UIO kernel driver only
supports a single interrupt however the CMT devices come with one interrupt
per channel on R-Car Gen3. Currently the code only uses a single IRQ.

If it turns out that the current test coverage should be extended then perhaps
it would be wise to also extend the UIO kernel driver with support for multiple
interrupts as well. To maintain the same user space interface the UIO driver
can simply have a list of interrupts associated with each device and then
enable/disable all of them on each IRQ. Not fast but good enough for testing.

Not-Yet-Signed-off-by: Magnus Damm <damm+renesas@xxxxxxxxxxxxx>
---

 Built on top of renesas-drivers-2020-12-15-v5.10
 Testing has been performed remotely on r8a77965 Salvator-X.

 arch/arm64/boot/dts/renesas/r8a77965.dtsi |   23 ++++++++++-------------
 drivers/uio/uio.c                         |    3 ++-
 drivers/uio/uio_pdrv_genirq.c             |   10 ++++++++--
 3 files changed, 20 insertions(+), 16 deletions(-)

--- 0001/arch/arm64/boot/dts/renesas/r8a77965.dtsi
+++ work/arch/arm64/boot/dts/renesas/r8a77965.dtsi	2020-12-21 22:20:47.036998593 +0900
@@ -334,19 +334,6 @@
 			reg = <0 0xe6060000 0 0x50c>;
 		};
 
-		cmt0: timer@e60f0000 {
-			compatible = "renesas,r8a77965-cmt0",
-				     "renesas,rcar-gen3-cmt0";
-			reg = <0 0xe60f0000 0 0x1004>;
-			interrupts = <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 303>;
-			clock-names = "fck";
-			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
-			resets = <&cpg 303>;
-			status = "disabled";
-		};
-
 		cmt1: timer@e6130000 {
 			compatible = "renesas,r8a77965-cmt1",
 				     "renesas,rcar-gen3-cmt1";
@@ -414,6 +401,16 @@
 			#reset-cells = <1>;
 		};
 
+		cmt0: timer@e60f0000 {
+			compatible = "uio_pdrv_genirq";
+			reg = <0 0xe60f0000 0 0x1004>;
+			interrupts = <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 303>;
+			clock-names = "fck";
+			power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+			resets = <&cpg 303>;
+		};
+
 		rst: reset-controller@e6160000 {
 			compatible = "renesas,r8a77965-rst";
 			reg = <0 0xe6160000 0 0x0200>;
--- 0001/drivers/uio/uio.c
+++ work/drivers/uio/uio.c	2020-12-21 22:16:51.680983772 +0900
@@ -11,7 +11,7 @@
  *
  * Base Functions
  */
-
+#define DEBUG
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/poll.h>
@@ -975,6 +975,7 @@ int __uio_register_device(struct module
 		 * FDs at the time of unregister and therefore may not be
 		 * freed until they are released.
 		 */
+		pr_debug("uio request_irq %lu\n", info->irq);
 		ret = request_irq(info->irq, uio_interrupt,
 				  info->irq_flags, info->name, idev);
 		if (ret) {
--- 0001/drivers/uio/uio_pdrv_genirq.c
+++ work/drivers/uio/uio_pdrv_genirq.c	2020-12-21 22:16:51.680983772 +0900
@@ -10,7 +10,7 @@
  * Copyright (C) 2008 by Digi International Inc.
  * All rights reserved.
  */
-
+#define DEBUG
 #include <linux/platform_device.h>
 #include <linux/uio_driver.h>
 #include <linux/spinlock.h>
@@ -66,6 +66,8 @@ static irqreturn_t uio_pdrv_genirq_handl
 	 * remember the state so we can allow user space to enable it later.
 	 */
 
+	pr_debug("irqhandler %d\n", irq);
+
 	spin_lock(&priv->lock);
 	if (!__test_and_set_bit(UIO_IRQ_DISABLED, &priv->flags))
 		disable_irq_nosync(irq);
@@ -87,6 +89,8 @@ static int uio_pdrv_genirq_irqcontrol(st
 	 * with irq handler on SMP systems.
 	 */
 
+	pr_debug("irqcontrol %d\n", irq_on);
+	
 	spin_lock_irqsave(&priv->lock, flags);
 	if (irq_on) {
 		if (__test_and_clear_bit(UIO_IRQ_DISABLED, &priv->flags))
@@ -172,6 +176,8 @@ static int uio_pdrv_genirq_probe(struct
 		}
 	}
 
+	pr_debug("uio irq %lu\n", uioinfo->irq);
+	
 	if (uioinfo->irq) {
 		struct irq_data *irq_data = irq_get_irq_data(uioinfo->irq);
 
@@ -276,7 +282,7 @@ static const struct dev_pm_ops uio_pdrv_
 
 #ifdef CONFIG_OF
 static struct of_device_id uio_of_genirq_match[] = {
-	{ /* This is filled with module_parm */ },
+	{ .compatible = "uio_pdrv_genirq", },
 	{ /* Sentinel */ },
 };
 MODULE_DEVICE_TABLE(of, uio_of_genirq_match);



[Index of Archives]     [Linux Samsung SOC]     [Linux Wireless]     [Linux Kernel]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]

  Powered by Linux