// SPDX-License-Identifier: GPL-2.0-only
/*
 * Generic OPP debugfs interface
 *
 * Copyright (C) 2015-2016 Viresh Kumar <viresh.kumar@linaro.org>
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/debugfs.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/of.h>
#include <linux/init.h>
#include <linux/limits.h>
#include <linux/slab.h>

#include "opp.h"

static struct dentry *rootdir;

static void opp_set_dev_name(const struct device *dev, char *name)
{
	if (dev->parent)
		snprintf(name, NAME_MAX, "%s-%s", dev_name(dev->parent),
			 dev_name(dev));
	else
		snprintf(name, NAME_MAX, "%s", dev_name(dev));
}

void opp_debug_remove_one(struct dev_pm_opp *opp)
{
	debugfs_remove_recursive(opp->dentry);
}

static ssize_t bw_name_read(struct file *fp, char __user *userbuf,
			    size_t count, loff_t *ppos)
{
	struct icc_path *path = fp->private_data;
	const char *name = icc_get_name(path);
	char buf[64];
	int i = 0;

	if (name)
		i = scnprintf(buf, sizeof(buf), "%.62s\n", name);

	return simple_read_from_buffer(userbuf, count, ppos, buf, i);
}

static const struct file_operations bw_name_fops = {
	.open = simple_open,
	.read = bw_name_read,
	.llseek = default_llseek,
};

static void opp_debug_create_bw(struct dev_pm_opp *opp,
				struct opp_table *opp_table,
				struct dentry *pdentry)
{
	struct dentry *d;
	char name[] = "icc-path-XXXXXXXXXXX"; /* Integers can take 11 chars max */
	int i;

	for (i = 0; i < opp_table->path_count; i++) {
		snprintf(name, sizeof(name), "icc-path-%d", i);

		/* Create per-path directory */
		d = debugfs_create_dir(name, pdentry);

		debugfs_create_file("name", S_IRUGO, d, opp_table->paths[i],
				    &bw_name_fops);
		debugfs_create_u32("peak_bw", S_IRUGO, d,
				   &opp->bandwidth[i].peak);
		debugfs_create_u32("avg_bw", S_IRUGO, d,
				   &opp->bandwidth[i].avg);
	}
}

static void opp_debug_create_clks(struct dev_pm_opp *opp,
				  struct opp_table *opp_table,
				  struct dentry *pdentry)
{
	char name[] = "rate_hz_XXXXXXXXXXX"; /* Integers can take 11 chars max */
	int i;

	if (opp_table->clk_count == 1) {
		debugfs_create_ulong("rate_hz", S_IRUGO, pdentry, &opp->rates[0]);
		return;
	}

	for (i = 0; i < opp_table->clk_count; i++) {
		snprintf(name, sizeof(name), "rate_hz_%d", i);
		debugfs_create_ulong(name, S_IRUGO, pdentry, &opp->rates[i]);
	}
}

static void opp_debug_create_supplies(struct dev_pm_opp *opp,
				      struct opp_table *opp_table,
				      struct dentry *pdentry)
{
	struct dentry *d;
	int i;

	for (i = 0; i < opp_table->regulator_count; i++) {
		char name[] = "supply-XXXXXXXXXXX"; /* Integers can take 11 chars max */

		snprintf(name, sizeof(name), "supply-%d", i);

		/* Create per-opp directory */
		d = debugfs_create_dir(name, pdentry);

		debugfs_create_ulong("u_volt_target", S_IRUGO, d,
				     &opp->supplies[i].u_volt);

		debugfs_create_ulong("u_volt_min", S_IRUGO, d,
				     &opp->supplies[i].u_volt_min);

		debugfs_create_ulong("u_volt_max", S_IRUGO, d,
				     &opp->supplies[i].u_volt_max);

		debugfs_create_ulong("u_amp", S_IRUGO, d,
				     &opp->supplies[i].u_amp);

		debugfs_create_ulong("u_watt", S_IRUGO, d,
				     &opp->supplies[i].u_watt);
	}
}

void opp_debug_create_one(struct dev_pm_opp *opp, struct opp_table *opp_table)
{
	struct dentry *pdentry = opp_table->dentry;
	struct dentry *d;
	char name[36];	/* "opp:"(4) + u64(20) + "-" (1) + u32(10) + NULL(1) */

	/*
	 * Get directory name for OPP.
	 *
	 * - Normally rate is unique to each OPP, use it to get unique opp-name,
	 *   together with performance level if available.
	 * - For some devices rate isn't available or there are multiple, use
	 *   index instead for them.
	 */
	if (likely(opp_table->clk_count == 1 && opp->rates[0])) {
		if (opp->level == OPP_LEVEL_UNSET)
			snprintf(name, sizeof(name), "opp:%lu", opp->rates[0]);
		else
			snprintf(name, sizeof(name), "opp:%lu-%u", opp->rates[0], opp->level);
	} else {
		snprintf(name, sizeof(name), "opp:%u", _get_opp_count(opp_table));
	}

	/* Create per-opp directory */
	d = debugfs_create_dir(name, pdentry);

	debugfs_create_bool("available", S_IRUGO, d, &opp->available);
	debugfs_create_bool("dynamic", S_IRUGO, d, &opp->dynamic);
	debugfs_create_bool("turbo", S_IRUGO, d, &opp->turbo);
	debugfs_create_bool("suspend", S_IRUGO, d, &opp->suspend);
	debugfs_create_u32("level", S_IRUGO, d, &opp->level);
	debugfs_create_ulong("clock_latency_ns", S_IRUGO, d,
			     &opp->clock_latency_ns);

	opp->of_name = of_node_full_name(opp->np);
	debugfs_create_str("of_name", S_IRUGO, d, (char **)&opp->of_name);

	opp_debug_create_clks(opp, opp_table, d);
	opp_debug_create_supplies(opp, opp_table, d);
	opp_debug_create_bw(opp, opp_table, d);

	opp->dentry = d;
}

static void opp_list_debug_create_dir(struct opp_device *opp_dev,
				      struct opp_table *opp_table)
{
	const struct device *dev = opp_dev->dev;
	struct dentry *d;

	opp_set_dev_name(dev, opp_table->dentry_name);

	/* Create device specific directory */
	d = debugfs_create_dir(opp_table->dentry_name, rootdir);

	opp_dev->dentry = d;
	opp_table->dentry = d;
}

static void opp_list_debug_create_link(struct opp_device *opp_dev,
				       struct opp_table *opp_table)
{
	char name[NAME_MAX];

	opp_set_dev_name(opp_dev->dev, name);

	/* Create device specific directory link */
	opp_dev->dentry = debugfs_create_symlink(name, rootdir,
						 opp_table->dentry_name);
}

/**
 * opp_debug_register - add a device opp node to the debugfs 'opp' directory
 * @opp_dev: opp-dev pointer for device
 * @opp_table: the device-opp being added
 *
 * Dynamically adds device specific directory in debugfs 'opp' directory. If the
 * device-opp is shared with other devices, then links will be created for all
 * devices except the first.
 */
void opp_debug_register(struct opp_device *opp_dev, struct opp_table *opp_table)
{
	if (opp_table->dentry)
		opp_list_debug_create_link(opp_dev, opp_table);
	else
		opp_list_debug_create_dir(opp_dev, opp_table);
}

static void opp_migrate_dentry(struct opp_device *opp_dev,
			       struct opp_table *opp_table)
{
	struct opp_device *new_dev = NULL, *iter;
	const struct device *dev;
	int err;

	/* Look for next opp-dev */
	list_for_each_entry(iter, &opp_table->dev_list, node)
		if (iter != opp_dev) {
			new_dev = iter;
			break;
		}

	BUG_ON(!new_dev);

	/* new_dev is guaranteed to be valid here */
	dev = new_dev->dev;
	debugfs_remove_recursive(new_dev->dentry);

	opp_set_dev_name(dev, opp_table->dentry_name);

	err = debugfs_change_name(opp_dev->dentry, "%s", opp_table->dentry_name);
	if (err) {
		dev_err(dev, "%s: Failed to rename link from: %s to %s\n",
			__func__, dev_name(opp_dev->dev), dev_name(dev));
		return;
	}

	new_dev->dentry = opp_table->dentry = opp_dev->dentry;
}

/**
 * opp_debug_unregister - remove a device opp node from debugfs opp directory
 * @opp_dev: opp-dev pointer for device
 * @opp_table: the device-opp being removed
 *
 * Dynamically removes device specific directory from debugfs 'opp' directory.
 */
void opp_debug_unregister(struct opp_device *opp_dev,
			  struct opp_table *opp_table)
{
	if (opp_dev->dentry == opp_table->dentry) {
		/* Move the real dentry object under another device */
		if (!list_is_singular(&opp_table->dev_list)) {
			opp_migrate_dentry(opp_dev, opp_table);
			goto out;
		}
		opp_table->dentry = NULL;
	}

	debugfs_remove_recursive(opp_dev->dentry);

out:
	opp_dev->dentry = NULL;
}

static int __init opp_debug_init(void)
{
	/* Create /sys/kernel/debug/opp directory */
	rootdir = debugfs_create_dir("opp", NULL);

	return 0;
}
core_initcall(opp_debug_init);
