diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2026-08-19 10:42:18 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2026-08-19 10:42:18 -0700 |
| commit | 59e6295fac26b8e85c1ea859cdd89fa1e47519d7 (patch) | |
| tree | 7c071f8bab440eddbb569e84e9f31c80f8a4e529 /samples/rust | |
| parent | c6cf4441a3a05bb7273ed022f3e56c4fc591da08 (diff) | |
| parent | 3b5ea0f078e1b72276e99c237f3dfc2fd72938bb (diff) | |
| download | linux-stable-59e6295fac26b8e85c1ea859cdd89fa1e47519d7.tar.gz linux-stable-59e6295fac26b8e85c1ea859cdd89fa1e47519d7.zip | |
Merge tag 'driver-core-7.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/driver-core/driver-core
Pull driver core updates from Danilo Krummrich:
"container_of:
- Apply typeof_member(), remove the local __mptr variable to
eliminate variable shadowing warnings on nested container_of()
calls, and remove unnecessary parentheses
core:
- Add driver name to probe debug print for initcall_debug
- Avoid repeatedly printing the same 'Fixed dependency cycle' log
- Unwind device_add() on attribute creation failure in
attribute_container_add_class_device()
- Remove statistics group if encryption group creation fails in
transport_add_class_device()
debugfs:
- Fix lockdown check for mmap_prepare()
- Warn if file creation failed due to uninitialized debugfs
device property:
- Implement fw_devlink support for software nodes by adding
software_node_add_links(), which creates fwnode links from
DEV_PROP_REF properties to enable automatic probe ordering. Add
kunit-managed fwnode helpers and test coverage
- Fix infinite loop in fwnode_for_each_child_node() when the
secondary fwnode has more than one child. Add test cases
- Fix out-of-bounds access in software_node_get_reference_args() when
called with index -1 (UINT_MAX)
- Refactor to use RAII approach with __free()
- Add Bartosz Golaszewski as software node reviewer
firmware loader:
- Fix race where a sysfs fallback request can complete before being
queued as pending, leading to a use-after-free on the next fallback
request
- Reject 0-size built-in firmware and fail the build on empty
firmware files in CONFIG_EXTRA_FIRMWARE
kobject:
- Provide __KOBJ_ATTR() and __KOBJ_ATTR_RO/WO() initialization macros
and allow the constification of kobject attributes, enabling them
to reside in read-only memory
platform:
- Provide platform_device_set_of_node(), platform_device_set_fwnode(),
and platform_device_set_of_node_from_dev() helpers that encapsulate
firmware node reference counting for dynamically allocated platform
devices
Convert all in-tree users that manually assigned dev.of_node or
dev.fwnode, fixing a pre-existing refcount bug in powermac. Switch
to counting references of all firmware node types, not only OF
nodes
- Unify the release path for dynamically allocated platform devices
by removing platform_device_release_full(). Amend the fwnode setter
API contract to warn if a primary software node is overwritten. Add
KUnit tests for correct software node removal on device
unregistration
Rust:
- Auxiliary:
- Add registration_data_with() closure-based API for invariant
ForLt types
- Debugfs:
- Migrate BinaryWriter and BinaryReaderMut trait requirements
from kernel::transmute traits to zerocopy traits
- Device:
- Add BoundInternal device context and InternalBoundContext trait
for bus abstractions that need internal access to a bound
device.
- Make the lifetime on Core and CoreInternal invariant to prevent
coercion to shorter lifetimes
- Devres:
- Fix race between concurrent revokers where the losing revoker
could return before the winning revoker finished dropping the
inner data, causing use-after-free.
- Ensure revocation is complete before the device finishes
unbinding by making the synchronization bidirectional.
- Add DevresLt<F: ForLt>, a wrapper around Devres that shortens
'static back to the caller's borrow scope. Implement ForLt and
CovariantForLt for Bar, IoMem, and ExclusiveIoMem
- Driver:
- Switch from index-based to pointer-based device ID info lookup,
storing static references in driver_data. Centralize device ID
handling in device_id.rs, removing the open-coded ACPI/OF
matching logic and duplicate ID table from driver.rs
- I/O:
- Make I/O regions typed (with a dynamically-sized Region type
for the existing untyped case), create view types representing
subregions of a mapped I/O region, and add io_project!() for
safely creating subviews.
- Split Io into a base trait (IoBase) and an extension trait (Io)
with a blanket implementation, preventing implementers from
overriding provided methods that unsafe code relies on.
- Add a SysMem backend for shared system memory with volatile
access, and make Coherent implement Io via an I/O view type.
Add IoSysMap as sum type of Mmio and SysMem. Add copying
methods (memcpy_{from,to}io()) and read_val()/write_val() for
typed access.
- Replace dma_read!()/dma_write!() with io_read!()/io_write!()
for primitives and copying methods for aggregates; drop the old
macros. Convert nova-core to use I/O projection.
- Fix internal shortcut rule dispatch in the register!() macro,
remove unused rule arguments, and use path fragments for alias
destinations
- IRQ:
- Make irq::Registration compatible with lifetime-bound drivers
by removing the 'static bound on Handler/ThreadedHandler and
replacing Devres<RegistrationInner> with direct
request_irq()/free_irq() calls. Handlers can now directly own
lifetime-bound device resources
- PCI:
- Convert IrqVectorRegistration to a lifetime-annotated owning
type, giving drivers explicit control over the allocation
lifetime. IrqVector embeds a resolved IrqRequest, making the
conversion infallible. Remove the redundant
request_irq()/request_threaded_irq() wrappers from pci::Device.
- Add pci_irq_type() C helper and expose it via irq_type() on
IrqVectorRegistration and IrqVector, returning PCI_IRQ_MSIX,
PCI_IRQ_MSI, or PCI_IRQ_INTX.
- Mark pci::Device refcount methods inline
- Serdev:
- Add Rust abstractions for the serial device bus, including
serdev::Driver trait, serdev::Device wrapping struct
serdev_device, and serdev::Adapter implementing
RegistrationOps. Includes a sample driver. Markus Probst takes
over as serdev maintainer for both C and Rust code
- Misc:
- Split ForLt into a base trait (providing the Of<'a> GAT) and an
unsafe CovariantForLt subtrait guaranteeing covariance,
enabling invariant types (e.g. those containing Mutex<&'bound T>)
to participate in the ForLt abstraction.
- Fix Coherent read past EOF returning -ERANGE instead of zero.
- Fix firmware example UB by avoiding null-pointer ARef
misc:
- Avoid iattr allocation in kernfs listxattr by using
kernfs_iattrs_noalloc().
- Unregister SoC bus on early device registration failure.
- Remove unused DMA_FENCE_TRACE Kconfig symbol.
- Fix /sys/module path in comment.
- Refactor ISA bus init to remove nested blocks.
- Remove redundant nodemask clears in numa_init().
- Add kernel-doc for fwnode_operations and sys_soc.h, mark
internal property data as private for kernel-doc, and add
property.h/fwnode.h to driver-api infrastructure docs.
- Add MAINTAINERS entry for sys_soc.h"
* tag 'driver-core-7.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/driver-core/driver-core: (129 commits)
rust: pci: expose the allocated interrupt type
PCI: Add pci_irq_type() to query the allocated interrupt type
rust: pci: remove request_irq() and request_threaded_irq() from Device
rust: pci: resolve IRQ in index() and embed IrqRequest in IrqVector
rust: pci: convert IrqVectorRegistration to a lifetime-managed owning type
kernfs: avoid iattr allocation in listxattr
rust: serdev: use ThisModule::as_ptr() instead of field access
ACPI/IORT: use platform_device_set_fwnode()
ACPI/APMT: use platform_device_set_fwnode()
firmware_loader: do not queue completed sysfs fallback requests
rust: pci: Mark Device refcount methods inline
rust: irq: make Registration compatible with lifetime-bound drivers
rust: net/phy: remove expansion from doc
rust: dma: return zero for Coherent reads past EOF
rust: io: register: use path fragment for alias destination
rust: io: register: remove unused rule arguments
rust: io: register: dispatch shortcut rules internally
MAINTAINERS: add sys_soc.h to DRIVER CORE
rust: debugfs: remove unsafe blocks from traits impl for Vec
rust: debugfs: migrate debugfs traits requirements to zerocopy
...
Diffstat (limited to 'samples/rust')
| -rw-r--r-- | samples/rust/Kconfig | 11 | ||||
| -rw-r--r-- | samples/rust/Makefile | 1 | ||||
| -rw-r--r-- | samples/rust/rust_debugfs.rs | 5 | ||||
| -rw-r--r-- | samples/rust/rust_debugfs_scoped.rs | 5 | ||||
| -rw-r--r-- | samples/rust/rust_dma.rs | 25 | ||||
| -rw-r--r-- | samples/rust/rust_driver_auxiliary.rs | 96 | ||||
| -rw-r--r-- | samples/rust/rust_driver_i2c.rs | 3 | ||||
| -rw-r--r-- | samples/rust/rust_driver_pci.rs | 4 | ||||
| -rw-r--r-- | samples/rust/rust_driver_platform.rs | 2 | ||||
| -rw-r--r-- | samples/rust/rust_driver_serdev.rs | 88 | ||||
| -rw-r--r-- | samples/rust/rust_driver_usb.rs | 3 | ||||
| -rw-r--r-- | samples/rust/rust_i2c_client.rs | 2 | ||||
| -rw-r--r-- | samples/rust/rust_soc.rs | 2 |
13 files changed, 195 insertions, 52 deletions
diff --git a/samples/rust/Kconfig b/samples/rust/Kconfig index c49ab9106..31d62533e 100644 --- a/samples/rust/Kconfig +++ b/samples/rust/Kconfig @@ -161,6 +161,17 @@ config SAMPLE_RUST_DRIVER_AUXILIARY If unsure, say N. +config SAMPLE_RUST_DRIVER_SERDEV + tristate "Serial Device Bus Device Driver" + select RUST_SERIAL_DEV_BUS_ABSTRACTIONS + help + This option builds the Rust serial device bus driver sample. + + To compile this as a module, choose M here: + the module will be called rust_driver_serdev. + + If unsure, say N. + config SAMPLE_RUST_SOC tristate "SoC Driver" select SOC_BUS diff --git a/samples/rust/Makefile b/samples/rust/Makefile index 6c0aaa58c..b986b681c 100644 --- a/samples/rust/Makefile +++ b/samples/rust/Makefile @@ -14,6 +14,7 @@ obj-$(CONFIG_SAMPLE_RUST_DRIVER_PLATFORM) += rust_driver_platform.o obj-$(CONFIG_SAMPLE_RUST_DRIVER_USB) += rust_driver_usb.o obj-$(CONFIG_SAMPLE_RUST_DRIVER_FAUX) += rust_driver_faux.o obj-$(CONFIG_SAMPLE_RUST_DRIVER_AUXILIARY) += rust_driver_auxiliary.o +obj-$(CONFIG_SAMPLE_RUST_DRIVER_SERDEV) += rust_driver_serdev.o obj-$(CONFIG_SAMPLE_RUST_CONFIGFS) += rust_configfs.o obj-$(CONFIG_SAMPLE_RUST_SOC) += rust_soc.o diff --git a/samples/rust/rust_debugfs.rs b/samples/rust/rust_debugfs.rs index 1f59e08aa..77c19a437 100644 --- a/samples/rust/rust_debugfs.rs +++ b/samples/rust/rust_debugfs.rs @@ -110,7 +110,6 @@ impl FromStr for Inner { kernel::acpi_device_table!( ACPI_TABLE, - MODULE_ACPI_TABLE, <RustDebugFs as platform::Driver>::IdInfo, [(acpi::DeviceId::new(c"LNUXBEEF"), ())] ); @@ -147,7 +146,9 @@ impl RustDebugFs { dir.read_write_file(c"pair", new_mutex!(Inner { x: 3, y: 10 })) } - fn new<'a>(pdev: &'a platform::Device<Core<'_>>) -> impl PinInit<Self, Error> + 'a { + fn new<'a, 'b>( + pdev: &'a platform::Device<Core<'b>>, + ) -> impl PinInit<Self, Error> + use<'a, 'b> { let debugfs = Dir::new(c"sample_debugfs"); let dev = pdev.as_ref(); diff --git a/samples/rust/rust_debugfs_scoped.rs b/samples/rust/rust_debugfs_scoped.rs index 6a575a15a..ca2b154be 100644 --- a/samples/rust/rust_debugfs_scoped.rs +++ b/samples/rust/rust_debugfs_scoped.rs @@ -75,7 +75,10 @@ fn create_file_write( GFP_KERNEL, )?; } - let blob = KBox::pin_init(new_mutex!([0x42; SZ_4K]), GFP_KERNEL)?; + let blob = KBox::pin_init( + new_mutex!(pin_init::init_array_from_fn(|_| 0x42)), + GFP_KERNEL, + )?; let scope = KBox::pin_init( mod_data.device_dir.scope( diff --git a/samples/rust/rust_dma.rs b/samples/rust/rust_dma.rs index 5046b4628..bd60034de 100644 --- a/samples/rust/rust_dma.rs +++ b/samples/rust/rust_dma.rs @@ -12,10 +12,19 @@ use kernel::{ Device, DmaMask, // }, - page, pci, + io::{ + io_project, + io_read, + Io, // + }, + page, + pci, prelude::*, - scatterlist::{Owned, SGTable}, - sync::aref::ARef, + scatterlist::{ + Owned, + SGTable, // + }, + sync::aref::ARef, // }; #[pin_data(PinnedDrop)] @@ -34,6 +43,7 @@ const TEST_VALUES: [(u32, u32); 5] = [ (0xcd, 0xef), ]; +#[derive(FromBytes, IntoBytes)] struct MyStruct { h: u32, b: u32, @@ -51,7 +61,6 @@ unsafe impl kernel::transmute::FromBytes for MyStruct {} kernel::pci_device_table!( PCI_TABLE, - MODULE_PCI_TABLE, <DmaSampleDriver as pci::Driver>::IdInfo, [(pci::DeviceId::from_id(pci::Vendor::REDHAT, 0x5), ())] ); @@ -63,7 +72,7 @@ impl pci::Driver for DmaSampleDriver { fn probe<'bound>( pdev: &'bound pci::Device<Core<'_>>, - _info: &'bound Self::IdInfo, + _info: Option<&'bound Self::IdInfo>, ) -> impl PinInit<Self, Error> + 'bound { pin_init::pin_init_scope(move || { dev_info!(pdev, "Probe DMA test driver.\n"); @@ -77,7 +86,7 @@ impl pci::Driver for DmaSampleDriver { Coherent::zeroed_slice(pdev.as_ref(), TEST_VALUES.len(), GFP_KERNEL)?; for (i, value) in TEST_VALUES.into_iter().enumerate() { - kernel::dma_write!(ca, [try: i], MyStruct::new(value.0, value.1)); + io_project!(ca, [panic: i]).copy_write(MyStruct::new(value.0, value.1)); } let size = 4 * page::PAGE_SIZE; @@ -97,8 +106,8 @@ impl pci::Driver for DmaSampleDriver { impl DmaSampleDriver { fn check_dma(&self) { for (i, value) in TEST_VALUES.into_iter().enumerate() { - let val0 = kernel::dma_read!(self.ca, [panic: i].h); - let val1 = kernel::dma_read!(self.ca, [panic: i].b); + let val0 = io_read!(self.ca, [panic: i].h); + let val1 = io_read!(self.ca, [panic: i].b); assert_eq!(val0, value.0); assert_eq!(val1, value.1); diff --git a/samples/rust/rust_driver_auxiliary.rs b/samples/rust/rust_driver_auxiliary.rs index 2c1351040..0bee16fae 100644 --- a/samples/rust/rust_driver_auxiliary.rs +++ b/samples/rust/rust_driver_auxiliary.rs @@ -11,20 +11,26 @@ use kernel::{ Core, // }, driver, + new_mutex, pci, prelude::*, - types::ForLt, + sync::Mutex, + types::{ + CovariantForLt, + ForLt, // + }, InPlaceModule, // }; const MODULE_NAME: &CStr = <LocalModule as kernel::ModuleMetadata>::NAME; const AUXILIARY_NAME: &CStr = c"auxiliary"; +const COVARIANT_DEV_ID: u32 = 0; +const INVARIANT_DEV_ID: u32 = 1; struct AuxiliaryDriver; kernel::auxiliary_device_table!( AUX_TABLE, - MODULE_AUX_TABLE, <AuxiliaryDriver as auxiliary::Driver>::IdInfo, [(auxiliary::DeviceId::new(MODULE_NAME, AUXILIARY_NAME), ())] ); @@ -56,17 +62,30 @@ struct Data<'bound> { parent: &'bound pci::Device<Bound>, } +/// Registration data with interior mutability. +/// +/// `Mutex<&'bound T>` is invariant over `'bound`, so this type cannot implement +/// [`CovariantForLt`](trait@CovariantForLt). Access must go through the closure-based +/// [`auxiliary::Device::registration_data_with()`]. +#[pin_data] +struct MutexData<'bound> { + #[pin] + parent: Mutex<&'bound pci::Device<Bound>>, + index: u32, +} + struct ParentDriver; #[allow(clippy::type_complexity)] +#[pin_data] struct ParentData<'bound> { - _reg0: auxiliary::Registration<'bound, ForLt!(Data<'_>)>, - _reg1: auxiliary::Registration<'bound, ForLt!(Data<'_>)>, + _reg0: auxiliary::Registration<'bound, CovariantForLt!(Data<'_>)>, + #[pin] + _reg1: auxiliary::Registration<'bound, ForLt!(MutexData<'_>)>, } kernel::pci_device_table!( PCI_TABLE, - MODULE_PCI_TABLE, <ParentDriver as pci::Driver>::IdInfo, [(pci::DeviceId::from_id(pci::Vendor::REDHAT, 0x5), ())] ); @@ -79,19 +98,19 @@ impl pci::Driver for ParentDriver { fn probe<'bound>( pdev: &'bound pci::Device<Core<'_>>, - _info: &'bound Self::IdInfo, + _info: Option<&'bound Self::IdInfo>, ) -> impl PinInit<Self::Data<'bound>, Error> + 'bound { - Ok(ParentData { + try_pin_init!(ParentData { // SAFETY: `ParentData` is the driver's private data, which is dropped when the // device is unbound; i.e. `mem::forget()` is never called on it. _reg0: unsafe { auxiliary::Registration::new_with_lt( pdev.as_ref(), AUXILIARY_NAME, - 0, + COVARIANT_DEV_ID, MODULE_NAME, Data { - index: 0, + index: COVARIANT_DEV_ID, parent: pdev, }, )? @@ -101,12 +120,16 @@ impl pci::Driver for ParentDriver { auxiliary::Registration::new_with_lt( pdev.as_ref(), AUXILIARY_NAME, - 1, + INVARIANT_DEV_ID, MODULE_NAME, - Data { - index: 1, - parent: pdev, - }, + pin_init!(MutexData { + parent <- { + let pdev: &pci::Device<Bound> = pdev; + + new_mutex!(pdev) + }, + index: INVARIANT_DEV_ID, + }), )? }, }) @@ -115,22 +138,39 @@ impl pci::Driver for ParentDriver { impl ParentDriver { fn connect(adev: &auxiliary::Device<Bound>) -> Result { - let data = adev.registration_data::<ForLt!(Data<'_>)>()?; - let pdev = data.parent; + match adev.id() { + // CovariantForLt types can use the direct-reference accessor. + COVARIANT_DEV_ID => { + let data = adev.registration_data::<CovariantForLt!(Data<'_>)>()?; + let pdev = data.parent; - dev_info!( - pdev, - "Connect auxiliary {} with parent: VendorID={}, DeviceID={:#x}\n", - adev.id(), - pdev.vendor_id(), - pdev.device_id() - ); + dev_info!( + pdev, + "Connect auxiliary {} with parent: VendorID={}, DeviceID={:#x}\n", + adev.id(), + pdev.vendor_id(), + pdev.device_id() + ); - dev_info!( - pdev, - "Connected to auxiliary device with index {}.\n", - data.index - ); + dev_info!( + pdev, + "Connected to auxiliary device with index {}.\n", + data.index + ); + } + // Invariant ForLt types (e.g. containing a Mutex) require the closure-based accessor. + INVARIANT_DEV_ID => { + adev.registration_data_with::<ForLt!(MutexData<'_>), _>(|data| { + let pdev = *data.parent.lock(); + dev_info!( + pdev, + "Connected to auxiliary device with index {} (via Mutex).\n", + data.index + ); + })?; + } + _ => return Err(EINVAL), + } Ok(()) } diff --git a/samples/rust/rust_driver_i2c.rs b/samples/rust/rust_driver_i2c.rs index ead8263a7..a0df0c609 100644 --- a/samples/rust/rust_driver_i2c.rs +++ b/samples/rust/rust_driver_i2c.rs @@ -14,21 +14,18 @@ struct SampleDriver; kernel::acpi_device_table! { ACPI_TABLE, - MODULE_ACPI_TABLE, <SampleDriver as i2c::Driver>::IdInfo, [(acpi::DeviceId::new(c"LNUXBEEF"), 0)] } kernel::i2c_device_table! { I2C_TABLE, - MODULE_I2C_TABLE, <SampleDriver as i2c::Driver>::IdInfo, [(i2c::DeviceId::new(c"rust_driver_i2c"), 0)] } kernel::of_device_table! { OF_TABLE, - MODULE_OF_TABLE, <SampleDriver as i2c::Driver>::IdInfo, [(of::DeviceId::new(c"test,rust_driver_i2c"), 0)] } diff --git a/samples/rust/rust_driver_pci.rs b/samples/rust/rust_driver_pci.rs index 1aa8197d8..2282191e6 100644 --- a/samples/rust/rust_driver_pci.rs +++ b/samples/rust/rust_driver_pci.rs @@ -74,7 +74,6 @@ struct SampleDriver; kernel::pci_device_table!( PCI_TABLE, - MODULE_PCI_TABLE, <SampleDriver as pci::Driver>::IdInfo, [( pci::DeviceId::from_id(pci::Vendor::REDHAT, 0x5), @@ -144,7 +143,7 @@ impl pci::Driver for SampleDriver { fn probe<'bound>( pdev: &'bound pci::Device<Core<'_>>, - info: &'bound Self::IdInfo, + info: Option<&'bound Self::IdInfo>, ) -> impl PinInit<Self::Data<'bound>, Error> + 'bound { let vendor = pdev.vendor_id(); dev_dbg!( @@ -153,6 +152,7 @@ impl pci::Driver for SampleDriver { vendor, pdev.device_id() ); + let info = info.ok_or(ENODEV)?; pdev.enable_device_mem()?; pdev.set_master(); diff --git a/samples/rust/rust_driver_platform.rs b/samples/rust/rust_driver_platform.rs index ec0d6cac4..710145b36 100644 --- a/samples/rust/rust_driver_platform.rs +++ b/samples/rust/rust_driver_platform.rs @@ -87,14 +87,12 @@ struct Info(u32); kernel::of_device_table!( OF_TABLE, - MODULE_OF_TABLE, <SampleDriver as platform::Driver>::IdInfo, [(of::DeviceId::new(c"test,rust-device"), Info(42))] ); kernel::acpi_device_table!( ACPI_TABLE, - MODULE_ACPI_TABLE, <SampleDriver as platform::Driver>::IdInfo, [(acpi::DeviceId::new(c"LNUXBEEF"), Info(0))] ); diff --git a/samples/rust/rust_driver_serdev.rs b/samples/rust/rust_driver_serdev.rs new file mode 100644 index 000000000..51b4898cd --- /dev/null +++ b/samples/rust/rust_driver_serdev.rs @@ -0,0 +1,88 @@ +// SPDX-License-Identifier: GPL-2.0 + +//! Rust Serial device bus device driver sample. + +use kernel::{ + acpi, + device::{ + Bound, + Core, // + }, + of, + prelude::*, + serdev, + sync::aref::ARef, // +}; + +struct SampleDriver { + sdev: ARef<serdev::Device>, +} + +kernel::of_device_table!( + OF_TABLE, + <SampleDriver as serdev::Driver>::IdInfo, + [(of::DeviceId::new(c"test,rust_driver_serdev"), ())] +); + +kernel::acpi_device_table!( + ACPI_TABLE, + <SampleDriver as serdev::Driver>::IdInfo, + [(acpi::DeviceId::new(c"LNUXBEEF"), ())] +); + +#[vtable] +impl serdev::Driver for SampleDriver { + type IdInfo = (); + type Data<'bound> = Self; + 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<'bound>( + sdev: &'bound serdev::Device<Core<'_>>, + _info: Option<&'bound Self::IdInfo>, + ) -> impl PinInit<Self, Error> + 'bound { + let dev = sdev.as_ref(); + + dev_dbg!(dev, "Probe Rust Serial device bus device driver sample.\n"); + + if sdev + .set_baudrate( + dev.fwnode() + .and_then(|fwnode| fwnode.property_read(c"baudrate").optional()) + .unwrap_or(115200), + ) + .is_err() + { + return Err(EINVAL); + } + sdev.set_flow_control(false); + sdev.set_parity(serdev::Parity::None)?; + + Ok(Self { sdev: sdev.into() }) + } + + fn receive<'bound>( + sdev: &'bound serdev::Device<Bound>, + _this: Pin<&Self>, + data: &[u8], + ) -> usize { + sdev.write(data).unwrap_or_default() as usize + } +} + +impl Drop for SampleDriver { + fn drop(&mut self) { + dev_dbg!( + self.sdev.as_ref(), + "Remove Rust Serial device bus device driver sample.\n" + ); + } +} + +kernel::module_serdev_device_driver! { + type: SampleDriver, + name: "rust_driver_serdev", + authors: ["Markus Probst"], + description: "Rust Serial device bus device driver", + license: "GPL v2", +} diff --git a/samples/rust/rust_driver_usb.rs b/samples/rust/rust_driver_usb.rs index 02bd5085f..7ef04e177 100644 --- a/samples/rust/rust_driver_usb.rs +++ b/samples/rust/rust_driver_usb.rs @@ -19,7 +19,6 @@ struct SampleDriver { kernel::usb_device_table!( USB_TABLE, - MODULE_USB_TABLE, <SampleDriver as usb::Driver>::IdInfo, [(usb::DeviceId::from_id(0x1234, 0x5678), ()),] ); @@ -32,7 +31,7 @@ impl usb::Driver for SampleDriver { fn probe<'bound>( intf: &'bound usb::Interface<Core<'_>>, _id: &usb::DeviceId, - _info: &'bound Self::IdInfo, + _info: Option<&'bound Self::IdInfo>, ) -> impl PinInit<Self, Error> + 'bound { let dev: &device::Device<Core<'_>> = intf.as_ref(); dev_info!(dev, "Rust USB driver sample probed\n"); diff --git a/samples/rust/rust_i2c_client.rs b/samples/rust/rust_i2c_client.rs index 2d876f4e3..c8a23875e 100644 --- a/samples/rust/rust_i2c_client.rs +++ b/samples/rust/rust_i2c_client.rs @@ -87,14 +87,12 @@ struct SampleDriver { kernel::of_device_table!( OF_TABLE, - MODULE_OF_TABLE, <SampleDriver as platform::Driver>::IdInfo, [(of::DeviceId::new(c"test,rust-device"), ())] ); kernel::acpi_device_table!( ACPI_TABLE, - MODULE_ACPI_TABLE, <SampleDriver as platform::Driver>::IdInfo, [(acpi::DeviceId::new(c"LNUXBEEF"), ())] ); diff --git a/samples/rust/rust_soc.rs b/samples/rust/rust_soc.rs index 808d58200..f5e5f2f9a 100644 --- a/samples/rust/rust_soc.rs +++ b/samples/rust/rust_soc.rs @@ -23,14 +23,12 @@ struct SampleSocDriver { kernel::of_device_table!( OF_TABLE, - MODULE_OF_TABLE, <SampleSocDriver as platform::Driver>::IdInfo, [(of::DeviceId::new(c"test,rust-device"), ())] ); kernel::acpi_device_table!( ACPI_TABLE, - MODULE_ACPI_TABLE, <SampleSocDriver as platform::Driver>::IdInfo, [(acpi::DeviceId::new(c"LNUXBEEF"), ())] ); |
