/*
 *
 * (C) COPYRIGHT 2017-2018 ARM Limited. All rights reserved.
 *
 * This program is free software and is provided to you under the terms of the
 * GNU General Public License version 2 as published by the Free Software
 * Foundation, and any use by you of this program is subject to the terms
 * of such GNU licence.
 *
 * 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.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, you can access it online at
 * http://www.gnu.org/licenses/gpl-2.0.html.
 *
 * SPDX-License-Identifier: GPL-2.0
 *
 */

#include <linux/debugfs.h>
#include <linux/list.h>
#include <linux/mutex.h>

#include "mali_kbase.h"
#include "mali_kbase_ipa.h"
#include "mali_kbase_ipa_debugfs.h"

#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 6, 0))
#define DEFINE_DEBUGFS_ATTRIBUTE DEFINE_SIMPLE_ATTRIBUTE
#endif

struct kbase_ipa_model_param {
	char *name;
	union {
		void *voidp;
		s32 *s32p;
		char *str;
	} addr;
	size_t size;
	enum kbase_ipa_model_param_type type;
	struct kbase_ipa_model *model;
	struct list_head link;
};

static int param_int_get(void *data, u64 *val)
{
	struct kbase_ipa_model_param *param = data;

	mutex_lock(&param->model->kbdev->ipa.lock);
	*(s64 *) val = *param->addr.s32p;
	mutex_unlock(&param->model->kbdev->ipa.lock);

	return 0;
}

static int param_int_set(void *data, u64 val)
{
	struct kbase_ipa_model_param *param = data;
	struct kbase_ipa_model *model = param->model;
	s64 sval = (s64) val;
	s32 old_val;
	int err = 0;

	if (sval < S32_MIN || sval > S32_MAX)
		return -ERANGE;

	mutex_lock(&param->model->kbdev->ipa.lock);
	old_val = *param->addr.s32p;
	*param->addr.s32p = val;
	err = kbase_ipa_model_recalculate(model);
	if (err < 0)
		*param->addr.s32p = old_val;
	mutex_unlock(&param->model->kbdev->ipa.lock);

	return err;
}

DEFINE_DEBUGFS_ATTRIBUTE(fops_s32, param_int_get, param_int_set, "%lld\n");

static ssize_t param_string_get(struct file *file, char __user *user_buf,
				size_t count, loff_t *ppos)
{
	struct kbase_ipa_model_param *param = file->private_data;
	ssize_t ret;
	size_t len;

	mutex_lock(&param->model->kbdev->ipa.lock);
	len = strnlen(param->addr.str, param->size - 1) + 1;
	ret = simple_read_from_buffer(user_buf, count, ppos,
				      param->addr.str, len);
	mutex_unlock(&param->model->kbdev->ipa.lock);

	return ret;
}

static ssize_t param_string_set(struct file *file, const char __user *user_buf,
				size_t count, loff_t *ppos)
{
	struct kbase_ipa_model_param *param = file->private_data;
	struct kbase_ipa_model *model = param->model;
	char *old_str = NULL;
	ssize_t ret = count;
	size_t buf_size;
	int err;

	mutex_lock(&model->kbdev->ipa.lock);

	if (count > param->size) {
		ret = -EINVAL;
		goto end;
	}

	old_str = kstrndup(param->addr.str, param->size, GFP_KERNEL);
	if (!old_str) {
		ret = -ENOMEM;
		goto end;
	}

	buf_size = min(param->size - 1, count);
	if (copy_from_user(param->addr.str, user_buf, buf_size)) {
		ret = -EFAULT;
		goto end;
	}

	param->addr.str[buf_size] = '\0';

	err = kbase_ipa_model_recalculate(model);
	if (err < 0) {
		ret = err;
		strlcpy(param->addr.str, old_str, param->size);
	}

end:
	kfree(old_str);
	mutex_unlock(&model->kbdev->ipa.lock);

	return ret;
}

static const struct file_operations fops_string = {
	.read = param_string_get,
	.write = param_string_set,
	.open = simple_open,
	.llseek = default_llseek,
};

int kbase_ipa_model_param_add(struct kbase_ipa_model *model, const char *name,
			      void *addr, size_t size,
			      enum kbase_ipa_model_param_type type)
{
	struct kbase_ipa_model_param *param;

	param = kzalloc(sizeof(*param), GFP_KERNEL);

	if (!param)
		return -ENOMEM;

	/* 'name' is stack-allocated for array elements, so copy it into
	 * heap-allocated storage */
	param->name = kstrdup(name, GFP_KERNEL);

	if (!param->name) {
		kfree(param);
		return -ENOMEM;
	}

	param->addr.voidp = addr;
	param->size = size;
	param->type = type;
	param->model = model;

	list_add(&param->link, &model->params);

	return 0;
}

void kbase_ipa_model_param_free_all(struct kbase_ipa_model *model)
{
	struct kbase_ipa_model_param *param_p, *param_n;

	list_for_each_entry_safe(param_p, param_n, &model->params, link) {
		list_del(&param_p->link);
		kfree(param_p->name);
		kfree(param_p);
	}
}

static int force_fallback_model_get(void *data, u64 *val)
{
	struct kbase_device *kbdev = data;

	mutex_lock(&kbdev->ipa.lock);
	*val = kbdev->ipa.force_fallback_model;
	mutex_unlock(&kbdev->ipa.lock);

	return 0;
}

static int force_fallback_model_set(void *data, u64 val)
{
	struct kbase_device *kbdev = data;

	mutex_lock(&kbdev->ipa.lock);
	kbdev->ipa.force_fallback_model = (val ? true : false);
	mutex_unlock(&kbdev->ipa.lock);

	return 0;
}

DEFINE_DEBUGFS_ATTRIBUTE(force_fallback_model,
		force_fallback_model_get,
		force_fallback_model_set,
		"%llu\n");

static int current_power_get(void *data, u64 *val)
{
	struct kbase_device *kbdev = data;
	struct devfreq *df = kbdev->devfreq;
	u32 power;

	kbase_pm_context_active(kbdev);
	kbase_get_real_power(df, &power,
		kbdev->current_nominal_freq, (kbdev->current_voltage / 1000));
	kbase_pm_context_idle(kbdev);

	*val = power;

	return 0;
}
DEFINE_DEBUGFS_ATTRIBUTE(current_power, current_power_get, NULL, "%llu\n");

static void kbase_ipa_model_debugfs_init(struct kbase_ipa_model *model)
{
	struct list_head *it;
	struct dentry *dir;

	lockdep_assert_held(&model->kbdev->ipa.lock);

	dir = debugfs_create_dir(model->ops->name,
				 model->kbdev->mali_debugfs_directory);

	if (!dir) {
		dev_err(model->kbdev->dev,
			"Couldn't create mali debugfs %s directory",
			model->ops->name);
		return;
	}

	list_for_each(it, &model->params) {
		struct kbase_ipa_model_param *param =
				list_entry(it,
					   struct kbase_ipa_model_param,
					   link);
		const struct file_operations *fops = NULL;

		switch (param->type) {
		case PARAM_TYPE_S32:
			fops = &fops_s32;
			break;
		case PARAM_TYPE_STRING:
			fops = &fops_string;
			break;
		}

		if (unlikely(!fops)) {
			dev_err(model->kbdev->dev,
				"Type not set for %s parameter %s\n",
				model->ops->name, param->name);
		} else {
			debugfs_create_file(param->name, S_IRUGO | S_IWUSR,
					    dir, param, fops);
		}
	}
}

void kbase_ipa_model_param_set_s32(struct kbase_ipa_model *model,
	const char *name, s32 val)
{
	struct kbase_ipa_model_param *param;

	mutex_lock(&model->kbdev->ipa.lock);

	list_for_each_entry(param, &model->params, link) {
		if (!strcmp(param->name, name)) {
			if (param->type == PARAM_TYPE_S32) {
				*param->addr.s32p = val;
			} else {
				dev_err(model->kbdev->dev,
					"Wrong type for %s parameter %s\n",
					model->ops->name, param->name);
			}
			break;
		}
	}

	mutex_unlock(&model->kbdev->ipa.lock);
}
KBASE_EXPORT_TEST_API(kbase_ipa_model_param_set_s32);

void kbase_ipa_debugfs_init(struct kbase_device *kbdev)
{
	mutex_lock(&kbdev->ipa.lock);

	if (kbdev->ipa.configured_model != kbdev->ipa.fallback_model)
		kbase_ipa_model_debugfs_init(kbdev->ipa.configured_model);
	kbase_ipa_model_debugfs_init(kbdev->ipa.fallback_model);

	debugfs_create_file("ipa_current_power", 0444,
		kbdev->mali_debugfs_directory, kbdev, &current_power);
	debugfs_create_file("ipa_force_fallback_model", 0644,
		kbdev->mali_debugfs_directory, kbdev, &force_fallback_model);

	mutex_unlock(&kbdev->ipa.lock);
}
