Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rust: add regulator consumer abstraction #1040

Draft
wants to merge 463 commits into
base: rust-dev
Choose a base branch
from

Conversation

Fabo
Copy link

@Fabo Fabo commented Nov 14, 2023

I'm currently working on a driver that needs the regulator consumer abstraction. The driver that will use it is not yet ready but I thought I would push here the abstraction in case anyone needs it as well.

I do not consider the abstraction finished. I need to revise the documentation and do more testing.

The abstraction itself depends on https://lore.kernel.org/rust-for-linux/[email protected]/ and is based on rust-dev (but could be rebased without issue on rust-next later on.

I also added a sample, but that one depends on a few things that I pulled from the rust branch such as OF, platform driver abstractions.

@Fabo Fabo force-pushed the fparent/rust-regulator branch from 6a6168b to e2ad4da Compare November 27, 2023 20:22
@Fabo Fabo force-pushed the fparent/rust-regulator branch from e2ad4da to 92ceb2e Compare December 7, 2023 22:08
@fbq fbq force-pushed the rust-dev branch 2 times, most recently from 5e2b9bc to 5cd4b93 Compare December 14, 2023 20:06
@fbq fbq force-pushed the rust-dev branch 2 times, most recently from 03ec649 to 8f7e376 Compare December 28, 2023 19:38
@fbq fbq force-pushed the rust-dev branch 2 times, most recently from 9bdbf5d to ddbd3ca Compare January 22, 2024 21:49
@fbq fbq force-pushed the rust-dev branch 3 times, most recently from 7b0b25e to ba2f66a Compare February 5, 2024 18:00
@fbq fbq force-pushed the rust-dev branch 3 times, most recently from 596f12c to 6bdd6e6 Compare February 19, 2024 01:41
@Fabo Fabo force-pushed the fparent/rust-regulator branch 6 times, most recently from 848cd82 to 152c1b6 Compare February 21, 2024 05:43
@Fabo Fabo force-pushed the fparent/rust-regulator branch 4 times, most recently from baa41ff to c13f777 Compare March 1, 2024 20:52
@Fabo Fabo force-pushed the fparent/rust-regulator branch 3 times, most recently from 6bf7bdd to 82b010e Compare March 7, 2024 02:00
Danilo Krummrich and others added 11 commits October 14, 2024 18:01
Add maintainers entry for the Rust `alloc` module.

Currently, this includes the `Allocator` API itself, `Allocator`
implementations, such as `Kmalloc` or `Vmalloc`, as well as the kernel's
implementation of the primary memory allocation data structures, `Box`
and `Vec`.

Signed-off-by: Danilo Krummrich <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Miguel Ojeda <[email protected]>
We'll need it, for example, when calling `register_filesystem` to
initialise a file system registration.

Signed-off-by: Wedson Almeida Filho <[email protected]>
Signed-off-by: Danilo Krummrich <[email protected]>
This allows modules to be initialised in-place in pinned memory, which
enables the usage of pinned types (e.g., mutexes, spinlocks, driver
registrations, etc.) in modules without any extra allocations.

Drivers that don't need this may continue to implement `Module` without
any changes.

Signed-off-by: Wedson Almeida Filho <[email protected]>
Signed-off-by: Danilo Krummrich <[email protected]>
In a subsequent patch we introduce the `Registration` abstraction used
to register driver structures. Some subsystems require the module name on
driver registration (e.g. PCI in __pci_register_driver()), hence pass
the module name to `Module::init`.

Signed-off-by: Danilo Krummrich <[email protected]>
Implement the generic `Registration` type and the `DriverOps` trait.

The `Registration` structure is the common type that represents a driver
registration and is typically bound to the lifetime of a module. However,
it doesn't implement actual calls to the kernel's driver core to register
drivers itself.

Instead the `DriverOps` trait is provided to subsystems, which have to
implement `DriverOps::register` and `DrvierOps::unregister`. Subsystems
have to provide an implementation for both of those methods where the
subsystem specific variants to register / unregister a driver have to
implemented.

For instance, the PCI subsystem would call __pci_register_driver() from
`DriverOps::register` and pci_unregister_driver() from
`DrvierOps::unregister`.

Co-developed-by: Wedson Almeida Filho <[email protected]>
Signed-off-by: Wedson Almeida Filho <[email protected]>
Signed-off-by: Danilo Krummrich <[email protected]>
Most subsystems use some kind of ID to match devices and drivers. Hence,
we have to provide Rust drivers an abstraction to register an ID table
for the driver to match.

Generally, those IDs are subsystem specific and hence need to be
implemented by the corresponding subsystem. However, the `IdArray`,
`IdTable` and `RawDeviceId` types provide a generalized implementation
that makes the life of subsystems easier to do so.

Co-developed-by: Wedson Almeida Filho <[email protected]>
Signed-off-by: Wedson Almeida Filho <[email protected]>
Co-developed-by: Gary Guo <[email protected]>
Signed-off-by: Gary Guo <[email protected]>
Signed-off-by: Danilo Krummrich <[email protected]>
Add a simple abstraction to guard critical code sections with an rcu
read lock.

Signed-off-by: Wedson Almeida Filho <[email protected]>
Signed-off-by: Danilo Krummrich <[email protected]>
Revocable allows access to objects to be safely revoked at run time.

This is useful, for example, for resources allocated during device probe;
when the device is removed, the driver should stop accessing the device
resources even if another state is kept in memory due to existing
references (i.e., device context data is ref-counted and has a non-zero
refcount after removal of the device).

Signed-off-by: Wedson Almeida Filho <[email protected]>
Signed-off-by: Danilo Krummrich <[email protected]>
Implement `dev_*` print macros for `device::Device`.

They behave like the macros with the same names in C, i.e., they print
messages to the kernel ring buffer with the given level, prefixing the
messages with corresponding device information.

Signed-off-by: Wedson Almeida Filho <[email protected]>
Signed-off-by: Danilo Krummrich <[email protected]>
I/O memory is typically either mapped through direct calls to ioremap()
or subsystem / bus specific ones such as pci_iomap().

Even though subsystem / bus specific functions to map I/O memory are
based on ioremap() / iounmap() it is not desirable to re-implement them
in Rust.

Instead, implement a base type for I/O mapped memory, which generically
provides the corresponding accessors, such as `Io::readb` or
`Io:try_readb`.

`Io` supports an optional const generic, such that a driver can indicate
the minimal expected and required size of the mapping at compile time.
Correspondingly, calls to the 'non-try' accessors, support compile time
checks of the I/O memory offset to read / write, while the 'try'
accessors, provide boundary checks on runtime.

`Io` is meant to be embedded into a structure (e.g. pci::Bar or
io::IoMem) which creates the actual I/O memory mapping and initializes
`Io` accordingly.

To ensure that I/O mapped memory can't out-live the device it may be
bound to, subsystems should embedd the corresponding I/O memory type
(e.g. pci::Bar) into a `Devres` container, such that it gets revoked
once the device is unbound.

Co-developed-by: Philipp Stanner <[email protected]>
Signed-off-by: Philipp Stanner <[email protected]>
Signed-off-by: Danilo Krummrich <[email protected]>
Add a Rust abstraction for the kernel's devres (device resource
management) implementation.

The Devres type acts as a container to manage the lifetime and
accessibility of device bound resources. Therefore it registers a
devres callback and revokes access to the resource on invocation.

Users of the Devres abstraction can simply free the corresponding
resources in their Drop implementation, which is invoked when either the
Devres instance goes out of scope or the devres callback leads to the
resource being revoked, which implies a call to drop_in_place().

Signed-off-by: Danilo Krummrich <[email protected]>
@Fabo Fabo force-pushed the fparent/rust-regulator branch from 0abbabb to ae4a84b Compare October 20, 2024 04:36
Fabo added 4 commits October 20, 2024 11:23
impl Deref doesn't work in const context. Add a function
that is similar to implementing `deref` but that can
be used in `const` context.

Signed-off-by: Fabien Parent <[email protected]>
For modpost to work, we need the device id table to be named as follow:
	__mod_{type}__{name}_device_table

In C, this is done by calling MODULE_DEVICE_TABLE(type, name), which declares
a new symbol that aliases to `name`.

As far as I know it is not possible to create such aliases in Rust, so
here we instead create a new static variable which contains a copy of the
device_id tables, but without the extra `id_infos` used on the Rust
side.

Signed-off-by: Fabien Parent <[email protected]>
@Fabo Fabo force-pushed the fparent/rust-regulator branch 2 times, most recently from 7b7dec9 to 3037545 Compare October 21, 2024 00:39
Sven Van Asbroeck and others added 11 commits October 21, 2024 08:39
Co-developed-by: Wedson Almeida Filho <[email protected]>
Signed-off-by: Wedson Almeida Filho <[email protected]>
Signed-off-by: Sven Van Asbroeck <[email protected]>
Signed-off-by: Fabien Parent <[email protected]>
Add a new Rust abstraction that allows writing drivers for I2C based
devices.

Signed-off-by: Fiona Behrens <[email protected]>
Co-developed-by: Fabien Parent <[email protected]>
Signed-off-by: Fabien Parent <[email protected]>
Create a function that is equivalent to Linux's GENMASK macro.

Signed-off-by: Fabien Parent <[email protected]>
The following code is currently working fine and will generate a struct
named "Test0":

	kernel::macros::paste! {
	    struct [<Test 0>];
	}

But if we need to use a "macro variable" like this:

	macro_rules! test {
	    ($i: literal) => {
		kernel::macros::paste! {
		    struct [<Test $i>];
		}
	    };
	}

	test!(0);

The code above will make the paste! macro panic:

	error: proc macro panicked
	  --> drivers/regulator/ncv6336.rs:25:9
	   |
	25 | /         kernel::macros::paste! {
	26 | |             struct [<Test $i>];
	27 | |         }
	   | |_________^
	...
	31 |   test!(0);
	   |   -------- in this macro invocation
	   |
	   = help: message: unexpected token in paste segments

The reason of this panic is that "macro variables" are creating
`Groups` [0], with the `None` delimiter [1], and currently `Groups`are not
handled by the paste! macro.

This commit adds support for TokenTree::Group token where the delimiter
is None in order to make the previous code snippet now work.

[0] https://doc.rust-lang.org/proc_macro/struct.Group.html
[1] https://doc.rust-lang.org/proc_macro/enum.Delimiter.html#variant.None

Signed-off-by: Fabien Parent <[email protected]>
Add a macro that can be used to repeat code.

It allows to use the following syntax:
	foreach!(i in 0..=4) {
		paste! {
			struct [<Bit $i>];
		}
	}

This will be used by the Regmap abstraction in order to prevent
redefining the same bit several times, hence prevent fields to
overlap.

Signed-off-by: Fabien Parent <[email protected]>
Add an abstraction to regmap for Rust.

Signed-off-by: Fabien Parent <[email protected]>
Add a missing errno for ENOTRECOVERABLE.

Signed-off-by: Fabien Parent <[email protected]>
Add a rust abstraction for the regulator consumer API.

Signed-off-by: Fabien Parent <[email protected]>
This commit adds a Rust abstraction to write Regulator drivers. Only
the features used by the NCV6336 driver were added to this abstraction.

Signed-off-by: Fabien Parent <[email protected]>
The regulator API offer many helpers to help simplifies drivers that
use the regmap API. This commit adds partial support for it, only the
function needed by the NCV6336 driver were added.

In case CONFIG_REGMAP=n, we create a dummy Regmap implementation in
order to avoid to have to surround a lot of the declarations and
statements with #[cfg(CONFIG_REGMAP)].

Signed-off-by: Fabien Parent <[email protected]>
@Fabo Fabo force-pushed the fparent/rust-regulator branch from 3037545 to 0b42512 Compare October 21, 2024 15:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.