CHROMIUM: rtc: s5m-rtc: Real-time clock driver for s5m8767.
[cascardo/linux.git] / drivers / rtc / rtc-s5m.c
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd
3  *              http://www.samsung.com
4  *
5  *  Copyright (C) 2013 Google, Inc
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License as published by
9  *  the Free Software Foundation; either version 2 of the License, or
10  *  (at your option) any later version.
11  *
12  *  This program is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *  GNU General Public License for more details.
16  *
17  *  You should have received a copy of the GNU General Public License
18  *  along with this program; if not, write to the Free Software
19  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  */
21
22 #include <linux/module.h>
23 #include <linux/i2c.h>
24 #include <linux/slab.h>
25 #include <linux/bcd.h>
26 #include <linux/bitops.h>
27 #include <linux/regmap.h>
28 #include <linux/rtc.h>
29 #include <linux/delay.h>
30 #include <linux/platform_device.h>
31 #include <linux/mfd/s5m87xx/s5m-core.h>
32 #include <linux/mfd/s5m87xx/s5m-rtc.h>
33
34 struct s5m_rtc_info {
35         struct device *dev;
36         struct s5m87xx_dev *s5m87xx;
37         struct regmap *rtc;
38         struct rtc_device *rtc_dev;
39         int irq;
40         int device_type;
41         int rtc_24hr_mode;
42         bool wtsr_smpl;
43 };
44
45 static void s5m8767_data_to_tm(u8 *data, struct rtc_time *tm,
46                                int rtc_24hr_mode)
47 {
48         tm->tm_sec = data[RTC_SEC] & 0x7f;
49         tm->tm_min = data[RTC_MIN] & 0x7f;
50         if (rtc_24hr_mode)
51                 tm->tm_hour = data[RTC_HOUR] & 0x1f;
52         else {
53                 tm->tm_hour = data[RTC_HOUR] & 0x0f;
54                 if (data[RTC_HOUR] & HOUR_PM_MASK)
55                         tm->tm_hour += 12;
56         }
57
58         tm->tm_wday = ffs(data[RTC_WEEKDAY] & 0x7f);
59         tm->tm_mday = data[RTC_DATE] & 0x1f;
60         tm->tm_mon = (data[RTC_MONTH] & 0x0f) - 1;
61         tm->tm_year = (data[RTC_YEAR1] & 0x7f) + 100;
62         tm->tm_yday = 0;
63         tm->tm_isdst = 0;
64 }
65
66 static int s5m8767_tm_to_data(struct rtc_time *tm, u8 *data)
67 {
68         data[RTC_SEC] = tm->tm_sec;
69         data[RTC_MIN] = tm->tm_min;
70
71         if (tm->tm_hour >= 12)
72                 data[RTC_HOUR] = tm->tm_hour | HOUR_PM_MASK;
73         else
74                 data[RTC_HOUR] = tm->tm_hour & ~HOUR_PM_MASK;
75
76         data[RTC_WEEKDAY] = 1 << tm->tm_wday;
77         data[RTC_DATE] = tm->tm_mday;
78         data[RTC_MONTH] = tm->tm_mon + 1;
79         data[RTC_YEAR1] = tm->tm_year > 100 ? (tm->tm_year - 100) : 0 ;
80
81         if (tm->tm_year < 100) {
82                 printk(KERN_ERR
83                        "s5m8767 RTC cannot handle the year %d.\n",
84                        1900 + tm->tm_year);
85                 return -EINVAL;
86         } else {
87                 return 0;
88         }
89 }
90
91 static inline int s5m8767_rtc_set_time_reg(struct s5m_rtc_info *info)
92 {
93         int ret;
94         unsigned int data;
95
96         ret = regmap_read(info->rtc, S5M87XX_RTC_UDR_CON, &data);
97         if (ret < 0) {
98                 dev_err(info->dev, "%s: fail to read update reg(%d)\n",
99                         __func__, ret);
100                 return ret;
101         }
102
103         data |= RTC_TIME_EN_MASK;
104         data |= RTC_UDR_MASK;
105
106         ret = regmap_write(info->rtc, S5M87XX_RTC_UDR_CON, data);
107         if (ret < 0) {
108                 dev_err(info->dev, "%s: fail to write update reg(%d)\n",
109                         __func__, ret);
110                 return ret;
111         }
112
113         do {
114                 ret = regmap_read(info->rtc, S5M87XX_RTC_UDR_CON, &data);
115         } while ((data & RTC_UDR_MASK) && !ret);
116
117         return ret;
118 }
119
120 static inline int s5m8767_rtc_set_alarm_reg(struct s5m_rtc_info *info)
121 {
122         int ret;
123         unsigned int data;
124
125         ret = regmap_read(info->rtc, S5M87XX_RTC_UDR_CON, &data);
126         if (ret < 0) {
127                 dev_err(info->dev, "%s: fail to read update reg(%d)\n",
128                         __func__, ret);
129                 return ret;
130         }
131
132         data &= ~RTC_TIME_EN_MASK;
133         data |= RTC_UDR_MASK;
134
135         ret = regmap_write(info->rtc, S5M87XX_RTC_UDR_CON, data);
136         if (ret < 0) {
137                 dev_err(info->dev, "%s: fail to write update reg(%d)\n",
138                         __func__, ret);
139                 return ret;
140         }
141
142         do {
143                 ret = regmap_read(info->rtc, S5M87XX_RTC_UDR_CON, &data);
144         } while ((data & RTC_UDR_MASK) && !ret);
145
146         return ret;
147 }
148
149 static void s5m8763_data_to_tm(u8 *data, struct rtc_time *tm)
150 {
151         tm->tm_sec = bcd2bin(data[RTC_SEC]);
152         tm->tm_min = bcd2bin(data[RTC_MIN]);
153
154         if (data[RTC_HOUR] & HOUR_12) {
155                 tm->tm_hour = bcd2bin(data[RTC_HOUR] & 0x1f);
156                 if (data[RTC_HOUR] & HOUR_PM)
157                         tm->tm_hour += 12;
158         } else
159                 tm->tm_hour = bcd2bin(data[RTC_HOUR] & 0x3f);
160
161         tm->tm_wday = data[RTC_WEEKDAY] & 0x07;
162         tm->tm_mday = bcd2bin(data[RTC_DATE]);
163         tm->tm_mon = bcd2bin(data[RTC_MONTH]);
164         tm->tm_year = bcd2bin(data[RTC_YEAR1]) + bcd2bin(data[RTC_YEAR2]) * 100;
165         tm->tm_year -= 1900;
166 }
167
168 static void s5m8763_tm_to_data(struct rtc_time *tm, u8 *data)
169 {
170         data[RTC_SEC] = bin2bcd(tm->tm_sec);
171         data[RTC_MIN] = bin2bcd(tm->tm_min);
172         data[RTC_HOUR] = bin2bcd(tm->tm_hour);
173         data[RTC_WEEKDAY] = tm->tm_wday;
174         data[RTC_DATE] = bin2bcd(tm->tm_mday);
175         data[RTC_MONTH] = bin2bcd(tm->tm_mon);
176         data[RTC_YEAR1] = bin2bcd(tm->tm_year % 100);
177         data[RTC_YEAR2] = bin2bcd((tm->tm_year + 1900) / 100);
178 }
179
180 static int s5m_rtc_read_time(struct device *dev, struct rtc_time *tm)
181 {
182         struct s5m_rtc_info *info = dev_get_drvdata(dev);
183         u8 data[8];
184         int ret;
185
186         ret = regmap_bulk_read(info->rtc, S5M87XX_RTC_SEC, data, 8);
187         if (ret < 0)
188                 return ret;
189
190         switch (info->device_type) {
191         case S5M8763X:
192                 s5m8763_data_to_tm(data, tm);
193                 break;
194
195         case S5M8767X:
196                 s5m8767_data_to_tm(data, tm, info->rtc_24hr_mode);
197                 break;
198
199         default:
200                 return -EINVAL;
201         }
202
203         dev_dbg(dev, "%s: %d/%d/%d %d:%d:%d(%d)\n", __func__,
204                 1900 + tm->tm_year, 1 + tm->tm_mon, tm->tm_mday,
205                 tm->tm_hour, tm->tm_min, tm->tm_sec, tm->tm_wday);
206
207         return rtc_valid_tm(tm);
208 }
209
210 static int s5m_rtc_set_time(struct device *dev, struct rtc_time *tm)
211 {
212         struct s5m_rtc_info *info = dev_get_drvdata(dev);
213         u8 data[8];
214         int ret = 0;
215
216         switch (info->device_type) {
217         case S5M8763X:
218                 s5m8763_tm_to_data(tm, data);
219                 break;
220         case S5M8767X:
221                 ret = s5m8767_tm_to_data(tm, data);
222                 break;
223         default:
224                 return -EINVAL;
225         }
226
227         if (ret < 0)
228                 return ret;
229
230         dev_dbg(dev, "%s: %d/%d/%d %d:%d:%d(%d)\n", __func__,
231                 1900 + tm->tm_year, 1 + tm->tm_mon, tm->tm_mday,
232                 tm->tm_hour, tm->tm_min, tm->tm_sec, tm->tm_wday);
233
234         ret = regmap_raw_write(info->rtc, S5M87XX_RTC_SEC, data, 8);
235         if (ret < 0)
236                 return ret;
237
238         ret = s5m8767_rtc_set_time_reg(info);
239
240         return ret;
241 }
242
243 static int s5m_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
244 {
245         struct s5m_rtc_info *info = dev_get_drvdata(dev);
246         u8 data[8];
247         unsigned int val;
248         int ret, i;
249
250         ret = regmap_bulk_read(info->rtc, S5M87XX_ALARM0_SEC, data, 8);
251         if (ret < 0)
252                 return ret;
253
254         switch (info->device_type) {
255         case S5M8763X:
256                 s5m8763_data_to_tm(data, &alrm->time);
257                 ret = regmap_read(info->rtc, S5M87XX_ALARM0_CONF, &val);
258                 if (ret < 0)
259                         return ret;
260
261                 alrm->enabled = !!val;
262
263                 ret = regmap_read(info->rtc, S5M87XX_RTC_STATUS, &val);
264                 if (ret < 0)
265                         return ret;
266
267                 break;
268
269         case S5M8767X:
270                 s5m8767_data_to_tm(data, &alrm->time, info->rtc_24hr_mode);
271                 dev_dbg(dev, "%s: %d/%d/%d %d:%d:%d(%d)\n", __func__,
272                         1900 + alrm->time.tm_year, 1 + alrm->time.tm_mon,
273                         alrm->time.tm_mday, alrm->time.tm_hour,
274                         alrm->time.tm_min, alrm->time.tm_sec,
275                         alrm->time.tm_wday);
276
277                 alrm->enabled = 0;
278                 for (i = 0; i < 7; i++) {
279                         if (data[i] & ALARM_ENABLE_MASK) {
280                                 alrm->enabled = 1;
281                                 break;
282                         }
283                 }
284
285                 alrm->pending = 0;
286                 ret = regmap_read(info->rtc, S5M87XX_RTC_STATUS, &val);
287                 if (ret < 0)
288                         return ret;
289                 break;
290
291         default:
292                 return -EINVAL;
293         }
294
295         if (val & ALARM0_STATUS)
296                 alrm->pending = 1;
297         else
298                 alrm->pending = 0;
299
300         return 0;
301 }
302
303 static int s5m_rtc_stop_alarm(struct s5m_rtc_info *info)
304 {
305         u8 data[8];
306         int ret, i;
307         struct rtc_time tm;
308
309         ret = regmap_bulk_read(info->rtc, S5M87XX_ALARM0_SEC, data, 8);
310         if (ret < 0)
311                 return ret;
312
313         s5m8767_data_to_tm(data, &tm, info->rtc_24hr_mode);
314         dev_dbg(info->dev, "%s: %d/%d/%d %d:%d:%d(%d)\n", __func__,
315                 1900 + tm.tm_year, 1 + tm.tm_mon, tm.tm_mday,
316                 tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_wday);
317
318         switch (info->device_type) {
319         case S5M8763X:
320                 ret = regmap_write(info->rtc, S5M87XX_ALARM0_CONF, 0);
321                 break;
322
323         case S5M8767X:
324                 for (i = 0; i < 7; i++)
325                         data[i] &= ~ALARM_ENABLE_MASK;
326
327                 ret = regmap_raw_write(info->rtc, S5M87XX_ALARM0_SEC, data, 8);
328                 if (ret < 0)
329                         return ret;
330
331                 ret = s5m8767_rtc_set_alarm_reg(info);
332
333                 break;
334
335         default:
336                 return -EINVAL;
337         }
338
339         return ret;
340 }
341
342 static int s5m_rtc_start_alarm(struct s5m_rtc_info *info)
343 {
344         int ret;
345         u8 data[8];
346         u8 alarm0_conf;
347         struct rtc_time tm;
348
349         ret = regmap_bulk_read(info->rtc, S5M87XX_ALARM0_SEC, data, 8);
350         if (ret < 0)
351                 return ret;
352
353         s5m8767_data_to_tm(data, &tm, info->rtc_24hr_mode);
354         dev_dbg(info->dev, "%s: %d/%d/%d %d:%d:%d(%d)\n", __func__,
355                 1900 + tm.tm_year, 1 + tm.tm_mon, tm.tm_mday,
356                 tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_wday);
357
358         switch (info->device_type) {
359         case S5M8763X:
360                 alarm0_conf = 0x77;
361                 ret = regmap_write(info->rtc, S5M87XX_ALARM0_CONF, alarm0_conf);
362                 break;
363
364         case S5M8767X:
365                 data[RTC_SEC] |= ALARM_ENABLE_MASK;
366                 data[RTC_MIN] |= ALARM_ENABLE_MASK;
367                 data[RTC_HOUR] |= ALARM_ENABLE_MASK;
368                 data[RTC_WEEKDAY] &= ~ALARM_ENABLE_MASK;
369                 if (data[RTC_DATE] & 0x1f)
370                         data[RTC_DATE] |= ALARM_ENABLE_MASK;
371                 if (data[RTC_MONTH] & 0xf)
372                         data[RTC_MONTH] |= ALARM_ENABLE_MASK;
373                 if (data[RTC_YEAR1] & 0x7f)
374                         data[RTC_YEAR1] |= ALARM_ENABLE_MASK;
375
376                 ret = regmap_raw_write(info->rtc, S5M87XX_ALARM0_SEC, data, 8);
377                 if (ret < 0)
378                         return ret;
379                 ret = s5m8767_rtc_set_alarm_reg(info);
380
381                 break;
382
383         default:
384                 return -EINVAL;
385         }
386
387         return ret;
388 }
389
390 static int s5m_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
391 {
392         struct s5m_rtc_info *info = dev_get_drvdata(dev);
393         u8 data[8];
394         int ret;
395
396         switch (info->device_type) {
397         case S5M8763X:
398                 s5m8763_tm_to_data(&alrm->time, data);
399                 break;
400
401         case S5M8767X:
402                 s5m8767_tm_to_data(&alrm->time, data);
403                 break;
404
405         default:
406                 return -EINVAL;
407         }
408
409         dev_dbg(dev, "%s: %d/%d/%d %d:%d:%d(%d)\n", __func__,
410                 1900 + alrm->time.tm_year, 1 + alrm->time.tm_mon,
411                 alrm->time.tm_mday, alrm->time.tm_hour, alrm->time.tm_min,
412                 alrm->time.tm_sec, alrm->time.tm_wday);
413
414         ret = s5m_rtc_stop_alarm(info);
415         if (ret < 0)
416                 return ret;
417
418         ret = regmap_raw_write(info->rtc, S5M87XX_ALARM0_SEC, data, 8);
419         if (ret < 0)
420                 return ret;
421
422         ret = s5m8767_rtc_set_alarm_reg(info);
423         if (ret < 0)
424                 return ret;
425
426         if (alrm->enabled)
427                 ret = s5m_rtc_start_alarm(info);
428
429         return ret;
430 }
431
432 static int s5m_rtc_alarm_irq_enable(struct device *dev,
433                                     unsigned int enabled)
434 {
435         struct s5m_rtc_info *info = dev_get_drvdata(dev);
436
437         if (enabled)
438                 return s5m_rtc_start_alarm(info);
439         else
440                 return s5m_rtc_stop_alarm(info);
441 }
442
443 static irqreturn_t s5m_rtc_alarm_irq(int irq, void *data)
444 {
445         struct s5m_rtc_info *info = data;
446
447         rtc_update_irq(info->rtc_dev, 1, RTC_IRQF | RTC_AF);
448
449         return IRQ_HANDLED;
450 }
451
452 static const struct rtc_class_ops s5m_rtc_ops = {
453         .read_time = s5m_rtc_read_time,
454         .set_time = s5m_rtc_set_time,
455         .read_alarm = s5m_rtc_read_alarm,
456         .set_alarm = s5m_rtc_set_alarm,
457         .alarm_irq_enable = s5m_rtc_alarm_irq_enable,
458 };
459
460 static void s5m_rtc_enable_wtsr(struct s5m_rtc_info *info, bool enable)
461 {
462         int ret;
463         ret = regmap_update_bits(info->rtc, S5M87XX_WTSR_SMPL_CNTL,
464                                  WTSR_ENABLE_MASK,
465                                  enable ? WTSR_ENABLE_MASK : 0);
466         if (ret < 0)
467                 dev_err(info->dev, "%s: fail to update WTSR reg(%d)\n",
468                         __func__, ret);
469 }
470
471 static void s5m_rtc_enable_smpl(struct s5m_rtc_info *info, bool enable)
472 {
473         int ret;
474         ret = regmap_update_bits(info->rtc, S5M87XX_WTSR_SMPL_CNTL,
475                                  SMPL_ENABLE_MASK,
476                                  enable ? SMPL_ENABLE_MASK : 0);
477         if (ret < 0)
478                 dev_err(info->dev, "%s: fail to update SMPL reg(%d)\n",
479                         __func__, ret);
480 }
481
482 static int s5m8767_rtc_init_reg(struct s5m_rtc_info *info)
483 {
484         u8 data[2];
485         unsigned int tp_read;
486         int ret;
487         struct rtc_time tm;
488
489         ret = regmap_read(info->rtc, S5M87XX_RTC_UDR_CON, &tp_read);
490         if (ret < 0) {
491                 dev_err(info->dev, "%s: fail to read control reg(%d)\n",
492                         __func__, ret);
493                 return ret;
494         }
495
496         /* Set RTC control register : Binary mode, 24hour mode */
497         data[0] = (1 << BCD_EN_SHIFT) | (1 << MODEL24_SHIFT);
498         data[1] = (0 << BCD_EN_SHIFT) | (1 << MODEL24_SHIFT);
499
500         info->rtc_24hr_mode = 1;
501         ret = regmap_raw_write(info->rtc, S5M87XX_ALARM0_CONF, data, 2);
502         if (ret < 0) {
503                 dev_err(info->dev, "%s: fail to write controlm reg(%d)\n",
504                         __func__, ret);
505                 return ret;
506         }
507
508         /* In first boot time, Set rtc time to 1/1/2012 00:00:00(SUN) */
509         if ((tp_read & RTC_TCON_MASK) == 0) {
510                 dev_dbg(info->dev, "rtc init\n");
511                 tm.tm_sec = 0;
512                 tm.tm_min = 0;
513                 tm.tm_hour = 0;
514                 tm.tm_wday = 0;
515                 tm.tm_mday = 1;
516                 tm.tm_mon = 0;
517                 tm.tm_year = 112;
518                 tm.tm_yday = 0;
519                 tm.tm_isdst = 0;
520                 ret = s5m_rtc_set_time(info->dev, &tm);
521         }
522
523         ret = regmap_update_bits(info->rtc, S5M87XX_RTC_UDR_CON,
524                                  RTC_TCON_MASK, tp_read | RTC_TCON_MASK);
525         if (ret < 0)
526                 dev_err(info->dev, "%s: fail to update TCON reg(%d)\n",
527                         __func__, ret);
528
529         return ret;
530 }
531
532 static int __devinit s5m_rtc_probe(struct platform_device *pdev)
533 {
534         struct s5m87xx_dev *s5m87xx = dev_get_drvdata(pdev->dev.parent);
535         struct s5m_platform_data *pdata = s5m87xx->pdata;
536         struct s5m_rtc_info *info;
537         int ret;
538
539         if (!pdata) {
540                 dev_err(pdev->dev.parent, "Platform data not supplied\n");
541                 return -ENODEV;
542         }
543
544         info = devm_kzalloc(&pdev->dev, sizeof(struct s5m_rtc_info),
545                             GFP_KERNEL);
546         if (!info)
547                 return -ENOMEM;
548
549         info->dev = &pdev->dev;
550         info->s5m87xx = s5m87xx;
551         info->rtc = s5m87xx->rtc;
552         info->device_type = s5m87xx->device_type;
553         info->wtsr_smpl = s5m87xx->wtsr_smpl;
554
555         switch (pdata->device_type) {
556         case S5M8763X:
557                 info->irq = s5m87xx->irq_base + S5M8763_IRQ_ALARM0;
558                 break;
559
560         case S5M8767X:
561                 info->irq = s5m87xx->irq_base + S5M8767_IRQ_RTCA1;
562                 break;
563
564         default:
565                 ret = -EINVAL;
566                 dev_err(&pdev->dev, "Unsupported device type: %d\n", ret);
567                 return ret;
568         }
569
570         platform_set_drvdata(pdev, info);
571
572         ret = s5m8767_rtc_init_reg(info);
573
574         if (info->wtsr_smpl) {
575                 s5m_rtc_enable_wtsr(info, true);
576                 s5m_rtc_enable_smpl(info, true);
577         }
578
579         device_init_wakeup(&pdev->dev, 1);
580
581         info->rtc_dev = rtc_device_register("s5m-rtc", &pdev->dev,
582                                             &s5m_rtc_ops, THIS_MODULE);
583
584         if (IS_ERR(info->rtc_dev)) {
585                 ret = PTR_ERR(info->rtc_dev);
586                 dev_err(&pdev->dev, "Failed to register RTC device: %d\n", ret);
587                 return ret;
588         }
589
590         ret = request_threaded_irq(info->irq, NULL, s5m_rtc_alarm_irq, 0,
591                                    "rtc-alarm0", info);
592
593         if (ret < 0)
594                 dev_err(&pdev->dev, "Failed to request alarm IRQ: %d: %d\n",
595                         info->irq, ret);
596
597         dev_info(&pdev->dev, "RTC CHIP NAME: %s\n", pdev->id_entry->name);
598
599         return 0;
600 }
601
602 static int __devexit s5m_rtc_remove(struct platform_device *pdev)
603 {
604         struct s5m_rtc_info *info = platform_get_drvdata(pdev);
605
606         if (info) {
607                 free_irq(info->irq, info);
608                 rtc_device_unregister(info->rtc_dev);
609         }
610
611         return 0;
612 }
613
614 static void s5m_rtc_shutdown(struct platform_device *pdev)
615 {
616         struct s5m_rtc_info *info = platform_get_drvdata(pdev);
617         int i;
618         unsigned int val = 0;
619         if (info->wtsr_smpl) {
620                 for (i = 0; i < 3; i++) {
621                         s5m_rtc_enable_wtsr(info, false);
622                         regmap_read(info->rtc, S5M87XX_WTSR_SMPL_CNTL, &val);
623                         pr_debug("%s: WTSR_SMPL reg(0x%02x)\n", __func__, val);
624                         if (val & WTSR_ENABLE_MASK)
625                                 pr_emerg("%s: fail to disable WTSR\n",
626                                          __func__);
627                         else {
628                                 pr_info("%s: success to disable WTSR\n",
629                                         __func__);
630                                 break;
631                         }
632                 }
633         }
634         /* Disable SMPL when power off */
635         s5m_rtc_enable_smpl(info, false);
636 }
637
638 static const struct platform_device_id s5m_rtc_id[] = {
639         { "s5m-rtc", 0 },
640 };
641
642 static struct platform_driver s5m_rtc_driver = {
643         .driver         = {
644                 .name   = "s5m-rtc",
645                 .owner  = THIS_MODULE,
646         },
647         .probe          = s5m_rtc_probe,
648         .remove         = __devexit_p(s5m_rtc_remove),
649         .shutdown       = s5m_rtc_shutdown,
650         .id_table       = s5m_rtc_id,
651 };
652
653 module_platform_driver(s5m_rtc_driver);
654
655 /* Module information */
656 MODULE_AUTHOR("Sangbeom Kim <sbkim73@samsung.com>");
657 MODULE_DESCRIPTION("Samsung S5M RTC driver");
658 MODULE_LICENSE("GPL");
659 MODULE_ALIAS("platform:s5m-rtc");