1 // SPDX-License-Identifier: GPL-2.0 2 3 //! I2C Driver subsystem 4 5 // I2C Driver abstractions. 6 use crate::{ 7 acpi, 8 container_of, 9 device, 10 device_id::{ 11 RawDeviceId, 12 RawDeviceIdIndex, // 13 }, 14 devres::Devres, 15 driver, 16 error::*, 17 of, 18 prelude::*, 19 types::{ 20 AlwaysRefCounted, 21 Opaque, // 22 }, // 23 }; 24 25 use core::{ 26 marker::PhantomData, 27 mem::offset_of, 28 ptr::{ 29 from_ref, 30 NonNull, // 31 }, // 32 }; 33 34 use kernel::types::ARef; 35 36 /// An I2C device id table. 37 #[repr(transparent)] 38 #[derive(Clone, Copy)] 39 pub struct DeviceId(bindings::i2c_device_id); 40 41 impl DeviceId { 42 const I2C_NAME_SIZE: usize = 20; 43 44 /// Create a new device id from an I2C 'id' string. 45 #[inline(always)] new(id: &'static CStr) -> Self46 pub const fn new(id: &'static CStr) -> Self { 47 let src = id.to_bytes_with_nul(); 48 build_assert!(src.len() <= Self::I2C_NAME_SIZE, "ID exceeds 20 bytes"); 49 let mut i2c: bindings::i2c_device_id = pin_init::zeroed(); 50 let mut i = 0; 51 while i < src.len() { 52 i2c.name[i] = src[i]; 53 i += 1; 54 } 55 56 Self(i2c) 57 } 58 } 59 60 // SAFETY: `DeviceId` is a `#[repr(transparent)]` wrapper of `i2c_device_id` and does not add 61 // additional invariants, so it's safe to transmute to `RawType`. 62 unsafe impl RawDeviceId for DeviceId { 63 type RawType = bindings::i2c_device_id; 64 } 65 66 // SAFETY: `DRIVER_DATA_OFFSET` is the offset to the `driver_data` field. 67 unsafe impl RawDeviceIdIndex for DeviceId { 68 const DRIVER_DATA_OFFSET: usize = core::mem::offset_of!(bindings::i2c_device_id, driver_data); 69 index(&self) -> usize70 fn index(&self) -> usize { 71 self.0.driver_data 72 } 73 } 74 75 /// IdTable type for I2C 76 pub type IdTable<T> = &'static dyn kernel::device_id::IdTable<DeviceId, T>; 77 78 /// Create a I2C `IdTable` with its alias for modpost. 79 #[macro_export] 80 macro_rules! i2c_device_table { 81 ($table_name:ident, $module_table_name:ident, $id_info_type: ty, $table_data: expr) => { 82 const $table_name: $crate::device_id::IdArray< 83 $crate::i2c::DeviceId, 84 $id_info_type, 85 { $table_data.len() }, 86 > = $crate::device_id::IdArray::new($table_data); 87 88 $crate::module_device_table!("i2c", $module_table_name, $table_name); 89 }; 90 } 91 92 /// An adapter for the registration of I2C drivers. 93 pub struct Adapter<T: Driver>(T); 94 95 // SAFETY: A call to `unregister` for a given instance of `RegType` is guaranteed to be valid if 96 // a preceding call to `register` has been successful. 97 unsafe impl<T: Driver + 'static> driver::RegistrationOps for Adapter<T> { 98 type RegType = bindings::i2c_driver; 99 register( idrv: &Opaque<Self::RegType>, name: &'static CStr, module: &'static ThisModule, ) -> Result100 unsafe fn register( 101 idrv: &Opaque<Self::RegType>, 102 name: &'static CStr, 103 module: &'static ThisModule, 104 ) -> Result { 105 build_assert!( 106 T::ACPI_ID_TABLE.is_some() || T::OF_ID_TABLE.is_some() || T::I2C_ID_TABLE.is_some(), 107 "At least one of ACPI/OF/Legacy tables must be present when registering an i2c driver" 108 ); 109 110 let i2c_table = match T::I2C_ID_TABLE { 111 Some(table) => table.as_ptr(), 112 None => core::ptr::null(), 113 }; 114 115 let of_table = match T::OF_ID_TABLE { 116 Some(table) => table.as_ptr(), 117 None => core::ptr::null(), 118 }; 119 120 let acpi_table = match T::ACPI_ID_TABLE { 121 Some(table) => table.as_ptr(), 122 None => core::ptr::null(), 123 }; 124 125 // SAFETY: It's safe to set the fields of `struct i2c_client` on initialization. 126 unsafe { 127 (*idrv.get()).driver.name = name.as_char_ptr(); 128 (*idrv.get()).probe = Some(Self::probe_callback); 129 (*idrv.get()).remove = Some(Self::remove_callback); 130 (*idrv.get()).shutdown = Some(Self::shutdown_callback); 131 (*idrv.get()).id_table = i2c_table; 132 (*idrv.get()).driver.of_match_table = of_table; 133 (*idrv.get()).driver.acpi_match_table = acpi_table; 134 } 135 136 // SAFETY: `idrv` is guaranteed to be a valid `RegType`. 137 to_result(unsafe { bindings::i2c_register_driver(module.0, idrv.get()) }) 138 } 139 unregister(idrv: &Opaque<Self::RegType>)140 unsafe fn unregister(idrv: &Opaque<Self::RegType>) { 141 // SAFETY: `idrv` is guaranteed to be a valid `RegType`. 142 unsafe { bindings::i2c_del_driver(idrv.get()) } 143 } 144 } 145 146 impl<T: Driver + 'static> Adapter<T> { probe_callback(idev: *mut bindings::i2c_client) -> kernel::ffi::c_int147 extern "C" fn probe_callback(idev: *mut bindings::i2c_client) -> kernel::ffi::c_int { 148 // SAFETY: The I2C bus only ever calls the probe callback with a valid pointer to a 149 // `struct i2c_client`. 150 // 151 // INVARIANT: `idev` is valid for the duration of `probe_callback()`. 152 let idev = unsafe { &*idev.cast::<I2cClient<device::CoreInternal>>() }; 153 154 let info = 155 Self::i2c_id_info(idev).or_else(|| <Self as driver::Adapter>::id_info(idev.as_ref())); 156 157 from_result(|| { 158 let data = T::probe(idev, info); 159 160 idev.as_ref().set_drvdata(data)?; 161 Ok(0) 162 }) 163 } 164 remove_callback(idev: *mut bindings::i2c_client)165 extern "C" fn remove_callback(idev: *mut bindings::i2c_client) { 166 // SAFETY: `idev` is a valid pointer to a `struct i2c_client`. 167 let idev = unsafe { &*idev.cast::<I2cClient<device::CoreInternal>>() }; 168 169 // SAFETY: `remove_callback` is only ever called after a successful call to 170 // `probe_callback`, hence it's guaranteed that `I2cClient::set_drvdata()` has been called 171 // and stored a `Pin<KBox<T>>`. 172 let data = unsafe { idev.as_ref().drvdata_obtain::<T>() }; 173 174 T::unbind(idev, data.as_ref()); 175 } 176 shutdown_callback(idev: *mut bindings::i2c_client)177 extern "C" fn shutdown_callback(idev: *mut bindings::i2c_client) { 178 // SAFETY: `shutdown_callback` is only ever called for a valid `idev` 179 let idev = unsafe { &*idev.cast::<I2cClient<device::CoreInternal>>() }; 180 181 // SAFETY: `shutdown_callback` is only ever called after a successful call to 182 // `probe_callback`, hence it's guaranteed that `Device::set_drvdata()` has been called 183 // and stored a `Pin<KBox<T>>`. 184 let data = unsafe { idev.as_ref().drvdata_obtain::<T>() }; 185 186 T::shutdown(idev, data.as_ref()); 187 } 188 189 /// The [`i2c::IdTable`] of the corresponding driver. i2c_id_table() -> Option<IdTable<<Self as driver::Adapter>::IdInfo>>190 fn i2c_id_table() -> Option<IdTable<<Self as driver::Adapter>::IdInfo>> { 191 T::I2C_ID_TABLE 192 } 193 194 /// Returns the driver's private data from the matching entry in the [`i2c::IdTable`], if any. 195 /// 196 /// If this returns `None`, it means there is no match with an entry in the [`i2c::IdTable`]. i2c_id_info(dev: &I2cClient) -> Option<&'static <Self as driver::Adapter>::IdInfo>197 fn i2c_id_info(dev: &I2cClient) -> Option<&'static <Self as driver::Adapter>::IdInfo> { 198 let table = Self::i2c_id_table()?; 199 200 // SAFETY: 201 // - `table` has static lifetime, hence it's valid for reads 202 // - `dev` is guaranteed to be valid while it's alive, and so is `dev.as_raw()`. 203 let raw_id = unsafe { bindings::i2c_match_id(table.as_ptr(), dev.as_raw()) }; 204 205 if raw_id.is_null() { 206 return None; 207 } 208 209 // SAFETY: `DeviceId` is a `#[repr(transparent)` wrapper of `struct i2c_device_id` and 210 // does not add additional invariants, so it's safe to transmute. 211 let id = unsafe { &*raw_id.cast::<DeviceId>() }; 212 213 Some(table.info(<DeviceId as RawDeviceIdIndex>::index(id))) 214 } 215 } 216 217 impl<T: Driver + 'static> driver::Adapter for Adapter<T> { 218 type IdInfo = T::IdInfo; 219 of_id_table() -> Option<of::IdTable<Self::IdInfo>>220 fn of_id_table() -> Option<of::IdTable<Self::IdInfo>> { 221 T::OF_ID_TABLE 222 } 223 acpi_id_table() -> Option<acpi::IdTable<Self::IdInfo>>224 fn acpi_id_table() -> Option<acpi::IdTable<Self::IdInfo>> { 225 T::ACPI_ID_TABLE 226 } 227 } 228 229 /// Declares a kernel module that exposes a single i2c driver. 230 /// 231 /// # Examples 232 /// 233 /// ```ignore 234 /// kernel::module_i2c_driver! { 235 /// type: MyDriver, 236 /// name: "Module name", 237 /// authors: ["Author name"], 238 /// description: "Description", 239 /// license: "GPL v2", 240 /// } 241 /// ``` 242 #[macro_export] 243 macro_rules! module_i2c_driver { 244 ($($f:tt)*) => { 245 $crate::module_driver!(<T>, $crate::i2c::Adapter<T>, { $($f)* }); 246 }; 247 } 248 249 /// The i2c driver trait. 250 /// 251 /// Drivers must implement this trait in order to get a i2c driver registered. 252 /// 253 /// # Example 254 /// 255 ///``` 256 /// # use kernel::{acpi, bindings, c_str, device::Core, i2c, of}; 257 /// 258 /// struct MyDriver; 259 /// 260 /// kernel::acpi_device_table!( 261 /// ACPI_TABLE, 262 /// MODULE_ACPI_TABLE, 263 /// <MyDriver as i2c::Driver>::IdInfo, 264 /// [ 265 /// (acpi::DeviceId::new(c_str!("LNUXBEEF")), ()) 266 /// ] 267 /// ); 268 /// 269 /// kernel::i2c_device_table!( 270 /// I2C_TABLE, 271 /// MODULE_I2C_TABLE, 272 /// <MyDriver as i2c::Driver>::IdInfo, 273 /// [ 274 /// (i2c::DeviceId::new(c_str!("rust_driver_i2c")), ()) 275 /// ] 276 /// ); 277 /// 278 /// kernel::of_device_table!( 279 /// OF_TABLE, 280 /// MODULE_OF_TABLE, 281 /// <MyDriver as i2c::Driver>::IdInfo, 282 /// [ 283 /// (of::DeviceId::new(c_str!("test,device")), ()) 284 /// ] 285 /// ); 286 /// 287 /// impl i2c::Driver for MyDriver { 288 /// type IdInfo = (); 289 /// const I2C_ID_TABLE: Option<i2c::IdTable<Self::IdInfo>> = Some(&I2C_TABLE); 290 /// const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = Some(&OF_TABLE); 291 /// const ACPI_ID_TABLE: Option<acpi::IdTable<Self::IdInfo>> = Some(&ACPI_TABLE); 292 /// 293 /// fn probe( 294 /// _idev: &i2c::I2cClient<Core>, 295 /// _id_info: Option<&Self::IdInfo>, 296 /// ) -> impl PinInit<Self, Error> { 297 /// Err(ENODEV) 298 /// } 299 /// 300 /// fn shutdown(_idev: &i2c::I2cClient<Core>, this: Pin<&Self>) { 301 /// } 302 /// } 303 ///``` 304 pub trait Driver: Send { 305 /// The type holding information about each device id supported by the driver. 306 // TODO: Use `associated_type_defaults` once stabilized: 307 // 308 // ``` 309 // type IdInfo: 'static = (); 310 // ``` 311 type IdInfo: 'static; 312 313 /// The table of device ids supported by the driver. 314 const I2C_ID_TABLE: Option<IdTable<Self::IdInfo>> = None; 315 316 /// The table of OF device ids supported by the driver. 317 const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = None; 318 319 /// The table of ACPI device ids supported by the driver. 320 const ACPI_ID_TABLE: Option<acpi::IdTable<Self::IdInfo>> = None; 321 322 /// I2C driver probe. 323 /// 324 /// Called when a new i2c client is added or discovered. 325 /// Implementers should attempt to initialize the client here. probe( dev: &I2cClient<device::Core>, id_info: Option<&Self::IdInfo>, ) -> impl PinInit<Self, Error>326 fn probe( 327 dev: &I2cClient<device::Core>, 328 id_info: Option<&Self::IdInfo>, 329 ) -> impl PinInit<Self, Error>; 330 331 /// I2C driver shutdown. 332 /// 333 /// Called by the kernel during system reboot or power-off to allow the [`Driver`] to bring the 334 /// [`I2cClient`] into a safe state. Implementing this callback is optional. 335 /// 336 /// Typical actions include stopping transfers, disabling interrupts, or resetting the hardware 337 /// to prevent undesired behavior during shutdown. 338 /// 339 /// This callback is distinct from final resource cleanup, as the driver instance remains valid 340 /// after it returns. Any deallocation or teardown of driver-owned resources should instead be 341 /// handled in `Self::drop`. shutdown(dev: &I2cClient<device::Core>, this: Pin<&Self>)342 fn shutdown(dev: &I2cClient<device::Core>, this: Pin<&Self>) { 343 let _ = (dev, this); 344 } 345 346 /// I2C driver unbind. 347 /// 348 /// Called when the [`I2cClient`] is unbound from its bound [`Driver`]. Implementing this 349 /// callback is optional. 350 /// 351 /// This callback serves as a place for drivers to perform teardown operations that require a 352 /// `&Device<Core>` or `&Device<Bound>` reference. For instance, drivers may try to perform I/O 353 /// operations to gracefully tear down the device. 354 /// 355 /// Otherwise, release operations for driver resources should be performed in `Self::drop`. unbind(dev: &I2cClient<device::Core>, this: Pin<&Self>)356 fn unbind(dev: &I2cClient<device::Core>, this: Pin<&Self>) { 357 let _ = (dev, this); 358 } 359 } 360 361 /// The i2c adapter representation. 362 /// 363 /// This structure represents the Rust abstraction for a C `struct i2c_adapter`. The 364 /// implementation abstracts the usage of an existing C `struct i2c_adapter` that 365 /// gets passed from the C side 366 /// 367 /// # Invariants 368 /// 369 /// A [`I2cAdapter`] instance represents a valid `struct i2c_adapter` created by the C portion of 370 /// the kernel. 371 #[repr(transparent)] 372 pub struct I2cAdapter<Ctx: device::DeviceContext = device::Normal>( 373 Opaque<bindings::i2c_adapter>, 374 PhantomData<Ctx>, 375 ); 376 377 impl<Ctx: device::DeviceContext> I2cAdapter<Ctx> { as_raw(&self) -> *mut bindings::i2c_adapter378 fn as_raw(&self) -> *mut bindings::i2c_adapter { 379 self.0.get() 380 } 381 } 382 383 impl I2cAdapter { 384 /// Returns the I2C Adapter index. 385 #[inline] index(&self) -> i32386 pub fn index(&self) -> i32 { 387 // SAFETY: `self.as_raw` is a valid pointer to a `struct i2c_adapter`. 388 unsafe { (*self.as_raw()).nr } 389 } 390 391 /// Gets pointer to an `i2c_adapter` by index. get(index: i32) -> Result<ARef<Self>>392 pub fn get(index: i32) -> Result<ARef<Self>> { 393 // SAFETY: `index` must refer to a valid I2C adapter; the kernel 394 // guarantees that `i2c_get_adapter(index)` returns either a valid 395 // pointer or NULL. `NonNull::new` guarantees the correct check. 396 let adapter = NonNull::new(unsafe { bindings::i2c_get_adapter(index) }).ok_or(ENODEV)?; 397 398 // SAFETY: `adapter` is non-null and points to a live `i2c_adapter`. 399 // `I2cAdapter` is #[repr(transparent)], so this cast is valid. 400 Ok(unsafe { (&*adapter.as_ptr().cast::<I2cAdapter<device::Normal>>()).into() }) 401 } 402 } 403 404 // SAFETY: `I2cAdapter` is a transparent wrapper of a type that doesn't depend on 405 // `I2cAdapter`'s generic argument. 406 kernel::impl_device_context_deref!(unsafe { I2cAdapter }); 407 kernel::impl_device_context_into_aref!(I2cAdapter); 408 409 // SAFETY: Instances of `I2cAdapter` are always reference-counted. 410 unsafe impl crate::types::AlwaysRefCounted for I2cAdapter { inc_ref(&self)411 fn inc_ref(&self) { 412 // SAFETY: The existence of a shared reference guarantees that the refcount is non-zero. 413 unsafe { bindings::i2c_get_adapter(self.index()) }; 414 } 415 dec_ref(obj: NonNull<Self>)416 unsafe fn dec_ref(obj: NonNull<Self>) { 417 // SAFETY: The safety requirements guarantee that the refcount is non-zero. 418 unsafe { bindings::i2c_put_adapter(obj.as_ref().as_raw()) } 419 } 420 } 421 422 /// The i2c board info representation 423 /// 424 /// This structure represents the Rust abstraction for a C `struct i2c_board_info` structure, 425 /// which is used for manual I2C client creation. 426 #[repr(transparent)] 427 pub struct I2cBoardInfo(bindings::i2c_board_info); 428 429 impl I2cBoardInfo { 430 const I2C_TYPE_SIZE: usize = 20; 431 /// Create a new [`I2cBoardInfo`] for a kernel driver. 432 #[inline(always)] new(type_: &'static CStr, addr: u16) -> Self433 pub const fn new(type_: &'static CStr, addr: u16) -> Self { 434 let src = type_.to_bytes_with_nul(); 435 build_assert!(src.len() <= Self::I2C_TYPE_SIZE, "Type exceeds 20 bytes"); 436 let mut i2c_board_info: bindings::i2c_board_info = pin_init::zeroed(); 437 let mut i: usize = 0; 438 while i < src.len() { 439 i2c_board_info.type_[i] = src[i]; 440 i += 1; 441 } 442 443 i2c_board_info.addr = addr; 444 Self(i2c_board_info) 445 } 446 as_raw(&self) -> *const bindings::i2c_board_info447 fn as_raw(&self) -> *const bindings::i2c_board_info { 448 from_ref(&self.0) 449 } 450 } 451 452 /// The i2c client representation. 453 /// 454 /// This structure represents the Rust abstraction for a C `struct i2c_client`. The 455 /// implementation abstracts the usage of an existing C `struct i2c_client` that 456 /// gets passed from the C side 457 /// 458 /// # Invariants 459 /// 460 /// A [`I2cClient`] instance represents a valid `struct i2c_client` created by the C portion of 461 /// the kernel. 462 #[repr(transparent)] 463 pub struct I2cClient<Ctx: device::DeviceContext = device::Normal>( 464 Opaque<bindings::i2c_client>, 465 PhantomData<Ctx>, 466 ); 467 468 impl<Ctx: device::DeviceContext> I2cClient<Ctx> { as_raw(&self) -> *mut bindings::i2c_client469 fn as_raw(&self) -> *mut bindings::i2c_client { 470 self.0.get() 471 } 472 } 473 474 // SAFETY: `I2cClient` is a transparent wrapper of `struct i2c_client`. 475 // The offset is guaranteed to point to a valid device field inside `I2cClient`. 476 unsafe impl<Ctx: device::DeviceContext> device::AsBusDevice<Ctx> for I2cClient<Ctx> { 477 const OFFSET: usize = offset_of!(bindings::i2c_client, dev); 478 } 479 480 // SAFETY: `I2cClient` is a transparent wrapper of a type that doesn't depend on 481 // `I2cClient`'s generic argument. 482 kernel::impl_device_context_deref!(unsafe { I2cClient }); 483 kernel::impl_device_context_into_aref!(I2cClient); 484 485 // SAFETY: Instances of `I2cClient` are always reference-counted. 486 unsafe impl AlwaysRefCounted for I2cClient { inc_ref(&self)487 fn inc_ref(&self) { 488 // SAFETY: The existence of a shared reference guarantees that the refcount is non-zero. 489 unsafe { bindings::get_device(self.as_ref().as_raw()) }; 490 } 491 dec_ref(obj: NonNull<Self>)492 unsafe fn dec_ref(obj: NonNull<Self>) { 493 // SAFETY: The safety requirements guarantee that the refcount is non-zero. 494 unsafe { bindings::put_device(&raw mut (*obj.as_ref().as_raw()).dev) } 495 } 496 } 497 498 impl<Ctx: device::DeviceContext> AsRef<device::Device<Ctx>> for I2cClient<Ctx> { as_ref(&self) -> &device::Device<Ctx>499 fn as_ref(&self) -> &device::Device<Ctx> { 500 let raw = self.as_raw(); 501 // SAFETY: By the type invariant of `Self`, `self.as_raw()` is a pointer to a valid 502 // `struct i2c_client`. 503 let dev = unsafe { &raw mut (*raw).dev }; 504 505 // SAFETY: `dev` points to a valid `struct device`. 506 unsafe { device::Device::from_raw(dev) } 507 } 508 } 509 510 impl<Ctx: device::DeviceContext> TryFrom<&device::Device<Ctx>> for &I2cClient<Ctx> { 511 type Error = kernel::error::Error; 512 try_from(dev: &device::Device<Ctx>) -> Result<Self, Self::Error>513 fn try_from(dev: &device::Device<Ctx>) -> Result<Self, Self::Error> { 514 // SAFETY: By the type invariant of `Device`, `dev.as_raw()` is a valid pointer to a 515 // `struct device`. 516 if unsafe { bindings::i2c_verify_client(dev.as_raw()).is_null() } { 517 return Err(EINVAL); 518 } 519 520 // SAFETY: We've just verified that the type of `dev` equals to 521 // `bindings::i2c_client_type`, hence `dev` must be embedded in a valid 522 // `struct i2c_client` as guaranteed by the corresponding C code. 523 let idev = unsafe { container_of!(dev.as_raw(), bindings::i2c_client, dev) }; 524 525 // SAFETY: `idev` is a valid pointer to a `struct i2c_client`. 526 Ok(unsafe { &*idev.cast() }) 527 } 528 } 529 530 // SAFETY: A `I2cClient` is always reference-counted and can be released from any thread. 531 unsafe impl Send for I2cClient {} 532 533 // SAFETY: `I2cClient` can be shared among threads because all methods of `I2cClient` 534 // (i.e. `I2cClient<Normal>) are thread safe. 535 unsafe impl Sync for I2cClient {} 536 537 /// The registration of an i2c client device. 538 /// 539 /// This type represents the registration of a [`struct i2c_client`]. When an instance of this 540 /// type is dropped, its respective i2c client device will be unregistered from the system. 541 /// 542 /// # Invariants 543 /// 544 /// `self.0` always holds a valid pointer to an initialized and registered 545 /// [`struct i2c_client`]. 546 #[repr(transparent)] 547 pub struct Registration(NonNull<bindings::i2c_client>); 548 549 impl Registration { 550 /// The C `i2c_new_client_device` function wrapper for manual I2C client creation. new<'a>( i2c_adapter: &I2cAdapter, i2c_board_info: &I2cBoardInfo, parent_dev: &'a device::Device<device::Bound>, ) -> impl PinInit<Devres<Self>, Error> + 'a551 pub fn new<'a>( 552 i2c_adapter: &I2cAdapter, 553 i2c_board_info: &I2cBoardInfo, 554 parent_dev: &'a device::Device<device::Bound>, 555 ) -> impl PinInit<Devres<Self>, Error> + 'a { 556 Devres::new(parent_dev, Self::try_new(i2c_adapter, i2c_board_info)) 557 } 558 try_new(i2c_adapter: &I2cAdapter, i2c_board_info: &I2cBoardInfo) -> Result<Self>559 fn try_new(i2c_adapter: &I2cAdapter, i2c_board_info: &I2cBoardInfo) -> Result<Self> { 560 // SAFETY: the kernel guarantees that `i2c_new_client_device()` returns either a valid 561 // pointer or NULL. `from_err_ptr` separates errors. Following `NonNull::new` 562 // checks for NULL. 563 let raw_dev = from_err_ptr(unsafe { 564 bindings::i2c_new_client_device(i2c_adapter.as_raw(), i2c_board_info.as_raw()) 565 })?; 566 567 let dev_ptr = NonNull::new(raw_dev).ok_or(ENODEV)?; 568 569 Ok(Self(dev_ptr)) 570 } 571 } 572 573 impl Drop for Registration { drop(&mut self)574 fn drop(&mut self) { 575 // SAFETY: `Drop` is only called for a valid `Registration`, which by invariant 576 // always contains a non-null pointer to an `i2c_client`. 577 unsafe { bindings::i2c_unregister_device(self.0.as_ptr()) } 578 } 579 } 580 581 // SAFETY: A `Registration` of a `struct i2c_client` can be released from any thread. 582 unsafe impl Send for Registration {} 583 584 // SAFETY: `Registration` offers no interior mutability (no mutation through &self 585 // and no mutable access is exposed) 586 unsafe impl Sync for Registration {} 587