Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0dab3364 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "soc: qcom: kryo-l2-accessors: Add debugfs support"

parents a98c93dd f2c28ef0
Loading
Loading
Loading
Loading
+105 −1
Original line number Original line Diff line number Diff line
/*
/*
 * Copyright (c) 2014, The Linux Foundation. All rights reserved.
 * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
 *
 *
 * This program is free software; you can redistribute it and/or modify
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * it under the terms of the GNU General Public License version 2 and
@@ -14,6 +14,8 @@
#include <linux/spinlock.h>
#include <linux/spinlock.h>
#include <linux/module.h>
#include <linux/module.h>
#include <linux/msm_rtb.h>
#include <linux/msm_rtb.h>
#include <linux/debugfs.h>
#include <linux/seq_file.h>
#include <asm/cputype.h>
#include <asm/cputype.h>


#include <soc/qcom/kryo-l2-accessors.h>
#include <soc/qcom/kryo-l2-accessors.h>
@@ -77,3 +79,105 @@ u64 get_l2_indirect_reg(u64 reg)
	return val;
	return val;
}
}
EXPORT_SYMBOL(get_l2_indirect_reg);
EXPORT_SYMBOL(get_l2_indirect_reg);

#if defined(CONFIG_DEBUG_FS)

static u32 debug_addr;
static int debug_target_cpu;

static void remote_l2_ia_read(void *data)
{
	u64 *val = data;
	*val = get_l2_indirect_reg(debug_addr);
}

static void remote_l2_ia_write(void *data)
{
	u64 *val = data;

	set_l2_indirect_reg(debug_addr, *val);
}

static int l2_indirect_target_cpu_set(void *data, u64 val)
{
	if (val > num_possible_cpus())
		return -EINVAL;

	debug_target_cpu = val;
	return 0;
}

static int l2_indirect_target_cpu_get(void *data, u64 *val)
{
	*val = debug_target_cpu;
	return 0;
}

DEFINE_SIMPLE_ATTRIBUTE(l2_ia_cpu_fops, l2_indirect_target_cpu_get,
			l2_indirect_target_cpu_set, "%llu\n");

static int l2_indirect_addr_set(void *data, u64 val)
{
	debug_addr = val;
	return 0;
}

static int l2_indirect_addr_get(void *data, u64 *val)
{
	*val = debug_addr;
	return 0;
}

DEFINE_SIMPLE_ATTRIBUTE(l2_ia_addr_fops, l2_indirect_addr_get,
			l2_indirect_addr_set, "%llu\n");

static int l2_indirect_val_set(void *data, u64 val)
{
	return smp_call_function_single(debug_target_cpu, remote_l2_ia_write,
					&val, 1);
}

DEFINE_SIMPLE_ATTRIBUTE(l2_ia_set_fops, NULL,
			l2_indirect_val_set, "%llu\n");

static int l2_indirect_get(void *data, u64 *val)
{
	return smp_call_function_single(debug_target_cpu, remote_l2_ia_read,
					val, 1);
}

DEFINE_SIMPLE_ATTRIBUTE(l2_ia_get_fops, l2_indirect_get,
			NULL, "%llu\n");

/**
 * l2_ia_debug_init() - Initialize L2 indirect access register debugfs
 */
static int l2_ia_debug_init(void)
{
	static struct dentry *debugfs_base;

	debugfs_base = debugfs_create_dir("l2_indirect", NULL);
	if (!debugfs_base)
		return -ENOMEM;

	if (!debugfs_create_file("get", S_IRUGO, debugfs_base, NULL,
				&l2_ia_get_fops))
		return -ENOMEM;

	if (!debugfs_create_file("set", S_IRUGO | S_IWUSR, debugfs_base, NULL,
				&l2_ia_set_fops))
		return -ENOMEM;

	if (!debugfs_create_file("address", S_IRUGO | S_IWUSR, debugfs_base,
				 NULL, &l2_ia_addr_fops))
		return -ENOMEM;

	if (!debugfs_create_file("target_cpu", S_IRUGO | S_IWUSR, debugfs_base,
				 NULL, &l2_ia_cpu_fops))
		return -ENOMEM;

	return 0;
}
late_initcall(l2_ia_debug_init);

#endif /* CONFIG_DEBUG_FS */