rust-for-linux.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Dirk Behme <dirk.behme@de.bosch.com>
To: "Daniel Almeida" <daniel.almeida@collabora.com>,
	"Miguel Ojeda" <ojeda@kernel.org>,
	"Alex Gaynor" <alex.gaynor@gmail.com>,
	"Boqun Feng" <boqun.feng@gmail.com>,
	"Gary Guo" <gary@garyguo.net>,
	"Björn Roy Baron" <bjorn3_gh@protonmail.com>,
	"Andreas Hindborg" <a.hindborg@kernel.org>,
	"Alice Ryhl" <aliceryhl@google.com>,
	"Trevor Gross" <tmgross@umich.edu>,
	"Danilo Krummrich" <dakr@kernel.org>,
	"Greg Kroah-Hartman" <gregkh@linuxfoundation.org>,
	"Rafael J. Wysocki" <rafael@kernel.org>,
	"Thomas Gleixner" <tglx@linutronix.de>,
	"Bjorn Helgaas" <bhelgaas@google.com>,
	"Krzysztof Wilczyński" <kwilczynski@kernel.org>,
	"Benno Lossin" <lossin@kernel.org>
Cc: <linux-kernel@vger.kernel.org>, <rust-for-linux@vger.kernel.org>,
	<linux-pci@vger.kernel.org>,
	Geert Uytterhoeven <geert+renesas@glider.be>,
	Wolfram Sang <wsa+renesas@sang-engineering.com>
Subject: Re: [PATCH v7 0/6] rust: add support for request_irq
Date: Tue, 22 Jul 2025 13:41:46 +0200	[thread overview]
Message-ID: <dd34e5f4-5027-4096-9f32-129c8a067d0a@de.bosch.com> (raw)
In-Reply-To: <20250715-topics-tyr-request_irq2-v7-0-d469c0f37c07@collabora.com>

On 15/07/2025 17:16, Daniel Almeida wrote:
> Changes in v7:
> - Rebased on top of driver-core-next
> - Added Flags::new(), which is a const fn. This lets us use build_assert!()
>   to verify the casts (hopefully this is what you meant, Alice?)
> - Changed the Flags inner type to take c_ulong directly, to minimize casts
>   (Thanks, Alice)
> - Moved the flag constants into Impl Flags, instead of using a separate
>   module (Alice)
> - Reverted to using #[repr(u32)] in Threaded/IrqReturn (Thanks Alice,
>   Benno)
> - Fixed all instances where the full path was specified for types in the
>   prelude (Alice)
> - Removed 'static from the CStr used to perform the lookup in the platform
>   accessor (Alice)
> - Renamed the PCI accessors, as asked by Danilo
> - Added more docs to Flags, going into more detail on what they do and how
>   to use them (Miguel)
> - Fixed the indentation in some of the docs (Alice)
> - Added Alice's r-b as appropriate
> - Link to v6: https://lore.kernel.org/rust-for-linux/20250703-topics-tyr-request_irq-v6-0-74103bdc7c52@collabora.com/


Looking for an easy way to test interrupts on an ARM64 Renesas RCar3 SoC
I found a quite simple timer unit (TMU) which has a configurable (start
value & frequency) count down. An interrupt is generated when the
counter reaches 0. And the counter restarts then. There is a C driver
for this already [1].

Using this patch series together with Alice's [2] I got a quite simple
periodic 1 min interrupt handling to run (just for testing, of course
not a full driver): [3] (output [4]).

With that:

Tested-by: Dirk Behme <dirk.behme@de.bosch.com>

Thanks to Daniel for the support!

Dirk

[1]
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/clocksource/sh_tmu.c

[2]
https://lore.kernel.org/rust-for-linux/20250721-irq-bound-device-v1-1-4fb2af418a63@google.com/

[3]

diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index 645f517a1ac2..d009a0e3508c 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -554,7 +554,16 @@ config RENESAS_OSTM
 	  Enables the support for the Renesas OSTM.

 config SH_TIMER_TMU
-	bool "Renesas TMU timer driver" if COMPILE_TEST
+	bool "Renesas TMU timer driver"
+	depends on HAS_IOMEM
+	default SYS_SUPPORTS_SH_TMU
+	help
+	  This enables build of a clocksource and clockevent driver for
+	  the 32-bit Timer Unit (TMU) hardware available on a wide range
+	  SoCs from Renesas.
+
+config SH_TIMER_TMU_RUST
+	bool "Renesas TMU Rust timer driver"
 	depends on HAS_IOMEM
 	default SYS_SUPPORTS_SH_TMU
 	help
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index 205bf3b0a8f3..66567f871502 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_SH_TIMER_CMT)	+= sh_cmt.o
 obj-$(CONFIG_SH_TIMER_MTU2)	+= sh_mtu2.o
 obj-$(CONFIG_RENESAS_OSTM)	+= renesas-ostm.o
 obj-$(CONFIG_SH_TIMER_TMU)	+= sh_tmu.o
+obj-$(CONFIG_SH_TIMER_TMU_RUST)	+= sh_tmu_rust.o
 obj-$(CONFIG_EM_TIMER_STI)	+= em_sti.o
 obj-$(CONFIG_CLKBLD_I8253)	+= i8253.o
 obj-$(CONFIG_CLKSRC_MMIO)	+= mmio.o
diff --git a/drivers/clocksource/sh_tmu_rust.rs
b/drivers/clocksource/sh_tmu_rust.rs
new file mode 100644
index 000000000000..328f9541d1bb
--- /dev/null
+++ b/drivers/clocksource/sh_tmu_rust.rs
@@ -0,0 +1,113 @@
+// SPDX-License-Identifier: GPL-2.0
+
+//! Rust Renesas TMU driver.
+
+use kernel::{
+    c_str,
+    device::{Core, Device, Bound},
+    devres::Devres,
+    io::mem::IoMem,
+    irq::{flags::Flags, IrqReturn, Registration},
+    of, platform,
+    prelude::*,
+    sync::Arc,
+    types::ARef,
+};
+
+struct RenesasTMUDriver {
+    pdev: ARef<platform::Device>,
+    _registration: Arc<Registration<Handler>>,
+    _iomem: Arc<Devres<IoMem>>,
+}
+
+struct Info;
+
+kernel::of_device_table!(
+    OF_TABLE,
+    MODULE_OF_TABLE,
+    <RenesasTMUDriver as platform::Driver>::IdInfo,
+    [(of::DeviceId::new(c_str!("renesas,tmu")), Info)]
+);
+
+const TSTR: usize =  0x4; //  8 Bit register
+const TCOR: usize =  0x8; // 32 Bit register
+const TCNT: usize =  0xC; // 32 Bit register
+const TCR:  usize = 0x10; // 16 Bit register
+
+struct Handler {
+    iomem: Arc<Devres<IoMem>>,
+}
+
+impl kernel::irq::request::Handler for Handler {
+    fn handle(&self, dev: &Device<Bound>) -> IrqReturn {
+        pr_info!("Renesas TMU IRQ handler called.\n");
+
+        // Reset the underflow flag
+        let io = self.iomem.access(dev).unwrap();
+        let tcr = io.try_read16_relaxed(TCR).unwrap_or(0);
+        if tcr & (0x1 << 8) != 0 {
+            io.try_write16_relaxed(tcr & !(0x1 << 8), TCR).unwrap_or(());
+        }
+
+        IrqReturn::Handled
+    }
+}
+
+impl platform::Driver for RenesasTMUDriver {
+    type IdInfo = Info;
+    const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = Some(&OF_TABLE);
+
+    fn probe(
+        pdev: &platform::Device<Core>,
+        _info: Option<&Self::IdInfo>,
+    ) -> Result<Pin<KBox<Self>>> {
+        let dev = pdev.as_ref();
+
+        dev_dbg!(dev, "Probe Rust Renesas TMU driver.\n");
+
+        let request = pdev.request_io_by_index(0).ok_or(EINVAL)?;
+        let iomem = Arc::pin_init(request.iomap()?, GFP_KERNEL)?;
+        let io = Arc::pin_init(iomem.access(dev)?, GFP_KERNEL)?;
+
+        // Set count to 1 minute. Clock is 16.66MHz / 4 = 4.165MHz
+        let timeout = 4165000 * 60; // 1 minute in clock ticks
+        io.try_write32_relaxed(timeout, TCOR)?;
+        io.try_write32_relaxed(timeout, TCNT)?;
+        // Enable underflow interrupt (UNIE, Underflow Interrupt Control)
+        let tcr = io.try_read16_relaxed(TCR)?;
+        io.try_write16_relaxed(tcr | 0x1 << 5, TCR)?;
+
+        let request = pdev.irq_by_index(0)?;
+        dev_info!(dev, "IRQ:  {}\n", request.irq());
+        let registration = Registration::new(request, Flags::SHARED,
c_str!("tmu"), Handler{iomem: iomem.clone()});
+        let registration = Arc::pin_init(registration, GFP_KERNEL)?;
+
+        // Enable TMU
+        io.try_write8_relaxed(0x1, TSTR)?;
+        // Read back registers to verify
+        dev_info!(dev, "TSTR: 0x{:x}\n", io.try_read8_relaxed(TSTR)?);
+        dev_info!(dev, "TCOR: 0x{:x}\n", io.try_read32_relaxed(TCOR)?);
+        dev_info!(dev, "TCNT: 0x{:x}\n", io.try_read32_relaxed(TCNT)?);
+        dev_info!(dev, "TCR:  0x{:x}\n", io.try_read16_relaxed(TCR)?);
+
+        let drvdata = KBox::pin_init(Self { pdev: pdev.into(),
_registration: registration, _iomem: iomem.clone()}, GFP_KERNEL)?;
+
+        dev_info!(dev, "probe done\n");
+
+        Ok(drvdata)
+    }
+}
+
+impl Drop for RenesasTMUDriver {
+    fn drop(&mut self) {
+        dev_dbg!(self.pdev.as_ref(), "Remove Rust Renesas TMU driver.\n");
+    }
+}
+
+kernel::module_platform_driver! {
+    type: RenesasTMUDriver,
+    name: "rust_tmu",
+    authors: ["Dirk Behme"],
+    description: "Rust Renesas TMU driver",
+    license: "GPL v2",
+}

[4] Interrupt each 60s:

...
[  430.655055] rust_tmu: Renesas TMU IRQ handler called.
[  490.637054] rust_tmu: Renesas TMU IRQ handler called.
[  550.619052] rust_tmu: Renesas TMU IRQ handler called.
[  610.601050] rust_tmu: Renesas TMU IRQ handler called.
[  670.583049] rust_tmu: Renesas TMU IRQ handler called.
[  730.565047] rust_tmu: Renesas TMU IRQ handler called.
...




  parent reply	other threads:[~2025-07-22 11:42 UTC|newest]

Thread overview: 37+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-07-15 15:16 [PATCH v7 0/6] rust: add support for request_irq Daniel Almeida
2025-07-15 15:16 ` [PATCH v7 1/6] rust: irq: add irq module Daniel Almeida
2025-07-15 15:16 ` [PATCH v7 2/6] rust: irq: add flags module Daniel Almeida
2025-07-16 14:20   ` Daniel Almeida
2025-07-16 14:45     ` Alice Ryhl
2025-07-15 15:16 ` [PATCH v7 3/6] rust: irq: add support for non-threaded IRQs and handlers Daniel Almeida
2025-07-16 23:45   ` kernel test robot
2025-07-17 16:20     ` Daniel Almeida
2025-07-21 14:17       ` Alice Ryhl
2025-07-21 14:45   ` Alice Ryhl
2025-07-21 15:10     ` Daniel Almeida
2025-07-21 15:28       ` Danilo Krummrich
2025-07-21 15:39         ` Daniel Almeida
2025-07-23  4:32   ` Boqun Feng
2025-07-23  4:57     ` Boqun Feng
2025-07-23  5:35     ` Alice Ryhl
2025-07-23 13:51       ` Boqun Feng
2025-07-23 13:55     ` Daniel Almeida
2025-07-23 14:26       ` Boqun Feng
2025-07-23 14:35         ` Danilo Krummrich
2025-07-23 14:56           ` Daniel Almeida
2025-07-23 15:03             ` Danilo Krummrich
2025-07-23 15:44               ` Alice Ryhl
2025-07-23 15:52                 ` Danilo Krummrich
2025-07-23 14:54         ` Daniel Almeida
2025-07-23 15:50           ` Boqun Feng
2025-07-23 16:07             ` Daniel Almeida
2025-07-23 16:11               ` Danilo Krummrich
2025-07-23 16:18                 ` Daniel Almeida
2025-07-23 21:31                   ` Danilo Krummrich
2025-07-15 15:16 ` [PATCH v7 4/6] rust: irq: add support for threaded " Daniel Almeida
2025-07-21 14:48   ` Alice Ryhl
2025-07-15 15:16 ` [PATCH v7 5/6] rust: platform: add irq accessors Daniel Almeida
2025-07-15 15:16 ` [PATCH v7 6/6] rust: pci: " Daniel Almeida
2025-07-15 15:32 ` [PATCH v7 0/6] rust: add support for request_irq Danilo Krummrich
2025-07-22 11:41 ` Dirk Behme [this message]
2025-07-22 14:52 ` Joel Fernandes

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=dd34e5f4-5027-4096-9f32-129c8a067d0a@de.bosch.com \
    --to=dirk.behme@de.bosch.com \
    --cc=a.hindborg@kernel.org \
    --cc=alex.gaynor@gmail.com \
    --cc=aliceryhl@google.com \
    --cc=bhelgaas@google.com \
    --cc=bjorn3_gh@protonmail.com \
    --cc=boqun.feng@gmail.com \
    --cc=dakr@kernel.org \
    --cc=daniel.almeida@collabora.com \
    --cc=gary@garyguo.net \
    --cc=geert+renesas@glider.be \
    --cc=gregkh@linuxfoundation.org \
    --cc=kwilczynski@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pci@vger.kernel.org \
    --cc=lossin@kernel.org \
    --cc=ojeda@kernel.org \
    --cc=rafael@kernel.org \
    --cc=rust-for-linux@vger.kernel.org \
    --cc=tglx@linutronix.de \
    --cc=tmgross@umich.edu \
    --cc=wsa+renesas@sang-engineering.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).