/*
 * Architecture specific debugfs files
 *
 * Copyright (C) 2007, Intel Corp.
 *	Huang Ying <ying.huang@intel.com>
 *
 * This file is released under the GPLv2.
 */
#include <linux/debugfs.h>
#include <linux/uaccess.h>
#include <linux/stat.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/mm.h>
#include <linux/module.h>

#include <asm/setup.h>

struct dentry *arch_debugfs_dir;
EXPORT_SYMBOL(arch_debugfs_dir);

#ifdef CONFIG_DEBUG_BOOT_PARAMS
struct setup_data_node {
	u64 paddr;
	u32 type;
	u32 len;
};

static ssize_t
setup_data_read(struct file *file, char __user *user_buf, size_t count,
		loff_t *ppos)
{
	struct setup_data_node *node = file->private_data;
	unsigned long remain;
	loff_t pos = *ppos;
	struct page *pg;
	void *p;
	u64 pa;

	if (pos < 0)
		return -EINVAL;
	if (pos >= node->len)
		return 0;

	if (count > node->len - pos)
		count = node->len - pos;
	pa = node->paddr + sizeof(struct setup_data) + pos;
	pg = pfn_to_page((pa + count - 1) >> PAGE_SHIFT);
	if (PageHighMem(pg)) {
		p = ioremap_cache(pa, count);
		if (!p)
			return -ENXIO;
	} else {
		p = __va(pa);
	}

	remain = copy_to_user(user_buf, p, count);

	if (PageHighMem(pg))
		iounmap(p);

	if (remain)
		return -EFAULT;

	*ppos = pos + count;

	return count;
}

static int setup_data_open(struct inode *inode, struct file *file)
{
	file->private_data = inode->i_private;
	return 0;
}

static const struct file_operations fops_setup_data = {
	.read =		setup_data_read,
	.open =		setup_data_open,
};

static int __init
create_setup_data_node(struct dentry *parent, int no,
		       struct setup_data_node *node)
{
	struct dentry *d, *type, *data;
	char buf[16];
	int error;

	sprintf(buf, "%d", no);
	d = debugfs_create_dir(buf, parent);
	if (!d) {
		error = -ENOMEM;
		goto err_return;
	}
	type = debugfs_create_x32("type", S_IRUGO, d, &node->type);
	if (!type) {
		error = -ENOMEM;
		goto err_dir;
	}
	data = debugfs_create_file("data", S_IRUGO, d, node, &fops_setup_data);
	if (!data) {
		error = -ENOMEM;
		goto err_type;
	}
	return 0;

err_type:
	debugfs_remove(type);
err_dir:
	debugfs_remove(d);
err_return:
	return error;
}

static int __init create_setup_data_nodes(struct dentry *parent)
{
	struct setup_data_node *node;
	struct setup_data *data;
	int error, no = 0;
	struct dentry *d;
	struct page *pg;
	u64 pa_data;

	d = debugfs_create_dir("setup_data", parent);
	if (!d) {
		error = -ENOMEM;
		goto err_return;
	}

	pa_data = boot_params.hdr.setup_data;

	while (pa_data) {
		node = kmalloc(sizeof(*node), GFP_KERNEL);
		if (!node) {
			error = -ENOMEM;
			goto err_dir;
		}
		pg = pfn_to_page((pa_data+sizeof(*data)-1) >> PAGE_SHIFT);
		if (PageHighMem(pg)) {
			data = ioremap_cache(pa_data, sizeof(*data));
			if (!data) {
				kfree(node);
				error = -ENXIO;
				goto err_dir;
			}
		} else {
			data = __va(pa_data);
		}

		node->paddr = pa_data;
		node->type = data->type;
		node->len = data->len;
		error = create_setup_data_node(d, no, node);
		pa_data = data->next;

		if (PageHighMem(pg))
			iounmap(data);
		if (error)
			goto err_dir;
		no++;
	}
	return 0;

err_dir:
	debugfs_remove(d);
err_return:
	return error;
}

static struct debugfs_blob_wrapper boot_params_blob = {
	.data		= &boot_params,
	.size		= sizeof(boot_params),
};

static int __init boot_params_kdebugfs_init(void)
{
	struct dentry *dbp, *version, *data;
	int error;

	dbp = debugfs_create_dir("boot_params", NULL);
	if (!dbp) {
		error = -ENOMEM;
		goto err_return;
	}
	version = debugfs_create_x16("version", S_IRUGO, dbp,
				     &boot_params.hdr.version);
	if (!version) {
		error = -ENOMEM;
		goto err_dir;
	}
	data = debugfs_create_blob("data", S_IRUGO, dbp,
				   &boot_params_blob);
	if (!data) {
		error = -ENOMEM;
		goto err_version;
	}
	error = create_setup_data_nodes(dbp);
	if (error)
		goto err_data;
	return 0;

err_data:
	debugfs_remove(data);
err_version:
	debugfs_remove(version);
err_dir:
	debugfs_remove(dbp);
err_return:
	return error;
}
#endif

static int __init arch_kdebugfs_init(void)
{
	int error = 0;

	arch_debugfs_dir = debugfs_create_dir("x86", NULL);
	if (!arch_debugfs_dir)
		return -ENOMEM;

#ifdef CONFIG_DEBUG_BOOT_PARAMS
	error = boot_params_kdebugfs_init();
#endif

	return error;
}
arch_initcall(arch_kdebugfs_init);
