/*
 *  linux/drivers/rtc/rtc-pl030.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/rtc.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/amba/bus.h>
#include <linux/io.h>
#include <linux/slab.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)

struct pl030_rtc {
	struct rtc_device	*rtc;
	void __iomem		*base;
};

static irqreturn_t pl030_interrupt(int irq, void *dev_id)
{
	struct pl030_rtc *rtc = dev_id;
	writel(0, rtc->base + RTC_EOI);
	return IRQ_HANDLED;
}

static int pl030_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{
	struct pl030_rtc *rtc = dev_get_drvdata(dev);

	rtc_time_to_tm(readl(rtc->base + RTC_MR), &alrm->time);
	return 0;
}

static int pl030_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{
	struct pl030_rtc *rtc = dev_get_drvdata(dev);
	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 pl030_read_time(struct device *dev, struct rtc_time *tm)
{
	struct pl030_rtc *rtc = dev_get_drvdata(dev);

	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 int pl030_set_time(struct device *dev, struct rtc_time *tm)
{
	struct pl030_rtc *rtc = dev_get_drvdata(dev);
	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 const struct rtc_class_ops pl030_ops = {
	.read_time	= pl030_read_time,
	.set_time	= pl030_set_time,
	.read_alarm	= pl030_read_alarm,
	.set_alarm	= pl030_set_alarm,
};

static int pl030_probe(struct amba_device *dev, const struct amba_id *id)
{
	struct pl030_rtc *rtc;
	int ret;

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

	rtc = devm_kzalloc(&dev->dev, sizeof(*rtc), GFP_KERNEL);
	if (!rtc) {
		ret = -ENOMEM;
		goto err_rtc;
	}

	rtc->base = ioremap(dev->res.start, resource_size(&dev->res));
	if (!rtc->base) {
		ret = -ENOMEM;
		goto err_rtc;
	}

	__raw_writel(0, rtc->base + RTC_CR);
	__raw_writel(0, rtc->base + RTC_EOI);

	amba_set_drvdata(dev, rtc);

	ret = request_irq(dev->irq[0], pl030_interrupt, 0,
			  "rtc-pl030", rtc);
	if (ret)
		goto err_irq;

	rtc->rtc = rtc_device_register("pl030", &dev->dev, &pl030_ops,
				       THIS_MODULE);
	if (IS_ERR(rtc->rtc)) {
		ret = PTR_ERR(rtc->rtc);
		goto err_reg;
	}

	return 0;

 err_reg:
	free_irq(dev->irq[0], rtc);
 err_irq:
	iounmap(rtc->base);
 err_rtc:
	amba_release_regions(dev);
 err_req:
	return ret;
}

static int pl030_remove(struct amba_device *dev)
{
	struct pl030_rtc *rtc = amba_get_drvdata(dev);

	writel(0, rtc->base + RTC_CR);

	free_irq(dev->irq[0], rtc);
	rtc_device_unregister(rtc->rtc);
	iounmap(rtc->base);
	amba_release_regions(dev);

	return 0;
}

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

MODULE_DEVICE_TABLE(amba, pl030_ids);

static struct amba_driver pl030_driver = {
	.drv		= {
		.name	= "rtc-pl030",
	},
	.probe		= pl030_probe,
	.remove		= pl030_remove,
	.id_table	= pl030_ids,
};

module_amba_driver(pl030_driver);

MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>");
MODULE_DESCRIPTION("ARM AMBA PL030 RTC Driver");
MODULE_LICENSE("GPL");
