From patchwork Tue Jan 12 00:40:18 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maurus Cuelenaere X-Patchwork-Id: 42669 Return-Path: <3CcVLSwsJCWUPFXHOHQDHUHJPDLO.FRPUWF-OLQXaJRRJOHJURXSV.FRP@listserv.bounces.google.com> X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from mail-yx0-f158.google.com (mail-yx0-f158.google.com [209.85.210.158]) by ozlabs.org (Postfix) with ESMTP id 5604A1007D2 for ; Tue, 12 Jan 2010 11:40:43 +1100 (EST) Received: by yxe30 with SMTP id 30sf53704152yxe.29 for ; Mon, 11 Jan 2010 16:40:42 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=googlegroups.com; s=beta; h=domainkey-signature:received:x-beenthere:received:received:received :received:received-spf:received:mime-version:received:from:date :message-id:subject:to:cc:x-original-authentication-results :x-original-sender:reply-to:precedence:mailing-list:list-id :list-post:list-help:list-archive:x-thread-url:x-message-url:sender :list-unsubscribe:list-subscribe:content-type; bh=7KkThX8dqV0DedCJTrpguBdVFzv6Dd++xa7oEFAlWl4=; b=vVOn5X1vtwCrpjF5JjOeIasKTS2hfAVta27eo7Vh2A+M9JGKw5OMviB+ructw0hwLl W8plCIIfH6GRkj75hYw0P9XNrcBkAWH/RLyb+ErQjJk1oW1T3Y2UjaMk20qeEhtisghq aLk0ZR9CzcE3MyQbfdOSrhaDhb3f2+6o+W2FQ= DomainKey-Signature: a=rsa-sha1; c=nofws; d=googlegroups.com; s=beta; h=x-beenthere:received-spf:mime-version:from:date:message-id:subject :to:cc:x-original-authentication-results:x-original-sender:reply-to :precedence:mailing-list:list-id:list-post:list-help:list-archive :x-thread-url:x-message-url:sender:list-unsubscribe:list-subscribe :content-type; b=vaPz80zmOgMGBEcB3QjX5LsxlR+rF6aaEZHpwg4zIKOrJPTj5/Zcrmp4N5/aAxECBf Lg6T3+IVuoceO4vcNZvhmsg5E+zQKTNgFbhY435jOWQmHb/JnjSOE/ljgVgFoPNUNECd MIJY4zMiltq2BRirzQsBL1EpyLNbMLks+Ydh0= Received: by 10.101.166.27 with SMTP id t27mr4014740ano.28.1263256841910; Mon, 11 Jan 2010 16:40:41 -0800 (PST) X-BeenThere: rtc-linux@googlegroups.com Received: by 10.223.98.89 with SMTP id p25ls782349fan.2.p; Mon, 11 Jan 2010 16:40:40 -0800 (PST) Received: by 10.223.64.65 with SMTP id d1mr1135fai.0.1263256840122; Mon, 11 Jan 2010 16:40:40 -0800 (PST) Received: by 10.223.64.65 with SMTP id d1mr1134fai.0.1263256840097; Mon, 11 Jan 2010 16:40:40 -0800 (PST) Received: from mail-bw0-f211.google.com (mail-bw0-f211.google.com [209.85.218.211]) by gmr-mx.google.com with ESMTP id 11si2574539fxm.6.2010.01.11.16.40.39; Mon, 11 Jan 2010 16:40:39 -0800 (PST) Received-SPF: pass (google.com: domain of mcuelenaere@gmail.com designates 209.85.218.211 as permitted sender) client-ip=209.85.218.211; Received: by bwz3 with SMTP id 3so17228130bwz.36 for ; Mon, 11 Jan 2010 16:40:38 -0800 (PST) MIME-Version: 1.0 Received: by 10.204.49.84 with SMTP id u20mr2039764bkf.199.1263256838135; Mon, 11 Jan 2010 16:40:38 -0800 (PST) From: Maurus Cuelenaere Date: Tue, 12 Jan 2010 01:40:18 +0100 Message-ID: Subject: [rtc-linux] [PATCH] S3C RTC driver: add support for S3C64xx To: rtc-linux Cc: Ben Dooks X-Original-Authentication-Results: gmr-mx.google.com; spf=pass (google.com: domain of mcuelenaere@gmail.com designates 209.85.218.211 as permitted sender) smtp.mail=mcuelenaere@gmail.com; dkim=pass (test mode) header.i=@gmail.com X-Original-Sender: mcuelenaere@gmail.com Reply-To: rtc-linux@googlegroups.com Precedence: list Mailing-list: list rtc-linux@googlegroups.com; contact rtc-linux+owners@googlegroups.com List-ID: List-Post: , List-Help: , List-Archive: X-Thread-Url: http://groups.google.com/group/rtc-linux/t/2a2dfc23a8042f3d X-Message-Url: http://groups.google.com/group/rtc-linux/msg/2057f26e79f82c96 Sender: rtc-linux@googlegroups.com List-Unsubscribe: , List-Subscribe: , S3C RTC driver: add support for S3C64xx Add support for the S3C64xx SoC to the generic S3C RTC driver. Signed-off-by: Maurus Cuelenaere Acked-By: Ben Dooks --- arch/arm/plat-s3c/include/plat/regs-rtc.h | 4 + drivers/rtc/Kconfig | 2 +- drivers/rtc/rtc-s3c.c | 107 +++++++++++++++++++++++------ 3 files changed, 92 insertions(+), 21 deletions(-) @@ -352,10 +384,16 @@ static void s3c_rtc_enable(struct platform_device *pdev, int en) if (!en) { tmp = readb(base + S3C2410_RTCCON); - writeb(tmp & ~S3C2410_RTCCON_RTCEN, base + S3C2410_RTCCON); - - tmp = readb(base + S3C2410_TICNT); - writeb(tmp & ~S3C2410_TICNT_ENABLE, base + S3C2410_TICNT); + if (s3c_rtc_cpu_type == TYPE_S3C64XX) + tmp &= ~S3C64XX_RTCCON_TICEN; + tmp &= ~S3C2410_RTCCON_RTCEN; + writeb(tmp, base + S3C2410_RTCCON); + + if (s3c_rtc_cpu_type == TYPE_S3C2410) { + tmp = readb(base + S3C2410_TICNT); + tmp &= ~S3C2410_TICNT_ENABLE; + writeb(tmp, base + S3C2410_TICNT); + } } else { /* re-enable the device, and check it is ok */ @@ -471,7 +509,12 @@ static int __devinit s3c_rtc_probe(struct platform_device *pdev) goto err_nortc; } - rtc->max_user_freq = 128; + if (s3c_rtc_cpu_type == TYPE_S3C64XX) + rtc->max_user_freq = 32768; + else + rtc->max_user_freq = 128; + + s3c_rtc_cpu_type = platform_get_device_id(pdev)->driver_data; platform_set_drvdata(pdev, rtc); return 0; @@ -491,20 +534,30 @@ static int __devinit s3c_rtc_probe(struct platform_device *pdev) /* RTC Power management control */ -static int ticnt_save; +static int ticnt_save, ticnt_en_save; static int s3c_rtc_suspend(struct platform_device *pdev, pm_message_t state) { /* save TICNT for anyone using periodic interrupts */ ticnt_save = readb(s3c_rtc_base + S3C2410_TICNT); + if (s3c_rtc_cpu_type == TYPE_S3C64XX) { + ticnt_en_save = readb(s3c_rtc_base + S3C2410_RTCCON); + ticnt_en_save &= S3C64XX_RTCCON_TICEN; + } s3c_rtc_enable(pdev, 0); return 0; } static int s3c_rtc_resume(struct platform_device *pdev) { + unsigned int tmp; + s3c_rtc_enable(pdev, 1); writeb(ticnt_save, s3c_rtc_base + S3C2410_TICNT); + if (s3c_rtc_cpu_type == TYPE_S3C64XX && ticnt_en_save) { + tmp = readb(s3c_rtc_base + S3C2410_RTCCON); + writeb(tmp | ticnt_en_save, s3c_rtc_base + S3C2410_RTCCON); + } return 0; } #else @@ -512,13 +565,27 @@ static int s3c_rtc_resume(struct platform_device *pdev) #define s3c_rtc_resume NULL #endif -static struct platform_driver s3c2410_rtc_driver = { +static struct platform_device_id s3c_rtc_driver_ids[] = { + { + .name = "s3c2410-rtc", + .driver_data = TYPE_S3C2410, + }, { + .name = "s3c64xx-rtc", + .driver_data = TYPE_S3C64XX, + }, + { } +}; + +MODULE_DEVICE_TABLE(platform, s3c_rtc_driver_ids); + +static struct platform_driver s3c_rtc_driver = { .probe = s3c_rtc_probe, .remove = __devexit_p(s3c_rtc_remove), .suspend = s3c_rtc_suspend, .resume = s3c_rtc_resume, + .id_table = s3c_rtc_driver_ids, .driver = { - .name = "s3c2410-rtc", + .name = "s3c-rtc", .owner = THIS_MODULE, }, }; @@ -528,12 +595,12 @@ static char __initdata banner[] = "S3C24XX RTC, (c) 2004,2006 Simtec Electronics static int __init s3c_rtc_init(void) { printk(banner); - return platform_driver_register(&s3c2410_rtc_driver); + return platform_driver_register(&s3c_rtc_driver); } static void __exit s3c_rtc_exit(void) { - platform_driver_unregister(&s3c2410_rtc_driver); + platform_driver_unregister(&s3c_rtc_driver); } module_init(s3c_rtc_init); diff --git a/arch/arm/plat-s3c/include/plat/regs-rtc.h b/arch/arm/plat-s3c/include/plat/regs-rtc.h index d5837cf..65c190d 100644 --- a/arch/arm/plat-s3c/include/plat/regs-rtc.h +++ b/arch/arm/plat-s3c/include/plat/regs-rtc.h @@ -20,6 +20,10 @@ #define S3C2410_RTCCON_CLKSEL (1<<1) #define S3C2410_RTCCON_CNTSEL (1<<2) #define S3C2410_RTCCON_CLKRST (1<<3) +#define S3C64XX_RTCCON_TICEN (1<<8) + +#define S3C64XX_RTCCON_TICMSK (0xF<<7) +#define S3C64XX_RTCCON_TICSHT (7) #define S3C2410_TICNT S3C2410_RTCREG(0x44) #define S3C2410_TICNT_ENABLE (1<<7) diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 8167e9e..b44db44 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -620,7 +620,7 @@ config RTC_DRV_OMAP config RTC_DRV_S3C tristate "Samsung S3C series SoC RTC" - depends on ARCH_S3C2410 + depends on ARCH_S3C2410 || ARCH_S3C64XX help RTC (Realtime Clock) driver for the clock inbuilt into the Samsung S3C24XX series of SoCs. This can provide periodic diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c index e0d7b99..798d2dd 100644 --- a/drivers/rtc/rtc-s3c.c +++ b/drivers/rtc/rtc-s3c.c @@ -28,6 +28,11 @@ #include #include +enum s3c_cpu_type { + TYPE_S3C2410, + TYPE_S3C64XX, +}; + /* I have yet to find an S3C implementation with more than one * of these rtc blocks in */ @@ -36,6 +41,7 @@ static struct resource *s3c_rtc_mem; static void __iomem *s3c_rtc_base; static int s3c_rtc_alarmno = NO_IRQ; static int s3c_rtc_tickno = NO_IRQ; +static enum s3c_cpu_type s3c_rtc_cpu_type; static DEFINE_SPINLOCK(s3c_rtc_pie_lock); @@ -79,12 +85,25 @@ static int s3c_rtc_setpie(struct device *dev, int enabled) pr_debug("%s: pie=%d\n", __func__, enabled); spin_lock_irq(&s3c_rtc_pie_lock); - tmp = readb(s3c_rtc_base + S3C2410_TICNT) & ~S3C2410_TICNT_ENABLE; - if (enabled) - tmp |= S3C2410_TICNT_ENABLE; + if (s3c_rtc_cpu_type == TYPE_S3C64XX) { + tmp = readb(s3c_rtc_base + S3C2410_RTCCON); + tmp &= ~S3C64XX_RTCCON_TICEN; + + if (enabled) + tmp |= S3C64XX_RTCCON_TICEN; + + writeb(tmp, s3c_rtc_base + S3C2410_RTCCON); + } else { + tmp = readb(s3c_rtc_base + S3C2410_TICNT); + tmp &= ~S3C2410_TICNT_ENABLE; + + if (enabled) + tmp |= S3C2410_TICNT_ENABLE; + + writeb(tmp, s3c_rtc_base + S3C2410_TICNT); + } - writeb(tmp, s3c_rtc_base + S3C2410_TICNT); spin_unlock_irq(&s3c_rtc_pie_lock); return 0; @@ -92,15 +111,21 @@ static int s3c_rtc_setpie(struct device *dev, int enabled) static int s3c_rtc_setfreq(struct device *dev, int freq) { - unsigned int tmp; + struct platform_device *pdev = to_platform_device(dev); + struct rtc_device *rtc_dev = platform_get_drvdata(pdev); + unsigned int tmp = 0; if (!is_power_of_2(freq)) return -EINVAL; spin_lock_irq(&s3c_rtc_pie_lock); - tmp = readb(s3c_rtc_base + S3C2410_TICNT) & S3C2410_TICNT_ENABLE; - tmp |= (128 / freq)-1; + if (s3c_rtc_cpu_type == TYPE_S3C2410) { + tmp = readb(s3c_rtc_base + S3C2410_TICNT); + tmp &= S3C2410_TICNT_ENABLE; + } + + tmp |= (rtc_dev->max_user_freq / freq)-1; writeb(tmp, s3c_rtc_base + S3C2410_TICNT); spin_unlock_irq(&s3c_rtc_pie_lock); @@ -282,10 +307,17 @@ static int s3c_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) static int s3c_rtc_proc(struct device *dev, struct seq_file *seq) { - unsigned int ticnt = readb(s3c_rtc_base + S3C2410_TICNT); + unsigned int ticnt; - seq_printf(seq, "periodic_IRQ\t: %s\n", - (ticnt & S3C2410_TICNT_ENABLE) ? "yes" : "no" ); + if (s3c_rtc_cpu_type == TYPE_S3C64XX) { + ticnt = readb(s3c_rtc_base + S3C2410_RTCCON); + ticnt &= S3C64XX_RTCCON_TICEN; + } else { + ticnt = readb(s3c_rtc_base + S3C2410_TICNT); + ticnt &= S3C2410_TICNT_ENABLE; + } + + seq_printf(seq, "periodic_IRQ\t: %s\n", ticnt ? "yes" : "no"); return 0; }