Re: [PATCH RFC 2/6] pwm: Add Rust driver for T-HEAD TH1520 SoC

Danilo Krummrich
2025-05-27T13:00:35Z

On Tue, May 27, 2025 at 02:44:57PM +0200, Michal Wilczynski/Kernel (PLT) /SRPOL/Engineer/Samsung Electronics wrote:
> W dniu 25.05.2025 o 14:03, Danilo Krummrich pisze:
> > On Sat, May 24, 2025 at 11:14:56PM +0200, Michal Wilczynski wrote:
> >> diff --git a/drivers/pwm/pwm_th1520.rs b/drivers/pwm/pwm_th1520.rs
> >> new file mode 100644
> >> index 0000000000000000000000000000000000000000..4665e293e8d0bdc1a62a4e295cdaf4d47b3dd134
> >> --- /dev/null
> >> +++ b/drivers/pwm/pwm_th1520.rs
> >> @@ -0,0 +1,272 @@
> >> +// SPDX-License-Identifier: GPL-2.0
> >> +// Copyright (c) 2025 Samsung Electronics Co., Ltd.
> >> +// Author: Michal Wilczynski <m.wilczynski@samsung.com>
> >> +
> >> +//! Rust T-HEAD TH1520 PWM driver
> >> +use kernel::{c_st
> >> +
> >> +struct Th1520PwmChipData {
> >> + clk: Clk,
> >> + iomem: kernel::devres::Devres<IoMem<0>>,
> > Why IoMem<0>? If you put the expected memory region size for this chip instead
> > all your subsequent accesses can be iomem.write() / iomem.read() rather than the
> > fallible try_{read,write}() variants.
> The size of the memory region is not known at the compile time. Instead
> it's configured
> via Device Tree. I'm not sure why it should work differently in Rust ?

There are two sizes:

(1) The size of the actual MMIO region, which comes from the device-tree.
(2) The size of the MMIO region that the driver knows it requires to work.

Let's say your driver uses registers with the following offsets.

REG0_OFFSET = 0x0
REG1_OFFSET = 0x4
REG2_OFFSET = 0x100

This means that the size of (2) is 0x100 + width of REG2 (let's say 0x4), which
means that you can safely define your MMIO memory type as IoMem<0x104>.

If you subsequently call pdev.ioremap_resource_sized() it will fail on runtime
if the MMIO region defined in the device-tree does not have a size of at least
0x104, i.e. (1) < (2). That's not a problem because if (1) < (2) your driver
can't work anyways.

In return, you can call the non-try variant of the read / write methods of
IoMem, which do boundary checks on compile time and hence are infallible.

Note that this does not prevent you to still call the try variants of read /
write in case you also have to deal with dynamic offsets that are not known at
compile time.

I hope this helps.

- Danilo