Merge branch 'for-rmk' of git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung into devel-stable

Conflicts:
	arch/arm/Kconfig
This commit is contained in:
Russell King
2010-08-09 14:07:19 +01:00
154 changed files with 5270 additions and 378 deletions

View File

@ -645,9 +645,16 @@ config RTC_DRV_OMAP
DA8xx/OMAP-L13x chips. This driver can also be built as a
module called rtc-omap.
config HAVE_S3C_RTC
bool
help
This will include RTC support for Samsung SoCs. If
you want to include RTC support for any machine, kindly
select this in the respective mach-XXXX/Kconfig file.
config RTC_DRV_S3C
tristate "Samsung S3C series SoC RTC"
depends on ARCH_S3C2410 || ARCH_S3C64XX
depends on ARCH_S3C2410 || ARCH_S3C64XX || HAVE_S3C_RTC
help
RTC (Realtime Clock) driver for the clock inbuilt into the
Samsung S3C24XX series of SoCs. This can provide periodic

View File

@ -1,4 +1,7 @@
/* drivers/rtc/rtc-s3c.c
*
* Copyright (c) 2010 Samsung Electronics Co., Ltd.
* http://www.samsung.com/
*
* Copyright (c) 2004,2006 Simtec Electronics
* Ben Dooks, <ben@simtec.co.uk>
@ -39,6 +42,7 @@ enum s3c_cpu_type {
static struct resource *s3c_rtc_mem;
static struct clk *rtc_clk;
static void __iomem *s3c_rtc_base;
static int s3c_rtc_alarmno = NO_IRQ;
static int s3c_rtc_tickno = NO_IRQ;
@ -53,6 +57,10 @@ static irqreturn_t s3c_rtc_alarmirq(int irq, void *id)
struct rtc_device *rdev = id;
rtc_update_irq(rdev, 1, RTC_AF | RTC_IRQF);
if (s3c_rtc_cpu_type == TYPE_S3C64XX)
writeb(S3C2410_INTP_ALM, s3c_rtc_base + S3C2410_INTP);
return IRQ_HANDLED;
}
@ -61,6 +69,10 @@ static irqreturn_t s3c_rtc_tickirq(int irq, void *id)
struct rtc_device *rdev = id;
rtc_update_irq(rdev, 1, RTC_PF | RTC_IRQF);
if (s3c_rtc_cpu_type == TYPE_S3C64XX)
writeb(S3C2410_INTP_TIC, s3c_rtc_base + S3C2410_INTP);
return IRQ_HANDLED;
}
@ -94,7 +106,7 @@ static int s3c_rtc_setpie(struct device *dev, int enabled)
if (enabled)
tmp |= S3C64XX_RTCCON_TICEN;
writeb(tmp, s3c_rtc_base + S3C2410_RTCCON);
writew(tmp, s3c_rtc_base + S3C2410_RTCCON);
} else {
tmp = readb(s3c_rtc_base + S3C2410_TICNT);
tmp &= ~S3C2410_TICNT_ENABLE;
@ -128,7 +140,7 @@ static int s3c_rtc_setfreq(struct device *dev, int freq)
tmp |= (rtc_dev->max_user_freq / freq)-1;
writeb(tmp, s3c_rtc_base + S3C2410_TICNT);
writel(tmp, s3c_rtc_base + S3C2410_TICNT);
spin_unlock_irq(&s3c_rtc_pie_lock);
return 0;
@ -431,6 +443,10 @@ static int __devexit s3c_rtc_remove(struct platform_device *dev)
s3c_rtc_setpie(&dev->dev, 0);
s3c_rtc_setaie(0);
clk_disable(rtc_clk);
clk_put(rtc_clk);
rtc_clk = NULL;
iounmap(s3c_rtc_base);
release_resource(s3c_rtc_mem);
kfree(s3c_rtc_mem);
@ -442,6 +458,7 @@ static int __devinit s3c_rtc_probe(struct platform_device *pdev)
{
struct rtc_device *rtc;
struct resource *res;
unsigned int tmp, i;
int ret;
pr_debug("%s: probe=%p\n", __func__, pdev);
@ -488,6 +505,16 @@ static int __devinit s3c_rtc_probe(struct platform_device *pdev)
goto err_nomap;
}
rtc_clk = clk_get(&pdev->dev, "rtc");
if (IS_ERR(rtc_clk)) {
dev_err(&pdev->dev, "failed to find rtc clock source\n");
ret = PTR_ERR(rtc_clk);
rtc_clk = NULL;
goto err_clk;
}
clk_enable(rtc_clk);
/* check to see if everything is setup correctly */
s3c_rtc_enable(pdev, 1);
@ -510,6 +537,15 @@ static int __devinit s3c_rtc_probe(struct platform_device *pdev)
s3c_rtc_cpu_type = platform_get_device_id(pdev)->driver_data;
/* Check RTC Time */
for (i = S3C2410_RTCSEC; i <= S3C2410_RTCYEAR; i += 0x4) {
tmp = readb(s3c_rtc_base + i);
if ((tmp & 0xf) > 0x9 || ((tmp >> 4) & 0xf) > 0x9)
writeb(0, s3c_rtc_base + i);
}
if (s3c_rtc_cpu_type == TYPE_S3C64XX)
rtc->max_user_freq = 32768;
else
@ -523,6 +559,10 @@ static int __devinit s3c_rtc_probe(struct platform_device *pdev)
err_nortc:
s3c_rtc_enable(pdev, 0);
clk_disable(rtc_clk);
clk_put(rtc_clk);
err_clk:
iounmap(s3c_rtc_base);
err_nomap: