/*
 * Copyright 2010 Benjamin Herrenschmidt, IBM Corp
 *                <benh@kernel.crashing.org>
 *     and        David Gibson, IBM Corporation.
 *
 *   This program is free software;  you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 2 of the License, or
 *   (at your option) any later version.
 *
 *   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, write to the Free Software
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */

#include <linux/kernel.h>
#include <linux/debugfs.h>
#include <linux/slab.h>
#include <linux/export.h>
#include <asm/prom.h>
#include <asm/scom.h>

const struct scom_controller *scom_controller;
EXPORT_SYMBOL_GPL(scom_controller);

struct device_node *scom_find_parent(struct device_node *node)
{
	struct device_node *par, *tmp;
	const u32 *p;

	for (par = of_node_get(node); par;) {
		if (of_get_property(par, "scom-controller", NULL))
			break;
		p = of_get_property(par, "scom-parent", NULL);
		tmp = par;
		if (p == NULL)
			par = of_get_parent(par);
		else
			par = of_find_node_by_phandle(*p);
		of_node_put(tmp);
	}
	return par;
}
EXPORT_SYMBOL_GPL(scom_find_parent);

scom_map_t scom_map_device(struct device_node *dev, int index)
{
	struct device_node *parent;
	unsigned int cells, size;
	const u32 *prop;
	u64 reg, cnt;
	scom_map_t ret;

	parent = scom_find_parent(dev);

	if (parent == NULL)
		return 0;

	prop = of_get_property(parent, "#scom-cells", NULL);
	cells = prop ? *prop : 1;

	prop = of_get_property(dev, "scom-reg", &size);
	if (!prop)
		return 0;
	size >>= 2;

	if (index >= (size / (2*cells)))
		return 0;

	reg = of_read_number(&prop[index * cells * 2], cells);
	cnt = of_read_number(&prop[index * cells * 2 + cells], cells);

	ret = scom_map(parent, reg, cnt);
	of_node_put(parent);

	return ret;
}
EXPORT_SYMBOL_GPL(scom_map_device);

#ifdef CONFIG_SCOM_DEBUGFS
struct scom_debug_entry {
	struct device_node *dn;
	unsigned long addr;
	scom_map_t map;
	spinlock_t lock;
	char name[8];
	struct debugfs_blob_wrapper blob;
};

static int scom_addr_set(void *data, u64 val)
{
	struct scom_debug_entry *ent = data;

	ent->addr = 0;
	scom_unmap(ent->map);

	ent->map = scom_map(ent->dn, val, 1);
	if (scom_map_ok(ent->map))
		ent->addr = val;
	else
		return -EFAULT;

	return 0;
}

static int scom_addr_get(void *data, u64 *val)
{
	struct scom_debug_entry *ent = data;
	*val = ent->addr;
	return 0;
}
DEFINE_SIMPLE_ATTRIBUTE(scom_addr_fops, scom_addr_get, scom_addr_set,
			"0x%llx\n");

static int scom_val_set(void *data, u64 val)
{
	struct scom_debug_entry *ent = data;

	if (!scom_map_ok(ent->map))
		return -EFAULT;

	scom_write(ent->map, 0, val);

	return 0;
}

static int scom_val_get(void *data, u64 *val)
{
	struct scom_debug_entry *ent = data;

	if (!scom_map_ok(ent->map))
		return -EFAULT;

	*val = scom_read(ent->map, 0);
	return 0;
}
DEFINE_SIMPLE_ATTRIBUTE(scom_val_fops, scom_val_get, scom_val_set,
			"0x%llx\n");

static int scom_debug_init_one(struct dentry *root, struct device_node *dn,
			       int i)
{
	struct scom_debug_entry *ent;
	struct dentry *dir;

	ent = kzalloc(sizeof(*ent), GFP_KERNEL);
	if (!ent)
		return -ENOMEM;

	ent->dn = of_node_get(dn);
	ent->map = SCOM_MAP_INVALID;
	spin_lock_init(&ent->lock);
	snprintf(ent->name, 8, "scom%d", i);
	ent->blob.data = dn->full_name;
	ent->blob.size = strlen(dn->full_name);

	dir = debugfs_create_dir(ent->name, root);
	if (!dir) {
		of_node_put(dn);
		kfree(ent);
		return -1;
	}

	debugfs_create_file("addr", 0600, dir, ent, &scom_addr_fops);
	debugfs_create_file("value", 0600, dir, ent, &scom_val_fops);
	debugfs_create_blob("path", 0400, dir, &ent->blob);

	return 0;
}

static int scom_debug_init(void)
{
	struct device_node *dn;
	struct dentry *root;
	int i, rc;

	root = debugfs_create_dir("scom", powerpc_debugfs_root);
	if (!root)
		return -1;

	i = rc = 0;
	for_each_node_with_property(dn, "scom-controller")
		rc |= scom_debug_init_one(root, dn, i++);

	return rc;
}
device_initcall(scom_debug_init);
#endif /* CONFIG_SCOM_DEBUGFS */
