// SPDX-License-Identifier: MIT
/*
 * Copyright © 2020 Intel Corporation
 */

#include <linux/fs.h>
#include <drm/drm_print.h>

#include "gt/debugfs_gt.h"
#include "intel_guc.h"
#include "intel_guc_log.h"
#include "intel_guc_log_debugfs.h"

static int guc_log_dump_show(struct seq_file *m, void *data)
{
	struct drm_printer p = drm_seq_file_printer(m);

	return intel_guc_log_dump(m->private, &p, false);
}
DEFINE_GT_DEBUGFS_ATTRIBUTE(guc_log_dump);

static int guc_load_err_log_dump_show(struct seq_file *m, void *data)
{
	struct drm_printer p = drm_seq_file_printer(m);

	return intel_guc_log_dump(m->private, &p, true);
}
DEFINE_GT_DEBUGFS_ATTRIBUTE(guc_load_err_log_dump);

static int guc_log_level_get(void *data, u64 *val)
{
	struct intel_guc_log *log = data;

	if (!intel_guc_is_used(log_to_guc(log)))
		return -ENODEV;

	*val = intel_guc_log_get_level(log);

	return 0;
}

static int guc_log_level_set(void *data, u64 val)
{
	struct intel_guc_log *log = data;

	if (!intel_guc_is_used(log_to_guc(log)))
		return -ENODEV;

	return intel_guc_log_set_level(log, val);
}

DEFINE_SIMPLE_ATTRIBUTE(guc_log_level_fops,
			guc_log_level_get, guc_log_level_set,
			"%lld\n");

static int guc_log_relay_open(struct inode *inode, struct file *file)
{
	struct intel_guc_log *log = inode->i_private;

	if (!intel_guc_is_ready(log_to_guc(log)))
		return -ENODEV;

	file->private_data = log;

	return intel_guc_log_relay_open(log);
}

static ssize_t
guc_log_relay_write(struct file *filp,
		    const char __user *ubuf,
		    size_t cnt,
		    loff_t *ppos)
{
	struct intel_guc_log *log = filp->private_data;
	int val;
	int ret;

	ret = kstrtoint_from_user(ubuf, cnt, 0, &val);
	if (ret < 0)
		return ret;

	/*
	 * Enable and start the guc log relay on value of 1.
	 * Flush log relay for any other value.
	 */
	if (val == 1)
		ret = intel_guc_log_relay_start(log);
	else
		intel_guc_log_relay_flush(log);

	return ret ?: cnt;
}

static int guc_log_relay_release(struct inode *inode, struct file *file)
{
	struct intel_guc_log *log = inode->i_private;

	intel_guc_log_relay_close(log);
	return 0;
}

static const struct file_operations guc_log_relay_fops = {
	.owner = THIS_MODULE,
	.open = guc_log_relay_open,
	.write = guc_log_relay_write,
	.release = guc_log_relay_release,
};

void intel_guc_log_debugfs_register(struct intel_guc_log *log,
				    struct dentry *root)
{
	static const struct debugfs_gt_file files[] = {
		{ "guc_log_dump", &guc_log_dump_fops, NULL },
		{ "guc_load_err_log_dump", &guc_load_err_log_dump_fops, NULL },
		{ "guc_log_level", &guc_log_level_fops, NULL },
		{ "guc_log_relay", &guc_log_relay_fops, NULL },
	};

	if (!intel_guc_is_supported(log_to_guc(log)))
		return;

	intel_gt_debugfs_register_files(root, files, ARRAY_SIZE(files), log);
}

