diff options
author | Mark Brown <broonie@kernel.org> | 2025-01-08 02:28:07 +0300 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2025-01-08 02:28:07 +0300 |
commit | d406b354df909155ff0122acf80f3bc7410fa27e (patch) | |
tree | 0cd68849c0c36fcf9e48ba71a9c0464b65297082 /rust/kernel/workqueue.rs | |
parent | eb708cd631a8dca17ff004ccc39bbeb096c1db22 (diff) | |
parent | 5bc493bf0c37c157bf2eb364e55a1c6f8bc43a69 (diff) | |
download | linux-d406b354df909155ff0122acf80f3bc7410fa27e.tar.xz |
Expand SoundWire MBQ register map support
Merge series from Charles Keepax <ckeepax@opensource.cirrus.com>:
The current SDCA MBQ (Multi-Byte Quantities) register map only
supports 16-bit types, add support for more sizes and then update
the rt722 driver to use the new support. We also add support for
the deferring feature of MBQs to allow hardware to indicate it is
not currently ready to service a read/write.
Afraid I don't have hardware to test the rt722 change so it is
only build tested, but I thought it good to include a change to
demonstrate the new features in use.
Diffstat (limited to 'rust/kernel/workqueue.rs')
-rw-r--r-- | rust/kernel/workqueue.rs | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/rust/kernel/workqueue.rs b/rust/kernel/workqueue.rs index 4d1d2062f6eb..fd3e97192ed8 100644 --- a/rust/kernel/workqueue.rs +++ b/rust/kernel/workqueue.rs @@ -519,7 +519,15 @@ impl_has_work! { impl{T} HasWork<Self> for ClosureWork<T> { self.work } } -// SAFETY: TODO. +// SAFETY: The `__enqueue` implementation in RawWorkItem uses a `work_struct` initialized with the +// `run` method of this trait as the function pointer because: +// - `__enqueue` gets the `work_struct` from the `Work` field, using `T::raw_get_work`. +// - The only safe way to create a `Work` object is through `Work::new`. +// - `Work::new` makes sure that `T::Pointer::run` is passed to `init_work_with_key`. +// - Finally `Work` and `RawWorkItem` guarantee that the correct `Work` field +// will be used because of the ID const generic bound. This makes sure that `T::raw_get_work` +// uses the correct offset for the `Work` field, and `Work::new` picks the correct +// implementation of `WorkItemPointer` for `Arc<T>`. unsafe impl<T, const ID: u64> WorkItemPointer<ID> for Arc<T> where T: WorkItem<ID, Pointer = Self>, @@ -537,7 +545,13 @@ where } } -// SAFETY: TODO. +// SAFETY: The `work_struct` raw pointer is guaranteed to be valid for the duration of the call to +// the closure because we get it from an `Arc`, which means that the ref count will be at least 1, +// and we don't drop the `Arc` ourselves. If `queue_work_on` returns true, it is further guaranteed +// to be valid until a call to the function pointer in `work_struct` because we leak the memory it +// points to, and only reclaim it if the closure returns false, or in `WorkItemPointer::run`, which +// is what the function pointer in the `work_struct` must be pointing to, according to the safety +// requirements of `WorkItemPointer`. unsafe impl<T, const ID: u64> RawWorkItem<ID> for Arc<T> where T: WorkItem<ID, Pointer = Self>, |