sound/soc/intel/avs/apl.c

Source file repositories/reference/linux-study-clean/sound/soc/intel/avs/apl.c

File Facts

System
Linux kernel
Corpus path
sound/soc/intel/avs/apl.c
Extension
.c
Size
7009 bytes
Lines
271
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.

Dependency Surface

Detected Declarations

Annotated Snippet

for_each_set_bit(i, &resource_mask, num_cores) {
			info->logs_core[i].enable = enable;
			info->logs_core[i].min_priority = *priorities++;
		}
	else
		for_each_set_bit(i, &resource_mask, num_cores)
			info->logs_core[i].enable = enable;

	ret = avs_ipc_set_enable_logs(adev, (u8 *)info, size);
	kfree(info);
	if (ret)
		return AVS_IPC_RET(ret);

	return 0;
}
#endif

int avs_apl_log_buffer_status(struct avs_dev *adev, union avs_notify_msg *msg)
{
	struct avs_apl_log_buffer_layout layout;
	void __iomem *addr, *buf;

	addr = avs_log_buffer_addr(adev, msg->log.core);
	if (!addr)
		return -ENXIO;

	memcpy_fromio(&layout, addr, sizeof(layout));

	if (!avs_logging_fw(adev))
		/* consume the logs regardless of consumer presence */
		goto update_read_ptr;

	buf = avs_apl_log_payload_addr(addr);

	if (layout.read_ptr > layout.write_ptr) {
		avs_dump_fw_log(adev, buf + layout.read_ptr,
				avs_apl_log_payload_size(adev) - layout.read_ptr);
		layout.read_ptr = 0;
	}
	avs_dump_fw_log_wakeup(adev, buf + layout.read_ptr, layout.write_ptr - layout.read_ptr);

update_read_ptr:
	writel(layout.write_ptr, addr);
	return 0;
}

static int avs_apl_wait_log_entry(struct avs_dev *adev, u32 core,
				  struct avs_apl_log_buffer_layout *layout)
{
	unsigned long timeout;
	void __iomem *addr;

	addr = avs_log_buffer_addr(adev, core);
	if (!addr)
		return -ENXIO;

	timeout = jiffies + msecs_to_jiffies(10);

	do {
		memcpy_fromio(layout, addr, sizeof(*layout));
		if (layout->read_ptr != layout->write_ptr)
			return 0;
		usleep_range(500, 1000);
	} while (!time_after(jiffies, timeout));

	return -ETIMEDOUT;
}

/* reads log header and tests its type */
#define avs_apl_is_entry_stackdump(addr) ((readl(addr) >> 30) & 0x1)

int avs_apl_coredump(struct avs_dev *adev, union avs_notify_msg *msg)
{
	struct avs_apl_log_buffer_layout layout;
	void __iomem *addr, *buf;
	size_t dump_size;
	u32 offset = 0;
	u8 *dump, *pos;

	dump_size = AVS_FW_REGS_SIZE + msg->ext.coredump.stack_dump_size;
	dump = vzalloc(dump_size);
	if (!dump)
		return -ENOMEM;

	memcpy_fromio(dump, avs_sram_addr(adev, AVS_FW_REGS_WINDOW), AVS_FW_REGS_SIZE);

	if (!msg->ext.coredump.stack_dump_size)
		goto exit;

	/* Dump the registers even if an external error prevents gathering the stack. */

Annotation

Implementation Notes