rtc-s3c.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /* drivers/rtc/rtc-s3c.c
  3. *
  4. * Copyright (c) 2010 Samsung Electronics Co., Ltd.
  5. * http://www.samsung.com/
  6. *
  7. * Copyright (c) 2004,2006 Simtec Electronics
  8. * Ben Dooks, <[email protected]>
  9. * http://armlinux.simtec.co.uk/
  10. *
  11. * S3C2410/S3C2440/S3C24XX Internal RTC Driver
  12. */
  13. #include <linux/module.h>
  14. #include <linux/fs.h>
  15. #include <linux/string.h>
  16. #include <linux/init.h>
  17. #include <linux/platform_device.h>
  18. #include <linux/interrupt.h>
  19. #include <linux/rtc.h>
  20. #include <linux/bcd.h>
  21. #include <linux/clk.h>
  22. #include <linux/log2.h>
  23. #include <linux/slab.h>
  24. #include <linux/of.h>
  25. #include <linux/of_device.h>
  26. #include <linux/uaccess.h>
  27. #include <linux/io.h>
  28. #include <asm/irq.h>
  29. #include "rtc-s3c.h"
  30. struct s3c_rtc {
  31. struct device *dev;
  32. struct rtc_device *rtc;
  33. void __iomem *base;
  34. struct clk *rtc_clk;
  35. struct clk *rtc_src_clk;
  36. bool alarm_enabled;
  37. const struct s3c_rtc_data *data;
  38. int irq_alarm;
  39. spinlock_t alarm_lock;
  40. bool wake_en;
  41. };
  42. struct s3c_rtc_data {
  43. bool needs_src_clk;
  44. void (*irq_handler) (struct s3c_rtc *info, int mask);
  45. void (*enable) (struct s3c_rtc *info);
  46. void (*disable) (struct s3c_rtc *info);
  47. };
  48. static int s3c_rtc_enable_clk(struct s3c_rtc *info)
  49. {
  50. int ret;
  51. ret = clk_enable(info->rtc_clk);
  52. if (ret)
  53. return ret;
  54. if (info->data->needs_src_clk) {
  55. ret = clk_enable(info->rtc_src_clk);
  56. if (ret) {
  57. clk_disable(info->rtc_clk);
  58. return ret;
  59. }
  60. }
  61. return 0;
  62. }
  63. static void s3c_rtc_disable_clk(struct s3c_rtc *info)
  64. {
  65. if (info->data->needs_src_clk)
  66. clk_disable(info->rtc_src_clk);
  67. clk_disable(info->rtc_clk);
  68. }
  69. /* IRQ Handler */
  70. static irqreturn_t s3c_rtc_alarmirq(int irq, void *id)
  71. {
  72. struct s3c_rtc *info = (struct s3c_rtc *)id;
  73. if (info->data->irq_handler)
  74. info->data->irq_handler(info, S3C2410_INTP_ALM);
  75. return IRQ_HANDLED;
  76. }
  77. /* Update control registers */
  78. static int s3c_rtc_setaie(struct device *dev, unsigned int enabled)
  79. {
  80. struct s3c_rtc *info = dev_get_drvdata(dev);
  81. unsigned long flags;
  82. unsigned int tmp;
  83. int ret;
  84. dev_dbg(info->dev, "%s: aie=%d\n", __func__, enabled);
  85. ret = s3c_rtc_enable_clk(info);
  86. if (ret)
  87. return ret;
  88. tmp = readb(info->base + S3C2410_RTCALM) & ~S3C2410_RTCALM_ALMEN;
  89. if (enabled)
  90. tmp |= S3C2410_RTCALM_ALMEN;
  91. writeb(tmp, info->base + S3C2410_RTCALM);
  92. spin_lock_irqsave(&info->alarm_lock, flags);
  93. if (info->alarm_enabled && !enabled)
  94. s3c_rtc_disable_clk(info);
  95. else if (!info->alarm_enabled && enabled)
  96. ret = s3c_rtc_enable_clk(info);
  97. info->alarm_enabled = enabled;
  98. spin_unlock_irqrestore(&info->alarm_lock, flags);
  99. s3c_rtc_disable_clk(info);
  100. return ret;
  101. }
  102. /* Read time from RTC and convert it from BCD */
  103. static int s3c_rtc_read_time(struct s3c_rtc *info, struct rtc_time *tm)
  104. {
  105. unsigned int have_retried = 0;
  106. int ret;
  107. ret = s3c_rtc_enable_clk(info);
  108. if (ret)
  109. return ret;
  110. retry_get_time:
  111. tm->tm_min = readb(info->base + S3C2410_RTCMIN);
  112. tm->tm_hour = readb(info->base + S3C2410_RTCHOUR);
  113. tm->tm_mday = readb(info->base + S3C2410_RTCDATE);
  114. tm->tm_mon = readb(info->base + S3C2410_RTCMON);
  115. tm->tm_year = readb(info->base + S3C2410_RTCYEAR);
  116. tm->tm_sec = readb(info->base + S3C2410_RTCSEC);
  117. /*
  118. * The only way to work out whether the system was mid-update
  119. * when we read it is to check the second counter, and if it
  120. * is zero, then we re-try the entire read
  121. */
  122. if (tm->tm_sec == 0 && !have_retried) {
  123. have_retried = 1;
  124. goto retry_get_time;
  125. }
  126. s3c_rtc_disable_clk(info);
  127. tm->tm_sec = bcd2bin(tm->tm_sec);
  128. tm->tm_min = bcd2bin(tm->tm_min);
  129. tm->tm_hour = bcd2bin(tm->tm_hour);
  130. tm->tm_mday = bcd2bin(tm->tm_mday);
  131. tm->tm_mon = bcd2bin(tm->tm_mon);
  132. tm->tm_year = bcd2bin(tm->tm_year);
  133. return 0;
  134. }
  135. /* Convert time to BCD and write it to RTC */
  136. static int s3c_rtc_write_time(struct s3c_rtc *info, const struct rtc_time *tm)
  137. {
  138. int ret;
  139. ret = s3c_rtc_enable_clk(info);
  140. if (ret)
  141. return ret;
  142. writeb(bin2bcd(tm->tm_sec), info->base + S3C2410_RTCSEC);
  143. writeb(bin2bcd(tm->tm_min), info->base + S3C2410_RTCMIN);
  144. writeb(bin2bcd(tm->tm_hour), info->base + S3C2410_RTCHOUR);
  145. writeb(bin2bcd(tm->tm_mday), info->base + S3C2410_RTCDATE);
  146. writeb(bin2bcd(tm->tm_mon), info->base + S3C2410_RTCMON);
  147. writeb(bin2bcd(tm->tm_year), info->base + S3C2410_RTCYEAR);
  148. s3c_rtc_disable_clk(info);
  149. return 0;
  150. }
  151. static int s3c_rtc_gettime(struct device *dev, struct rtc_time *tm)
  152. {
  153. struct s3c_rtc *info = dev_get_drvdata(dev);
  154. int ret;
  155. ret = s3c_rtc_read_time(info, tm);
  156. if (ret)
  157. return ret;
  158. /* Convert internal representation to actual date/time */
  159. tm->tm_year += 100;
  160. tm->tm_mon -= 1;
  161. dev_dbg(dev, "read time %ptR\n", tm);
  162. return 0;
  163. }
  164. static int s3c_rtc_settime(struct device *dev, struct rtc_time *tm)
  165. {
  166. struct s3c_rtc *info = dev_get_drvdata(dev);
  167. struct rtc_time rtc_tm = *tm;
  168. dev_dbg(dev, "set time %ptR\n", tm);
  169. /*
  170. * Convert actual date/time to internal representation.
  171. * We get around Y2K by simply not supporting it.
  172. */
  173. rtc_tm.tm_year -= 100;
  174. rtc_tm.tm_mon += 1;
  175. return s3c_rtc_write_time(info, &rtc_tm);
  176. }
  177. static int s3c_rtc_getalarm(struct device *dev, struct rtc_wkalrm *alrm)
  178. {
  179. struct s3c_rtc *info = dev_get_drvdata(dev);
  180. struct rtc_time *alm_tm = &alrm->time;
  181. unsigned int alm_en;
  182. int ret;
  183. ret = s3c_rtc_enable_clk(info);
  184. if (ret)
  185. return ret;
  186. alm_tm->tm_sec = readb(info->base + S3C2410_ALMSEC);
  187. alm_tm->tm_min = readb(info->base + S3C2410_ALMMIN);
  188. alm_tm->tm_hour = readb(info->base + S3C2410_ALMHOUR);
  189. alm_tm->tm_mon = readb(info->base + S3C2410_ALMMON);
  190. alm_tm->tm_mday = readb(info->base + S3C2410_ALMDATE);
  191. alm_tm->tm_year = readb(info->base + S3C2410_ALMYEAR);
  192. alm_en = readb(info->base + S3C2410_RTCALM);
  193. s3c_rtc_disable_clk(info);
  194. alrm->enabled = (alm_en & S3C2410_RTCALM_ALMEN) ? 1 : 0;
  195. dev_dbg(dev, "read alarm %d, %ptR\n", alm_en, alm_tm);
  196. /* decode the alarm enable field */
  197. if (alm_en & S3C2410_RTCALM_SECEN)
  198. alm_tm->tm_sec = bcd2bin(alm_tm->tm_sec);
  199. if (alm_en & S3C2410_RTCALM_MINEN)
  200. alm_tm->tm_min = bcd2bin(alm_tm->tm_min);
  201. if (alm_en & S3C2410_RTCALM_HOUREN)
  202. alm_tm->tm_hour = bcd2bin(alm_tm->tm_hour);
  203. if (alm_en & S3C2410_RTCALM_DAYEN)
  204. alm_tm->tm_mday = bcd2bin(alm_tm->tm_mday);
  205. if (alm_en & S3C2410_RTCALM_MONEN) {
  206. alm_tm->tm_mon = bcd2bin(alm_tm->tm_mon);
  207. alm_tm->tm_mon -= 1;
  208. }
  209. if (alm_en & S3C2410_RTCALM_YEAREN)
  210. alm_tm->tm_year = bcd2bin(alm_tm->tm_year);
  211. return 0;
  212. }
  213. static int s3c_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
  214. {
  215. struct s3c_rtc *info = dev_get_drvdata(dev);
  216. struct rtc_time *tm = &alrm->time;
  217. unsigned int alrm_en;
  218. int ret;
  219. dev_dbg(dev, "s3c_rtc_setalarm: %d, %ptR\n", alrm->enabled, tm);
  220. ret = s3c_rtc_enable_clk(info);
  221. if (ret)
  222. return ret;
  223. alrm_en = readb(info->base + S3C2410_RTCALM) & S3C2410_RTCALM_ALMEN;
  224. writeb(0x00, info->base + S3C2410_RTCALM);
  225. if (tm->tm_sec < 60 && tm->tm_sec >= 0) {
  226. alrm_en |= S3C2410_RTCALM_SECEN;
  227. writeb(bin2bcd(tm->tm_sec), info->base + S3C2410_ALMSEC);
  228. }
  229. if (tm->tm_min < 60 && tm->tm_min >= 0) {
  230. alrm_en |= S3C2410_RTCALM_MINEN;
  231. writeb(bin2bcd(tm->tm_min), info->base + S3C2410_ALMMIN);
  232. }
  233. if (tm->tm_hour < 24 && tm->tm_hour >= 0) {
  234. alrm_en |= S3C2410_RTCALM_HOUREN;
  235. writeb(bin2bcd(tm->tm_hour), info->base + S3C2410_ALMHOUR);
  236. }
  237. if (tm->tm_mon < 12 && tm->tm_mon >= 0) {
  238. alrm_en |= S3C2410_RTCALM_MONEN;
  239. writeb(bin2bcd(tm->tm_mon + 1), info->base + S3C2410_ALMMON);
  240. }
  241. if (tm->tm_mday <= 31 && tm->tm_mday >= 1) {
  242. alrm_en |= S3C2410_RTCALM_DAYEN;
  243. writeb(bin2bcd(tm->tm_mday), info->base + S3C2410_ALMDATE);
  244. }
  245. dev_dbg(dev, "setting S3C2410_RTCALM to %08x\n", alrm_en);
  246. writeb(alrm_en, info->base + S3C2410_RTCALM);
  247. s3c_rtc_setaie(dev, alrm->enabled);
  248. s3c_rtc_disable_clk(info);
  249. return 0;
  250. }
  251. static const struct rtc_class_ops s3c_rtcops = {
  252. .read_time = s3c_rtc_gettime,
  253. .set_time = s3c_rtc_settime,
  254. .read_alarm = s3c_rtc_getalarm,
  255. .set_alarm = s3c_rtc_setalarm,
  256. .alarm_irq_enable = s3c_rtc_setaie,
  257. };
  258. static void s3c24xx_rtc_enable(struct s3c_rtc *info)
  259. {
  260. unsigned int con, tmp;
  261. con = readw(info->base + S3C2410_RTCCON);
  262. /* re-enable the device, and check it is ok */
  263. if ((con & S3C2410_RTCCON_RTCEN) == 0) {
  264. dev_info(info->dev, "rtc disabled, re-enabling\n");
  265. tmp = readw(info->base + S3C2410_RTCCON);
  266. writew(tmp | S3C2410_RTCCON_RTCEN, info->base + S3C2410_RTCCON);
  267. }
  268. if (con & S3C2410_RTCCON_CNTSEL) {
  269. dev_info(info->dev, "removing RTCCON_CNTSEL\n");
  270. tmp = readw(info->base + S3C2410_RTCCON);
  271. writew(tmp & ~S3C2410_RTCCON_CNTSEL,
  272. info->base + S3C2410_RTCCON);
  273. }
  274. if (con & S3C2410_RTCCON_CLKRST) {
  275. dev_info(info->dev, "removing RTCCON_CLKRST\n");
  276. tmp = readw(info->base + S3C2410_RTCCON);
  277. writew(tmp & ~S3C2410_RTCCON_CLKRST,
  278. info->base + S3C2410_RTCCON);
  279. }
  280. }
  281. static void s3c24xx_rtc_disable(struct s3c_rtc *info)
  282. {
  283. unsigned int con;
  284. con = readw(info->base + S3C2410_RTCCON);
  285. con &= ~S3C2410_RTCCON_RTCEN;
  286. writew(con, info->base + S3C2410_RTCCON);
  287. con = readb(info->base + S3C2410_TICNT);
  288. con &= ~S3C2410_TICNT_ENABLE;
  289. writeb(con, info->base + S3C2410_TICNT);
  290. }
  291. static void s3c6410_rtc_disable(struct s3c_rtc *info)
  292. {
  293. unsigned int con;
  294. con = readw(info->base + S3C2410_RTCCON);
  295. con &= ~S3C64XX_RTCCON_TICEN;
  296. con &= ~S3C2410_RTCCON_RTCEN;
  297. writew(con, info->base + S3C2410_RTCCON);
  298. }
  299. static int s3c_rtc_remove(struct platform_device *pdev)
  300. {
  301. struct s3c_rtc *info = platform_get_drvdata(pdev);
  302. s3c_rtc_setaie(info->dev, 0);
  303. if (info->data->needs_src_clk)
  304. clk_unprepare(info->rtc_src_clk);
  305. clk_unprepare(info->rtc_clk);
  306. return 0;
  307. }
  308. static int s3c_rtc_probe(struct platform_device *pdev)
  309. {
  310. struct s3c_rtc *info = NULL;
  311. int ret;
  312. info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
  313. if (!info)
  314. return -ENOMEM;
  315. info->dev = &pdev->dev;
  316. info->data = of_device_get_match_data(&pdev->dev);
  317. if (!info->data) {
  318. dev_err(&pdev->dev, "failed getting s3c_rtc_data\n");
  319. return -EINVAL;
  320. }
  321. spin_lock_init(&info->alarm_lock);
  322. platform_set_drvdata(pdev, info);
  323. info->irq_alarm = platform_get_irq(pdev, 0);
  324. if (info->irq_alarm < 0)
  325. return info->irq_alarm;
  326. dev_dbg(&pdev->dev, "s3c2410_rtc: alarm irq %d\n", info->irq_alarm);
  327. /* get the memory region */
  328. info->base = devm_platform_ioremap_resource(pdev, 0);
  329. if (IS_ERR(info->base))
  330. return PTR_ERR(info->base);
  331. info->rtc_clk = devm_clk_get(&pdev->dev, "rtc");
  332. if (IS_ERR(info->rtc_clk)) {
  333. ret = PTR_ERR(info->rtc_clk);
  334. if (ret != -EPROBE_DEFER)
  335. dev_err(&pdev->dev, "failed to find rtc clock\n");
  336. else
  337. dev_dbg(&pdev->dev, "probe deferred due to missing rtc clk\n");
  338. return ret;
  339. }
  340. ret = clk_prepare_enable(info->rtc_clk);
  341. if (ret)
  342. return ret;
  343. if (info->data->needs_src_clk) {
  344. info->rtc_src_clk = devm_clk_get(&pdev->dev, "rtc_src");
  345. if (IS_ERR(info->rtc_src_clk)) {
  346. ret = dev_err_probe(&pdev->dev, PTR_ERR(info->rtc_src_clk),
  347. "failed to find rtc source clock\n");
  348. goto err_src_clk;
  349. }
  350. ret = clk_prepare_enable(info->rtc_src_clk);
  351. if (ret)
  352. goto err_src_clk;
  353. }
  354. /* disable RTC enable bits potentially set by the bootloader */
  355. if (info->data->disable)
  356. info->data->disable(info);
  357. /* check to see if everything is setup correctly */
  358. if (info->data->enable)
  359. info->data->enable(info);
  360. dev_dbg(&pdev->dev, "s3c2410_rtc: RTCCON=%02x\n",
  361. readw(info->base + S3C2410_RTCCON));
  362. device_init_wakeup(&pdev->dev, 1);
  363. info->rtc = devm_rtc_allocate_device(&pdev->dev);
  364. if (IS_ERR(info->rtc)) {
  365. ret = PTR_ERR(info->rtc);
  366. goto err_nortc;
  367. }
  368. info->rtc->ops = &s3c_rtcops;
  369. info->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
  370. info->rtc->range_max = RTC_TIMESTAMP_END_2099;
  371. ret = devm_rtc_register_device(info->rtc);
  372. if (ret)
  373. goto err_nortc;
  374. ret = devm_request_irq(&pdev->dev, info->irq_alarm, s3c_rtc_alarmirq,
  375. 0, "s3c2410-rtc alarm", info);
  376. if (ret) {
  377. dev_err(&pdev->dev, "IRQ%d error %d\n", info->irq_alarm, ret);
  378. goto err_nortc;
  379. }
  380. s3c_rtc_disable_clk(info);
  381. return 0;
  382. err_nortc:
  383. if (info->data->disable)
  384. info->data->disable(info);
  385. if (info->data->needs_src_clk)
  386. clk_disable_unprepare(info->rtc_src_clk);
  387. err_src_clk:
  388. clk_disable_unprepare(info->rtc_clk);
  389. return ret;
  390. }
  391. #ifdef CONFIG_PM_SLEEP
  392. static int s3c_rtc_suspend(struct device *dev)
  393. {
  394. struct s3c_rtc *info = dev_get_drvdata(dev);
  395. int ret;
  396. ret = s3c_rtc_enable_clk(info);
  397. if (ret)
  398. return ret;
  399. if (info->data->disable)
  400. info->data->disable(info);
  401. if (device_may_wakeup(dev) && !info->wake_en) {
  402. if (enable_irq_wake(info->irq_alarm) == 0)
  403. info->wake_en = true;
  404. else
  405. dev_err(dev, "enable_irq_wake failed\n");
  406. }
  407. return 0;
  408. }
  409. static int s3c_rtc_resume(struct device *dev)
  410. {
  411. struct s3c_rtc *info = dev_get_drvdata(dev);
  412. if (info->data->enable)
  413. info->data->enable(info);
  414. s3c_rtc_disable_clk(info);
  415. if (device_may_wakeup(dev) && info->wake_en) {
  416. disable_irq_wake(info->irq_alarm);
  417. info->wake_en = false;
  418. }
  419. return 0;
  420. }
  421. #endif
  422. static SIMPLE_DEV_PM_OPS(s3c_rtc_pm_ops, s3c_rtc_suspend, s3c_rtc_resume);
  423. static void s3c24xx_rtc_irq(struct s3c_rtc *info, int mask)
  424. {
  425. rtc_update_irq(info->rtc, 1, RTC_AF | RTC_IRQF);
  426. }
  427. static void s3c6410_rtc_irq(struct s3c_rtc *info, int mask)
  428. {
  429. rtc_update_irq(info->rtc, 1, RTC_AF | RTC_IRQF);
  430. writeb(mask, info->base + S3C2410_INTP);
  431. }
  432. static struct s3c_rtc_data const s3c2410_rtc_data = {
  433. .irq_handler = s3c24xx_rtc_irq,
  434. .enable = s3c24xx_rtc_enable,
  435. .disable = s3c24xx_rtc_disable,
  436. };
  437. static struct s3c_rtc_data const s3c2416_rtc_data = {
  438. .irq_handler = s3c24xx_rtc_irq,
  439. .enable = s3c24xx_rtc_enable,
  440. .disable = s3c24xx_rtc_disable,
  441. };
  442. static struct s3c_rtc_data const s3c2443_rtc_data = {
  443. .irq_handler = s3c24xx_rtc_irq,
  444. .enable = s3c24xx_rtc_enable,
  445. .disable = s3c24xx_rtc_disable,
  446. };
  447. static struct s3c_rtc_data const s3c6410_rtc_data = {
  448. .needs_src_clk = true,
  449. .irq_handler = s3c6410_rtc_irq,
  450. .enable = s3c24xx_rtc_enable,
  451. .disable = s3c6410_rtc_disable,
  452. };
  453. static const __maybe_unused struct of_device_id s3c_rtc_dt_match[] = {
  454. {
  455. .compatible = "samsung,s3c2410-rtc",
  456. .data = &s3c2410_rtc_data,
  457. }, {
  458. .compatible = "samsung,s3c2416-rtc",
  459. .data = &s3c2416_rtc_data,
  460. }, {
  461. .compatible = "samsung,s3c2443-rtc",
  462. .data = &s3c2443_rtc_data,
  463. }, {
  464. .compatible = "samsung,s3c6410-rtc",
  465. .data = &s3c6410_rtc_data,
  466. }, {
  467. .compatible = "samsung,exynos3250-rtc",
  468. .data = &s3c6410_rtc_data,
  469. },
  470. { /* sentinel */ },
  471. };
  472. MODULE_DEVICE_TABLE(of, s3c_rtc_dt_match);
  473. static struct platform_driver s3c_rtc_driver = {
  474. .probe = s3c_rtc_probe,
  475. .remove = s3c_rtc_remove,
  476. .driver = {
  477. .name = "s3c-rtc",
  478. .pm = &s3c_rtc_pm_ops,
  479. .of_match_table = of_match_ptr(s3c_rtc_dt_match),
  480. },
  481. };
  482. module_platform_driver(s3c_rtc_driver);
  483. MODULE_DESCRIPTION("Samsung S3C RTC Driver");
  484. MODULE_AUTHOR("Ben Dooks <[email protected]>");
  485. MODULE_LICENSE("GPL");
  486. MODULE_ALIAS("platform:s3c2410-rtc");