drivers/remoteproc/qcom_common.c

Source file repositories/reference/linux-study-clean/drivers/remoteproc/qcom_common.c

File Facts

System
Linux kernel
Corpus path
drivers/remoteproc/qcom_common.c
Extension
.c
Size
16698 bytes
Lines
628
Domain
Driver Families
Bucket
drivers/remoteproc
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.

Dependency Surface

Detected Declarations

Annotated Snippet

struct minidump_region {
	char	name[MAX_REGION_NAME_LENGTH];
	__le32	seq_num;
	__le32	valid;
	__le64	address;
	__le64	size;
};

/**
 * struct minidump_subsystem - Subsystem's SMEM Table of content
 * @status : Subsystem toc init status
 * @enabled : if set to 1, this region would be copied during coredump
 * @encryption_status: Encryption status for this subsystem
 * @encryption_required : Decides to encrypt the subsystem regions or not
 * @region_count : Number of regions added in this subsystem toc
 * @regions_baseptr : regions base pointer of the subsystem
 */
struct minidump_subsystem {
	__le32	status;
	__le32	enabled;
	__le32	encryption_status;
	__le32	encryption_required;
	__le32	region_count;
	__le64	regions_baseptr;
};

/**
 * struct minidump_global_toc - Global Table of Content
 * @status : Global Minidump init status
 * @md_revision : Minidump revision
 * @enabled : Minidump enable status
 * @subsystems : Array of subsystems toc
 */
struct minidump_global_toc {
	__le32				status;
	__le32				md_revision;
	__le32				enabled;
	struct minidump_subsystem	subsystems[];
};

struct qcom_ssr_subsystem {
	const char *name;
	struct srcu_notifier_head notifier_list;
	struct list_head list;
};

static LIST_HEAD(qcom_ssr_subsystem_list);
static DEFINE_MUTEX(qcom_ssr_subsys_lock);

static void qcom_minidump_cleanup(struct rproc *rproc)
{
	struct rproc_dump_segment *entry, *tmp;

	list_for_each_entry_safe(entry, tmp, &rproc->dump_segments, node) {
		list_del(&entry->node);
		kfree(entry->priv);
		kfree(entry);
	}
}

static int qcom_add_minidump_segments(struct rproc *rproc, struct minidump_subsystem *subsystem,
			void (*rproc_dumpfn_t)(struct rproc *rproc, struct rproc_dump_segment *segment,
				void *dest, size_t offset, size_t size))
{
	struct minidump_region __iomem *ptr;
	struct minidump_region region;
	int seg_cnt, i;
	int ret = 0;
	dma_addr_t da;
	size_t size;
	char *name;

	if (WARN_ON(!list_empty(&rproc->dump_segments))) {
		dev_err(&rproc->dev, "dump segment list already populated\n");
		return -EUCLEAN;
	}

	seg_cnt = le32_to_cpu(subsystem->region_count);
	ptr = ioremap((unsigned long)le64_to_cpu(subsystem->regions_baseptr),
		      seg_cnt * sizeof(struct minidump_region));
	if (!ptr)
		return -EFAULT;

	for (i = 0; i < seg_cnt; i++) {
		memcpy_fromio(&region, ptr + i, sizeof(region));
		if (le32_to_cpu(region.valid) == MINIDUMP_REGION_VALID) {
			name = kstrndup(region.name, MAX_REGION_NAME_LENGTH - 1, GFP_KERNEL);
			if (!name) {
				ret = -ENOMEM;
				break;

Annotation

Implementation Notes