sound/soc/intel/avs/cldma.c
Source file repositories/reference/linux-study-clean/sound/soc/intel/avs/cldma.c
File Facts
- System
- Linux kernel
- Corpus path
sound/soc/intel/avs/cldma.c- Extension
.c- Size
- 7406 bytes
- Lines
- 291
- Domain
- Driver Families
- Bucket
- sound/soc
- Inferred role
- Driver Families: implementation source
- Status
- source 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.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/pci.hsound/hda_register.hsound/hdaudio_ext.hcldma.hregisters.h
Detected Declarations
struct hda_cldmafunction hda_cldma_fillfunction cldma_memcpy_workfunction hda_cldma_transferfunction hda_cldma_startfunction hda_cldma_stopfunction hda_cldma_resetfunction hda_cldma_set_datafunction cldma_setup_bdlefunction hda_cldma_setupfunction hda_cldma_interruptfunction hda_cldma_initfunction hda_cldma_free
Annotated Snippet
struct hda_cldma {
struct device *dev;
struct hdac_bus *bus;
void __iomem *dsp_ba;
unsigned int buffer_size;
unsigned int num_periods;
unsigned char stream_tag;
void __iomem *sd_addr;
struct snd_dma_buffer dmab_data;
struct snd_dma_buffer dmab_bdl;
struct delayed_work memcpy_work;
struct completion completion;
/* runtime */
void *position;
unsigned int remaining;
unsigned int sd_status;
};
static void cldma_memcpy_work(struct work_struct *work);
struct hda_cldma code_loader = {
.stream_tag = AVS_CL_STREAM_INDEX + 1,
.memcpy_work = __DELAYED_WORK_INITIALIZER(code_loader.memcpy_work, cldma_memcpy_work, 0),
.completion = COMPLETION_INITIALIZER(code_loader.completion),
};
void hda_cldma_fill(struct hda_cldma *cl)
{
unsigned int size, offset;
if (cl->remaining > cl->buffer_size)
size = cl->buffer_size;
else
size = cl->remaining;
offset = snd_hdac_stream_readl(cl, CL_SD_SPIB);
if (offset + size > cl->buffer_size) {
unsigned int ss;
ss = cl->buffer_size - offset;
memcpy(cl->dmab_data.area + offset, cl->position, ss);
offset = 0;
size -= ss;
cl->position += ss;
cl->remaining -= ss;
}
memcpy(cl->dmab_data.area + offset, cl->position, size);
cl->position += size;
cl->remaining -= size;
snd_hdac_stream_writel(cl, CL_SD_SPIB, offset + size);
}
static void cldma_memcpy_work(struct work_struct *work)
{
struct hda_cldma *cl = container_of(work, struct hda_cldma, memcpy_work.work);
int ret;
ret = hda_cldma_start(cl);
if (ret < 0) {
dev_err(cl->dev, "cldma set RUN failed: %d\n", ret);
return;
}
while (true) {
ret = wait_for_completion_timeout(&cl->completion,
msecs_to_jiffies(AVS_CL_IOC_TIMEOUT_MS));
if (!ret) {
dev_err(cl->dev, "cldma IOC timeout\n");
break;
}
if (!(cl->sd_status & SD_INT_COMPLETE)) {
dev_err(cl->dev, "cldma transfer error, SD status: 0x%08x\n",
cl->sd_status);
break;
}
if (!cl->remaining)
break;
reinit_completion(&cl->completion);
hda_cldma_fill(cl);
/* enable CLDMA interrupt */
snd_hdac_adsp_updatel(cl, AVS_ADSP_REG_ADSPIC, AVS_ADSP_ADSPIC_CLDMA,
AVS_ADSP_ADSPIC_CLDMA);
Annotation
- Immediate include surface: `linux/pci.h`, `sound/hda_register.h`, `sound/hdaudio_ext.h`, `cldma.h`, `registers.h`.
- Detected declarations: `struct hda_cldma`, `function hda_cldma_fill`, `function cldma_memcpy_work`, `function hda_cldma_transfer`, `function hda_cldma_start`, `function hda_cldma_stop`, `function hda_cldma_reset`, `function hda_cldma_set_data`, `function cldma_setup_bdle`, `function hda_cldma_setup`.
- Atlas domain: Driver Families / sound/soc.
- Implementation status: source implementation candidate.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
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.