Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

rust: platform: use generic device drvdata accessors

Take advantage of the generic drvdata accessors of the generic Device
type.

While at it, use from_result() instead of match.

Link: https://lore.kernel.org/r/20250621195118.124245-4-dakr@kernel.org
Signed-off-by: Danilo Krummrich <dakr@kernel.org>

+17 -29
-10
rust/helpers/platform.c
··· 2 2 3 3 #include <linux/platform_device.h> 4 4 5 - void *rust_helper_platform_get_drvdata(const struct platform_device *pdev) 6 - { 7 - return platform_get_drvdata(pdev); 8 - } 9 - 10 - void rust_helper_platform_set_drvdata(struct platform_device *pdev, void *data) 11 - { 12 - platform_set_drvdata(pdev, data); 13 - } 14 - 15 5 bool rust_helper_dev_is_platform(const struct device *dev) 16 6 { 17 7 return dev_is_platform(dev);
+17 -19
rust/kernel/platform.rs
··· 6 6 7 7 use crate::{ 8 8 acpi, bindings, container_of, device, driver, 9 - error::{to_result, Result}, 9 + error::{from_result, to_result, Result}, 10 10 of, 11 11 prelude::*, 12 - types::{ForeignOwnable, Opaque}, 12 + types::Opaque, 13 13 ThisModule, 14 14 }; 15 15 ··· 66 66 // `struct platform_device`. 67 67 // 68 68 // INVARIANT: `pdev` is valid for the duration of `probe_callback()`. 69 - let pdev = unsafe { &*pdev.cast::<Device<device::Core>>() }; 70 - 69 + let pdev = unsafe { &*pdev.cast::<Device<device::CoreInternal>>() }; 71 70 let info = <Self as driver::Adapter>::id_info(pdev.as_ref()); 72 - match T::probe(pdev, info) { 73 - Ok(data) => { 74 - // Let the `struct platform_device` own a reference of the driver's private data. 75 - // SAFETY: By the type invariant `pdev.as_raw` returns a valid pointer to a 76 - // `struct platform_device`. 77 - unsafe { bindings::platform_set_drvdata(pdev.as_raw(), data.into_foreign() as _) }; 78 - } 79 - Err(err) => return Error::to_errno(err), 80 - } 81 71 82 - 0 72 + from_result(|| { 73 + let data = T::probe(pdev, info)?; 74 + 75 + pdev.as_ref().set_drvdata(data); 76 + Ok(0) 77 + }) 83 78 } 84 79 85 80 extern "C" fn remove_callback(pdev: *mut bindings::platform_device) { 86 - // SAFETY: `pdev` is a valid pointer to a `struct platform_device`. 87 - let ptr = unsafe { bindings::platform_get_drvdata(pdev) }.cast(); 81 + // SAFETY: The platform bus only ever calls the remove callback with a valid pointer to a 82 + // `struct platform_device`. 83 + // 84 + // INVARIANT: `pdev` is valid for the duration of `probe_callback()`. 85 + let pdev = unsafe { &*pdev.cast::<Device<device::CoreInternal>>() }; 88 86 89 87 // SAFETY: `remove_callback` is only ever called after a successful call to 90 - // `probe_callback`, hence it's guaranteed that `ptr` points to a valid and initialized 91 - // `KBox<T>` pointer created through `KBox::into_foreign`. 92 - let _ = unsafe { KBox::<T>::from_foreign(ptr) }; 88 + // `probe_callback`, hence it's guaranteed that `Device::set_drvdata()` has been called 89 + // and stored a `Pin<KBox<T>>`. 90 + let _ = unsafe { pdev.as_ref().drvdata_obtain::<Pin<KBox<T>>>() }; 93 91 } 94 92 } 95 93