Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /* drivers/rtc/rtc-s3c.c
0003  *
0004  * Copyright (c) 2010 Samsung Electronics Co., Ltd.
0005  *      http://www.samsung.com/
0006  *
0007  * Copyright (c) 2004,2006 Simtec Electronics
0008  *  Ben Dooks, <ben@simtec.co.uk>
0009  *  http://armlinux.simtec.co.uk/
0010  *
0011  * S3C2410/S3C2440/S3C24XX Internal RTC Driver
0012 */
0013 
0014 #include <linux/module.h>
0015 #include <linux/fs.h>
0016 #include <linux/string.h>
0017 #include <linux/init.h>
0018 #include <linux/platform_device.h>
0019 #include <linux/interrupt.h>
0020 #include <linux/rtc.h>
0021 #include <linux/bcd.h>
0022 #include <linux/clk.h>
0023 #include <linux/log2.h>
0024 #include <linux/slab.h>
0025 #include <linux/of.h>
0026 #include <linux/of_device.h>
0027 #include <linux/uaccess.h>
0028 #include <linux/io.h>
0029 
0030 #include <asm/irq.h>
0031 #include "rtc-s3c.h"
0032 
0033 struct s3c_rtc {
0034     struct device *dev;
0035     struct rtc_device *rtc;
0036 
0037     void __iomem *base;
0038     struct clk *rtc_clk;
0039     struct clk *rtc_src_clk;
0040     bool alarm_enabled;
0041 
0042     const struct s3c_rtc_data *data;
0043 
0044     int irq_alarm;
0045     spinlock_t alarm_lock;
0046 
0047     bool wake_en;
0048 };
0049 
0050 struct s3c_rtc_data {
0051     bool needs_src_clk;
0052 
0053     void (*irq_handler) (struct s3c_rtc *info, int mask);
0054     void (*enable) (struct s3c_rtc *info);
0055     void (*disable) (struct s3c_rtc *info);
0056 };
0057 
0058 static int s3c_rtc_enable_clk(struct s3c_rtc *info)
0059 {
0060     int ret;
0061 
0062     ret = clk_enable(info->rtc_clk);
0063     if (ret)
0064         return ret;
0065 
0066     if (info->data->needs_src_clk) {
0067         ret = clk_enable(info->rtc_src_clk);
0068         if (ret) {
0069             clk_disable(info->rtc_clk);
0070             return ret;
0071         }
0072     }
0073     return 0;
0074 }
0075 
0076 static void s3c_rtc_disable_clk(struct s3c_rtc *info)
0077 {
0078     if (info->data->needs_src_clk)
0079         clk_disable(info->rtc_src_clk);
0080     clk_disable(info->rtc_clk);
0081 }
0082 
0083 /* IRQ Handler */
0084 static irqreturn_t s3c_rtc_alarmirq(int irq, void *id)
0085 {
0086     struct s3c_rtc *info = (struct s3c_rtc *)id;
0087 
0088     if (info->data->irq_handler)
0089         info->data->irq_handler(info, S3C2410_INTP_ALM);
0090 
0091     return IRQ_HANDLED;
0092 }
0093 
0094 /* Update control registers */
0095 static int s3c_rtc_setaie(struct device *dev, unsigned int enabled)
0096 {
0097     struct s3c_rtc *info = dev_get_drvdata(dev);
0098     unsigned long flags;
0099     unsigned int tmp;
0100     int ret;
0101 
0102     dev_dbg(info->dev, "%s: aie=%d\n", __func__, enabled);
0103 
0104     ret = s3c_rtc_enable_clk(info);
0105     if (ret)
0106         return ret;
0107 
0108     tmp = readb(info->base + S3C2410_RTCALM) & ~S3C2410_RTCALM_ALMEN;
0109 
0110     if (enabled)
0111         tmp |= S3C2410_RTCALM_ALMEN;
0112 
0113     writeb(tmp, info->base + S3C2410_RTCALM);
0114 
0115     spin_lock_irqsave(&info->alarm_lock, flags);
0116 
0117     if (info->alarm_enabled && !enabled)
0118         s3c_rtc_disable_clk(info);
0119     else if (!info->alarm_enabled && enabled)
0120         ret = s3c_rtc_enable_clk(info);
0121 
0122     info->alarm_enabled = enabled;
0123     spin_unlock_irqrestore(&info->alarm_lock, flags);
0124 
0125     s3c_rtc_disable_clk(info);
0126 
0127     return ret;
0128 }
0129 
0130 /* Read time from RTC and convert it from BCD */
0131 static int s3c_rtc_read_time(struct s3c_rtc *info, struct rtc_time *tm)
0132 {
0133     unsigned int have_retried = 0;
0134     int ret;
0135 
0136     ret = s3c_rtc_enable_clk(info);
0137     if (ret)
0138         return ret;
0139 
0140 retry_get_time:
0141     tm->tm_min  = readb(info->base + S3C2410_RTCMIN);
0142     tm->tm_hour = readb(info->base + S3C2410_RTCHOUR);
0143     tm->tm_mday = readb(info->base + S3C2410_RTCDATE);
0144     tm->tm_mon  = readb(info->base + S3C2410_RTCMON);
0145     tm->tm_year = readb(info->base + S3C2410_RTCYEAR);
0146     tm->tm_sec  = readb(info->base + S3C2410_RTCSEC);
0147 
0148     /*
0149      * The only way to work out whether the system was mid-update
0150      * when we read it is to check the second counter, and if it
0151      * is zero, then we re-try the entire read
0152      */
0153     if (tm->tm_sec == 0 && !have_retried) {
0154         have_retried = 1;
0155         goto retry_get_time;
0156     }
0157 
0158     s3c_rtc_disable_clk(info);
0159 
0160     tm->tm_sec  = bcd2bin(tm->tm_sec);
0161     tm->tm_min  = bcd2bin(tm->tm_min);
0162     tm->tm_hour = bcd2bin(tm->tm_hour);
0163     tm->tm_mday = bcd2bin(tm->tm_mday);
0164     tm->tm_mon  = bcd2bin(tm->tm_mon);
0165     tm->tm_year = bcd2bin(tm->tm_year);
0166 
0167     return 0;
0168 }
0169 
0170 /* Convert time to BCD and write it to RTC */
0171 static int s3c_rtc_write_time(struct s3c_rtc *info, const struct rtc_time *tm)
0172 {
0173     int ret;
0174 
0175     ret = s3c_rtc_enable_clk(info);
0176     if (ret)
0177         return ret;
0178 
0179     writeb(bin2bcd(tm->tm_sec),  info->base + S3C2410_RTCSEC);
0180     writeb(bin2bcd(tm->tm_min),  info->base + S3C2410_RTCMIN);
0181     writeb(bin2bcd(tm->tm_hour), info->base + S3C2410_RTCHOUR);
0182     writeb(bin2bcd(tm->tm_mday), info->base + S3C2410_RTCDATE);
0183     writeb(bin2bcd(tm->tm_mon),  info->base + S3C2410_RTCMON);
0184     writeb(bin2bcd(tm->tm_year), info->base + S3C2410_RTCYEAR);
0185 
0186     s3c_rtc_disable_clk(info);
0187 
0188     return 0;
0189 }
0190 
0191 static int s3c_rtc_gettime(struct device *dev, struct rtc_time *tm)
0192 {
0193     struct s3c_rtc *info = dev_get_drvdata(dev);
0194     int ret;
0195 
0196     ret = s3c_rtc_read_time(info, tm);
0197     if (ret)
0198         return ret;
0199 
0200     /* Convert internal representation to actual date/time */
0201     tm->tm_year += 100;
0202     tm->tm_mon -= 1;
0203 
0204     dev_dbg(dev, "read time %ptR\n", tm);
0205     return 0;
0206 }
0207 
0208 static int s3c_rtc_settime(struct device *dev, struct rtc_time *tm)
0209 {
0210     struct s3c_rtc *info = dev_get_drvdata(dev);
0211     struct rtc_time rtc_tm = *tm;
0212 
0213     dev_dbg(dev, "set time %ptR\n", tm);
0214 
0215     /*
0216      * Convert actual date/time to internal representation.
0217      * We get around Y2K by simply not supporting it.
0218      */
0219     rtc_tm.tm_year -= 100;
0220     rtc_tm.tm_mon += 1;
0221 
0222     return s3c_rtc_write_time(info, &rtc_tm);
0223 }
0224 
0225 static int s3c_rtc_getalarm(struct device *dev, struct rtc_wkalrm *alrm)
0226 {
0227     struct s3c_rtc *info = dev_get_drvdata(dev);
0228     struct rtc_time *alm_tm = &alrm->time;
0229     unsigned int alm_en;
0230     int ret;
0231 
0232     ret = s3c_rtc_enable_clk(info);
0233     if (ret)
0234         return ret;
0235 
0236     alm_tm->tm_sec  = readb(info->base + S3C2410_ALMSEC);
0237     alm_tm->tm_min  = readb(info->base + S3C2410_ALMMIN);
0238     alm_tm->tm_hour = readb(info->base + S3C2410_ALMHOUR);
0239     alm_tm->tm_mon  = readb(info->base + S3C2410_ALMMON);
0240     alm_tm->tm_mday = readb(info->base + S3C2410_ALMDATE);
0241     alm_tm->tm_year = readb(info->base + S3C2410_ALMYEAR);
0242 
0243     alm_en = readb(info->base + S3C2410_RTCALM);
0244 
0245     s3c_rtc_disable_clk(info);
0246 
0247     alrm->enabled = (alm_en & S3C2410_RTCALM_ALMEN) ? 1 : 0;
0248 
0249     dev_dbg(dev, "read alarm %d, %ptR\n", alm_en, alm_tm);
0250 
0251     /* decode the alarm enable field */
0252     if (alm_en & S3C2410_RTCALM_SECEN)
0253         alm_tm->tm_sec = bcd2bin(alm_tm->tm_sec);
0254 
0255     if (alm_en & S3C2410_RTCALM_MINEN)
0256         alm_tm->tm_min = bcd2bin(alm_tm->tm_min);
0257 
0258     if (alm_en & S3C2410_RTCALM_HOUREN)
0259         alm_tm->tm_hour = bcd2bin(alm_tm->tm_hour);
0260 
0261     if (alm_en & S3C2410_RTCALM_DAYEN)
0262         alm_tm->tm_mday = bcd2bin(alm_tm->tm_mday);
0263 
0264     if (alm_en & S3C2410_RTCALM_MONEN) {
0265         alm_tm->tm_mon = bcd2bin(alm_tm->tm_mon);
0266         alm_tm->tm_mon -= 1;
0267     }
0268 
0269     if (alm_en & S3C2410_RTCALM_YEAREN)
0270         alm_tm->tm_year = bcd2bin(alm_tm->tm_year);
0271 
0272     return 0;
0273 }
0274 
0275 static int s3c_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
0276 {
0277     struct s3c_rtc *info = dev_get_drvdata(dev);
0278     struct rtc_time *tm = &alrm->time;
0279     unsigned int alrm_en;
0280     int ret;
0281 
0282     dev_dbg(dev, "s3c_rtc_setalarm: %d, %ptR\n", alrm->enabled, tm);
0283 
0284     ret = s3c_rtc_enable_clk(info);
0285     if (ret)
0286         return ret;
0287 
0288     alrm_en = readb(info->base + S3C2410_RTCALM) & S3C2410_RTCALM_ALMEN;
0289     writeb(0x00, info->base + S3C2410_RTCALM);
0290 
0291     if (tm->tm_sec < 60 && tm->tm_sec >= 0) {
0292         alrm_en |= S3C2410_RTCALM_SECEN;
0293         writeb(bin2bcd(tm->tm_sec), info->base + S3C2410_ALMSEC);
0294     }
0295 
0296     if (tm->tm_min < 60 && tm->tm_min >= 0) {
0297         alrm_en |= S3C2410_RTCALM_MINEN;
0298         writeb(bin2bcd(tm->tm_min), info->base + S3C2410_ALMMIN);
0299     }
0300 
0301     if (tm->tm_hour < 24 && tm->tm_hour >= 0) {
0302         alrm_en |= S3C2410_RTCALM_HOUREN;
0303         writeb(bin2bcd(tm->tm_hour), info->base + S3C2410_ALMHOUR);
0304     }
0305 
0306     if (tm->tm_mon < 12 && tm->tm_mon >= 0) {
0307         alrm_en |= S3C2410_RTCALM_MONEN;
0308         writeb(bin2bcd(tm->tm_mon + 1), info->base + S3C2410_ALMMON);
0309     }
0310 
0311     if (tm->tm_mday <= 31 && tm->tm_mday >= 1) {
0312         alrm_en |= S3C2410_RTCALM_DAYEN;
0313         writeb(bin2bcd(tm->tm_mday), info->base + S3C2410_ALMDATE);
0314     }
0315 
0316     dev_dbg(dev, "setting S3C2410_RTCALM to %08x\n", alrm_en);
0317 
0318     writeb(alrm_en, info->base + S3C2410_RTCALM);
0319 
0320     s3c_rtc_setaie(dev, alrm->enabled);
0321 
0322     s3c_rtc_disable_clk(info);
0323 
0324     return 0;
0325 }
0326 
0327 static const struct rtc_class_ops s3c_rtcops = {
0328     .read_time  = s3c_rtc_gettime,
0329     .set_time   = s3c_rtc_settime,
0330     .read_alarm = s3c_rtc_getalarm,
0331     .set_alarm  = s3c_rtc_setalarm,
0332     .alarm_irq_enable = s3c_rtc_setaie,
0333 };
0334 
0335 static void s3c24xx_rtc_enable(struct s3c_rtc *info)
0336 {
0337     unsigned int con, tmp;
0338 
0339     con = readw(info->base + S3C2410_RTCCON);
0340     /* re-enable the device, and check it is ok */
0341     if ((con & S3C2410_RTCCON_RTCEN) == 0) {
0342         dev_info(info->dev, "rtc disabled, re-enabling\n");
0343 
0344         tmp = readw(info->base + S3C2410_RTCCON);
0345         writew(tmp | S3C2410_RTCCON_RTCEN, info->base + S3C2410_RTCCON);
0346     }
0347 
0348     if (con & S3C2410_RTCCON_CNTSEL) {
0349         dev_info(info->dev, "removing RTCCON_CNTSEL\n");
0350 
0351         tmp = readw(info->base + S3C2410_RTCCON);
0352         writew(tmp & ~S3C2410_RTCCON_CNTSEL,
0353                info->base + S3C2410_RTCCON);
0354     }
0355 
0356     if (con & S3C2410_RTCCON_CLKRST) {
0357         dev_info(info->dev, "removing RTCCON_CLKRST\n");
0358 
0359         tmp = readw(info->base + S3C2410_RTCCON);
0360         writew(tmp & ~S3C2410_RTCCON_CLKRST,
0361                info->base + S3C2410_RTCCON);
0362     }
0363 }
0364 
0365 static void s3c24xx_rtc_disable(struct s3c_rtc *info)
0366 {
0367     unsigned int con;
0368 
0369     con = readw(info->base + S3C2410_RTCCON);
0370     con &= ~S3C2410_RTCCON_RTCEN;
0371     writew(con, info->base + S3C2410_RTCCON);
0372 
0373     con = readb(info->base + S3C2410_TICNT);
0374     con &= ~S3C2410_TICNT_ENABLE;
0375     writeb(con, info->base + S3C2410_TICNT);
0376 }
0377 
0378 static void s3c6410_rtc_disable(struct s3c_rtc *info)
0379 {
0380     unsigned int con;
0381 
0382     con = readw(info->base + S3C2410_RTCCON);
0383     con &= ~S3C64XX_RTCCON_TICEN;
0384     con &= ~S3C2410_RTCCON_RTCEN;
0385     writew(con, info->base + S3C2410_RTCCON);
0386 }
0387 
0388 static int s3c_rtc_remove(struct platform_device *pdev)
0389 {
0390     struct s3c_rtc *info = platform_get_drvdata(pdev);
0391 
0392     s3c_rtc_setaie(info->dev, 0);
0393 
0394     if (info->data->needs_src_clk)
0395         clk_unprepare(info->rtc_src_clk);
0396     clk_unprepare(info->rtc_clk);
0397 
0398     return 0;
0399 }
0400 
0401 static int s3c_rtc_probe(struct platform_device *pdev)
0402 {
0403     struct s3c_rtc *info = NULL;
0404     int ret;
0405 
0406     info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
0407     if (!info)
0408         return -ENOMEM;
0409 
0410     info->dev = &pdev->dev;
0411     info->data = of_device_get_match_data(&pdev->dev);
0412     if (!info->data) {
0413         dev_err(&pdev->dev, "failed getting s3c_rtc_data\n");
0414         return -EINVAL;
0415     }
0416     spin_lock_init(&info->alarm_lock);
0417 
0418     platform_set_drvdata(pdev, info);
0419 
0420     info->irq_alarm = platform_get_irq(pdev, 0);
0421     if (info->irq_alarm < 0)
0422         return info->irq_alarm;
0423 
0424     dev_dbg(&pdev->dev, "s3c2410_rtc: alarm irq %d\n", info->irq_alarm);
0425 
0426     /* get the memory region */
0427     info->base = devm_platform_ioremap_resource(pdev, 0);
0428     if (IS_ERR(info->base))
0429         return PTR_ERR(info->base);
0430 
0431     info->rtc_clk = devm_clk_get(&pdev->dev, "rtc");
0432     if (IS_ERR(info->rtc_clk)) {
0433         ret = PTR_ERR(info->rtc_clk);
0434         if (ret != -EPROBE_DEFER)
0435             dev_err(&pdev->dev, "failed to find rtc clock\n");
0436         else
0437             dev_dbg(&pdev->dev, "probe deferred due to missing rtc clk\n");
0438         return ret;
0439     }
0440     ret = clk_prepare_enable(info->rtc_clk);
0441     if (ret)
0442         return ret;
0443 
0444     if (info->data->needs_src_clk) {
0445         info->rtc_src_clk = devm_clk_get(&pdev->dev, "rtc_src");
0446         if (IS_ERR(info->rtc_src_clk)) {
0447             ret = dev_err_probe(&pdev->dev, PTR_ERR(info->rtc_src_clk),
0448                         "failed to find rtc source clock\n");
0449             goto err_src_clk;
0450         }
0451         ret = clk_prepare_enable(info->rtc_src_clk);
0452         if (ret)
0453             goto err_src_clk;
0454     }
0455 
0456     /* disable RTC enable bits potentially set by the bootloader */
0457     if (info->data->disable)
0458         info->data->disable(info);
0459 
0460     /* check to see if everything is setup correctly */
0461     if (info->data->enable)
0462         info->data->enable(info);
0463 
0464     dev_dbg(&pdev->dev, "s3c2410_rtc: RTCCON=%02x\n",
0465         readw(info->base + S3C2410_RTCCON));
0466 
0467     device_init_wakeup(&pdev->dev, 1);
0468 
0469     info->rtc = devm_rtc_allocate_device(&pdev->dev);
0470     if (IS_ERR(info->rtc)) {
0471         ret = PTR_ERR(info->rtc);
0472         goto err_nortc;
0473     }
0474 
0475     info->rtc->ops = &s3c_rtcops;
0476     info->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
0477     info->rtc->range_max = RTC_TIMESTAMP_END_2099;
0478 
0479     ret = devm_rtc_register_device(info->rtc);
0480     if (ret)
0481         goto err_nortc;
0482 
0483     ret = devm_request_irq(&pdev->dev, info->irq_alarm, s3c_rtc_alarmirq,
0484                    0, "s3c2410-rtc alarm", info);
0485     if (ret) {
0486         dev_err(&pdev->dev, "IRQ%d error %d\n", info->irq_alarm, ret);
0487         goto err_nortc;
0488     }
0489 
0490     s3c_rtc_disable_clk(info);
0491 
0492     return 0;
0493 
0494 err_nortc:
0495     if (info->data->disable)
0496         info->data->disable(info);
0497 
0498     if (info->data->needs_src_clk)
0499         clk_disable_unprepare(info->rtc_src_clk);
0500 err_src_clk:
0501     clk_disable_unprepare(info->rtc_clk);
0502 
0503     return ret;
0504 }
0505 
0506 #ifdef CONFIG_PM_SLEEP
0507 
0508 static int s3c_rtc_suspend(struct device *dev)
0509 {
0510     struct s3c_rtc *info = dev_get_drvdata(dev);
0511     int ret;
0512 
0513     ret = s3c_rtc_enable_clk(info);
0514     if (ret)
0515         return ret;
0516 
0517     if (info->data->disable)
0518         info->data->disable(info);
0519 
0520     if (device_may_wakeup(dev) && !info->wake_en) {
0521         if (enable_irq_wake(info->irq_alarm) == 0)
0522             info->wake_en = true;
0523         else
0524             dev_err(dev, "enable_irq_wake failed\n");
0525     }
0526 
0527     return 0;
0528 }
0529 
0530 static int s3c_rtc_resume(struct device *dev)
0531 {
0532     struct s3c_rtc *info = dev_get_drvdata(dev);
0533 
0534     if (info->data->enable)
0535         info->data->enable(info);
0536 
0537     s3c_rtc_disable_clk(info);
0538 
0539     if (device_may_wakeup(dev) && info->wake_en) {
0540         disable_irq_wake(info->irq_alarm);
0541         info->wake_en = false;
0542     }
0543 
0544     return 0;
0545 }
0546 #endif
0547 static SIMPLE_DEV_PM_OPS(s3c_rtc_pm_ops, s3c_rtc_suspend, s3c_rtc_resume);
0548 
0549 static void s3c24xx_rtc_irq(struct s3c_rtc *info, int mask)
0550 {
0551     rtc_update_irq(info->rtc, 1, RTC_AF | RTC_IRQF);
0552 }
0553 
0554 static void s3c6410_rtc_irq(struct s3c_rtc *info, int mask)
0555 {
0556     rtc_update_irq(info->rtc, 1, RTC_AF | RTC_IRQF);
0557     writeb(mask, info->base + S3C2410_INTP);
0558 }
0559 
0560 static struct s3c_rtc_data const s3c2410_rtc_data = {
0561     .irq_handler        = s3c24xx_rtc_irq,
0562     .enable         = s3c24xx_rtc_enable,
0563     .disable        = s3c24xx_rtc_disable,
0564 };
0565 
0566 static struct s3c_rtc_data const s3c2416_rtc_data = {
0567     .irq_handler        = s3c24xx_rtc_irq,
0568     .enable         = s3c24xx_rtc_enable,
0569     .disable        = s3c24xx_rtc_disable,
0570 };
0571 
0572 static struct s3c_rtc_data const s3c2443_rtc_data = {
0573     .irq_handler        = s3c24xx_rtc_irq,
0574     .enable         = s3c24xx_rtc_enable,
0575     .disable        = s3c24xx_rtc_disable,
0576 };
0577 
0578 static struct s3c_rtc_data const s3c6410_rtc_data = {
0579     .needs_src_clk      = true,
0580     .irq_handler        = s3c6410_rtc_irq,
0581     .enable         = s3c24xx_rtc_enable,
0582     .disable        = s3c6410_rtc_disable,
0583 };
0584 
0585 static const __maybe_unused struct of_device_id s3c_rtc_dt_match[] = {
0586     {
0587         .compatible = "samsung,s3c2410-rtc",
0588         .data = &s3c2410_rtc_data,
0589     }, {
0590         .compatible = "samsung,s3c2416-rtc",
0591         .data = &s3c2416_rtc_data,
0592     }, {
0593         .compatible = "samsung,s3c2443-rtc",
0594         .data = &s3c2443_rtc_data,
0595     }, {
0596         .compatible = "samsung,s3c6410-rtc",
0597         .data = &s3c6410_rtc_data,
0598     }, {
0599         .compatible = "samsung,exynos3250-rtc",
0600         .data = &s3c6410_rtc_data,
0601     },
0602     { /* sentinel */ },
0603 };
0604 MODULE_DEVICE_TABLE(of, s3c_rtc_dt_match);
0605 
0606 static struct platform_driver s3c_rtc_driver = {
0607     .probe      = s3c_rtc_probe,
0608     .remove     = s3c_rtc_remove,
0609     .driver     = {
0610         .name   = "s3c-rtc",
0611         .pm = &s3c_rtc_pm_ops,
0612         .of_match_table = of_match_ptr(s3c_rtc_dt_match),
0613     },
0614 };
0615 module_platform_driver(s3c_rtc_driver);
0616 
0617 MODULE_DESCRIPTION("Samsung S3C RTC Driver");
0618 MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
0619 MODULE_LICENSE("GPL");
0620 MODULE_ALIAS("platform:s3c2410-rtc");