/*
 * omap iommu: debugfs interface
 *
 * Copyright (C) 2008-2009 Nokia Corporation
 *
 * Written by Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#include <linux/module.h>
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/platform_device.h>
#include <linux/debugfs.h>
#include <linux/omap-iommu.h>
#include <linux/platform_data/iommu-omap.h>

#include "omap-iopgtable.h"
#include "omap-iommu.h"

#define MAXCOLUMN 100 /* for short messages */

static DEFINE_MUTEX(iommu_debug_lock);

static struct dentry *iommu_debug_root;

static ssize_t debug_read_ver(struct file *file, char __user *userbuf,
			      size_t count, loff_t *ppos)
{
	u32 ver = omap_iommu_arch_version();
	char buf[MAXCOLUMN], *p = buf;

	p += sprintf(p, "H/W version: %d.%d\n", (ver >> 4) & 0xf , ver & 0xf);

	return simple_read_from_buffer(userbuf, count, ppos, buf, p - buf);
}

static ssize_t debug_read_regs(struct file *file, char __user *userbuf,
			       size_t count, loff_t *ppos)
{
	struct device *dev = file->private_data;
	struct omap_iommu *obj = dev_to_omap_iommu(dev);
	char *p, *buf;
	ssize_t bytes;

	buf = kmalloc(count, GFP_KERNEL);
	if (!buf)
		return -ENOMEM;
	p = buf;

	mutex_lock(&iommu_debug_lock);

	bytes = omap_iommu_dump_ctx(obj, p, count);
	bytes = simple_read_from_buffer(userbuf, count, ppos, buf, bytes);

	mutex_unlock(&iommu_debug_lock);
	kfree(buf);

	return bytes;
}

static ssize_t debug_read_tlb(struct file *file, char __user *userbuf,
			      size_t count, loff_t *ppos)
{
	struct device *dev = file->private_data;
	struct omap_iommu *obj = dev_to_omap_iommu(dev);
	char *p, *buf;
	ssize_t bytes, rest;

	buf = kmalloc(count, GFP_KERNEL);
	if (!buf)
		return -ENOMEM;
	p = buf;

	mutex_lock(&iommu_debug_lock);

	p += sprintf(p, "%8s %8s\n", "cam:", "ram:");
	p += sprintf(p, "-----------------------------------------\n");
	rest = count - (p - buf);
	p += omap_dump_tlb_entries(obj, p, rest);

	bytes = simple_read_from_buffer(userbuf, count, ppos, buf, p - buf);

	mutex_unlock(&iommu_debug_lock);
	kfree(buf);

	return bytes;
}

static ssize_t debug_write_pagetable(struct file *file,
		     const char __user *userbuf, size_t count, loff_t *ppos)
{
	struct iotlb_entry e;
	struct cr_regs cr;
	int err;
	struct device *dev = file->private_data;
	struct omap_iommu *obj = dev_to_omap_iommu(dev);
	char buf[MAXCOLUMN], *p = buf;

	count = min(count, sizeof(buf));

	mutex_lock(&iommu_debug_lock);
	if (copy_from_user(p, userbuf, count)) {
		mutex_unlock(&iommu_debug_lock);
		return -EFAULT;
	}

	sscanf(p, "%x %x", &cr.cam, &cr.ram);
	if (!cr.cam || !cr.ram) {
		mutex_unlock(&iommu_debug_lock);
		return -EINVAL;
	}

	omap_iotlb_cr_to_e(&cr, &e);
	err = omap_iopgtable_store_entry(obj, &e);
	if (err)
		dev_err(obj->dev, "%s: fail to store cr\n", __func__);

	mutex_unlock(&iommu_debug_lock);
	return count;
}

#define dump_ioptable_entry_one(lv, da, val)			\
	({							\
		int __err = 0;					\
		ssize_t bytes;					\
		const int maxcol = 22;				\
		const char *str = "%d: %08x %08x\n";		\
		bytes = snprintf(p, maxcol, str, lv, da, val);	\
		p += bytes;					\
		len -= bytes;					\
		if (len < maxcol)				\
			__err = -ENOMEM;			\
		__err;						\
	})

static ssize_t dump_ioptable(struct omap_iommu *obj, char *buf, ssize_t len)
{
	int i;
	u32 *iopgd;
	char *p = buf;

	spin_lock(&obj->page_table_lock);

	iopgd = iopgd_offset(obj, 0);
	for (i = 0; i < PTRS_PER_IOPGD; i++, iopgd++) {
		int j, err;
		u32 *iopte;
		u32 da;

		if (!*iopgd)
			continue;

		if (!(*iopgd & IOPGD_TABLE)) {
			da = i << IOPGD_SHIFT;

			err = dump_ioptable_entry_one(1, da, *iopgd);
			if (err)
				goto out;
			continue;
		}

		iopte = iopte_offset(iopgd, 0);

		for (j = 0; j < PTRS_PER_IOPTE; j++, iopte++) {
			if (!*iopte)
				continue;

			da = (i << IOPGD_SHIFT) + (j << IOPTE_SHIFT);
			err = dump_ioptable_entry_one(2, da, *iopgd);
			if (err)
				goto out;
		}
	}
out:
	spin_unlock(&obj->page_table_lock);

	return p - buf;
}

static ssize_t debug_read_pagetable(struct file *file, char __user *userbuf,
				    size_t count, loff_t *ppos)
{
	struct device *dev = file->private_data;
	struct omap_iommu *obj = dev_to_omap_iommu(dev);
	char *p, *buf;
	size_t bytes;

	buf = (char *)__get_free_page(GFP_KERNEL);
	if (!buf)
		return -ENOMEM;
	p = buf;

	p += sprintf(p, "L: %8s %8s\n", "da:", "pa:");
	p += sprintf(p, "-----------------------------------------\n");

	mutex_lock(&iommu_debug_lock);

	bytes = PAGE_SIZE - (p - buf);
	p += dump_ioptable(obj, p, bytes);

	bytes = simple_read_from_buffer(userbuf, count, ppos, buf, p - buf);

	mutex_unlock(&iommu_debug_lock);
	free_page((unsigned long)buf);

	return bytes;
}

#define DEBUG_FOPS(name)						\
	static const struct file_operations debug_##name##_fops = {	\
		.open = simple_open,					\
		.read = debug_read_##name,				\
		.write = debug_write_##name,				\
		.llseek = generic_file_llseek,				\
	};

#define DEBUG_FOPS_RO(name)						\
	static const struct file_operations debug_##name##_fops = {	\
		.open = simple_open,					\
		.read = debug_read_##name,				\
		.llseek = generic_file_llseek,				\
	};

DEBUG_FOPS_RO(ver);
DEBUG_FOPS_RO(regs);
DEBUG_FOPS_RO(tlb);
DEBUG_FOPS(pagetable);

#define __DEBUG_ADD_FILE(attr, mode)					\
	{								\
		struct dentry *dent;					\
		dent = debugfs_create_file(#attr, mode, parent,		\
					   dev, &debug_##attr##_fops);	\
		if (!dent)						\
			return -ENOMEM;					\
	}

#define DEBUG_ADD_FILE(name) __DEBUG_ADD_FILE(name, 0600)
#define DEBUG_ADD_FILE_RO(name) __DEBUG_ADD_FILE(name, 0400)

static int iommu_debug_register(struct device *dev, void *data)
{
	struct platform_device *pdev = to_platform_device(dev);
	struct omap_iommu *obj = platform_get_drvdata(pdev);
	struct omap_iommu_arch_data *arch_data;
	struct dentry *d, *parent;

	if (!obj || !obj->dev)
		return -EINVAL;

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

	arch_data->iommu_dev = obj;

	dev->archdata.iommu = arch_data;

	d = debugfs_create_dir(obj->name, iommu_debug_root);
	if (!d)
		goto nomem;
	parent = d;

	d = debugfs_create_u8("nr_tlb_entries", 400, parent,
			      (u8 *)&obj->nr_tlb_entries);
	if (!d)
		goto nomem;

	DEBUG_ADD_FILE_RO(ver);
	DEBUG_ADD_FILE_RO(regs);
	DEBUG_ADD_FILE_RO(tlb);
	DEBUG_ADD_FILE(pagetable);

	return 0;

nomem:
	kfree(arch_data);
	return -ENOMEM;
}

static int iommu_debug_unregister(struct device *dev, void *data)
{
	if (!dev->archdata.iommu)
		return 0;

	kfree(dev->archdata.iommu);

	dev->archdata.iommu = NULL;

	return 0;
}

static int __init iommu_debug_init(void)
{
	struct dentry *d;
	int err;

	d = debugfs_create_dir("iommu", NULL);
	if (!d)
		return -ENOMEM;
	iommu_debug_root = d;

	err = omap_foreach_iommu_device(d, iommu_debug_register);
	if (err)
		goto err_out;
	return 0;

err_out:
	debugfs_remove_recursive(iommu_debug_root);
	return err;
}
module_init(iommu_debug_init)

static void __exit iommu_debugfs_exit(void)
{
	debugfs_remove_recursive(iommu_debug_root);
	omap_foreach_iommu_device(NULL, iommu_debug_unregister);
}
module_exit(iommu_debugfs_exit)

MODULE_DESCRIPTION("omap iommu: debugfs interface");
MODULE_AUTHOR("Hiroshi DOYU <Hiroshi.DOYU@nokia.com>");
MODULE_LICENSE("GPL v2");
