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

#include <linux/debugfs.h>
#include <linux/kernel.h>

#include <drm/drm_drv.h>

#include "intel_display_debugfs_params.h"
#include "i915_drv.h"
#include "intel_display_params.h"

/* int param */
static int intel_display_param_int_show(struct seq_file *m, void *data)
{
	int *value = m->private;

	seq_printf(m, "%d\n", *value);

	return 0;
}

static int intel_display_param_int_open(struct inode *inode, struct file *file)
{
	return single_open(file, intel_display_param_int_show, inode->i_private);
}

static ssize_t intel_display_param_int_write(struct file *file,
					     const char __user *ubuf, size_t len,
					     loff_t *offp)
{
	struct seq_file *m = file->private_data;
	int *value = m->private;
	int ret;

	ret = kstrtoint_from_user(ubuf, len, 0, value);
	if (ret) {
		/* support boolean values too */
		bool b;

		ret = kstrtobool_from_user(ubuf, len, &b);
		if (!ret)
			*value = b;
	}

	return ret ?: len;
}

static const struct file_operations intel_display_param_int_fops = {
	.owner = THIS_MODULE,
	.open = intel_display_param_int_open,
	.read = seq_read,
	.write = intel_display_param_int_write,
	.llseek = default_llseek,
	.release = single_release,
};

static const struct file_operations intel_display_param_int_fops_ro = {
	.owner = THIS_MODULE,
	.open = intel_display_param_int_open,
	.read = seq_read,
	.llseek = default_llseek,
	.release = single_release,
};

/* unsigned int param */
static int intel_display_param_uint_show(struct seq_file *m, void *data)
{
	unsigned int *value = m->private;

	seq_printf(m, "%u\n", *value);

	return 0;
}

static int intel_display_param_uint_open(struct inode *inode, struct file *file)
{
	return single_open(file, intel_display_param_uint_show, inode->i_private);
}

static ssize_t intel_display_param_uint_write(struct file *file,
					      const char __user *ubuf, size_t len,
					      loff_t *offp)
{
	struct seq_file *m = file->private_data;
	unsigned int *value = m->private;
	int ret;

	ret = kstrtouint_from_user(ubuf, len, 0, value);
	if (ret) {
		/* support boolean values too */
		bool b;

		ret = kstrtobool_from_user(ubuf, len, &b);
		if (!ret)
			*value = b;
	}

	return ret ?: len;
}

static const struct file_operations intel_display_param_uint_fops = {
	.owner = THIS_MODULE,
	.open = intel_display_param_uint_open,
	.read = seq_read,
	.write = intel_display_param_uint_write,
	.llseek = default_llseek,
	.release = single_release,
};

static const struct file_operations intel_display_param_uint_fops_ro = {
	.owner = THIS_MODULE,
	.open = intel_display_param_uint_open,
	.read = seq_read,
	.llseek = default_llseek,
	.release = single_release,
};

#define RO(mode) (((mode) & 0222) == 0)

__maybe_unused static struct dentry *
intel_display_debugfs_create_int(const char *name, umode_t mode,
			struct dentry *parent, int *value)
{
	return debugfs_create_file_unsafe(name, mode, parent, value,
					  RO(mode) ? &intel_display_param_int_fops_ro :
					  &intel_display_param_int_fops);
}

__maybe_unused static struct dentry *
intel_display_debugfs_create_uint(const char *name, umode_t mode,
			 struct dentry *parent, unsigned int *value)
{
	return debugfs_create_file_unsafe(name, mode, parent, value,
					  RO(mode) ? &intel_display_param_uint_fops_ro :
					  &intel_display_param_uint_fops);
}

#define _intel_display_param_create_file(parent, name, mode, valp)	\
	do {								\
		if (mode)						\
			_Generic(valp,					\
				 bool * : debugfs_create_bool,		\
				 int * : intel_display_debugfs_create_int, \
				 unsigned int * : intel_display_debugfs_create_uint, \
				 unsigned long * : debugfs_create_ulong, \
				 char ** : debugfs_create_str) \
				(name, mode, parent, valp);		\
	} while (0)

/* add a subdirectory with files for each intel display param */
void intel_display_debugfs_params(struct drm_i915_private *i915)
{
	struct drm_minor *minor = i915->drm.primary;
	struct dentry *dir;
	char dirname[16];

	snprintf(dirname, sizeof(dirname), "%s_params", i915->drm.driver->name);
	dir = debugfs_lookup(dirname, minor->debugfs_root);
	if (!dir)
		dir = debugfs_create_dir(dirname, minor->debugfs_root);
	if (IS_ERR(dir))
		return;

	/*
	 * Note: We could create files for params needing special handling
	 * here. Set mode in params to 0 to skip the generic create file, or
	 * just let the generic create file fail silently with -EEXIST.
	 */

#define REGISTER(T, x, unused, mode, ...) _intel_display_param_create_file( \
		dir, #x, mode, &i915->display.params.x);
	INTEL_DISPLAY_PARAMS_FOR_EACH(REGISTER);
#undef REGISTER
}
