diff options
| author | Mark Brown <broonie@kernel.org> | 2026-01-28 11:22:06 +0000 |
|---|---|---|
| committer | Mark Brown <broonie@kernel.org> | 2026-01-28 11:22:06 +0000 |
| commit | 751ec6dd6773237bf480291ca894a696a2991c62 (patch) | |
| tree | 6ac1b53826f7836b3f7b29f3f17bb45d118535c0 /rust/kernel/usb.rs | |
| parent | e540be7d56d740144b1bd6f220b61ffe2f3830d4 (diff) | |
| parent | 04f7516ab70f7b82aae1d2830af2ee6f17f3fe98 (diff) | |
spi: aspeed: Improve handling of shared SPI
Merge series from Chin-Ting Kuo <chin-ting_kuo@aspeedtech.com>:
This patch series improves handling of SPI controllers that are
shared by spi-mem devices and other SPI peripherals.
The primary goal of this series is to support non-spi-mem devices in
the ASPEED FMC/SPI controller driver. It also addresses an issue in
the spi-mem framework observed when different types of SPI devices
operate concurrently on the same controller, ensuring that spi-mem
operations are properly serialized.
Diffstat (limited to 'rust/kernel/usb.rs')
| -rw-r--r-- | rust/kernel/usb.rs | 27 |
1 files changed, 18 insertions, 9 deletions
diff --git a/rust/kernel/usb.rs b/rust/kernel/usb.rs index d10b65e9fb6a..67ce5c85c619 100644 --- a/rust/kernel/usb.rs +++ b/rust/kernel/usb.rs @@ -27,13 +27,22 @@ use core::{ /// An adapter for the registration of USB drivers. pub struct Adapter<T: Driver>(T); -// SAFETY: A call to `unregister` for a given instance of `RegType` is guaranteed to be valid if +// SAFETY: +// - `bindings::usb_driver` is a C type declared as `repr(C)`. +// - `T` is the type of the driver's device private data. +// - `struct usb_driver` embeds a `struct device_driver`. +// - `DEVICE_DRIVER_OFFSET` is the correct byte offset to the embedded `struct device_driver`. +unsafe impl<T: Driver + 'static> driver::DriverLayout for Adapter<T> { + type DriverType = bindings::usb_driver; + type DriverData = T; + const DEVICE_DRIVER_OFFSET: usize = core::mem::offset_of!(Self::DriverType, driver); +} + +// SAFETY: A call to `unregister` for a given instance of `DriverType` is guaranteed to be valid if // a preceding call to `register` has been successful. unsafe impl<T: Driver + 'static> driver::RegistrationOps for Adapter<T> { - type RegType = bindings::usb_driver; - unsafe fn register( - udrv: &Opaque<Self::RegType>, + udrv: &Opaque<Self::DriverType>, name: &'static CStr, module: &'static ThisModule, ) -> Result { @@ -45,14 +54,14 @@ unsafe impl<T: Driver + 'static> driver::RegistrationOps for Adapter<T> { (*udrv.get()).id_table = T::ID_TABLE.as_ptr(); } - // SAFETY: `udrv` is guaranteed to be a valid `RegType`. + // SAFETY: `udrv` is guaranteed to be a valid `DriverType`. to_result(unsafe { bindings::usb_register_driver(udrv.get(), module.0, name.as_char_ptr()) }) } - unsafe fn unregister(udrv: &Opaque<Self::RegType>) { - // SAFETY: `udrv` is guaranteed to be a valid `RegType`. + unsafe fn unregister(udrv: &Opaque<Self::DriverType>) { + // SAFETY: `udrv` is guaranteed to be a valid `DriverType`. unsafe { bindings::usb_deregister(udrv.get()) }; } } @@ -94,9 +103,9 @@ impl<T: Driver + 'static> Adapter<T> { // SAFETY: `disconnect_callback` is only ever called after a successful call to // `probe_callback`, hence it's guaranteed that `Device::set_drvdata()` has been called // and stored a `Pin<KBox<T>>`. - let data = unsafe { dev.drvdata_obtain::<T>() }; + let data = unsafe { dev.drvdata_borrow::<T>() }; - T::disconnect(intf, data.as_ref()); + T::disconnect(intf, data); } } |
