summaryrefslogtreecommitdiff
path: root/drivers/devfreq/devfreq_spdm_debugfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/devfreq/devfreq_spdm_debugfs.c')
-rw-r--r--drivers/devfreq/devfreq_spdm_debugfs.c456
1 files changed, 456 insertions, 0 deletions
diff --git a/drivers/devfreq/devfreq_spdm_debugfs.c b/drivers/devfreq/devfreq_spdm_debugfs.c
new file mode 100644
index 000000000000..ef7ac3323ce2
--- /dev/null
+++ b/drivers/devfreq/devfreq_spdm_debugfs.c
@@ -0,0 +1,456 @@
+/*
+*Copyright (c) 2014, The Linux Foundation. All rights reserved.
+*
+*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
+*only version 2 as published by the Free Software Foundation.
+*
+*This program is distributed in the hope that it will be useful,
+*but WITHOUT ANY WARRANTY; without even the implied warranty of
+*MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+*GNU General Public License for more details.
+*/
+#include <linux/debugfs.h>
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+#include <soc/qcom/hvc.h>
+#include "devfreq_spdm.h"
+
+static int spdm_open(struct inode *inode, struct file *file)
+{
+ file->private_data = inode->i_private;
+ return 0;
+}
+
+static ssize_t pl_write(struct file *file, const char __user *data,
+ size_t size, loff_t *offset)
+{
+ struct spdm_data *spdm_data = file->private_data;
+ char *buf;
+ struct hvc_desc desc;
+ int i;
+
+ buf = kzalloc(size, GFP_KERNEL);
+
+ if (!buf)
+ return -ENOMEM;
+ if (copy_from_user(buf, data, size))
+ return -EINVAL;
+
+ sscanf(buf, "%u %u\n", &spdm_data->config_data.pl_freqs[0],
+ &spdm_data->config_data.pl_freqs[1]);
+
+
+ desc.arg[0] = SPDM_CMD_CFG_PL;
+ desc.arg[1] = spdm_data->spdm_client;
+ for (i = 0; i < SPDM_PL_COUNT - 1; i++)
+ desc.arg[i+2] = spdm_data->config_data.pl_freqs[i];
+ if (hvc(HVC_FN_SIP(SPDM_HYP_FNID), &desc))
+ pr_debug("check hvc logs");
+ *offset += size;
+ kfree(buf);
+ return size;
+}
+
+static const struct file_operations pl_fops = {
+ .open = spdm_open,
+ .write = pl_write,
+};
+
+static ssize_t rejrate_low_write(struct file *file, const char __user *data,
+ size_t size, loff_t *offset)
+{
+ struct spdm_data *spdm_data = file->private_data;
+ char *buf;
+ struct hvc_desc desc;
+
+ buf = kzalloc(size, GFP_KERNEL);
+
+ if (!buf)
+ return -ENOMEM;
+ if (copy_from_user(buf, data, size))
+ return -EINVAL;
+
+ sscanf(buf, "%u %u\n", &spdm_data->config_data.reject_rate[0],
+ &spdm_data->config_data.reject_rate[1]);
+
+ desc.arg[0] = SPDM_CMD_CFG_REJRATE_LOW;
+ desc.arg[1] = spdm_data->spdm_client;
+ desc.arg[2] = spdm_data->config_data.reject_rate[0];
+ desc.arg[3] = spdm_data->config_data.reject_rate[1];
+ if (hvc(HVC_FN_SIP(SPDM_HYP_FNID), &desc))
+ pr_debug("check hvc logs");
+ *offset += size;
+ kfree(buf);
+ return size;
+}
+
+static const struct file_operations rrl_fops = {
+ .open = spdm_open,
+ .write = rejrate_low_write,
+};
+
+static ssize_t rejrate_med_write(struct file *file, const char __user *data,
+ size_t size, loff_t *offset)
+{
+ struct spdm_data *spdm_data = file->private_data;
+ char *buf;
+ struct hvc_desc desc;
+
+ buf = kzalloc(size, GFP_KERNEL);
+
+ if (!buf)
+ return -ENOMEM;
+ if (copy_from_user(buf, data, size))
+ return -EINVAL;
+ sscanf(buf, "%u %u\n", &spdm_data->config_data.reject_rate[2],
+ &spdm_data->config_data.reject_rate[3]);
+
+ desc.arg[0] = SPDM_CMD_CFG_REJRATE_MED;
+ desc.arg[1] = spdm_data->spdm_client;
+ desc.arg[2] = spdm_data->config_data.reject_rate[2];
+ desc.arg[3] = spdm_data->config_data.reject_rate[3];
+ if (hvc(HVC_FN_SIP(SPDM_HYP_FNID), &desc))
+ pr_debug("check hvc logs");
+ *offset += size;
+ kfree(buf);
+ return size;
+}
+
+static const struct file_operations rrm_fops = {
+ .open = spdm_open,
+ .write = rejrate_med_write,
+};
+
+static ssize_t rejrate_high_write(struct file *file, const char __user *data,
+ size_t size, loff_t *offset)
+{
+ struct spdm_data *spdm_data = file->private_data;
+ char *buf;
+ struct hvc_desc desc;
+
+ buf = kzalloc(size, GFP_KERNEL);
+
+ if (!buf)
+ return -ENOMEM;
+ if (copy_from_user(buf, data, size))
+ return -EINVAL;
+ sscanf(buf, "%u %u\n", &spdm_data->config_data.reject_rate[4],
+ &spdm_data->config_data.reject_rate[5]);
+
+ desc.arg[0] = SPDM_CMD_CFG_REJRATE_HIGH;
+ desc.arg[1] = spdm_data->spdm_client;
+ desc.arg[2] = spdm_data->config_data.reject_rate[4];
+ desc.arg[3] = spdm_data->config_data.reject_rate[5];
+ if (hvc(HVC_FN_SIP(SPDM_HYP_FNID), &desc))
+ pr_debug("check hvc logs");
+ *offset += size;
+ kfree(buf);
+ return size;
+}
+
+static const struct file_operations rrh_fops = {
+ .open = spdm_open,
+ .write = rejrate_high_write,
+};
+
+static ssize_t resptime_low_write(struct file *file, const char __user *data,
+ size_t size, loff_t *offset)
+{
+ struct spdm_data *spdm_data = file->private_data;
+ char *buf;
+ struct hvc_desc desc;
+
+ buf = kzalloc(size, GFP_KERNEL);
+
+ if (!buf)
+ return -ENOMEM;
+ if (copy_from_user(buf, data, size))
+ return -EINVAL;
+ sscanf(buf, "%u %u\n", &spdm_data->config_data.response_time_us[0],
+ &spdm_data->config_data.response_time_us[1]);
+
+ desc.arg[0] = SPDM_CMD_CFG_RESPTIME_LOW;
+ desc.arg[1] = spdm_data->spdm_client;
+ desc.arg[2] = spdm_data->config_data.response_time_us[0];
+ desc.arg[3] = spdm_data->config_data.response_time_us[1];
+ if (hvc(HVC_FN_SIP(SPDM_HYP_FNID), &desc))
+ pr_debug("check hvc logs");
+ *offset += size;
+ kfree(buf);
+ return size;
+}
+
+static const struct file_operations rtl_fops = {
+ .open = spdm_open,
+ .write = resptime_low_write,
+};
+
+static ssize_t resptime_med_write(struct file *file, const char __user *data,
+ size_t size, loff_t *offset)
+{
+ struct spdm_data *spdm_data = file->private_data;
+ char *buf;
+ struct hvc_desc desc;
+
+ buf = kzalloc(size, GFP_KERNEL);
+
+ if (!buf)
+ return -ENOMEM;
+ if (copy_from_user(buf, data, size))
+ return -EINVAL;
+ sscanf(buf, "%u %u\n", &spdm_data->config_data.response_time_us[2],
+ &spdm_data->config_data.response_time_us[3]);
+
+ desc.arg[0] = SPDM_CMD_CFG_RESPTIME_MED;
+ desc.arg[1] = spdm_data->spdm_client;
+ desc.arg[2] = spdm_data->config_data.response_time_us[2];
+ desc.arg[3] = spdm_data->config_data.response_time_us[3];
+ if (hvc(HVC_FN_SIP(SPDM_HYP_FNID), &desc))
+ pr_debug("check hvc logs");
+ *offset += size;
+ kfree(buf);
+ return size;
+}
+
+static const struct file_operations rtm_fops = {
+ .open = spdm_open,
+ .write = resptime_med_write,
+};
+
+static ssize_t resptime_high_write(struct file *file, const char __user *data,
+ size_t size, loff_t *offset)
+{
+ struct spdm_data *spdm_data = file->private_data;
+ char *buf;
+ struct hvc_desc desc;
+
+ buf = kzalloc(size, GFP_KERNEL);
+
+ if (!buf)
+ return -ENOMEM;
+ if (copy_from_user(buf, data, size))
+ return -EINVAL;
+ sscanf(buf, "%u %u\n", &spdm_data->config_data.response_time_us[4],
+ &spdm_data->config_data.response_time_us[5]);
+
+ desc.arg[0] = SPDM_CMD_CFG_RESPTIME_HIGH;
+ desc.arg[1] = spdm_data->spdm_client;
+ desc.arg[2] = spdm_data->config_data.response_time_us[4];
+ desc.arg[3] = spdm_data->config_data.response_time_us[5];
+ if (hvc(HVC_FN_SIP(SPDM_HYP_FNID), &desc))
+ pr_debug("check hvc logs");
+ *offset += size;
+ kfree(buf);
+ return size;
+}
+
+static const struct file_operations rth_fops = {
+ .open = spdm_open,
+ .write = resptime_high_write,
+};
+
+static ssize_t cciresptime_low_write(struct file *file, const char __user *data,
+ size_t size, loff_t *offset)
+{
+ struct spdm_data *spdm_data = file->private_data;
+ char *buf;
+ struct hvc_desc desc;
+
+ buf = kzalloc(size, GFP_KERNEL);
+
+ if (!buf)
+ return -ENOMEM;
+ if (copy_from_user(buf, data, size))
+ return -EINVAL;
+ sscanf(buf, "%u %u\n", &spdm_data->config_data.cci_response_time_us[0],
+ &spdm_data->config_data.cci_response_time_us[1]);
+
+ desc.arg[0] = SPDM_CMD_CFG_CCIRESPTIME_LOW;
+ desc.arg[1] = spdm_data->spdm_client;
+ desc.arg[2] = spdm_data->config_data.cci_response_time_us[0];
+ desc.arg[3] = spdm_data->config_data.cci_response_time_us[1];
+ if (hvc(HVC_FN_SIP(SPDM_HYP_FNID), &desc))
+ pr_debug("check hvc logs");
+ *offset += size;
+ kfree(buf);
+ return size;
+}
+
+static const struct file_operations ccil_fops = {
+ .open = spdm_open,
+ .write = cciresptime_low_write,
+};
+
+static ssize_t cciresptime_med_write(struct file *file, const char __user *data,
+ size_t size, loff_t *offset)
+{
+ struct spdm_data *spdm_data = file->private_data;
+ char *buf;
+ struct hvc_desc desc;
+
+ buf = kzalloc(size, GFP_KERNEL);
+
+ if (!buf)
+ return -ENOMEM;
+ if (copy_from_user(buf, data, size))
+ return -EINVAL;
+ sscanf(buf, "%u %u\n", &spdm_data->config_data.cci_response_time_us[2],
+ &spdm_data->config_data.cci_response_time_us[3]);
+
+ desc.arg[0] = SPDM_CMD_CFG_CCIRESPTIME_MED;
+ desc.arg[1] = spdm_data->spdm_client;
+ desc.arg[2] = spdm_data->config_data.cci_response_time_us[2];
+ desc.arg[3] = spdm_data->config_data.cci_response_time_us[3];
+ if (hvc(HVC_FN_SIP(SPDM_HYP_FNID), &desc))
+ pr_debug("check hvc logs");
+ *offset += size;
+ kfree(buf);
+ return size;
+}
+
+static const struct file_operations ccim_fops = {
+ .open = spdm_open,
+ .write = cciresptime_med_write,
+};
+
+static ssize_t cciresptime_high_write(struct file *file,
+ const char __user *data,
+ size_t size, loff_t *offset)
+{
+ struct spdm_data *spdm_data = file->private_data;
+ char *buf;
+ struct hvc_desc desc;
+
+ buf = kzalloc(size, GFP_KERNEL);
+
+ if (!buf)
+ return -ENOMEM;
+ if (copy_from_user(buf, data, size))
+ return -EINVAL;
+ sscanf(buf, "%u %u\n", &spdm_data->config_data.cci_response_time_us[4],
+ &spdm_data->config_data.cci_response_time_us[5]);
+
+ desc.arg[0] = SPDM_CMD_CFG_CCIRESPTIME_HIGH;
+ desc.arg[1] = spdm_data->spdm_client;
+ desc.arg[2] = spdm_data->config_data.cci_response_time_us[4];
+ desc.arg[3] = spdm_data->config_data.cci_response_time_us[5];
+ if (hvc(HVC_FN_SIP(SPDM_HYP_FNID), &desc))
+ pr_debug("check hvc logs");
+ *offset += size;
+ kfree(buf);
+ return size;
+}
+
+static const struct file_operations ccih_fops = {
+ .open = spdm_open,
+ .write = cciresptime_high_write,
+};
+
+static ssize_t cci_max_write(struct file *file, const char __user *data,
+ size_t size, loff_t *offset)
+{
+ struct spdm_data *spdm_data = file->private_data;
+ char *buf;
+ struct hvc_desc desc;
+
+ buf = kzalloc(size, GFP_KERNEL);
+
+ if (!buf)
+ return -ENOMEM;
+ if (copy_from_user(buf, data, size))
+ return -EINVAL;
+ sscanf(buf, "%u\n", &spdm_data->config_data.max_cci_freq);
+
+ desc.arg[0] = SPDM_CMD_CFG_MAXCCI;
+ desc.arg[1] = spdm_data->spdm_client;
+ desc.arg[2] = spdm_data->config_data.max_cci_freq;
+ if (hvc(HVC_FN_SIP(SPDM_HYP_FNID), &desc))
+ pr_debug("check hvc logs");
+ *offset += size;
+ kfree(buf);
+ return size;
+}
+
+static const struct file_operations ccimax_fops = {
+ .open = spdm_open,
+ .write = cci_max_write,
+};
+
+static ssize_t vote_cfg_write(struct file *file, const char __user *data,
+ size_t size, loff_t *offset)
+{
+ struct spdm_data *spdm_data = file->private_data;
+ char *buf;
+ struct hvc_desc desc;
+
+ buf = kzalloc(size, GFP_KERNEL);
+
+ if (!buf)
+ return -ENOMEM;
+ if (copy_from_user(buf, data, size))
+ return -EINVAL;
+ sscanf(buf, "%u %u %u %u\n", &spdm_data->config_data.upstep,
+ &spdm_data->config_data.downstep,
+ &spdm_data->config_data.max_vote,
+ &spdm_data->config_data.up_step_multp);
+
+ desc.arg[0] = SPDM_CMD_CFG_VOTES;
+ desc.arg[1] = spdm_data->spdm_client;
+ desc.arg[2] = spdm_data->config_data.upstep;
+ desc.arg[3] = spdm_data->config_data.downstep;
+ desc.arg[4] = spdm_data->config_data.max_vote;
+ desc.arg[5] = spdm_data->config_data.up_step_multp;
+ if (hvc(HVC_FN_SIP(SPDM_HYP_FNID), &desc))
+ pr_debug("check hvc logs");
+ *offset += size;
+ kfree(buf);
+ return size;
+}
+
+static const struct file_operations vote_fops = {
+ .open = spdm_open,
+ .write = vote_cfg_write,
+};
+
+void spdm_init_debugfs(struct device *dev)
+{
+ struct spdm_data *data = 0;
+
+ data = dev_get_drvdata(dev);
+ data->debugfs_dir = debugfs_create_dir(dev_name(dev), NULL);
+
+ debugfs_create_file("pl_freqs", 0x700, data->debugfs_dir, data,
+ &pl_fops);
+ debugfs_create_file("rej_rate_low", 0x700, data->debugfs_dir, data,
+ &rrl_fops);
+ debugfs_create_file("rej_rate_med", 0x700, data->debugfs_dir, data,
+ &rrm_fops);
+ debugfs_create_file("rej_rate_high", 0x700, data->debugfs_dir, data,
+ &rrh_fops);
+ debugfs_create_file("resp_time_low", 0x700, data->debugfs_dir, data,
+ &rtl_fops);
+ debugfs_create_file("resp_time_med", 0x700, data->debugfs_dir, data,
+ &rtm_fops);
+ debugfs_create_file("resp_time_high", 0x700, data->debugfs_dir, data,
+ &rth_fops);
+ debugfs_create_file("cci_resp_time_low", 0x700, data->debugfs_dir, data,
+ &ccil_fops);
+ debugfs_create_file("cci_resp_time_med", 0x700, data->debugfs_dir, data,
+ &ccim_fops);
+ debugfs_create_file("cci_resp_time_high", 0x700, data->debugfs_dir,
+ data, &ccih_fops);
+ debugfs_create_file("cci_max", 0x700, data->debugfs_dir, data,
+ &ccimax_fops);
+ debugfs_create_file("vote_cfg", 0x700, data->debugfs_dir, data,
+ &vote_fops);
+}
+
+void spdm_remove_debugfs(struct spdm_data *data)
+{
+ debugfs_remove_recursive(data->debugfs_dir);
+}
+
+MODULE_LICENSE("GPL v2");