From: Igor Korotin <igor.korotin.linux@gmail.com>
To: Daniel Almeida <daniel.almeida@collabora.com>
Cc: "Miguel Ojeda" <ojeda@kernel.org>,
"Alex Gaynor" <alex.gaynor@gmail.com>,
"Boqun Feng" <boqun.feng@gmail.com>,
"Gary Guo" <gary@garyguo.net>,
"Björn Roy Baron" <bjorn3_gh@protonmail.com>,
"Benno Lossin" <lossin@kernel.org>,
"Andreas Hindborg" <a.hindborg@kernel.org>,
"Alice Ryhl" <aliceryhl@google.com>,
"Trevor Gross" <tmgross@umich.edu>,
"Danilo Krummrich" <dakr@kernel.org>,
rust-for-linux@vger.kernel.org
Subject: Re: [PATCH v3 1/3] rust: i2c: add basic I2C device and driver abstractions
Date: Mon, 4 Aug 2025 15:16:57 +0100 [thread overview]
Message-ID: <ff90c4d7-733a-4d76-a939-b460d66389bc@gmail.com> (raw)
In-Reply-To: <F8F4578D-9095-48D4-BC21-67177F2DDD6F@collabora.com>
Hello Daniel
Thank you for the review.
On 8/1/25 18:14, Daniel Almeida wrote:
>> +
>> + Self(i2c)
>> + }
>> +}
>> +
>> +// SAFETY: `DeviceId` is a `#[repr(transparent)]` wrapper of `i2c_device_id` and does not add
>> +// additional invariants, so it's safe to transmute to `RawType`.
>> +unsafe impl RawDeviceId for DeviceId {
>> + type RawType = bindings::i2c_device_id;
>> +}
>> +
>> +// SAFETY: `DRIVER_DATA_OFFSET` is the offset to the `driver_data` field.
>> +unsafe impl RawDeviceIdIndex for DeviceId {
>> + const DRIVER_DATA_OFFSET: usize = core::mem::offset_of!(bindings::i2c_device_id, driver_data);
>> +
>> + fn index(&self) -> usize {
>> + self.0.driver_data as _
>> + }
>> +}
>> +
>> +/// IdTable type for I2C
>> +pub type IdTable<T> = &'static dyn kernel::device_id::IdTable<DeviceId, T>;
>> +
>> +/// Create a I2C `IdTable` with its alias for modpost.
>> +#[macro_export]
>> +macro_rules! i2c_device_table {
>> + ($table_name:ident, $module_table_name:ident, $id_info_type: ty, $table_data: expr) => {
>> + const $table_name: $crate::device_id::IdArray<
>> + $crate::i2c::DeviceId,
>> + $id_info_type,
>> + { $table_data.len() },
>> + > = $crate::device_id::IdArray::new($table_data);
>> +
>> + $crate::module_device_table!("i2c", $module_table_name, $table_name);
>> + };
>> +}
>> +
>> +/// An adapter for the registration of I2C drivers.
>> +pub struct Adapter<T: Driver>(T);
>> +
>> +// SAFETY: A call to `unregister` for a given instance of `RegType` 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::i2c_driver;
>> +
>> + unsafe fn register(
>> + pdrv: &Opaque<Self::RegType>,
>> + name: &'static CStr,
>> + module: &'static ThisModule,
>> + ) -> Result {
>> + let i2c_table = match T::I2C_ID_TABLE {
>> + Some(table) => table.as_ptr(),
>> + None => core::ptr::null(),
>> + };
>> +
>> + let of_table = match T::OF_ID_TABLE {
>> + Some(table) => table.as_ptr(),
>> + None => core::ptr::null(),
>> + };
>> +
>> + let acpi_table = match T::ACPI_ID_TABLE {
>> + Some(table) => table.as_ptr(),
>> + None => core::ptr::null(),
>> + };
>
> I wonder what happens if these are all None?
>
C code in the i2c_register_driver function doesn't require id_table, OF
table, or ACPI table to be non-NULL. Technically, there's no issue
registering such an I2C driver. Though there's the following code in
i2c_device_probe:
/*
* An I2C ID table is not mandatory, if and only if, a suitable OF
* or ACPI ID table is supplied for the probing device.
*/
if (!driver->id_table &&
!acpi_driver_match_device(dev, dev->driver) &&
!i2c_of_match_device(dev->driver->of_match_table, client)) {
status = -ENODEV;
goto put_sync_adapter;
}
Based on that, maybe it makes sense to add some kind of
compile-time/build-time assertion to make sure the developer defines at
least one of those tables. If so, I'm happy to think about how to
implement something like that.
>> +
>> + // SAFETY: It's safe to set the fields of `struct i2c_client` on initialization.
>> + unsafe {
>> + (*pdrv.get()).driver.name = name.as_char_ptr();
>> + (*pdrv.get()).probe = Some(Self::probe_callback);
>> + (*pdrv.get()).remove = Some(Self::remove_callback);
>> + (*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`.
>> + to_result(unsafe { bindings::i2c_register_driver(module.0, pdrv.get()) })
>> + }
>> +
>> + unsafe fn unregister(pdrv: &Opaque<Self::RegType>) {
>> + // SAFETY: `pdrv` is guaranteed to be a valid `RegType`.
>> + unsafe { bindings::i2c_del_driver(pdrv.get()) }
>> + }
>> +}
>> +
>> +impl<T: Driver + 'static> Adapter<T> {
>> + extern "C" fn probe_callback(pdev: *mut bindings::i2c_client) -> kernel::ffi::c_int {
>
> Nit: throughout the file: I think that pdev comes either from pci or platform
> devices? Maybe a different variable name should be used?
>
To be honest, I always thought pdev/pdrv/etc just meant "pointer to
device"/"pointer to driver" and not necessarily PCI/platform. If it
actually implies platform/PCI, then yeah, I agree — better to use
something like idev/idrv, as Danilo also pointed out.
>> + // - `dev` is guaranteed to be valid while it's alive, and so is `pdev.as_ref().as_raw()`.
>> + let raw_id = unsafe { bindings::i2c_match_id(table.as_ptr(), dev.as_raw()) };
>
> Wait, where’s `pdev.as_ref().as_raw()` here?
>
Yeah, good catch. There was a significant rework between v2 and v3, and
I didn’t clean up all the comments properly. My bad.
Noted all the other comments too — I’ll fix those in the next drop.
Best Regards
Igor
next prev parent reply other threads:[~2025-08-04 14:19 UTC|newest]
Thread overview: 39+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-08-01 15:37 [PATCH v3 0/3] rust: i2c: Add basic I2C driver abstractions Igor Korotin
2025-08-01 15:40 ` [PATCH v3 1/3] rust: i2c: add basic I2C device and " Igor Korotin
2025-08-01 17:14 ` Daniel Almeida
2025-08-02 0:22 ` Danilo Krummrich
2025-08-04 14:16 ` Igor Korotin [this message]
2025-08-02 0:00 ` Danilo Krummrich
2025-08-02 9:07 ` Wolfram Sang
2025-08-02 10:51 ` Danilo Krummrich
2025-08-02 12:14 ` Wolfram Sang
2025-08-02 12:41 ` Danilo Krummrich
2025-08-04 14:58 ` Igor Korotin
2025-08-04 15:17 ` Danilo Krummrich
2025-08-04 15:24 ` Miguel Ojeda
2025-08-04 15:40 ` Igor Korotin
2025-08-04 16:11 ` Wolfram Sang
2025-08-04 17:15 ` Danilo Krummrich
2025-08-04 22:01 ` Wolfram Sang
2025-08-05 8:37 ` Igor Korotin
2025-08-05 9:28 ` Wolfram Sang
2025-08-05 12:40 ` Daniel Almeida
2025-08-04 17:26 ` Igor Korotin
2025-08-04 17:46 ` Miguel Ojeda
2025-08-04 21:57 ` Wolfram Sang
2025-08-15 15:40 ` Igor Korotin
2025-08-15 16:03 ` Danilo Krummrich
2025-08-15 17:04 ` Greg KH
2025-08-15 17:16 ` Danilo Krummrich
2025-08-01 15:44 ` [PATCH v3 2/3] rust: i2c: add manual I2C device creation abstractions Igor Korotin
2025-08-01 17:59 ` Daniel Almeida
2025-08-02 0:26 ` Danilo Krummrich
2025-08-04 14:38 ` Igor Korotin
2025-08-02 0:12 ` Danilo Krummrich
2025-08-01 15:45 ` [PATCH v3 3/3] samples: rust: add Rust I2C sample driver Igor Korotin
2025-08-01 18:09 ` Daniel Almeida
2025-08-04 14:43 ` Igor Korotin
2025-08-04 14:58 ` Daniel Almeida
2025-08-02 0:18 ` Danilo Krummrich
2025-08-07 8:42 ` kernel test robot
2025-08-04 15:07 ` [PATCH v3 0/3] rust: i2c: Add basic I2C driver abstractions Daniel Almeida
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=ff90c4d7-733a-4d76-a939-b460d66389bc@gmail.com \
--to=igor.korotin.linux@gmail.com \
--cc=a.hindborg@kernel.org \
--cc=alex.gaynor@gmail.com \
--cc=aliceryhl@google.com \
--cc=bjorn3_gh@protonmail.com \
--cc=boqun.feng@gmail.com \
--cc=dakr@kernel.org \
--cc=daniel.almeida@collabora.com \
--cc=gary@garyguo.net \
--cc=lossin@kernel.org \
--cc=ojeda@kernel.org \
--cc=rust-for-linux@vger.kernel.org \
--cc=tmgross@umich.edu \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).