sound/soc/sof/intel/hda-loader.c
Source file repositories/reference/linux-study-clean/sound/soc/sof/intel/hda-loader.c
File Facts
- System
- Linux kernel
- Corpus path
sound/soc/sof/intel/hda-loader.c- Extension
.c- Size
- 20185 bytes
- Lines
- 641
- Domain
- Driver Families
- Bucket
- sound/soc
- Inferred role
- Driver Families: exported/initcall integration point
- Status
- integration implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/firmware.hsound/hdaudio_ext.hsound/hda_register.hsound/sof.hsound/sof/ipc4/header.hext_manifest.h../ipc4-priv.h../ops.h../sof-priv.hhda.h
Detected Declarations
function hda_ssp_set_cbp_cfpfunction hda_cl_preparefunction coresfunction hda_cl_triggerfunction hda_cl_cleanupfunction hda_cl_copy_fwfunction hda_dsp_cl_boot_firmware_iccmaxfunction hda_dsp_boot_imrfunction hda_dsp_cl_boot_firmwarefunction hda_dsp_ipc4_load_libraryfunction hda_dsp_ext_man_get_cavs_config_data
Annotated Snippet
if (!ret) {
hda->booted_from_imr = true;
return 0;
}
dev_warn(sdev->dev, "IMR restore failed, trying to cold boot\n");
}
hda->booted_from_imr = false;
chip_info = desc->chip_info;
if (sdev->basefw.fw->size <= sdev->basefw.payload_offset) {
dev_err(sdev->dev, "error: firmware size must be greater than firmware offset\n");
return -EINVAL;
}
/* init for booting wait */
init_waitqueue_head(&sdev->boot_wait);
/* prepare DMA for code loader stream */
stripped_firmware.size = sdev->basefw.fw->size - sdev->basefw.payload_offset;
hext_stream = hda_cl_prepare(sdev->dev, HDA_CL_STREAM_FORMAT,
stripped_firmware.size,
&hda->cl_dmab, persistent_cl_buffer,
SNDRV_PCM_STREAM_PLAYBACK, false);
if (IS_ERR(hext_stream)) {
dev_err(sdev->dev, "error: dma prepare for fw loading failed\n");
return PTR_ERR(hext_stream);
}
/*
* Copy the payload to the DMA buffer if it is temporary or if the
* buffer is persistent but it does not have the basefw payload either
* because this is the first boot and the buffer needs to be initialized,
* or a library got loaded and it replaced the basefw.
*/
if (!persistent_cl_buffer || !hda->cl_dmab_contains_basefw) {
stripped_firmware.data = sdev->basefw.fw->data + sdev->basefw.payload_offset;
memcpy(hda->cl_dmab.area, stripped_firmware.data, stripped_firmware.size);
hda->cl_dmab_contains_basefw = true;
}
/* try ROM init a few times before giving up */
for (i = 0; i < HDA_FW_BOOT_ATTEMPTS; i++) {
dev_dbg(sdev->dev,
"Attempting iteration %d of Core En/ROM load...\n", i);
hda->boot_iteration = i + 1;
if (chip_info->cl_init)
ret = chip_info->cl_init(sdev, hext_stream->hstream.stream_tag, false);
else
ret = -EINVAL;
/* don't retry anymore if successful */
if (!ret)
break;
}
if (i == HDA_FW_BOOT_ATTEMPTS) {
dev_err(sdev->dev, "error: dsp init failed after %d attempts with err: %d\n",
i, ret);
goto cleanup;
}
/*
* When a SoundWire link is in clock stop state, a Slave
* device may trigger in-band wakes for events such as jack
* insertion or acoustic event detection. This event will lead
* to a WAKEEN interrupt, handled by the PCI device and routed
* to PME if the PCI device is in D3. The resume function in
* audio PCI driver will be invoked by ACPI for PME event and
* initialize the device and process WAKEEN interrupt.
*
* The WAKEEN interrupt should be processed ASAP to prevent an
* interrupt flood, otherwise other interrupts, such IPC,
* cannot work normally. The WAKEEN is handled after the ROM
* is initialized successfully, which ensures power rails are
* enabled before accessing the SoundWire SHIM registers
*/
if (!sdev->first_boot)
hda_sdw_process_wakeen(sdev);
/*
* Set the boot_iteration to the last attempt, indicating that the
* DSP ROM has been initialized and from this point there will be no
* retry done to boot.
*
* Continue with code loading and firmware boot
*/
Annotation
- Immediate include surface: `linux/firmware.h`, `sound/hdaudio_ext.h`, `sound/hda_register.h`, `sound/sof.h`, `sound/sof/ipc4/header.h`, `ext_manifest.h`, `../ipc4-priv.h`, `../ops.h`.
- Detected declarations: `function hda_ssp_set_cbp_cfp`, `function hda_cl_prepare`, `function cores`, `function hda_cl_trigger`, `function hda_cl_cleanup`, `function hda_cl_copy_fw`, `function hda_dsp_cl_boot_firmware_iccmax`, `function hda_dsp_boot_imr`, `function hda_dsp_cl_boot_firmware`, `function hda_dsp_ipc4_load_library`.
- Atlas domain: Driver Families / sound/soc.
- Implementation status: integration implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.