// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
 * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
 */

#include <linux/module.h>
#include <linux/debugfs.h>
#include <linux/clk.h>
#include <linux/slab.h>
#include <linux/clk-provider.h>
#include <linux/uaccess.h>
#include <linux/amlogic/clk_measure.h>
#include <linux/kallsyms.h>
#include <linux/arm-smccc.h>

static struct clk *debug_clk;

static ssize_t parent_write(struct file *file, const char __user *buffer,
			    size_t count, loff_t *ppos)
{
	int ret;
	char clk_name[20];
	char input[20];
	struct clk *clk;

	if (count >= sizeof(input)) {
		pr_err("wrong notice: clk_name too long  > 20, pls shorten clk_name\n");
		return -EINVAL;
	}

	if (copy_from_user(input, buffer, count))
		return -EFAULT;

	input[count] = '\0';

	ret = sscanf(input, "%s", clk_name);
	if (ret != 1) {
		pr_err("wrong usage, try: echo clk_name  > clk\n");
		return -EINVAL;
	}

	clk = clk_get_sys(clk_name, NULL);
	if (IS_ERR_OR_NULL(clk)) {  /* error code or NULL may be returned */
		pr_err("Can't find the clock, have a look in /sys/kernel/debug/clk\n");
		return -EPERM;
	}

	if (debug_clk) {
		ret = clk_set_parent(debug_clk, clk);
		if (ret < 0)
			pr_err("failed to set parent for %s\n",
			       __clk_get_name(debug_clk));
		else
			pr_info("now %s parent is %s\n",
				__clk_get_name(debug_clk),
				__clk_get_name(clk_get_parent(debug_clk)));
	} else {
		pr_err("try: echo clk_name > clk,echo clk_name > parent\n");
	}

	return count;
}

static ssize_t measure_write(struct file *file, const char __user *buffer,
			     size_t count, loff_t *ppos)
{
	int ret;
	char input[5];
	unsigned int id = 0, rate;

	count = min_t(size_t, count, (sizeof(input) - 1));
	if (copy_from_user(input, buffer, count))
		return -EFAULT;

	input[count] = '\0';

	ret = kstrtouint(input, 0, &id);
	if (ret)
		return -EINVAL;

	rate = meson_clk_measure(id);
	pr_info("Measure the index %u clock,its rate = %u\n", id, rate);

	return count;
}

static ssize_t enable_read(struct file *file, char __user *buffer,
			   size_t count, loff_t *ppos)
{
	char buf[4];
	unsigned int len;

	len = sprintf(buf, "%d\n", __clk_is_enabled(debug_clk) ? 1 : 0);

	return simple_read_from_buffer(buffer, count, ppos, buf, len);
}

static ssize_t enable_write(struct file *file, const char __user *buffer,
			    size_t count, loff_t *ppos)
{
	int ret;
	char *input;
	unsigned int enable = 0;

	input = kzalloc(count, GFP_KERNEL);
	if (!input) {
		kfree(input);
		return -ENOMEM;
	}
	if (copy_from_user(input, buffer, count)) {
		kfree(input);
		return -EFAULT;
	}

	ret = kstrtouint(input, 0, &enable);
	if (ret) {
		kfree(input);
		return -EINVAL;
	}

	if (enable != 0)
		clk_prepare_enable(debug_clk);
	else
		clk_disable_unprepare(debug_clk);

	kfree(input);
	return count;
}

static ssize_t rate_read(struct file *file, char __user *buffer,
			 size_t count, loff_t *ppos)
{
	/*
	 * the rate unit is HZ, need 16 char
	 */
	char buf[16];
	unsigned int len;

	len = sprintf(buf, "%lu\n", clk_get_rate(debug_clk));

	return simple_read_from_buffer(buffer, count, ppos, buf, len);
}

static ssize_t rate_write(struct file *file, const char __user *buffer,
			  size_t count, loff_t *ppos)
{
	int ret;
	char *input;
	unsigned long rate = 0;

	input = kzalloc(count, GFP_KERNEL);
	if (!input) {
		kfree(input);
		return -ENOMEM;
	}

	if (copy_from_user(input, buffer, count)) {
		kfree(input);
		return -EFAULT;
	}
	ret = kstrtoul(input, 0, &rate);
	if (ret) {
		kfree(input);
		return -EINVAL;
	}
	pr_info("input rate = %lu, old rate = %lu\n", rate,
		clk_get_rate(debug_clk));

	ret = clk_set_rate(debug_clk, rate);
	if (ret) {
		kfree(input);
		pr_err("failed to set rate,ret =%d\n", ret);
		return ret;
	}

	pr_info("current rate = %lu\n", clk_get_rate(debug_clk));

	kfree(input);

	return count;
}

static ssize_t clk_read(struct file *file, char __user *buffer,
			size_t count, loff_t *ppos)
{
	char buf[48];
	unsigned int len;

	len = sprintf(buf, "get %s clock, its rate = %lu\n",
		      __clk_get_name(debug_clk),
		      clk_get_rate(debug_clk));

	return simple_read_from_buffer(buffer, count, ppos, buf, len);
}

static ssize_t clk_write(struct file *file, const char __user *buffer,
			 size_t count, loff_t *ppos)
{
	int ret;
	char clk_name[20];
	char input[20];
	struct clk *clk;

	if (count >= sizeof(input)) {
		pr_err("wrong notice: clk_name too long  > 20, pls shorten clk_name\n");
		return -EINVAL;
	}

	if (copy_from_user(input, buffer, count))
		return -EFAULT;

	input[count] = '\0';

	ret = sscanf(input, "%s", clk_name);
	if (ret != 1) {
		pr_err("wrong usage, try: echo clk_name  > clk\n");
		return -EINVAL;
	}

	clk = clk_get_sys(clk_name, NULL);
	/* error code or NULL may be returned */
	if (!IS_ERR_OR_NULL(clk)) {
		pr_info("success get %s clock, its rate = %lu, its parent is %s\n",
			clk_name, clk_get_rate(clk), __clk_get_name(clk_get_parent(clk)));
		/* store the clk pointer */
		if (debug_clk)
			clk_put(debug_clk);

		debug_clk = clk;
	} else {
		pr_err("Can't find the clock, have a look in /sys/kernel/debug/clk.\n");
	}

	return count;
}

static ssize_t secure_reg_write(struct file *file, const char __user *buffer,
				size_t count, loff_t *ppos)
{
	int ret;
	char *input;
	unsigned long reg = 0;
	struct arm_smccc_res res;

	input = kzalloc(count, GFP_KERNEL);
	if (!input) {
		kfree(input);
		return -ENOMEM;
	}

	if (copy_from_user(input, buffer, count)) {
		kfree(input);
		return -EFAULT;
	}
	ret = kstrtoul(input, 0, &reg);
	if (ret) {
		kfree(input);
		return -EINVAL;
	}

	arm_smccc_smc(0x82000099, 0x30,
		      reg, 0, 0, 0, 0, 0, &res);

	kfree(input);

	return count;
}

static const struct file_operations parent_file_ops = {
	.open		= simple_open,
	.write		= parent_write,
};

static const struct file_operations measure_file_ops = {
	.open		= simple_open,
	.write		= measure_write,
};

static const struct file_operations enable_file_ops = {
	.open		= simple_open,
	.read		= enable_read,
	.write		= enable_write,
};

static const struct file_operations rate_file_ops = {
	.open		= simple_open,
	.read		= rate_read,
	.write		= rate_write,
};

static const struct file_operations clk_file_ops = {
	.open		= simple_open,
	.read		= clk_read,
	.write		= clk_write,
};

static const struct file_operations secure_file_ops = {
	.open		= simple_open,
	.write		= secure_reg_write,
};

int __init clk_debug_init(void)
{
	struct dentry *root;

	root = debugfs_create_dir("clk_debug", NULL);
	debugfs_create_file("clk", 0600, root, NULL, &clk_file_ops);
	debugfs_create_file("rate", 0600, root, NULL, &rate_file_ops);
	debugfs_create_file("enable", 0600, root, NULL, &enable_file_ops);
	debugfs_create_file("parent", 0200, root, NULL, &parent_file_ops);
	debugfs_create_file("measure", 0200, root, NULL, &measure_file_ops);
	debugfs_create_file("secure_reg", 0200, root, NULL, &secure_file_ops);

	return 0;
}

#ifndef MODULE
late_initcall_sync(clk_debug_init);
#endif

MODULE_DESCRIPTION("Amlogic meson clock debug driver");
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("jian hu <jian.hu@amlogic.com>");
