drivers/interconnect/debugfs-client.c

Source file repositories/reference/linux-study-clean/drivers/interconnect/debugfs-client.c

File Facts

System
Linux kernel
Corpus path
drivers/interconnect/debugfs-client.c
Extension
.c
Size
3895 bytes
Lines
182
Domain
Driver Families
Bucket
drivers/interconnect
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

struct debugfs_path {
	const char *src;
	const char *dst;
	struct icc_path *path;
	struct list_head list;
};

static struct icc_path *get_path(const char *src, const char *dst)
{
	struct debugfs_path *path;

	list_for_each_entry(path, &debugfs_paths, list) {
		if (!strcmp(path->src, src) && !strcmp(path->dst, dst))
			return path->path;
	}

	return NULL;
}

static int icc_get_set(void *data, u64 val)
{
	struct debugfs_path *debugfs_path;
	char *src, *dst;
	int ret = 0;

	mutex_lock(&debugfs_lock);

	rcu_read_lock();
	src = rcu_dereference(src_node);
	dst = rcu_dereference(dst_node);

	/*
	 * If we've already looked up a path, then use the existing one instead
	 * of calling icc_get() again. This allows for updating previous BW
	 * votes when "get" is written to multiple times for multiple paths.
	 */
	cur_path = get_path(src, dst);
	if (cur_path) {
		rcu_read_unlock();
		goto out;
	}

	src = kstrdup(src, GFP_ATOMIC);
	dst = kstrdup(dst, GFP_ATOMIC);
	rcu_read_unlock();

	if (!src || !dst) {
		ret = -ENOMEM;
		goto err_free;
	}

	cur_path = icc_get(&pdev->dev, src, dst);
	if (IS_ERR(cur_path)) {
		ret = PTR_ERR(cur_path);
		goto err_free;
	}

	debugfs_path = kzalloc_obj(*debugfs_path);
	if (!debugfs_path) {
		ret = -ENOMEM;
		goto err_put;
	}

	debugfs_path->path = cur_path;
	debugfs_path->src = src;
	debugfs_path->dst = dst;
	list_add_tail(&debugfs_path->list, &debugfs_paths);

	goto out;

err_put:
	icc_put(cur_path);
err_free:
	kfree(src);
	kfree(dst);
out:
	mutex_unlock(&debugfs_lock);
	return ret;
}

DEFINE_DEBUGFS_ATTRIBUTE(icc_get_fops, NULL, icc_get_set, "%llu\n");

static int icc_commit_set(void *data, u64 val)
{
	int ret;

	mutex_lock(&debugfs_lock);

	if (!cur_path) {
		ret = -EINVAL;

Annotation

Implementation Notes