/*
 *  linux/arch/arm/mach-integrator/time.c
 *
 *  Copyright (C) 2000-2001 Deep Blue Solutions Ltd.
 *
 * 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/kernel.h>
#include <linux/time.h>
#include <linux/mc146818rtc.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/device.h>

#include <asm/hardware/amba.h>
#include <asm/hardware.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include <asm/rtc.h>

#include <asm/mach/time.h>

#define RTC_DR		(0)
#define RTC_MR		(4)
#define RTC_STAT	(8)
#define RTC_EOI		(8)
#define RTC_LR		(12)
#define RTC_CR		(16)
#define RTC_CR_MIE	(1 << 0)

extern int (*set_rtc)(void);
static void __iomem *rtc_base;

static int integrator_set_rtc(void)
{
	__raw_writel(xtime.tv_sec, rtc_base + RTC_LR);
	return 1;
}

static void rtc_read_alarm(struct rtc_wkalrm *alrm)
{
	rtc_time_to_tm(readl(rtc_base + RTC_MR), &alrm->time);
}

static int rtc_set_alarm(struct rtc_wkalrm *alrm)
{
	unsigned long time;
	int ret;

	ret = rtc_tm_to_time(&alrm->time, &time);
	if (ret == 0)
		writel(time, rtc_base + RTC_MR);
	return ret;
}

static void rtc_read_time(struct rtc_time *tm)
{
	rtc_time_to_tm(readl(rtc_base + RTC_DR), tm);
}

/*
 * Set the RTC time.  Unfortunately, we can't accurately set
 * the point at which the counter updates.
 *
 * Also, since RTC_LR is transferred to RTC_CR on next rising
 * edge of the 1Hz clock, we must write the time one second
 * in advance.
 */
static int rtc_set_time(struct rtc_time *tm)
{
	unsigned long time;
	int ret;

	ret = rtc_tm_to_time(tm, &time);
	if (ret == 0)
		writel(time + 1, rtc_base + RTC_LR);

	return ret;
}

static struct rtc_ops rtc_ops = {
	.owner		= THIS_MODULE,
	.read_time	= rtc_read_time,
	.set_time	= rtc_set_time,
	.read_alarm	= rtc_read_alarm,
	.set_alarm	= rtc_set_alarm,
};

static irqreturn_t rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
	writel(0, rtc_base + RTC_EOI);
	return IRQ_HANDLED;
}

static int rtc_probe(struct amba_device *dev, void *id)
{
	int ret;

	if (rtc_base)
		return -EBUSY;

	ret = amba_request_regions(dev, NULL);
	if (ret)
		goto out;

	rtc_base = ioremap(dev->res.start, SZ_4K);
	if (!rtc_base) {
		ret = -ENOMEM;
		goto res_out;
	}

	__raw_writel(0, rtc_base + RTC_CR);
	__raw_writel(0, rtc_base + RTC_EOI);

	xtime.tv_sec = __raw_readl(rtc_base + RTC_DR);

	ret = request_irq(dev->irq[0], rtc_interrupt, SA_INTERRUPT,
			  "rtc-pl030", dev);
	if (ret)
		goto map_out;

	ret = register_rtc(&rtc_ops);
	if (ret)
		goto irq_out;

	set_rtc = integrator_set_rtc;
	return 0;

 irq_out:
	free_irq(dev->irq[0], dev);
 map_out:
	iounmap(rtc_base);
	rtc_base = NULL;
 res_out:
	amba_release_regions(dev);
 out:
	return ret;
}

static int rtc_remove(struct amba_device *dev)
{
	set_rtc = NULL;

	writel(0, rtc_base + RTC_CR);

	free_irq(dev->irq[0], dev);
	unregister_rtc(&rtc_ops);

	iounmap(rtc_base);
	rtc_base = NULL;
	amba_release_regions(dev);

	return 0;
}

static struct timespec rtc_delta;

static int rtc_suspend(struct amba_device *dev, pm_message_t state)
{
	struct timespec rtc;

	rtc.tv_sec = readl(rtc_base + RTC_DR);
	rtc.tv_nsec = 0;
	save_time_delta(&rtc_delta, &rtc);

	return 0;
}

static int rtc_resume(struct amba_device *dev)
{
	struct timespec rtc;

	rtc.tv_sec = readl(rtc_base + RTC_DR);
	rtc.tv_nsec = 0;
	restore_time_delta(&rtc_delta, &rtc);

	return 0;
}

static struct amba_id rtc_ids[] = {
	{
		.id	= 0x00041030,
		.mask	= 0x000fffff,
	},
	{ 0, 0 },
};

static struct amba_driver rtc_driver = {
	.drv		= {
		.name	= "rtc-pl030",
	},
	.probe		= rtc_probe,
	.remove		= rtc_remove,
	.suspend	= rtc_suspend,
	.resume		= rtc_resume,
	.id_table	= rtc_ids,
};

static int __init integrator_rtc_init(void)
{
	return amba_driver_register(&rtc_driver);
}

static void __exit integrator_rtc_exit(void)
{
	amba_driver_unregister(&rtc_driver);
}

module_init(integrator_rtc_init);
module_exit(integrator_rtc_exit);
