rust: Add basic I2C driver abstractions
Subsystems (3)
cover rust: Add basic I2C driver abstractions
This patch series introduces basic Rust I2C driver abstractions and optional ACPI match-table support and provides a sample driver demonstrating both OF and ACPI binding
Currently Rust I2C abstractions support only Open Firmware OF device matching. This series splits the work into four patches so that the core abstractions and sample driver can land immediately while ACPI integration may be reviewed once the ACPI macros are upstream
Changes include
- core I2C abstractions i2c::Device i2c::Driver i2c::Adapter built on struct i2c_client and struct i2c_driver
- a standalone Rust sample driver exercising Legacy I2C ID and OF ID matching
- optional ACPI ID-table support in the i2c::Driver abstraction
- ACPI-enabled sample driver showing kernel::acpi_device_table! usage
This separation lets maintainers review and merge the non-ACPI portions immediately while patches 3 and 4 both depending on the ACPI infrastructure can be queued once the ACPI macros are upstream
Patch series:
1 rust: i2c: add basic I2C device and driver abstractions 2 samples: rust: add I2C sample driver (OF only)
3 rust: i2c: support ACPI match-table in driver abstractions
Depends-on: [email protected] 4 samples: rust: show ACPI ID-table in I2C sample driver
Depends-on: [email protected]
Igor Korotin (4):
rust: i2c: add basic I2C device and driver abstractions
samples: rust: add Rust I2C sample driver
rust: i2c: ACPI ID-table support for I2C abstractions
samples: rust: show ACPI ID-table in I2C sample driver
MAINTAINERS | 3 + rust/bindings/bindings_helper.h | 1 + rust/helpers/helpers.c | 1 + rust/helpers/i2c.c | 15 ++ rust/kernel/i2c.rs | 386 ++++++++++++++++++++++++++++++++ rust/kernel/lib.rs | 2 + samples/rust/Kconfig | 11 + samples/rust/Makefile | 1 + samples/rust/rust_driver_i2c.rs | 69 ++++++ 9 files changed, 489 insertions(+) create mode 100644 rust/helpers/i2c.c create mode 100644 rust/kernel/i2c.rs create mode 100644 samples/rust/rust_driver_i2c.rs
base-commit: 63dafeb392139b893a73b6331f347613f0929702
Signature · 1 line
2.43.0
PATCH 1/4 rust: i2c: add basic I2C device and driver abstractions
Implement the core abstractions needed for I2C drivers, including:
* i2c::Driver — the trait drivers must implement, including probe
* i2c::Device — a safe wrapper around struct i2c_client
* i2c::Adapter — implements driver::RegistrationOps to hook into the generic driver::Registration machinery
* i2c::DeviceId — a RawDeviceId implementation for I2C device IDs
--- MAINTAINERS | 2 + rust/bindings/bindings_helper.h | 1 + rust/helpers/helpers.c | 1 + rust/helpers/i2c.c | 15 ++ rust/kernel/i2c.rs | 363 ++++++++++++++++++++++++++++++++ rust/kernel/lib.rs | 2 + 6 files changed, 384 insertions(+) create mode 100644 rust/helpers/i2c.c create mode 100644 rust/kernel/i2c.rs
MAINTAINERS +2 -0
@@ -11362,6 +11362,8 @@ F: include/linux/i2c-smbus.h F: include/linux/i2c.h F: include/uapi/linux/i2c-*.h F: include/uapi/linux/i2c.h +F: rust/helpers/i2c.c +F: rust/kernel/i2c.rs I2C SUBSYSTEM HOST DRIVERS M: Andi Shyti <[email protected]>
rust/bindings/bindings_helper.h +1 -0
@@ -52,6 +52,7 @@#include <linux/file.h> #include <linux/firmware.h> #include <linux/fs.h> +#include <linux/i2c.h> #include <linux/jiffies.h> #include <linux/jump_label.h> #include <linux/mdio.h>
rust/helpers/helpers.c +1 -0
@@ -23,6 +23,7 @@#include "drm.c" #include "err.c" #include "fs.c" +#include "i2c.c" #include "io.c" #include "jump_label.c" #include "kunit.c"
rust/helpers/i2c.c new file +15 -0
@@ -0,0 +1,15 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include <linux/i2c.h> + +void *rust_helper_i2c_get_clientdata (struct i2c_client *client) +{ +return i2c_get_clientdata (client); +} + +void rust_helper_i2c_set_clientdata (struct i2c_client *client,void *data) +{ +i2c_set_clientdata (client, data); +} + +
rust/kernel/i2c.rs new file +363 -0
363 lines not on this page · raw message
rust/kernel/lib.rs +2 -0
@@ -78,6 +78,8 @@#[cfg( CONFIG_RUST_FW_LOADER_ABSTRACTIONS )] pub mod firmware;pub mod fs; +#[cfg( CONFIG_I2C )] +pub mod i2c;pub mod init;pub mod io;pub mod ioctl;
Signature · 1 line
2.43.0
PATCH 2/4 samples: rust: add Rust I2C sample driver
In reply to Igor KorotinAdd a new rust_driver_i2c sample, showing how to bind an I2C client in Rust via legacy I2C-ID or OF compatible tables.
--- MAINTAINERS | 1 + samples/rust/Kconfig | 11 ++++++ samples/rust/Makefile | 1 + samples/rust/rust_driver_i2c.rs | 61 +++++++++++++++++++++++++++++++++ 4 files changed, 74 insertions(+) create mode 100644 samples/rust/rust_driver_i2c.rs
MAINTAINERS +1 -0
@@ -11364,6 +11364,7 @@ F: include/uapi/linux/i2c-*.h F: include/uapi/linux/i2c.h F: rust/helpers/i2c.c F: rust/kernel/i2c.rs +F: samples/rust/rust_driver_i2c.rs I2C SUBSYSTEM HOST DRIVERS M: Andi Shyti <[email protected]>
samples/rust/Kconfig +11 -0
@@ -62,6 +62,17 @@ config SAMPLE_RUST_DMA If unsure, say N. +config SAMPLE_RUST_DRIVER_I2C + tristate "I2C Driver" + depends on I2C + help + This option builds the Rust I2C driver sample. + + To compile this as a module, choose M here: + the module will be called rust_driver_i2c. + + If unsure, say N. + config SAMPLE_RUST_DRIVER_PCI tristate "PCI Driver" depends on PCI
samples/rust/Makefile +1 -0
@@ -5,6 +5,7 @@ obj-$(CONFIG_SAMPLE_RUST_MINIMAL) += rust_minimal.o obj-$(CONFIG_SAMPLE_RUST_MISC_DEVICE) += rust_misc_device.o obj-$(CONFIG_SAMPLE_RUST_PRINT) += rust_print.o obj-$(CONFIG_SAMPLE_RUST_DMA) += rust_dma.o +obj-$(CONFIG_SAMPLE_RUST_DRIVER_I2C) += rust_driver_i2c.o obj-$(CONFIG_SAMPLE_RUST_DRIVER_PCI) += rust_driver_pci.o obj-$(CONFIG_SAMPLE_RUST_DRIVER_PLATFORM) += rust_driver_platform.o obj-$(CONFIG_SAMPLE_RUST_DRIVER_FAUX) += rust_driver_faux.o
samples/rust/rust_driver_i2c.rs new file +61 -0
61 lines not on this page · raw message
Signature · 1 line
2.43.0
PATCH 3/4 rust: i2c: ACPI ID-table support for I2C abstractions
In reply to Igor KorotinPopulate driver.acpi_match_table from T::ACPI_ID_TABLE (defaults to None).
Depends-on: <[email protected]>
--- rust/kernel/i2c.rs | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-)
rust/kernel/i2c.rs +25 -2
@@ -4,7 +4,7 @@// I2C Driver abstractions. use crate ::{ - container_of, device, + acpi, container_of, device, device_id::RawDeviceId , driver, error::*,
@@ -96,6 +96,11 @@ unsafe fn register( None => core::ptr::null(), }; +let acpi_table =match T ::ACPI_ID_TABLE { +Some (table) => table.as_ptr (), +None => core::ptr::null (), + }; +// SAFETY: It's safe to set the fields of `struct i2c_client` on initialization. unsafe { (*pdrv.get ()).driver.name = name.as_char_ptr ();
@@ -104,6 +109,7 @@ unsafe fn register( (*pdrv.get ()).shutdown =Some (Self ::shutdown_callback); (*pdrv.get ()).id_table = i2c_table; (*pdrv.get ()).driver.of_match_table = of_table; + (*pdrv.get ()).driver.acpi_match_table = acpi_table; }// SAFETY: `pdrv` is guaranteed to be a valid `RegType`.
@@ -187,6 +193,10 @@ impl<T: Driver + 'static> driver::Adapter for Adapter<T> {fn of_id_table () ->Option <of::IdTable <Self ::IdInfo >> {T ::OF_ID_TABLE } + +fn acpi_id_table () ->Option <acpi::IdTable <Self ::IdInfo >> { +T ::ACPI_ID_TABLE + } }/// Declares a kernel module that exposes a single i2c driver.
@@ -216,10 +226,19 @@ macro_rules! module_i2c_driver {/// # Example /// ///``` -/// # use kernel::{bindings, c_str, device::Core, i2c, of}; +/// # use kernel::{acpi, bindings, c_str, device::Core, i2c, of}; /// /// struct MyDriver; /// +/// kernel::acpi_device_table!( +/// ACPI_TABLE, +/// MODULE_ACPI_TABLE, +/// <MyDriver as i2c::Driver>::IdInfo, +/// [ +/// (acpi::DeviceId::new(b"TST0001"), ()) +/// ] +/// ); +/// /// kernel::i2c_device_table!( /// I2C_TABLE, /// MODULE_I2C_TABLE,
@@ -242,6 +261,7 @@ macro_rules! module_i2c_driver {/// type IdInfo = (); /// const I2C_ID_TABLE: Option<i2c::IdTable<Self::IdInfo>> = Some(&I2C_TABLE); /// const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = Some(&OF_TABLE); +/// const ACPI_ID_TABLE: Option<acpi::IdTable<Self::IdInfo>> = Some(&ACPI_TABLE); /// /// fn probe( /// _pdev: &i2c::Device<Core>,
@@ -269,6 +289,9 @@ pub trait Driver: Send {/// The table of OF device ids supported by the driver. const OF_ID_TABLE :Option <of::IdTable <Self ::IdInfo >> =None ; +/// The table of ACPI device ids supported by the driver. +const ACPI_ID_TABLE :Option <acpi::IdTable <Self ::IdInfo >> =None ; +/// I2C driver probe. /// /// Called when a new i2c device is added or discovered.
Signature · 1 line
2.43.0
PATCH 4/4 samples: rust: show ACPI ID-table in I2C sample driver
In reply to Igor KorotinAdd an acpi_device_table! example and set SampleDriver::ACPI_ID_TABLE to demonstrate ACPI usage.
Depends-on: <[email protected]>
--- samples/rust/rust_driver_i2c.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-)
samples/rust/rust_driver_i2c.rs +9 -1
@@ -2,12 +2,19 @@//! Rust I2C driver sample. -use kernel::{c_str, device::Core , i2c, of, prelude::*, types::ARef }; +use kernel::{acpi, c_str, device::Core , i2c, of, prelude::*, types::ARef };struct SampleDriver { pdev:ARef <i2c::Device >, } +kernel::acpi_device_table! { +ACPI_TABLE , +MODULE_ACPI_TABLE , + <SampleDriver as i2c::Driver >::IdInfo , + [(acpi::DeviceId ::new (b"TST0001" ),0 )] +} + kernel::i2c_device_table! {I2C_TABLE ,MODULE_I2C_TABLE ,
@@ -25,6 +32,7 @@ struct SampleDriver {impl i2c::Driver for SampleDriver {type IdInfo =u32 ; +const ACPI_ID_TABLE :Option <acpi::IdTable <Self ::IdInfo >> =Some (&ACPI_TABLE );const I2C_ID_TABLE :Option <i2c::IdTable <Self ::IdInfo >> =Some (&I2C_TABLE );const OF_ID_TABLE :Option <of::IdTable <Self ::IdInfo >> =Some (&OF_TABLE );
Signature · 1 line
2.43.0