diff options
| author | Danilo Krummrich <dakr@kernel.org> | 2025-12-18 16:50:48 +0100 |
|---|---|---|
| committer | Danilo Krummrich <dakr@kernel.org> | 2025-12-29 17:54:31 +0100 |
| commit | db22fbc15a9cea7e3f74a53d36c381503b6ca43e (patch) | |
| tree | aec41f457c691b65b5deeb7589dd55bbac9825c0 | |
| parent | 255153afbcfdcf30d20048fb76a6d9418537b5d9 (diff) | |
gpu: nova-core: fw: get rid of redundant Result in GspFirmware::new()
In GspFirmware::new(), utilize pin_init_scope() to get rid of the Result
in the returned
Result<impl PinInit<T, Error>>
which is unnecessarily redundant.
Reviewed-by: Joel Fernandes <joelagnelf@nvidia.com>
Link: https://patch.msgid.link/20251218155239.25243-2-dakr@kernel.org
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
| -rw-r--r-- | drivers/gpu/nova-core/firmware/gsp.rs | 132 | ||||
| -rw-r--r-- | drivers/gpu/nova-core/gsp/boot.rs | 5 |
2 files changed, 68 insertions, 69 deletions
diff --git a/drivers/gpu/nova-core/firmware/gsp.rs b/drivers/gpu/nova-core/firmware/gsp.rs index 0549805282ab..e034268be3c5 100644 --- a/drivers/gpu/nova-core/firmware/gsp.rs +++ b/drivers/gpu/nova-core/firmware/gsp.rs @@ -153,82 +153,84 @@ pub(crate) struct GspFirmware { impl GspFirmware { /// Loads the GSP firmware binaries, map them into `dev`'s address-space, and creates the page /// tables expected by the GSP bootloader to load it. - pub(crate) fn new<'a, 'b>( + pub(crate) fn new<'a>( dev: &'a device::Device<device::Bound>, chipset: Chipset, - ver: &'b str, - ) -> Result<impl PinInit<Self, Error> + 'a> { - let fw = super::request_firmware(dev, chipset, "gsp", ver)?; + ver: &'a str, + ) -> impl PinInit<Self, Error> + 'a { + pin_init::pin_init_scope(move || { + let fw = super::request_firmware(dev, chipset, "gsp", ver)?; - let fw_section = elf::elf64_section(fw.data(), ".fwimage").ok_or(EINVAL)?; + let fw_section = elf::elf64_section(fw.data(), ".fwimage").ok_or(EINVAL)?; - let sigs_section = match chipset.arch() { - Architecture::Ampere => ".fwsignature_ga10x", - Architecture::Ada => ".fwsignature_ad10x", - _ => return Err(ENOTSUPP), - }; - let signatures = elf::elf64_section(fw.data(), sigs_section) - .ok_or(EINVAL) - .and_then(|data| DmaObject::from_data(dev, data))?; + let sigs_section = match chipset.arch() { + Architecture::Ampere => ".fwsignature_ga10x", + Architecture::Ada => ".fwsignature_ad10x", + _ => return Err(ENOTSUPP), + }; + let signatures = elf::elf64_section(fw.data(), sigs_section) + .ok_or(EINVAL) + .and_then(|data| DmaObject::from_data(dev, data))?; - let size = fw_section.len(); + let size = fw_section.len(); - // Move the firmware into a vmalloc'd vector and map it into the device address - // space. - let fw_vvec = VVec::with_capacity(fw_section.len(), GFP_KERNEL) - .and_then(|mut v| { - v.extend_from_slice(fw_section, GFP_KERNEL)?; - Ok(v) - }) - .map_err(|_| ENOMEM)?; + // Move the firmware into a vmalloc'd vector and map it into the device address + // space. + let fw_vvec = VVec::with_capacity(fw_section.len(), GFP_KERNEL) + .and_then(|mut v| { + v.extend_from_slice(fw_section, GFP_KERNEL)?; + Ok(v) + }) + .map_err(|_| ENOMEM)?; - let bl = super::request_firmware(dev, chipset, "bootloader", ver)?; - let bootloader = RiscvFirmware::new(dev, &bl)?; + let bl = super::request_firmware(dev, chipset, "bootloader", ver)?; + let bootloader = RiscvFirmware::new(dev, &bl)?; - Ok(try_pin_init!(Self { - fw <- SGTable::new(dev, fw_vvec, DataDirection::ToDevice, GFP_KERNEL), - level2 <- { - // Allocate the level 2 page table, map the firmware onto it, and map it into the - // device address space. - VVec::<u8>::with_capacity( - fw.iter().count() * core::mem::size_of::<u64>(), - GFP_KERNEL, - ) - .map_err(|_| ENOMEM) - .and_then(|level2| map_into_lvl(&fw, level2)) - .map(|level2| SGTable::new(dev, level2, DataDirection::ToDevice, GFP_KERNEL))? - }, - level1 <- { - // Allocate the level 1 page table, map the level 2 page table onto it, and map it - // into the device address space. - VVec::<u8>::with_capacity( - level2.iter().count() * core::mem::size_of::<u64>(), - GFP_KERNEL, - ) - .map_err(|_| ENOMEM) - .and_then(|level1| map_into_lvl(&level2, level1)) - .map(|level1| SGTable::new(dev, level1, DataDirection::ToDevice, GFP_KERNEL))? - }, - level0: { - // Allocate the level 0 page table as a device-visible DMA object, and map the - // level 1 page table onto it. + Ok(try_pin_init!(Self { + fw <- SGTable::new(dev, fw_vvec, DataDirection::ToDevice, GFP_KERNEL), + level2 <- { + // Allocate the level 2 page table, map the firmware onto it, and map it into + // the device address space. + VVec::<u8>::with_capacity( + fw.iter().count() * core::mem::size_of::<u64>(), + GFP_KERNEL, + ) + .map_err(|_| ENOMEM) + .and_then(|level2| map_into_lvl(&fw, level2)) + .map(|level2| SGTable::new(dev, level2, DataDirection::ToDevice, GFP_KERNEL))? + }, + level1 <- { + // Allocate the level 1 page table, map the level 2 page table onto it, and map + // it into the device address space. + VVec::<u8>::with_capacity( + level2.iter().count() * core::mem::size_of::<u64>(), + GFP_KERNEL, + ) + .map_err(|_| ENOMEM) + .and_then(|level1| map_into_lvl(&level2, level1)) + .map(|level1| SGTable::new(dev, level1, DataDirection::ToDevice, GFP_KERNEL))? + }, + level0: { + // Allocate the level 0 page table as a device-visible DMA object, and map the + // level 1 page table onto it. - // Level 0 page table data. - let mut level0_data = kvec![0u8; GSP_PAGE_SIZE]?; + // Level 0 page table data. + let mut level0_data = kvec![0u8; GSP_PAGE_SIZE]?; - // Fill level 1 page entry. - let level1_entry = level1.iter().next().ok_or(EINVAL)?; - let level1_entry_addr = level1_entry.dma_address(); - let dst = &mut level0_data[..size_of_val(&level1_entry_addr)]; - dst.copy_from_slice(&level1_entry_addr.to_le_bytes()); + // Fill level 1 page entry. + let level1_entry = level1.iter().next().ok_or(EINVAL)?; + let level1_entry_addr = level1_entry.dma_address(); + let dst = &mut level0_data[..size_of_val(&level1_entry_addr)]; + dst.copy_from_slice(&level1_entry_addr.to_le_bytes()); - // Turn the level0 page table into a [`DmaObject`]. - DmaObject::from_data(dev, &level0_data)? - }, - size, - signatures, - bootloader, - })) + // Turn the level0 page table into a [`DmaObject`]. + DmaObject::from_data(dev, &level0_data)? + }, + size, + signatures, + bootloader, + })) + }) } /// Returns the DMA handle of the radix3 level 0 page table. diff --git a/drivers/gpu/nova-core/gsp/boot.rs b/drivers/gpu/nova-core/gsp/boot.rs index 54937606b5b0..a53d80620468 100644 --- a/drivers/gpu/nova-core/gsp/boot.rs +++ b/drivers/gpu/nova-core/gsp/boot.rs @@ -139,10 +139,7 @@ impl super::Gsp { let bios = Vbios::new(dev, bar)?; - let gsp_fw = KBox::pin_init( - GspFirmware::new(dev, chipset, FIRMWARE_VERSION)?, - GFP_KERNEL, - )?; + let gsp_fw = KBox::pin_init(GspFirmware::new(dev, chipset, FIRMWARE_VERSION), GFP_KERNEL)?; let fb_layout = FbLayout::new(chipset, bar, &gsp_fw)?; dev_dbg!(dev, "{:#x?}\n", fb_layout); |
