[PATCH v25 2/4] rust: leds: add Mode trait
From: Markus Probst <markus.probst@posteo.de>
Date: 2026-09-13 16:15:32
Also in:
linux-leds, linux-pci, lkml
Subsystem:
rust, the rest · Maintainers:
Miguel Ojeda, Linus Torvalds
Add the `led::Mode` trait to allow for other types of led class devices in `led::LedOps`. Signed-off-by: Markus Probst <markus.probst@posteo.de> --- rust/kernel/led.rs | 37 ++++++++++++++++++++++++++----------- rust/kernel/led/normal.rs | 12 ++++++++++-- 2 files changed, 36 insertions(+), 13 deletions(-)
diff --git a/rust/kernel/led.rs b/rust/kernel/led.rs
index deda8cc548a8..7cd8f0504649 100644
--- a/rust/kernel/led.rs
+++ b/rust/kernel/led.rs@@ -4,11 +4,7 @@ //! //! C header: [`include/linux/leds.h`](srctree/include/linux/leds.h) -use core::{ - marker::PhantomData, - mem::transmute, - ptr::NonNull, // -}; +use core::{marker::PhantomData, mem::transmute, ops::Deref, ptr::NonNull}; use crate::{ container_of,
@@ -31,7 +27,10 @@ mod normal; -pub use normal::Device; +pub use normal::{ + Device, + Normal, // +}; /// The name of the led is determined by the driver. pub enum Named {}
@@ -156,6 +155,7 @@ pub fn name(self, name: &'init CStr) -> Self { /// /// #[vtable] /// impl led::LedOps for MyLedOps { +/// type Mode = led::Normal; /// const BLOCKING: bool = false; /// const MAX_BRIGHTNESS: u32 = 255; ///
@@ -176,16 +176,21 @@ pub trait LedOps: Send + Sync + Sized { const BLOCKING: bool; /// The max brightness level. const MAX_BRIGHTNESS: u32; - /// Sets the brightness level. /// /// See also [`LedOps::BLOCKING`]. - fn brightness_set<'bound>(self: &Device<'bound, Self>, brightness: u32) -> Result<()>; - + fn brightness_set<'bound>( + self: &<Self::Mode as Mode>::Device<'bound, Self>, + brightness: u32, + ) -> Result<()>; /// Gets the current brightness level. - fn brightness_get<'bound>(self: &Device<'bound, Self>) -> Result<u32> { + fn brightness_get<'bound>(self: &<Self::Mode as Mode>::Device<'bound, Self>) -> Result<u32> { build_error!(VTABLE_DEFAULT_ERROR) } + /// The led mode to use. + /// + /// See [`Mode`]. + type Mode: Mode; /// Activates hardware accelerated blinking. ///
@@ -196,7 +201,7 @@ fn brightness_get<'bound>(self: &Device<'bound, Self>) -> Result<u32> { /// /// See also [`LedOps::BLOCKING`]. fn blink_set<'bound>( - self: &Device<'bound, Self>, + self: &<Self::Mode as Mode>::Device<'bound, Self>, delay_on: &mut usize, delay_off: &mut usize, ) -> Result<()> {
@@ -260,6 +265,16 @@ fn try_from(value: u32) -> core::result::Result<Self, Self::Error> { } } +/// The led mode. +/// +/// Each led mode has its own led class device type with different capabilities. +/// +/// See [`Normal`]. +pub trait Mode: private::Sealed { + /// The class device for the led mode. + type Device<'bound, T: LedOps<Mode = Self> + 'bound>: Deref<Target = T>; +} + mod private { pub trait Sealed {} }
diff --git a/rust/kernel/led/normal.rs b/rust/kernel/led/normal.rs
index a22c29cfd262..992353319522 100644
--- a/rust/kernel/led/normal.rs
+++ b/rust/kernel/led/normal.rs@@ -8,6 +8,14 @@ use super::*; +/// The led mode for the `struct led_classdev`. Leds with this mode can only have a fixed color. +pub enum Normal {} + +impl Mode for Normal { + type Device<'bound, T: LedOps<Mode = Self> + 'bound> = Device<'bound, T>; +} +impl private::Sealed for Normal {} + /// The led class device representation. /// /// This structure represents the Rust abstraction for a led class device.
@@ -22,7 +30,7 @@ pub struct Device<'bound, T: 'bound = ()> { impl<'init, S: DeviceBuilderState> DeviceBuilder<'init, S> { /// Registers a new [`Device`]. - pub fn build<'bound: 'init, T: LedOps + 'bound>( + pub fn build<'bound: 'init, T: LedOps<Mode = Normal> + 'bound>( self, parent: &'bound device::Device<Bound>, ops: impl PinInit<T, Error> + 'init,
@@ -120,7 +128,7 @@ struct Adapter<T: LedOps> { _p: PhantomData<T>, } -impl<T: LedOps> Adapter<T> { +impl<T: LedOps<Mode = Normal>> Adapter<T> { /// # Safety /// `led_cdev` must be a valid pointer to a `led_classdev` embedded within a /// `led::Device`.
--
2.55.0