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: pci: add irq accessors

These accessors can be used to retrieve a irq::Registration or a
irq::ThreadedRegistration from a pci device. Alternatively, drivers can
retrieve an IrqRequest from a bound PCI device for later use.

These accessors ensure that only valid IRQ lines can ever be registered.

Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Tested-by: Joel Fernandes <joelagnelf@nvidia.com>
Tested-by: Dirk Behme <dirk.behme@de.bosch.com>
Signed-off-by: Daniel Almeida <daniel.almeida@collabora.com>
Link: https://lore.kernel.org/r/20250811-topics-tyr-request_irq2-v9-6-0485dcd9bcbf@collabora.com
Signed-off-by: Danilo Krummrich <dakr@kernel.org>

authored by

Daniel Almeida and committed by
Danilo Krummrich
9b6d4fb9 17e70f0c

+51 -2
+8
rust/helpers/pci.c
··· 11 11 { 12 12 return dev_is_pci(dev); 13 13 } 14 + 15 + #ifndef CONFIG_PCI_MSI 16 + int rust_helper_pci_irq_vector(struct pci_dev *pdev, unsigned int nvec) 17 + { 18 + return pci_irq_vector(pdev, nvec); 19 + } 20 + 21 + #endif
+43 -2
rust/kernel/pci.rs
··· 10 10 devres::Devres, 11 11 driver, 12 12 error::{from_result, to_result, Result}, 13 - io::Io, 14 - io::IoRaw, 13 + io::{Io, IoRaw}, 14 + irq::{self, IrqRequest}, 15 15 str::CStr, 16 16 types::{ARef, Opaque}, 17 17 ThisModule, ··· 430 430 name: &'a CStr, 431 431 ) -> impl PinInit<Devres<Bar>, Error> + 'a { 432 432 self.iomap_region_sized::<0>(bar, name) 433 + } 434 + 435 + /// Returns an [`IrqRequest`] for the IRQ vector at the given index, if any. 436 + pub fn irq_vector(&self, index: u32) -> Result<IrqRequest<'_>> { 437 + // SAFETY: `self.as_raw` returns a valid pointer to a `struct pci_dev`. 438 + let irq = unsafe { crate::bindings::pci_irq_vector(self.as_raw(), index) }; 439 + if irq < 0 { 440 + return Err(crate::error::Error::from_errno(irq)); 441 + } 442 + // SAFETY: `irq` is guaranteed to be a valid IRQ number for `&self`. 443 + Ok(unsafe { IrqRequest::new(self.as_ref(), irq as u32) }) 444 + } 445 + 446 + /// Returns a [`kernel::irq::Registration`] for the IRQ vector at the given 447 + /// index. 448 + pub fn request_irq<'a, T: crate::irq::Handler + 'static>( 449 + &'a self, 450 + index: u32, 451 + flags: irq::Flags, 452 + name: &'static CStr, 453 + handler: impl PinInit<T, Error> + 'a, 454 + ) -> Result<impl PinInit<irq::Registration<T>, Error> + 'a> { 455 + let request = self.irq_vector(index)?; 456 + 457 + Ok(irq::Registration::<T>::new(request, flags, name, handler)) 458 + } 459 + 460 + /// Returns a [`kernel::irq::ThreadedRegistration`] for the IRQ vector at 461 + /// the given index. 462 + pub fn request_threaded_irq<'a, T: crate::irq::ThreadedHandler + 'static>( 463 + &'a self, 464 + index: u32, 465 + flags: irq::Flags, 466 + name: &'static CStr, 467 + handler: impl PinInit<T, Error> + 'a, 468 + ) -> Result<impl PinInit<irq::ThreadedRegistration<T>, Error> + 'a> { 469 + let request = self.irq_vector(index)?; 470 + 471 + Ok(irq::ThreadedRegistration::<T>::new( 472 + request, flags, name, handler, 473 + )) 433 474 } 434 475 } 435 476