Merge branches 'at91', 'dyntick', 'ep93xx', 'iop', 'ixp', 'misc', 'orion', 'omap-reviewed', 'rpc', 'rtc' and 's3c' into devel

This commit is contained in:
Russell King
2008-07-10 16:38:50 +01:00
committed by Russell King
555 changed files with 38141 additions and 8535 deletions

View File

@@ -469,6 +469,16 @@ config RTC_DRV_VR41XX
To compile this driver as a module, choose M here: the
module will be called rtc-vr41xx.
config RTC_DRV_PL030
tristate "ARM AMBA PL030 RTC"
depends on ARM_AMBA
help
If you say Y here you will get access to ARM AMBA
PrimeCell PL030 RTC found on certain ARM SOCs.
To compile this driver as a module, choose M here: the
module will be called rtc-pl030.
config RTC_DRV_PL031
tristate "ARM AMBA PL031 RTC"
depends on ARM_AMBA
@@ -495,12 +505,13 @@ config RTC_DRV_AT91RM9200
this is powered by the backup power supply.
config RTC_DRV_AT91SAM9
tristate "AT91SAM9x"
tristate "AT91SAM9x/AT91CAP9"
depends on ARCH_AT91 && !(ARCH_AT91RM9200 || ARCH_AT91X40)
help
RTC driver for the Atmel AT91SAM9x internal RTT (Real Time Timer).
These timers are powered by the backup power supply (such as a
small coin cell battery), but do not need to be used as RTCs.
RTC driver for the Atmel AT91SAM9x and AT91CAP9 internal RTT
(Real Time Timer). These timers are powered by the backup power
supply (such as a small coin cell battery), but do not need to
be used as RTCs.
(On AT91SAM9rl chips you probably want to use the dedicated RTC
module and leave the RTT available for other uses.)

View File

@@ -41,6 +41,7 @@ obj-$(CONFIG_RTC_DRV_MAX6902) += rtc-max6902.o
obj-$(CONFIG_RTC_DRV_OMAP) += rtc-omap.o
obj-$(CONFIG_RTC_DRV_PCF8563) += rtc-pcf8563.o
obj-$(CONFIG_RTC_DRV_PCF8583) += rtc-pcf8583.o
obj-$(CONFIG_RTC_DRV_PL030) += rtc-pl030.o
obj-$(CONFIG_RTC_DRV_PL031) += rtc-pl031.o
obj-$(CONFIG_RTC_DRV_PPC) += rtc-ppc.o
obj-$(CONFIG_RTC_DRV_R9701) += rtc-r9701.o

View File

@@ -29,10 +29,6 @@
#include <linux/completion.h>
#include <asm/uaccess.h>
#include <asm/rtc.h>
#include <asm/mach/time.h>
#include <asm/arch/at91_rtc.h>

View File

@@ -19,7 +19,6 @@
#include <linux/interrupt.h>
#include <linux/ioctl.h>
#include <asm/mach/time.h>
#include <asm/arch/board.h>
#include <asm/arch/at91_rtt.h>

View File

@@ -22,7 +22,6 @@
#include <linux/platform_device.h>
#include <asm/io.h>
#include <asm/mach/time.h>
/* The OMAP1 RTC is a year/month/day/hours/minutes/seconds BCD clock

217
drivers/rtc/rtc-pl030.c Normal file
View File

@@ -0,0 +1,217 @@
/*
* 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>
#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_open(struct device *dev)
{
return 0;
}
static void pl030_release(struct device *dev)
{
}
static int pl030_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
{
return -ENOIOCTLCMD;
}
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 = {
.open = pl030_open,
.release = pl030_release,
.ioctl = pl030_ioctl,
.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, void *id)
{
struct pl030_rtc *rtc;
int ret;
ret = amba_request_regions(dev, NULL);
if (ret)
goto err_req;
rtc = kmalloc(sizeof(*rtc), GFP_KERNEL);
if (!rtc) {
ret = -ENOMEM;
goto err_rtc;
}
rtc->base = ioremap(dev->res.start, SZ_4K);
if (!rtc->base) {
ret = -ENOMEM;
goto err_map;
}
__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, IRQF_DISABLED,
"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_map:
kfree(rtc);
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);
amba_set_drvdata(dev, NULL);
writel(0, rtc->base + RTC_CR);
free_irq(dev->irq[0], rtc);
rtc_device_unregister(rtc->rtc);
iounmap(rtc->base);
kfree(rtc);
amba_release_regions(dev);
return 0;
}
static struct amba_id pl030_ids[] = {
{
.id = 0x00041030,
.mask = 0x000fffff,
},
{ 0, 0 },
};
static struct amba_driver pl030_driver = {
.drv = {
.name = "rtc-pl030",
},
.probe = pl030_probe,
.remove = pl030_remove,
.id_table = pl030_ids,
};
static int __init pl030_init(void)
{
return amba_driver_register(&pl030_driver);
}
static void __exit pl030_exit(void)
{
amba_driver_unregister(&pl030_driver);
}
module_init(pl030_init);
module_exit(pl030_exit);
MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>");
MODULE_DESCRIPTION("ARM AMBA PL030 RTC Driver");
MODULE_LICENSE("GPL");

View File

@@ -12,23 +12,12 @@
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
#include <linux/platform_device.h>
#include <linux/module.h>
#include <linux/rtc.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/interrupt.h>
#include <linux/string.h>
#include <linux/pm.h>
#include <linux/bitops.h>
#include <linux/amba/bus.h>
#include <asm/io.h>
#include <asm/hardware.h>
#include <asm/irq.h>
#include <asm/rtc.h>
#include <linux/io.h>
/*
* Register definitions
@@ -142,13 +131,12 @@ static int pl031_remove(struct amba_device *adev)
{
struct pl031_local *ldata = dev_get_drvdata(&adev->dev);
if (ldata) {
dev_set_drvdata(&adev->dev, NULL);
free_irq(adev->irq[0], ldata->rtc);
rtc_device_unregister(ldata->rtc);
iounmap(ldata->base);
kfree(ldata);
}
amba_set_drvdata(adev, NULL);
free_irq(adev->irq[0], ldata->rtc);
rtc_device_unregister(ldata->rtc);
iounmap(ldata->base);
kfree(ldata);
amba_release_regions(adev);
return 0;
}
@@ -158,13 +146,15 @@ static int pl031_probe(struct amba_device *adev, void *id)
int ret;
struct pl031_local *ldata;
ret = amba_request_regions(adev, NULL);
if (ret)
goto err_req;
ldata = kmalloc(sizeof(struct pl031_local), GFP_KERNEL);
if (!ldata) {
ret = -ENOMEM;
goto out;
}
dev_set_drvdata(&adev->dev, ldata);
ldata->base = ioremap(adev->res.start,
adev->res.end - adev->res.start + 1);
@@ -173,6 +163,8 @@ static int pl031_probe(struct amba_device *adev, void *id)
goto out_no_remap;
}
amba_set_drvdata(adev, ldata);
if (request_irq(adev->irq[0], pl031_interrupt, IRQF_DISABLED,
"rtc-pl031", ldata->rtc)) {
ret = -EIO;
@@ -192,10 +184,12 @@ out_no_rtc:
free_irq(adev->irq[0], ldata->rtc);
out_no_irq:
iounmap(ldata->base);
amba_set_drvdata(adev, NULL);
out_no_remap:
dev_set_drvdata(&adev->dev, NULL);
kfree(ldata);
out:
amba_release_regions(adev);
err_req:
return ret;
}

View File

@@ -26,10 +26,6 @@
#include <asm/uaccess.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/rtc.h>
#include <asm/mach/time.h>
#include <asm/plat-s3c/regs-rtc.h>
/* I have yet to find an S3C implementation with more than one

View File

@@ -33,7 +33,6 @@
#include <asm/hardware.h>
#include <asm/irq.h>
#include <asm/rtc.h>
#ifdef CONFIG_ARCH_PXA
#include <asm/arch/pxa-regs.h>
@@ -47,6 +46,42 @@ static unsigned long rtc_freq = 1024;
static struct rtc_time rtc_alarm;
static DEFINE_SPINLOCK(sa1100_rtc_lock);
static inline int rtc_periodic_alarm(struct rtc_time *tm)
{
return (tm->tm_year == -1) ||
((unsigned)tm->tm_mon >= 12) ||
((unsigned)(tm->tm_mday - 1) >= 31) ||
((unsigned)tm->tm_hour > 23) ||
((unsigned)tm->tm_min > 59) ||
((unsigned)tm->tm_sec > 59);
}
/*
* Calculate the next alarm time given the requested alarm time mask
* and the current time.
*/
static void rtc_next_alarm_time(struct rtc_time *next, struct rtc_time *now, struct rtc_time *alrm)
{
unsigned long next_time;
unsigned long now_time;
next->tm_year = now->tm_year;
next->tm_mon = now->tm_mon;
next->tm_mday = now->tm_mday;
next->tm_hour = alrm->tm_hour;
next->tm_min = alrm->tm_min;
next->tm_sec = alrm->tm_sec;
rtc_tm_to_time(now, &now_time);
rtc_tm_to_time(next, &next_time);
if (next_time < now_time) {
/* Advance one day */
next_time += 60 * 60 * 24;
rtc_time_to_tm(next_time, next);
}
}
static int rtc_update_alarm(struct rtc_time *alrm)
{
struct rtc_time alarm_tm, now_tm;
@@ -331,14 +366,14 @@ static int sa1100_rtc_probe(struct platform_device *pdev)
RCNR = 0;
}
device_init_wakeup(&pdev->dev, 1);
rtc = rtc_device_register(pdev->name, &pdev->dev, &sa1100_rtc_ops,
THIS_MODULE);
if (IS_ERR(rtc))
return PTR_ERR(rtc);
device_init_wakeup(&pdev->dev, 1);
platform_set_drvdata(pdev, rtc);
return 0;