/**
 * @file op_rtc.c
 * Setup and handling of RTC interrupts
 *
 * @remark Copyright 2002 OProfile authors
 * @remark Read the file COPYING
 *
 * @author Bob Montgomery
 * @author Philippe Elie
 * @author John Levon
 */

#include <linux/ioport.h>
#include <linux/mc146818rtc.h>
#include <asm/ptrace.h>

#include "oprofile.h"
#include "op_arch.h"
#include "op_util.h"

#define RTC_IO_PORTS 2

/* not in 2.2 */
#ifndef RTC_IRQ
#define RTC_IRQ 8
#endif

/* ---------------- RTC handler ------------------ */

static void do_rtc_interrupt(int irq, void * dev_id, struct pt_regs * regs)
{
	uint cpu = op_cpu_id();
	unsigned char intr_flags;
	unsigned long flags;

	int usermode = user_mode(regs);
	if ((sysctl.ctr[0].kernel && usermode)
		|| (sysctl.ctr[0].user && !usermode))
		return;

	lock_rtc(flags);

	/* read and ack the interrupt */
	intr_flags = CMOS_READ(RTC_INTR_FLAGS);
	/* Is this my type of interrupt? */
	if (intr_flags & RTC_PF) {
		op_do_profile(cpu, instruction_pointer(regs), IRQ_ENABLED(regs), 0);
	}

	unlock_rtc(flags);

	return;
}

static int rtc_setup(void)
{
	unsigned char tmp_control;
	unsigned long flags;
	unsigned char tmp_freq_select;
	unsigned long target;
	unsigned int exp, freq;

	lock_rtc(flags);

	/* disable periodic interrupts */
	tmp_control = CMOS_READ(RTC_CONTROL);
	tmp_control &= ~RTC_PIE;
	CMOS_WRITE(tmp_control, RTC_CONTROL);
	CMOS_READ(RTC_INTR_FLAGS);

	/* Set the frequency for periodic interrupts by finding the
	 * closest power of two within the allowed range.
	 */

	target = sysctl.ctr[0].count;

	exp = 0;
	while (target > (1 << exp) + ((1 << exp) >> 1))
		exp++;
	freq = 16 - exp;

	tmp_freq_select = CMOS_READ(RTC_FREQ_SELECT);
	tmp_freq_select = (tmp_freq_select & 0xf0) | freq;
	CMOS_WRITE(tmp_freq_select, RTC_FREQ_SELECT);

	/* Update /proc with the actual frequency. */
	sysctl_parms.ctr[0].count = sysctl.ctr[0].count = 1<<exp;

	unlock_rtc(flags);
	return 0;
}

static void rtc_start(void)
{
	unsigned char tmp_control;
	unsigned long flags;

	lock_rtc(flags);

	/* Enable periodic interrupts */
	tmp_control = CMOS_READ(RTC_CONTROL);
	tmp_control |= RTC_PIE;
	CMOS_WRITE(tmp_control, RTC_CONTROL);

	/* read the flags register to start interrupts */
	CMOS_READ(RTC_INTR_FLAGS);

	unlock_rtc(flags);
}

static void rtc_stop(void)
{
	unsigned char tmp_control;
	unsigned long flags;

	lock_rtc(flags);

	/* disable periodic interrupts */
	tmp_control = CMOS_READ(RTC_CONTROL);
	tmp_control &= ~RTC_PIE;
	CMOS_WRITE(tmp_control, RTC_CONTROL);
	CMOS_READ(RTC_INTR_FLAGS);

	unlock_rtc(flags);
}

static void rtc_start_cpu(uint cpu)
{
	rtc_start();
}

static void rtc_stop_cpu(uint cpu)
{
	rtc_stop();
}

static int rtc_check_params(void)
{
	int target = sysctl.ctr[0].count;

	if (check_range(target, OP_MIN_RTC_COUNT, OP_MAX_RTC_COUNT,
		"RTC value %d is out of range (%d-%d)\n"))
		return -EINVAL;

	return 0;
}

static int rtc_init(void)
{
	 /* request_region returns 0 on **failure** */
	if (!request_region_check(RTC_PORT(0), RTC_IO_PORTS, "oprofile")) {
		printk(KERN_ERR "oprofile: can't get RTC I/O Ports\n");
		return -EBUSY;
	}

	/* request_irq returns 0 on **success** */
	if (request_irq(RTC_IRQ, do_rtc_interrupt,
			SA_INTERRUPT, "oprofile", NULL)) {
		printk(KERN_ERR "oprofile: IRQ%d busy \n", RTC_IRQ);
		release_region(RTC_PORT(0), RTC_IO_PORTS);
		return -EBUSY;
	}
	return 0;
}

static void rtc_deinit(void)
{
	free_irq(RTC_IRQ, NULL);
	release_region(RTC_PORT(0), RTC_IO_PORTS);
}

static int rtc_add_sysctls(ctl_table * next)
{
	*next = ((ctl_table) { 1, "rtc_value", &sysctl_parms.ctr[0].count, sizeof(int), 0600, NULL, lproc_dointvec, NULL, });
	return 0;
}

static void rtc_remove_sysctls(ctl_table * next)
{
	/* nothing to do */
}

struct op_int_operations op_rtc_ops = {
	init: rtc_init,
	deinit: rtc_deinit,
	add_sysctls: rtc_add_sysctls,
	remove_sysctls: rtc_remove_sysctls,
	check_params: rtc_check_params,
	setup: rtc_setup,
	start: rtc_start,
	stop: rtc_stop,
	start_cpu: rtc_start_cpu,
	stop_cpu: rtc_stop_cpu,
};
