/*
 *  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 <linux/amba/bus.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 int integrator_rtc_read_alarm(struct rtc_wkalrm *alrm)
{
	rtc_time_to_tm(readl(rtc_base + RTC_MR), &alrm->time);
	return 0;
}

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

	/*
	 * At the moment, we can only deal with non-wildcarded alarm times.
	 */
	ret = rtc_valid_tm(&alrm->time);
	if (ret == 0)
		ret = rtc_tm_to_time(&alrm->time, &time);
	if (ret == 0)
		writel(time, rtc_base + RTC_MR);
	return ret;
}

static int integrator_rtc_read_time(struct rtc_time *tm)
{
	rtc_time_to_tm(readl(rtc_base + RTC_DR), tm);
	return 0;
}

/*
 * 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 inline int integrator_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	= integrator_rtc_read_time,
	.set_time	= integrator_rtc_set_time,
	.read_alarm	= integrator_rtc_read_alarm,
	.set_alarm	= integrator_rtc_set_alarm,
};

static irqreturn_t arm_rtc_interrupt(int irq, void *dev_id)
{
	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], arm_rtc_interrupt, IRQF_DISABLED,
			  "rtc-pl030", NULL);
	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);
