mirror of
https://github.com/torvalds/linux.git
synced 2025-12-07 20:06:24 +00:00
Pull driver core updates from Danilo Krummrich:
"Arch Topology:
- Move parse_acpi_topology() from arm64 to common code for reuse in
RISC-V
CPU:
- Expose housekeeping CPUs through /sys/devices/system/cpu/housekeeping
- Print a newline (or 0x0A) instead of '(null)' reading
/sys/devices/system/cpu/nohz_full when nohz_full= is not set
debugfs
- Remove (broken) 'no-mount' mode
- Remove redundant access mode checks in debugfs_get_tree() and
debugfs_create_*() functions
Devres:
- Remove unused devm_free_percpu() helper
- Move devm_alloc_percpu() from device.h to devres.h
Firmware Loader:
- Replace simple_strtol() with kstrtoint()
- Do not call cancel_store() when no upload is in progress
kernfs:
- Increase struct super_block::maxbytes to MAX_LFS_FILESIZE
- Fix a missing unwind path in __kernfs_new_node()
Misc:
- Increase the name size in struct auxiliary_device_id to 40
characters
- Replace system_unbound_wq with system_dfl_wq and add WQ_PERCPU to
alloc_workqueue()
Platform:
- Replace ERR_PTR() with IOMEM_ERR_PTR() in platform ioremap
functions
Rust:
- Auxiliary:
- Unregister auxiliary device on parent device unbind
- Move parent() to impl Device; implement device context aware
parent() for Device<Bound>
- Illustrate how to safely obtain a driver's device private data
when calling from an auxiliary driver into the parant device
driver
- DebugFs:
- Implement support for binary large objects
- Device:
- Let probe() return the driver's device private data as pinned
initializer, i.e. impl PinInit<Self, Error>
- Implement safe accessor for a driver's device private data for
Device<Bound> (returned reference can't out-live driver binding
and guarantees the correct private data type)
- Implement AsBusDevice trait, to be used by class device
abstractions to derive the bus device type of the parent device
- DMA:
- Store raw pointer of allocation as NonNull
- Use start_ptr() and start_ptr_mut() to inherit correct
mutability of self
- FS:
- Add file::Offset type alias
- I2C:
- Add abstractions for I2C device / driver infrastructure
- Implement abstractions for manual I2C device registrations
- I/O:
- Use "kernel vertical" style for imports
- Define ResourceSize as resource_size_t
- Move ResourceSize to top-level I/O module
- Add type alias for phys_addr_t
- Implement Rust version of read_poll_timeout_atomic()
- PCI:
- Use "kernel vertical" style for imports
- Move I/O and IRQ infrastructure to separate files
- Add support for PCI interrupt vectors
- Implement TryInto<IrqRequest<'a>> for IrqVector<'a> to convert
an IrqVector bound to specific pci::Device into an IrqRequest
bound to the same pci::Device's parent Device
- Leverage pin_init_scope() to get rid of redundant Result in IRQ
methods
- PinInit:
- Add {pin_}init_scope() to execute code before creating an
initializer
- Platform:
- Leverage pin_init_scope() to get rid of redundant Result in IRQ
methods
- Timekeeping:
- Implement abstraction of udelay()
- Uaccess:
- Implement read_slice_partial() and read_slice_file() for
UserSliceReader
- Implement write_slice_partial() and write_slice_file() for
UserSliceWriter
sysfs:
- Prepare the constification of struct attribute"
* tag 'driver-core-6.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/driver-core/driver-core: (75 commits)
rust: pci: fix build failure when CONFIG_PCI_MSI is disabled
debugfs: Fix default access mode config check
debugfs: Remove broken no-mount mode
debugfs: Remove redundant access mode checks
driver core: Check drivers_autoprobe for all added devices
driver core: WQ_PERCPU added to alloc_workqueue users
driver core: replace use of system_unbound_wq with system_dfl_wq
tick/nohz: Expose housekeeping CPUs in sysfs
tick/nohz: avoid showing '(null)' if nohz_full= not set
sysfs/cpu: Use DEVICE_ATTR_RO for nohz_full attribute
kernfs: fix memory leak of kernfs_iattrs in __kernfs_new_node
fs/kernfs: raise sb->maxbytes to MAX_LFS_FILESIZE
mod_devicetable: Bump auxiliary_device_id name size
sysfs: simplify attribute definition macros
samples/kobject: constify 'struct foo_attribute'
samples/kobject: add is_visible() callback to attribute group
sysfs: attribute_group: enable const variants of is_visible()
sysfs: introduce __SYSFS_FUNCTION_ALTERNATIVE()
sysfs: transparently handle const pointers in ATTRIBUTE_GROUPS()
sysfs: attribute_group: allow registration of const attribute
...
164 lines
4.6 KiB
Rust
164 lines
4.6 KiB
Rust
// SPDX-License-Identifier: GPL-2.0
|
|
|
|
// Copyright (C) 2025 Google LLC.
|
|
|
|
//! Sample DebugFS exporting platform driver
|
|
//!
|
|
//! To successfully probe this driver with ACPI, use an ssdt that looks like
|
|
//!
|
|
//! ```dsl
|
|
//! DefinitionBlock ("", "SSDT", 2, "TEST", "VIRTACPI", 0x00000001)
|
|
//! {
|
|
//! Scope (\_SB)
|
|
//! {
|
|
//! Device (T432)
|
|
//! {
|
|
//! Name (_HID, "LNUXBEEF") // ACPI hardware ID to match
|
|
//! Name (_UID, 1)
|
|
//! Name (_STA, 0x0F) // Device present, enabled
|
|
//! Name (_DSD, Package () { // Sample attribute
|
|
//! ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
|
|
//! Package() {
|
|
//! Package(2) {"compatible", "sample-debugfs"}
|
|
//! }
|
|
//! })
|
|
//! Name (_CRS, ResourceTemplate ()
|
|
//! {
|
|
//! Memory32Fixed (ReadWrite, 0xFED00000, 0x1000)
|
|
//! })
|
|
//! }
|
|
//! }
|
|
//! }
|
|
//! ```
|
|
|
|
use core::str::FromStr;
|
|
use kernel::c_str;
|
|
use kernel::debugfs::{Dir, File};
|
|
use kernel::new_mutex;
|
|
use kernel::prelude::*;
|
|
use kernel::sizes::*;
|
|
use kernel::sync::atomic::{Atomic, Relaxed};
|
|
use kernel::sync::Mutex;
|
|
use kernel::{acpi, device::Core, of, platform, str::CString, types::ARef};
|
|
|
|
kernel::module_platform_driver! {
|
|
type: RustDebugFs,
|
|
name: "rust_debugfs",
|
|
authors: ["Matthew Maurer"],
|
|
description: "Rust DebugFS usage sample",
|
|
license: "GPL",
|
|
}
|
|
|
|
#[pin_data]
|
|
struct RustDebugFs {
|
|
pdev: ARef<platform::Device>,
|
|
// As we only hold these for drop effect (to remove the directory/files) we have a leading
|
|
// underscore to indicate to the compiler that we don't expect to use this field directly.
|
|
_debugfs: Dir,
|
|
#[pin]
|
|
_compatible: File<CString>,
|
|
#[pin]
|
|
counter: File<Atomic<usize>>,
|
|
#[pin]
|
|
inner: File<Mutex<Inner>>,
|
|
#[pin]
|
|
array_blob: File<Mutex<[u8; 4]>>,
|
|
#[pin]
|
|
vector_blob: File<Mutex<KVec<u8>>>,
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
struct Inner {
|
|
x: u32,
|
|
y: u32,
|
|
}
|
|
|
|
impl FromStr for Inner {
|
|
type Err = Error;
|
|
fn from_str(s: &str) -> Result<Self> {
|
|
let mut parts = s.split_whitespace();
|
|
let x = parts
|
|
.next()
|
|
.ok_or(EINVAL)?
|
|
.parse::<u32>()
|
|
.map_err(|_| EINVAL)?;
|
|
let y = parts
|
|
.next()
|
|
.ok_or(EINVAL)?
|
|
.parse::<u32>()
|
|
.map_err(|_| EINVAL)?;
|
|
if parts.next().is_some() {
|
|
return Err(EINVAL);
|
|
}
|
|
Ok(Inner { x, y })
|
|
}
|
|
}
|
|
|
|
kernel::acpi_device_table!(
|
|
ACPI_TABLE,
|
|
MODULE_ACPI_TABLE,
|
|
<RustDebugFs as platform::Driver>::IdInfo,
|
|
[(acpi::DeviceId::new(c_str!("LNUXBEEF")), ())]
|
|
);
|
|
|
|
impl platform::Driver for RustDebugFs {
|
|
type IdInfo = ();
|
|
const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = None;
|
|
const ACPI_ID_TABLE: Option<acpi::IdTable<Self::IdInfo>> = Some(&ACPI_TABLE);
|
|
|
|
fn probe(
|
|
pdev: &platform::Device<Core>,
|
|
_info: Option<&Self::IdInfo>,
|
|
) -> impl PinInit<Self, Error> {
|
|
RustDebugFs::new(pdev).pin_chain(|this| {
|
|
this.counter.store(91, Relaxed);
|
|
{
|
|
let mut guard = this.inner.lock();
|
|
guard.x = guard.y;
|
|
guard.y = 42;
|
|
}
|
|
|
|
Ok(())
|
|
})
|
|
}
|
|
}
|
|
|
|
impl RustDebugFs {
|
|
fn build_counter(dir: &Dir) -> impl PinInit<File<Atomic<usize>>> + '_ {
|
|
dir.read_write_file(c_str!("counter"), Atomic::<usize>::new(0))
|
|
}
|
|
|
|
fn build_inner(dir: &Dir) -> impl PinInit<File<Mutex<Inner>>> + '_ {
|
|
dir.read_write_file(c_str!("pair"), new_mutex!(Inner { x: 3, y: 10 }))
|
|
}
|
|
|
|
fn new(pdev: &platform::Device<Core>) -> impl PinInit<Self, Error> + '_ {
|
|
let debugfs = Dir::new(c_str!("sample_debugfs"));
|
|
let dev = pdev.as_ref();
|
|
|
|
try_pin_init! {
|
|
Self {
|
|
_compatible <- debugfs.read_only_file(
|
|
c_str!("compatible"),
|
|
dev.fwnode()
|
|
.ok_or(ENOENT)?
|
|
.property_read::<CString>(c_str!("compatible"))
|
|
.required_by(dev)?,
|
|
),
|
|
counter <- Self::build_counter(&debugfs),
|
|
inner <- Self::build_inner(&debugfs),
|
|
array_blob <- debugfs.read_write_binary_file(
|
|
c_str!("array_blob"),
|
|
new_mutex!([0x62, 0x6c, 0x6f, 0x62]),
|
|
),
|
|
vector_blob <- debugfs.read_write_binary_file(
|
|
c_str!("vector_blob"),
|
|
new_mutex!(kernel::kvec!(0x42; SZ_4K)?),
|
|
),
|
|
_debugfs: debugfs,
|
|
pdev: pdev.into(),
|
|
}
|
|
}
|
|
}
|
|
}
|