/*
 * FR-V Power Management Routines
 *
 * Copyright (c) 2004 Red Hat, Inc.
 *
 * Based on SA1100 version:
 * Copyright (c) 2001 Cliff Brake <cbrake@accelent.com>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License.
 *
 */

#include <linux/init.h>
#include <linux/module.h>
#include <linux/pm.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/sysctl.h>
#include <linux/errno.h>
#include <linux/delay.h>
#include <linux/uaccess.h>

#include <asm/mb86943a.h>

#include "local.h"

/*
 * Debug macros
 */
#define DEBUG

int pm_do_suspend(void)
{
	local_irq_disable();

	__set_LEDS(0xb1);

	/* go zzz */
	frv_cpu_suspend(pdm_suspend_mode);

	__set_LEDS(0xb2);

	local_irq_enable();

	return 0;
}

static unsigned long __irq_mask;

/*
 * Setup interrupt masks, etc to enable wakeup by power switch
 */
static void __default_power_switch_setup(void)
{
	/* default is to mask all interrupt sources. */
	__irq_mask = *(unsigned long *)0xfeff9820;
	*(unsigned long *)0xfeff9820 = 0xfffe0000;
}

/*
 * Cleanup interrupt masks, etc after wakeup by power switch
 */
static void __default_power_switch_cleanup(void)
{
	*(unsigned long *)0xfeff9820 = __irq_mask;
}

/*
 * Return non-zero if wakeup irq was caused by power switch
 */
static int __default_power_switch_check(void)
{
	return 1;
}

void (*__power_switch_wake_setup)(void) = __default_power_switch_setup;
int  (*__power_switch_wake_check)(void) = __default_power_switch_check;
void (*__power_switch_wake_cleanup)(void) = __default_power_switch_cleanup;

int pm_do_bus_sleep(void)
{
	local_irq_disable();

	/*
         * Here is where we need some platform-dependent setup
	 * of the interrupt state so that appropriate wakeup
	 * sources are allowed and all others are masked.
	 */
	__power_switch_wake_setup();

	__set_LEDS(0xa1);

	/* go zzz
	 *
	 * This is in a loop in case power switch shares an irq with other
	 * devices. The wake_check() tells us if we need to finish waking
	 * or go back to sleep.
	 */
	do {
		frv_cpu_suspend(HSR0_PDM_BUS_SLEEP);
	} while (__power_switch_wake_check && !__power_switch_wake_check());

	__set_LEDS(0xa2);

	/*
         * Here is where we need some platform-dependent restore
	 * of the interrupt state prior to being called.
	 */
	__power_switch_wake_cleanup();

	local_irq_enable();

	return 0;
}

unsigned long sleep_phys_sp(void *sp)
{
	return virt_to_phys(sp);
}

#ifdef CONFIG_SYSCTL
/*
 * Use a temporary sysctl number. Horrid, but will be cleaned up in 2.6
 * when all the PM interfaces exist nicely.
 */
#define CTL_PM_SUSPEND 1
#define CTL_PM_CMODE 2
#define CTL_PM_P0 4
#define CTL_PM_CM 5

static int user_atoi(char __user *ubuf, size_t len)
{
	char buf[16];
	unsigned long ret;

	if (len > 15)
		return -EINVAL;

	if (copy_from_user(buf, ubuf, len))
		return -EFAULT;

	buf[len] = 0;
	ret = simple_strtoul(buf, NULL, 0);
	if (ret > INT_MAX)
		return -ERANGE;
	return ret;
}

/*
 * Send us to sleep.
 */
static int sysctl_pm_do_suspend(struct ctl_table *ctl, int write,
				void __user *buffer, size_t *lenp, loff_t *fpos)
{
	int mode;

	if (*lenp <= 0)
		return -EIO;

	mode = user_atoi(buffer, *lenp);
	switch (mode) {
	case 1:
	    return pm_do_suspend();

	case 5:
	    return pm_do_bus_sleep();

	default:
	    return -EINVAL;
	}
}

static int try_set_cmode(int new_cmode)
{
	if (new_cmode > 15)
		return -EINVAL;
	if (!(clock_cmodes_permitted & (1<<new_cmode)))
		return -EINVAL;

	/* now change cmode */
	local_irq_disable();
	frv_dma_pause_all();

	frv_change_cmode(new_cmode);

	determine_clocks(0);
	time_divisor_init();

#ifdef DEBUG
	determine_clocks(1);
#endif
	frv_dma_resume_all();
	local_irq_enable();

	return 0;
}


static int cmode_procctl(struct ctl_table *ctl, int write,
			 void __user *buffer, size_t *lenp, loff_t *fpos)
{
	int new_cmode;

	if (!write)
		return proc_dointvec(ctl, write, buffer, lenp, fpos);

	new_cmode = user_atoi(buffer, *lenp);

	return try_set_cmode(new_cmode)?:*lenp;
}

static int try_set_p0(int new_p0)
{
	unsigned long flags, clkc;

	if (new_p0 < 0 || new_p0 > 1)
		return -EINVAL;

	local_irq_save(flags);
	__set_PSR(flags & ~PSR_ET);

	frv_dma_pause_all();

	clkc = __get_CLKC();
	if (new_p0)
		clkc |= CLKC_P0;
	else
		clkc &= ~CLKC_P0;
	__set_CLKC(clkc);

	determine_clocks(0);
	time_divisor_init();

#ifdef DEBUG
	determine_clocks(1);
#endif
	frv_dma_resume_all();
	local_irq_restore(flags);
	return 0;
}

static int try_set_cm(int new_cm)
{
	unsigned long flags, clkc;

	if (new_cm < 0 || new_cm > 1)
		return -EINVAL;

	local_irq_save(flags);
	__set_PSR(flags & ~PSR_ET);

	frv_dma_pause_all();

	clkc = __get_CLKC();
	clkc &= ~CLKC_CM;
	clkc |= new_cm;
	__set_CLKC(clkc);

	determine_clocks(0);
	time_divisor_init();

#if 1 //def DEBUG
	determine_clocks(1);
#endif

	frv_dma_resume_all();
	local_irq_restore(flags);
	return 0;
}

static int p0_procctl(struct ctl_table *ctl, int write,
		      void __user *buffer, size_t *lenp, loff_t *fpos)
{
	int new_p0;

	if (!write)
		return proc_dointvec(ctl, write, buffer, lenp, fpos);

	new_p0 = user_atoi(buffer, *lenp);

	return try_set_p0(new_p0)?:*lenp;
}

static int cm_procctl(struct ctl_table *ctl, int write,
		      void __user *buffer, size_t *lenp, loff_t *fpos)
{
	int new_cm;

	if (!write)
		return proc_dointvec(ctl, write, buffer, lenp, fpos);

	new_cm = user_atoi(buffer, *lenp);

	return try_set_cm(new_cm)?:*lenp;
}

static struct ctl_table pm_table[] =
{
	{
		.procname	= "suspend",
		.data		= NULL,
		.maxlen		= 0,
		.mode		= 0200,
		.proc_handler	= sysctl_pm_do_suspend,
	},
	{
		.procname	= "cmode",
		.data		= &clock_cmode_current,
		.maxlen		= sizeof(int),
		.mode		= 0644,
		.proc_handler	= cmode_procctl,
	},
	{
		.procname	= "p0",
		.data		= &clock_p0_current,
		.maxlen		= sizeof(int),
		.mode		= 0644,
		.proc_handler	= p0_procctl,
	},
	{
		.procname	= "cm",
		.data		= &clock_cm_current,
		.maxlen		= sizeof(int),
		.mode		= 0644,
		.proc_handler	= cm_procctl,
	},
	{ }
};

static struct ctl_table pm_dir_table[] =
{
	{
		.procname	= "pm",
		.mode		= 0555,
		.child		= pm_table,
	},
	{ }
};

/*
 * Initialize power interface
 */
static int __init pm_init(void)
{
	register_sysctl_table(pm_dir_table);
	return 0;
}

__initcall(pm_init);

#endif
