/*
 * Timer device implementation for SGI UV platform.
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 *
 * Copyright (c) 2009 Silicon Graphics, Inc.  All rights reserved.
 *
 */

#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/ioctl.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/mm.h>
#include <linux/fs.h>
#include <linux/mmtimer.h>
#include <linux/miscdevice.h>
#include <linux/posix-timers.h>
#include <linux/interrupt.h>
#include <linux/time.h>
#include <linux/math64.h>
#include <linux/smp_lock.h>

#include <asm/genapic.h>
#include <asm/uv/uv_hub.h>
#include <asm/uv/bios.h>
#include <asm/uv/uv.h>

MODULE_AUTHOR("Dimitri Sivanich <sivanich@sgi.com>");
MODULE_DESCRIPTION("SGI UV Memory Mapped RTC Timer");
MODULE_LICENSE("GPL");

/* name of the device, usually in /dev */
#define UV_MMTIMER_NAME "mmtimer"
#define UV_MMTIMER_DESC "SGI UV Memory Mapped RTC Timer"
#define UV_MMTIMER_VERSION "1.0"

static long uv_mmtimer_ioctl(struct file *file, unsigned int cmd,
						unsigned long arg);
static int uv_mmtimer_mmap(struct file *file, struct vm_area_struct *vma);

/*
 * Period in femtoseconds (10^-15 s)
 */
static unsigned long uv_mmtimer_femtoperiod;

static const struct file_operations uv_mmtimer_fops = {
	.owner = THIS_MODULE,
	.mmap =	uv_mmtimer_mmap,
	.unlocked_ioctl = uv_mmtimer_ioctl,
};

/**
 * uv_mmtimer_ioctl - ioctl interface for /dev/uv_mmtimer
 * @file: file structure for the device
 * @cmd: command to execute
 * @arg: optional argument to command
 *
 * Executes the command specified by @cmd.  Returns 0 for success, < 0 for
 * failure.
 *
 * Valid commands:
 *
 * %MMTIMER_GETOFFSET - Should return the offset (relative to the start
 * of the page where the registers are mapped) for the counter in question.
 *
 * %MMTIMER_GETRES - Returns the resolution of the clock in femto (10^-15)
 * seconds
 *
 * %MMTIMER_GETFREQ - Copies the frequency of the clock in Hz to the address
 * specified by @arg
 *
 * %MMTIMER_GETBITS - Returns the number of bits in the clock's counter
 *
 * %MMTIMER_MMAPAVAIL - Returns 1 if registers can be mmap'd into userspace
 *
 * %MMTIMER_GETCOUNTER - Gets the current value in the counter and places it
 * in the address specified by @arg.
 */
static long uv_mmtimer_ioctl(struct file *file, unsigned int cmd,
						unsigned long arg)
{
	int ret = 0;

	switch (cmd) {
	case MMTIMER_GETOFFSET:	/* offset of the counter */
		/*
		 * UV RTC register is on its own page
		 */
		if (PAGE_SIZE <= (1 << 16))
			ret = ((UV_LOCAL_MMR_BASE | UVH_RTC) & (PAGE_SIZE-1))
				/ 8;
		else
			ret = -ENOSYS;
		break;

	case MMTIMER_GETRES: /* resolution of the clock in 10^-15 s */
		if (copy_to_user((unsigned long __user *)arg,
				&uv_mmtimer_femtoperiod, sizeof(unsigned long)))
			ret = -EFAULT;
		break;

	case MMTIMER_GETFREQ: /* frequency in Hz */
		if (copy_to_user((unsigned long __user *)arg,
				&sn_rtc_cycles_per_second,
				sizeof(unsigned long)))
			ret = -EFAULT;
		break;

	case MMTIMER_GETBITS: /* number of bits in the clock */
		ret = hweight64(UVH_RTC_REAL_TIME_CLOCK_MASK);
		break;

	case MMTIMER_MMAPAVAIL: /* can we mmap the clock into userspace? */
		ret = (PAGE_SIZE <= (1 << 16)) ? 1 : 0;
		break;

	case MMTIMER_GETCOUNTER:
		if (copy_to_user((unsigned long __user *)arg,
				(unsigned long *)uv_local_mmr_address(UVH_RTC),
				sizeof(unsigned long)))
			ret = -EFAULT;
		break;
	default:
		ret = -ENOTTY;
		break;
	}
	return ret;
}

/**
 * uv_mmtimer_mmap - maps the clock's registers into userspace
 * @file: file structure for the device
 * @vma: VMA to map the registers into
 *
 * Calls remap_pfn_range() to map the clock's registers into
 * the calling process' address space.
 */
static int uv_mmtimer_mmap(struct file *file, struct vm_area_struct *vma)
{
	unsigned long uv_mmtimer_addr;

	if (vma->vm_end - vma->vm_start != PAGE_SIZE)
		return -EINVAL;

	if (vma->vm_flags & VM_WRITE)
		return -EPERM;

	if (PAGE_SIZE > (1 << 16))
		return -ENOSYS;

	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);

	uv_mmtimer_addr = UV_LOCAL_MMR_BASE | UVH_RTC;
	uv_mmtimer_addr &= ~(PAGE_SIZE - 1);
	uv_mmtimer_addr &= 0xfffffffffffffffUL;

	if (remap_pfn_range(vma, vma->vm_start, uv_mmtimer_addr >> PAGE_SHIFT,
					PAGE_SIZE, vma->vm_page_prot)) {
		printk(KERN_ERR "remap_pfn_range failed in uv_mmtimer_mmap\n");
		return -EAGAIN;
	}

	return 0;
}

static struct miscdevice uv_mmtimer_miscdev = {
	MISC_DYNAMIC_MINOR,
	UV_MMTIMER_NAME,
	&uv_mmtimer_fops
};


/**
 * uv_mmtimer_init - device initialization routine
 *
 * Does initial setup for the uv_mmtimer device.
 */
static int __init uv_mmtimer_init(void)
{
	if (!is_uv_system()) {
		printk(KERN_ERR "%s: Hardware unsupported\n", UV_MMTIMER_NAME);
		return -1;
	}

	/*
	 * Sanity check the cycles/sec variable
	 */
	if (sn_rtc_cycles_per_second < 100000) {
		printk(KERN_ERR "%s: unable to determine clock frequency\n",
		       UV_MMTIMER_NAME);
		return -1;
	}

	uv_mmtimer_femtoperiod = ((unsigned long)1E15 +
				sn_rtc_cycles_per_second / 2) /
				sn_rtc_cycles_per_second;

	if (misc_register(&uv_mmtimer_miscdev)) {
		printk(KERN_ERR "%s: failed to register device\n",
		       UV_MMTIMER_NAME);
		return -1;
	}

	printk(KERN_INFO "%s: v%s, %ld MHz\n", UV_MMTIMER_DESC,
		UV_MMTIMER_VERSION,
		sn_rtc_cycles_per_second/(unsigned long)1E6);

	return 0;
}

module_init(uv_mmtimer_init);
