/*
 * iSeries_proc.c
 * Copyright (C) 2001  Kyle A. Lucke IBM Corporation
 * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen 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/init.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/param.h>		/* for HZ */
#include <asm/paca.h>
#include <asm/processor.h>
#include <asm/time.h>
#include <asm/lppaca.h>
#include <asm/iSeries/ItLpQueue.h>
#include <asm/iSeries/HvCallXm.h>
#include <asm/iSeries/IoHriMainStore.h>
#include <asm/iSeries/LparData.h>
#include <asm/iSeries/iSeries_proc.h>

static int __init iseries_proc_create(void)
{
	struct proc_dir_entry *e = proc_mkdir("iSeries", 0);
	if (!e)
		return 1;

	return 0;
}
core_initcall(iseries_proc_create);

static char *event_types[9] = {
	"Hypervisor\t\t",
	"Machine Facilities\t",
	"Session Manager\t",
	"SPD I/O\t\t",
	"Virtual Bus\t\t",
	"PCI I/O\t\t",
	"RIO I/O\t\t",
	"Virtual Lan\t\t",
	"Virtual I/O\t\t"
};

static int proc_lpevents_show(struct seq_file *m, void *v)
{
	unsigned int i;

	seq_printf(m, "LpEventQueue 0\n");
	seq_printf(m, "  events processed:\t%lu\n",
		   (unsigned long)xItLpQueue.xLpIntCount);

	for (i = 0; i < 9; ++i)
		seq_printf(m, "    %s %10lu\n", event_types[i],
			   (unsigned long)xItLpQueue.xLpIntCountByType[i]);

	seq_printf(m, "\n  events processed by processor:\n");

	for_each_online_cpu(i)
		seq_printf(m, "    CPU%02d  %10u\n", i, paca[i].lpevent_count);

	return 0;
}

static int proc_lpevents_open(struct inode *inode, struct file *file)
{
	return single_open(file, proc_lpevents_show, NULL);
}

static struct file_operations proc_lpevents_operations = {
	.open		= proc_lpevents_open,
	.read		= seq_read,
	.llseek		= seq_lseek,
	.release	= single_release,
};

static unsigned long startTitan = 0;
static unsigned long startTb = 0;

static int proc_titantod_show(struct seq_file *m, void *v)
{
	unsigned long tb0, titan_tod;

	tb0 = get_tb();
	titan_tod = HvCallXm_loadTod();

	seq_printf(m, "Titan\n" );
	seq_printf(m, "  time base =          %016lx\n", tb0);
	seq_printf(m, "  titan tod =          %016lx\n", titan_tod);
	seq_printf(m, "  xProcFreq =          %016x\n",
		   xIoHriProcessorVpd[0].xProcFreq);
	seq_printf(m, "  xTimeBaseFreq =      %016x\n",
		   xIoHriProcessorVpd[0].xTimeBaseFreq);
	seq_printf(m, "  tb_ticks_per_jiffy = %lu\n", tb_ticks_per_jiffy);
	seq_printf(m, "  tb_ticks_per_usec  = %lu\n", tb_ticks_per_usec);

	if (!startTitan) {
		startTitan = titan_tod;
		startTb = tb0;
	} else {
		unsigned long titan_usec = (titan_tod - startTitan) >> 12;
		unsigned long tb_ticks = (tb0 - startTb);
		unsigned long titan_jiffies = titan_usec / (1000000/HZ);
		unsigned long titan_jiff_usec = titan_jiffies * (1000000/HZ);
		unsigned long titan_jiff_rem_usec = titan_usec - titan_jiff_usec;
		unsigned long tb_jiffies = tb_ticks / tb_ticks_per_jiffy;
		unsigned long tb_jiff_ticks = tb_jiffies * tb_ticks_per_jiffy;
		unsigned long tb_jiff_rem_ticks = tb_ticks - tb_jiff_ticks;
		unsigned long tb_jiff_rem_usec = tb_jiff_rem_ticks / tb_ticks_per_usec;
		unsigned long new_tb_ticks_per_jiffy = (tb_ticks * (1000000/HZ))/titan_usec;

		seq_printf(m, "  titan elapsed = %lu uSec\n", titan_usec);
		seq_printf(m, "  tb elapsed    = %lu ticks\n", tb_ticks);
		seq_printf(m, "  titan jiffies = %lu.%04lu \n", titan_jiffies,
			   titan_jiff_rem_usec);
		seq_printf(m, "  tb jiffies    = %lu.%04lu\n", tb_jiffies,
			   tb_jiff_rem_usec);
		seq_printf(m, "  new tb_ticks_per_jiffy = %lu\n",
			   new_tb_ticks_per_jiffy);
	}

	return 0;
}

static int proc_titantod_open(struct inode *inode, struct file *file)
{
	return single_open(file, proc_titantod_show, NULL);
}

static struct file_operations proc_titantod_operations = {
	.open		= proc_titantod_open,
	.read		= seq_read,
	.llseek		= seq_lseek,
	.release	= single_release,
};

static int __init iseries_proc_init(void)
{
	struct proc_dir_entry *e;

	e = create_proc_entry("iSeries/lpevents", S_IFREG|S_IRUGO, NULL);
	if (e)
		e->proc_fops = &proc_lpevents_operations;

	e = create_proc_entry("iSeries/titanTod", S_IFREG|S_IRUGO, NULL);
	if (e)
		e->proc_fops = &proc_titantod_operations;

	return 0;
}
__initcall(iseries_proc_init);
