Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
[cascardo/linux.git] / drivers / rtc / rtc-s3c.c
1 /* drivers/rtc/rtc-s3c.c
2  *
3  * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4  *              http://www.samsung.com/
5  *
6  * Copyright (c) 2004,2006 Simtec Electronics
7  *      Ben Dooks, <ben@simtec.co.uk>
8  *      http://armlinux.simtec.co.uk/
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License version 2 as
12  * published by the Free Software Foundation.
13  *
14  * S3C2410/S3C2440/S3C24XX Internal RTC Driver
15 */
16
17 #include <linux/module.h>
18 #include <linux/fs.h>
19 #include <linux/string.h>
20 #include <linux/init.h>
21 #include <linux/platform_device.h>
22 #include <linux/interrupt.h>
23 #include <linux/rtc.h>
24 #include <linux/bcd.h>
25 #include <linux/clk.h>
26 #include <linux/log2.h>
27 #include <linux/slab.h>
28 #include <linux/of.h>
29 #include <linux/uaccess.h>
30 #include <linux/io.h>
31
32 #include <asm/irq.h>
33 #include "rtc-s3c.h"
34
35 struct s3c_rtc {
36         struct device *dev;
37         struct rtc_device *rtc;
38
39         void __iomem *base;
40         struct clk *rtc_clk;
41         struct clk *rtc_src_clk;
42         bool enabled;
43
44         struct s3c_rtc_data *data;
45
46         int irq_alarm;
47         int irq_tick;
48
49         spinlock_t pie_lock;
50         spinlock_t alarm_clk_lock;
51
52         int ticnt_save, ticnt_en_save;
53         bool wake_en;
54 };
55
56 struct s3c_rtc_data {
57         int max_user_freq;
58         bool needs_src_clk;
59
60         void (*irq_handler) (struct s3c_rtc *info, int mask);
61         void (*set_freq) (struct s3c_rtc *info, int freq);
62         void (*enable_tick) (struct s3c_rtc *info, struct seq_file *seq);
63         void (*select_tick_clk) (struct s3c_rtc *info);
64         void (*save_tick_cnt) (struct s3c_rtc *info);
65         void (*restore_tick_cnt) (struct s3c_rtc *info);
66         void (*enable) (struct s3c_rtc *info);
67         void (*disable) (struct s3c_rtc *info);
68 };
69
70 static void s3c_rtc_alarm_clk_enable(struct s3c_rtc *info, bool enable)
71 {
72         unsigned long irq_flags;
73
74         spin_lock_irqsave(&info->alarm_clk_lock, irq_flags);
75         if (enable) {
76                 if (!info->enabled) {
77                         clk_enable(info->rtc_clk);
78                         if (info->data->needs_src_clk)
79                                 clk_enable(info->rtc_src_clk);
80                         info->enabled = true;
81                 }
82         } else {
83                 if (info->enabled) {
84                         if (info->data->needs_src_clk)
85                                 clk_disable(info->rtc_src_clk);
86                         clk_disable(info->rtc_clk);
87                         info->enabled = false;
88                 }
89         }
90         spin_unlock_irqrestore(&info->alarm_clk_lock, irq_flags);
91 }
92
93 /* IRQ Handlers */
94 static irqreturn_t s3c_rtc_tickirq(int irq, void *id)
95 {
96         struct s3c_rtc *info = (struct s3c_rtc *)id;
97
98         if (info->data->irq_handler)
99                 info->data->irq_handler(info, S3C2410_INTP_TIC);
100
101         return IRQ_HANDLED;
102 }
103
104 static irqreturn_t s3c_rtc_alarmirq(int irq, void *id)
105 {
106         struct s3c_rtc *info = (struct s3c_rtc *)id;
107
108         if (info->data->irq_handler)
109                 info->data->irq_handler(info, S3C2410_INTP_ALM);
110
111         return IRQ_HANDLED;
112 }
113
114 /* Update control registers */
115 static int s3c_rtc_setaie(struct device *dev, unsigned int enabled)
116 {
117         struct s3c_rtc *info = dev_get_drvdata(dev);
118         unsigned int tmp;
119
120         dev_dbg(info->dev, "%s: aie=%d\n", __func__, enabled);
121
122         clk_enable(info->rtc_clk);
123         if (info->data->needs_src_clk)
124                 clk_enable(info->rtc_src_clk);
125         tmp = readb(info->base + S3C2410_RTCALM) & ~S3C2410_RTCALM_ALMEN;
126
127         if (enabled)
128                 tmp |= S3C2410_RTCALM_ALMEN;
129
130         writeb(tmp, info->base + S3C2410_RTCALM);
131         if (info->data->needs_src_clk)
132                 clk_disable(info->rtc_src_clk);
133         clk_disable(info->rtc_clk);
134
135         s3c_rtc_alarm_clk_enable(info, enabled);
136
137         return 0;
138 }
139
140 /* Set RTC frequency */
141 static int s3c_rtc_setfreq(struct s3c_rtc *info, int freq)
142 {
143         if (!is_power_of_2(freq))
144                 return -EINVAL;
145
146         clk_enable(info->rtc_clk);
147         if (info->data->needs_src_clk)
148                 clk_enable(info->rtc_src_clk);
149         spin_lock_irq(&info->pie_lock);
150
151         if (info->data->set_freq)
152                 info->data->set_freq(info, freq);
153
154         spin_unlock_irq(&info->pie_lock);
155         if (info->data->needs_src_clk)
156                 clk_disable(info->rtc_src_clk);
157         clk_disable(info->rtc_clk);
158
159         return 0;
160 }
161
162 /* Time read/write */
163 static int s3c_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm)
164 {
165         struct s3c_rtc *info = dev_get_drvdata(dev);
166         unsigned int have_retried = 0;
167
168         clk_enable(info->rtc_clk);
169         if (info->data->needs_src_clk)
170                 clk_enable(info->rtc_src_clk);
171
172  retry_get_time:
173         rtc_tm->tm_min  = readb(info->base + S3C2410_RTCMIN);
174         rtc_tm->tm_hour = readb(info->base + S3C2410_RTCHOUR);
175         rtc_tm->tm_mday = readb(info->base + S3C2410_RTCDATE);
176         rtc_tm->tm_mon  = readb(info->base + S3C2410_RTCMON);
177         rtc_tm->tm_year = readb(info->base + S3C2410_RTCYEAR);
178         rtc_tm->tm_sec  = readb(info->base + S3C2410_RTCSEC);
179
180         /* the only way to work out whether the system was mid-update
181          * when we read it is to check the second counter, and if it
182          * is zero, then we re-try the entire read
183          */
184
185         if (rtc_tm->tm_sec == 0 && !have_retried) {
186                 have_retried = 1;
187                 goto retry_get_time;
188         }
189
190         rtc_tm->tm_sec = bcd2bin(rtc_tm->tm_sec);
191         rtc_tm->tm_min = bcd2bin(rtc_tm->tm_min);
192         rtc_tm->tm_hour = bcd2bin(rtc_tm->tm_hour);
193         rtc_tm->tm_mday = bcd2bin(rtc_tm->tm_mday);
194         rtc_tm->tm_mon = bcd2bin(rtc_tm->tm_mon);
195         rtc_tm->tm_year = bcd2bin(rtc_tm->tm_year);
196
197         rtc_tm->tm_year += 100;
198
199         dev_dbg(dev, "read time %04d.%02d.%02d %02d:%02d:%02d\n",
200                  1900 + rtc_tm->tm_year, rtc_tm->tm_mon, rtc_tm->tm_mday,
201                  rtc_tm->tm_hour, rtc_tm->tm_min, rtc_tm->tm_sec);
202
203         rtc_tm->tm_mon -= 1;
204
205         if (info->data->needs_src_clk)
206                 clk_disable(info->rtc_src_clk);
207         clk_disable(info->rtc_clk);
208
209         return rtc_valid_tm(rtc_tm);
210 }
211
212 static int s3c_rtc_settime(struct device *dev, struct rtc_time *tm)
213 {
214         struct s3c_rtc *info = dev_get_drvdata(dev);
215         int year = tm->tm_year - 100;
216
217         dev_dbg(dev, "set time %04d.%02d.%02d %02d:%02d:%02d\n",
218                  1900 + tm->tm_year, tm->tm_mon, tm->tm_mday,
219                  tm->tm_hour, tm->tm_min, tm->tm_sec);
220
221         /* we get around y2k by simply not supporting it */
222
223         if (year < 0 || year >= 100) {
224                 dev_err(dev, "rtc only supports 100 years\n");
225                 return -EINVAL;
226         }
227
228         clk_enable(info->rtc_clk);
229         if (info->data->needs_src_clk)
230                 clk_enable(info->rtc_src_clk);
231
232         writeb(bin2bcd(tm->tm_sec),  info->base + S3C2410_RTCSEC);
233         writeb(bin2bcd(tm->tm_min),  info->base + S3C2410_RTCMIN);
234         writeb(bin2bcd(tm->tm_hour), info->base + S3C2410_RTCHOUR);
235         writeb(bin2bcd(tm->tm_mday), info->base + S3C2410_RTCDATE);
236         writeb(bin2bcd(tm->tm_mon + 1), info->base + S3C2410_RTCMON);
237         writeb(bin2bcd(year), info->base + S3C2410_RTCYEAR);
238
239         if (info->data->needs_src_clk)
240                 clk_disable(info->rtc_src_clk);
241         clk_disable(info->rtc_clk);
242
243         return 0;
244 }
245
246 static int s3c_rtc_getalarm(struct device *dev, struct rtc_wkalrm *alrm)
247 {
248         struct s3c_rtc *info = dev_get_drvdata(dev);
249         struct rtc_time *alm_tm = &alrm->time;
250         unsigned int alm_en;
251
252         clk_enable(info->rtc_clk);
253         if (info->data->needs_src_clk)
254                 clk_enable(info->rtc_src_clk);
255
256         alm_tm->tm_sec  = readb(info->base + S3C2410_ALMSEC);
257         alm_tm->tm_min  = readb(info->base + S3C2410_ALMMIN);
258         alm_tm->tm_hour = readb(info->base + S3C2410_ALMHOUR);
259         alm_tm->tm_mon  = readb(info->base + S3C2410_ALMMON);
260         alm_tm->tm_mday = readb(info->base + S3C2410_ALMDATE);
261         alm_tm->tm_year = readb(info->base + S3C2410_ALMYEAR);
262
263         alm_en = readb(info->base + S3C2410_RTCALM);
264
265         alrm->enabled = (alm_en & S3C2410_RTCALM_ALMEN) ? 1 : 0;
266
267         dev_dbg(dev, "read alarm %d, %04d.%02d.%02d %02d:%02d:%02d\n",
268                  alm_en,
269                  1900 + alm_tm->tm_year, alm_tm->tm_mon, alm_tm->tm_mday,
270                  alm_tm->tm_hour, alm_tm->tm_min, alm_tm->tm_sec);
271
272
273         /* decode the alarm enable field */
274
275         if (alm_en & S3C2410_RTCALM_SECEN)
276                 alm_tm->tm_sec = bcd2bin(alm_tm->tm_sec);
277         else
278                 alm_tm->tm_sec = -1;
279
280         if (alm_en & S3C2410_RTCALM_MINEN)
281                 alm_tm->tm_min = bcd2bin(alm_tm->tm_min);
282         else
283                 alm_tm->tm_min = -1;
284
285         if (alm_en & S3C2410_RTCALM_HOUREN)
286                 alm_tm->tm_hour = bcd2bin(alm_tm->tm_hour);
287         else
288                 alm_tm->tm_hour = -1;
289
290         if (alm_en & S3C2410_RTCALM_DAYEN)
291                 alm_tm->tm_mday = bcd2bin(alm_tm->tm_mday);
292         else
293                 alm_tm->tm_mday = -1;
294
295         if (alm_en & S3C2410_RTCALM_MONEN) {
296                 alm_tm->tm_mon = bcd2bin(alm_tm->tm_mon);
297                 alm_tm->tm_mon -= 1;
298         } else {
299                 alm_tm->tm_mon = -1;
300         }
301
302         if (alm_en & S3C2410_RTCALM_YEAREN)
303                 alm_tm->tm_year = bcd2bin(alm_tm->tm_year);
304         else
305                 alm_tm->tm_year = -1;
306
307         if (info->data->needs_src_clk)
308                 clk_disable(info->rtc_src_clk);
309         clk_disable(info->rtc_clk);
310
311         return 0;
312 }
313
314 static int s3c_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
315 {
316         struct s3c_rtc *info = dev_get_drvdata(dev);
317         struct rtc_time *tm = &alrm->time;
318         unsigned int alrm_en;
319
320         clk_enable(info->rtc_clk);
321         if (info->data->needs_src_clk)
322                 clk_enable(info->rtc_src_clk);
323
324         dev_dbg(dev, "s3c_rtc_setalarm: %d, %04d.%02d.%02d %02d:%02d:%02d\n",
325                  alrm->enabled,
326                  1900 + tm->tm_year, tm->tm_mon + 1, tm->tm_mday,
327                  tm->tm_hour, tm->tm_min, tm->tm_sec);
328
329         alrm_en = readb(info->base + S3C2410_RTCALM) & S3C2410_RTCALM_ALMEN;
330         writeb(0x00, info->base + S3C2410_RTCALM);
331
332         if (tm->tm_sec < 60 && tm->tm_sec >= 0) {
333                 alrm_en |= S3C2410_RTCALM_SECEN;
334                 writeb(bin2bcd(tm->tm_sec), info->base + S3C2410_ALMSEC);
335         }
336
337         if (tm->tm_min < 60 && tm->tm_min >= 0) {
338                 alrm_en |= S3C2410_RTCALM_MINEN;
339                 writeb(bin2bcd(tm->tm_min), info->base + S3C2410_ALMMIN);
340         }
341
342         if (tm->tm_hour < 24 && tm->tm_hour >= 0) {
343                 alrm_en |= S3C2410_RTCALM_HOUREN;
344                 writeb(bin2bcd(tm->tm_hour), info->base + S3C2410_ALMHOUR);
345         }
346
347         dev_dbg(dev, "setting S3C2410_RTCALM to %08x\n", alrm_en);
348
349         writeb(alrm_en, info->base + S3C2410_RTCALM);
350
351         s3c_rtc_setaie(dev, alrm->enabled);
352
353         if (info->data->needs_src_clk)
354                 clk_disable(info->rtc_src_clk);
355         clk_disable(info->rtc_clk);
356
357         return 0;
358 }
359
360 static int s3c_rtc_proc(struct device *dev, struct seq_file *seq)
361 {
362         struct s3c_rtc *info = dev_get_drvdata(dev);
363
364         clk_enable(info->rtc_clk);
365         if (info->data->needs_src_clk)
366                 clk_enable(info->rtc_src_clk);
367
368         if (info->data->enable_tick)
369                 info->data->enable_tick(info, seq);
370
371         if (info->data->needs_src_clk)
372                 clk_disable(info->rtc_src_clk);
373         clk_disable(info->rtc_clk);
374
375         return 0;
376 }
377
378 static const struct rtc_class_ops s3c_rtcops = {
379         .read_time      = s3c_rtc_gettime,
380         .set_time       = s3c_rtc_settime,
381         .read_alarm     = s3c_rtc_getalarm,
382         .set_alarm      = s3c_rtc_setalarm,
383         .proc           = s3c_rtc_proc,
384         .alarm_irq_enable = s3c_rtc_setaie,
385 };
386
387 static void s3c24xx_rtc_enable(struct s3c_rtc *info)
388 {
389         unsigned int con, tmp;
390
391         clk_enable(info->rtc_clk);
392         if (info->data->needs_src_clk)
393                 clk_enable(info->rtc_src_clk);
394
395         con = readw(info->base + S3C2410_RTCCON);
396         /* re-enable the device, and check it is ok */
397         if ((con & S3C2410_RTCCON_RTCEN) == 0) {
398                 dev_info(info->dev, "rtc disabled, re-enabling\n");
399
400                 tmp = readw(info->base + S3C2410_RTCCON);
401                 writew(tmp | S3C2410_RTCCON_RTCEN,
402                         info->base + S3C2410_RTCCON);
403         }
404
405         if (con & S3C2410_RTCCON_CNTSEL) {
406                 dev_info(info->dev, "removing RTCCON_CNTSEL\n");
407
408                 tmp = readw(info->base + S3C2410_RTCCON);
409                 writew(tmp & ~S3C2410_RTCCON_CNTSEL,
410                         info->base + S3C2410_RTCCON);
411         }
412
413         if (con & S3C2410_RTCCON_CLKRST) {
414                 dev_info(info->dev, "removing RTCCON_CLKRST\n");
415
416                 tmp = readw(info->base + S3C2410_RTCCON);
417                 writew(tmp & ~S3C2410_RTCCON_CLKRST,
418                         info->base + S3C2410_RTCCON);
419         }
420
421         if (info->data->needs_src_clk)
422                 clk_disable(info->rtc_src_clk);
423         clk_disable(info->rtc_clk);
424 }
425
426 static void s3c24xx_rtc_disable(struct s3c_rtc *info)
427 {
428         unsigned int con;
429
430         clk_enable(info->rtc_clk);
431         if (info->data->needs_src_clk)
432                 clk_enable(info->rtc_src_clk);
433
434         con = readw(info->base + S3C2410_RTCCON);
435         con &= ~S3C2410_RTCCON_RTCEN;
436         writew(con, info->base + S3C2410_RTCCON);
437
438         con = readb(info->base + S3C2410_TICNT);
439         con &= ~S3C2410_TICNT_ENABLE;
440         writeb(con, info->base + S3C2410_TICNT);
441
442         if (info->data->needs_src_clk)
443                 clk_disable(info->rtc_src_clk);
444         clk_disable(info->rtc_clk);
445 }
446
447 static void s3c6410_rtc_disable(struct s3c_rtc *info)
448 {
449         unsigned int con;
450
451         clk_enable(info->rtc_clk);
452         if (info->data->needs_src_clk)
453                 clk_enable(info->rtc_src_clk);
454
455         con = readw(info->base + S3C2410_RTCCON);
456         con &= ~S3C64XX_RTCCON_TICEN;
457         con &= ~S3C2410_RTCCON_RTCEN;
458         writew(con, info->base + S3C2410_RTCCON);
459
460         if (info->data->needs_src_clk)
461                 clk_disable(info->rtc_src_clk);
462         clk_disable(info->rtc_clk);
463 }
464
465 static int s3c_rtc_remove(struct platform_device *pdev)
466 {
467         struct s3c_rtc *info = platform_get_drvdata(pdev);
468
469         s3c_rtc_setaie(info->dev, 0);
470
471         clk_unprepare(info->rtc_clk);
472         info->rtc_clk = NULL;
473
474         return 0;
475 }
476
477 static const struct of_device_id s3c_rtc_dt_match[];
478
479 static struct s3c_rtc_data *s3c_rtc_get_data(struct platform_device *pdev)
480 {
481         const struct of_device_id *match;
482
483         match = of_match_node(s3c_rtc_dt_match, pdev->dev.of_node);
484         return (struct s3c_rtc_data *)match->data;
485 }
486
487 static int s3c_rtc_probe(struct platform_device *pdev)
488 {
489         struct s3c_rtc *info = NULL;
490         struct rtc_time rtc_tm;
491         struct resource *res;
492         int ret;
493
494         info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
495         if (!info)
496                 return -ENOMEM;
497
498         /* find the IRQs */
499         info->irq_tick = platform_get_irq(pdev, 1);
500         if (info->irq_tick < 0) {
501                 dev_err(&pdev->dev, "no irq for rtc tick\n");
502                 return info->irq_tick;
503         }
504
505         info->dev = &pdev->dev;
506         info->data = s3c_rtc_get_data(pdev);
507         if (!info->data) {
508                 dev_err(&pdev->dev, "failed getting s3c_rtc_data\n");
509                 return -EINVAL;
510         }
511         spin_lock_init(&info->pie_lock);
512         spin_lock_init(&info->alarm_clk_lock);
513
514         platform_set_drvdata(pdev, info);
515
516         info->irq_alarm = platform_get_irq(pdev, 0);
517         if (info->irq_alarm < 0) {
518                 dev_err(&pdev->dev, "no irq for alarm\n");
519                 return info->irq_alarm;
520         }
521
522         dev_dbg(&pdev->dev, "s3c2410_rtc: tick irq %d, alarm irq %d\n",
523                  info->irq_tick, info->irq_alarm);
524
525         /* get the memory region */
526         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
527         info->base = devm_ioremap_resource(&pdev->dev, res);
528         if (IS_ERR(info->base))
529                 return PTR_ERR(info->base);
530
531         info->rtc_clk = devm_clk_get(&pdev->dev, "rtc");
532         if (IS_ERR(info->rtc_clk)) {
533                 dev_err(&pdev->dev, "failed to find rtc clock\n");
534                 return PTR_ERR(info->rtc_clk);
535         }
536         clk_prepare_enable(info->rtc_clk);
537
538         if (info->data->needs_src_clk) {
539                 info->rtc_src_clk = devm_clk_get(&pdev->dev, "rtc_src");
540                 if (IS_ERR(info->rtc_src_clk)) {
541                         dev_err(&pdev->dev,
542                                 "failed to find rtc source clock\n");
543                         return PTR_ERR(info->rtc_src_clk);
544                 }
545                 clk_prepare_enable(info->rtc_src_clk);
546         }
547
548         /* check to see if everything is setup correctly */
549         if (info->data->enable)
550                 info->data->enable(info);
551
552         dev_dbg(&pdev->dev, "s3c2410_rtc: RTCCON=%02x\n",
553                  readw(info->base + S3C2410_RTCCON));
554
555         device_init_wakeup(&pdev->dev, 1);
556
557         /* register RTC and exit */
558         info->rtc = devm_rtc_device_register(&pdev->dev, "s3c", &s3c_rtcops,
559                                   THIS_MODULE);
560         if (IS_ERR(info->rtc)) {
561                 dev_err(&pdev->dev, "cannot attach rtc\n");
562                 ret = PTR_ERR(info->rtc);
563                 goto err_nortc;
564         }
565
566         ret = devm_request_irq(&pdev->dev, info->irq_alarm, s3c_rtc_alarmirq,
567                           0,  "s3c2410-rtc alarm", info);
568         if (ret) {
569                 dev_err(&pdev->dev, "IRQ%d error %d\n", info->irq_alarm, ret);
570                 goto err_nortc;
571         }
572
573         ret = devm_request_irq(&pdev->dev, info->irq_tick, s3c_rtc_tickirq,
574                           0,  "s3c2410-rtc tick", info);
575         if (ret) {
576                 dev_err(&pdev->dev, "IRQ%d error %d\n", info->irq_tick, ret);
577                 goto err_nortc;
578         }
579
580         /* Check RTC Time */
581         s3c_rtc_gettime(&pdev->dev, &rtc_tm);
582
583         if (rtc_valid_tm(&rtc_tm)) {
584                 rtc_tm.tm_year  = 100;
585                 rtc_tm.tm_mon   = 0;
586                 rtc_tm.tm_mday  = 1;
587                 rtc_tm.tm_hour  = 0;
588                 rtc_tm.tm_min   = 0;
589                 rtc_tm.tm_sec   = 0;
590
591                 s3c_rtc_settime(&pdev->dev, &rtc_tm);
592
593                 dev_warn(&pdev->dev, "warning: invalid RTC value so initializing it\n");
594         }
595
596         if (info->data->select_tick_clk)
597                 info->data->select_tick_clk(info);
598
599         s3c_rtc_setfreq(info, 1);
600
601         if (info->data->needs_src_clk)
602                 clk_disable(info->rtc_src_clk);
603         clk_disable(info->rtc_clk);
604
605         return 0;
606
607  err_nortc:
608         if (info->data->disable)
609                 info->data->disable(info);
610         clk_disable_unprepare(info->rtc_clk);
611
612         return ret;
613 }
614
615 #ifdef CONFIG_PM_SLEEP
616
617 static int s3c_rtc_suspend(struct device *dev)
618 {
619         struct s3c_rtc *info = dev_get_drvdata(dev);
620
621         clk_enable(info->rtc_clk);
622         if (info->data->needs_src_clk)
623                 clk_enable(info->rtc_src_clk);
624
625         /* save TICNT for anyone using periodic interrupts */
626         if (info->data->save_tick_cnt)
627                 info->data->save_tick_cnt(info);
628
629         if (info->data->disable)
630                 info->data->disable(info);
631
632         if (device_may_wakeup(dev) && !info->wake_en) {
633                 if (enable_irq_wake(info->irq_alarm) == 0)
634                         info->wake_en = true;
635                 else
636                         dev_err(dev, "enable_irq_wake failed\n");
637         }
638
639         if (info->data->needs_src_clk)
640                 clk_disable(info->rtc_src_clk);
641         clk_disable(info->rtc_clk);
642
643         return 0;
644 }
645
646 static int s3c_rtc_resume(struct device *dev)
647 {
648         struct s3c_rtc *info = dev_get_drvdata(dev);
649
650         clk_enable(info->rtc_clk);
651         if (info->data->needs_src_clk)
652                 clk_enable(info->rtc_src_clk);
653
654         if (info->data->enable)
655                 info->data->enable(info);
656
657         if (info->data->restore_tick_cnt)
658                 info->data->restore_tick_cnt(info);
659
660         if (device_may_wakeup(dev) && info->wake_en) {
661                 disable_irq_wake(info->irq_alarm);
662                 info->wake_en = false;
663         }
664
665         if (info->data->needs_src_clk)
666                 clk_disable(info->rtc_src_clk);
667         clk_disable(info->rtc_clk);
668
669         return 0;
670 }
671 #endif
672 static SIMPLE_DEV_PM_OPS(s3c_rtc_pm_ops, s3c_rtc_suspend, s3c_rtc_resume);
673
674 static void s3c24xx_rtc_irq(struct s3c_rtc *info, int mask)
675 {
676         clk_enable(info->rtc_clk);
677         if (info->data->needs_src_clk)
678                 clk_enable(info->rtc_src_clk);
679         rtc_update_irq(info->rtc, 1, RTC_AF | RTC_IRQF);
680         if (info->data->needs_src_clk)
681                 clk_disable(info->rtc_src_clk);
682         clk_disable(info->rtc_clk);
683
684         s3c_rtc_alarm_clk_enable(info, false);
685 }
686
687 static void s3c6410_rtc_irq(struct s3c_rtc *info, int mask)
688 {
689         clk_enable(info->rtc_clk);
690         if (info->data->needs_src_clk)
691                 clk_enable(info->rtc_src_clk);
692         rtc_update_irq(info->rtc, 1, RTC_AF | RTC_IRQF);
693         writeb(mask, info->base + S3C2410_INTP);
694         if (info->data->needs_src_clk)
695                 clk_disable(info->rtc_src_clk);
696         clk_disable(info->rtc_clk);
697
698         s3c_rtc_alarm_clk_enable(info, false);
699 }
700
701 static void s3c2410_rtc_setfreq(struct s3c_rtc *info, int freq)
702 {
703         unsigned int tmp = 0;
704         int val;
705
706         tmp = readb(info->base + S3C2410_TICNT);
707         tmp &= S3C2410_TICNT_ENABLE;
708
709         val = (info->rtc->max_user_freq / freq) - 1;
710         tmp |= val;
711
712         writel(tmp, info->base + S3C2410_TICNT);
713 }
714
715 static void s3c2416_rtc_setfreq(struct s3c_rtc *info, int freq)
716 {
717         unsigned int tmp = 0;
718         int val;
719
720         tmp = readb(info->base + S3C2410_TICNT);
721         tmp &= S3C2410_TICNT_ENABLE;
722
723         val = (info->rtc->max_user_freq / freq) - 1;
724
725         tmp |= S3C2443_TICNT_PART(val);
726         writel(S3C2443_TICNT1_PART(val), info->base + S3C2443_TICNT1);
727
728         writel(S3C2416_TICNT2_PART(val), info->base + S3C2416_TICNT2);
729
730         writel(tmp, info->base + S3C2410_TICNT);
731 }
732
733 static void s3c2443_rtc_setfreq(struct s3c_rtc *info, int freq)
734 {
735         unsigned int tmp = 0;
736         int val;
737
738         tmp = readb(info->base + S3C2410_TICNT);
739         tmp &= S3C2410_TICNT_ENABLE;
740
741         val = (info->rtc->max_user_freq / freq) - 1;
742
743         tmp |= S3C2443_TICNT_PART(val);
744         writel(S3C2443_TICNT1_PART(val), info->base + S3C2443_TICNT1);
745
746         writel(tmp, info->base + S3C2410_TICNT);
747 }
748
749 static void s3c6410_rtc_setfreq(struct s3c_rtc *info, int freq)
750 {
751         int val;
752
753         val = (info->rtc->max_user_freq / freq) - 1;
754         writel(val, info->base + S3C2410_TICNT);
755 }
756
757 static void s3c24xx_rtc_enable_tick(struct s3c_rtc *info, struct seq_file *seq)
758 {
759         unsigned int ticnt;
760
761         ticnt = readb(info->base + S3C2410_TICNT);
762         ticnt &= S3C2410_TICNT_ENABLE;
763
764         seq_printf(seq, "periodic_IRQ\t: %s\n", ticnt  ? "yes" : "no");
765 }
766
767 static void s3c2416_rtc_select_tick_clk(struct s3c_rtc *info)
768 {
769         unsigned int con;
770
771         con = readw(info->base + S3C2410_RTCCON);
772         con |= S3C2443_RTCCON_TICSEL;
773         writew(con, info->base + S3C2410_RTCCON);
774 }
775
776 static void s3c6410_rtc_enable_tick(struct s3c_rtc *info, struct seq_file *seq)
777 {
778         unsigned int ticnt;
779
780         ticnt = readw(info->base + S3C2410_RTCCON);
781         ticnt &= S3C64XX_RTCCON_TICEN;
782
783         seq_printf(seq, "periodic_IRQ\t: %s\n", ticnt  ? "yes" : "no");
784 }
785
786 static void s3c24xx_rtc_save_tick_cnt(struct s3c_rtc *info)
787 {
788         info->ticnt_save = readb(info->base + S3C2410_TICNT);
789 }
790
791 static void s3c24xx_rtc_restore_tick_cnt(struct s3c_rtc *info)
792 {
793         writeb(info->ticnt_save, info->base + S3C2410_TICNT);
794 }
795
796 static void s3c6410_rtc_save_tick_cnt(struct s3c_rtc *info)
797 {
798         info->ticnt_en_save = readw(info->base + S3C2410_RTCCON);
799         info->ticnt_en_save &= S3C64XX_RTCCON_TICEN;
800         info->ticnt_save = readl(info->base + S3C2410_TICNT);
801 }
802
803 static void s3c6410_rtc_restore_tick_cnt(struct s3c_rtc *info)
804 {
805         unsigned int con;
806
807         writel(info->ticnt_save, info->base + S3C2410_TICNT);
808         if (info->ticnt_en_save) {
809                 con = readw(info->base + S3C2410_RTCCON);
810                 writew(con | info->ticnt_en_save,
811                                 info->base + S3C2410_RTCCON);
812         }
813 }
814
815 static struct s3c_rtc_data const s3c2410_rtc_data = {
816         .max_user_freq          = 128,
817         .irq_handler            = s3c24xx_rtc_irq,
818         .set_freq               = s3c2410_rtc_setfreq,
819         .enable_tick            = s3c24xx_rtc_enable_tick,
820         .save_tick_cnt          = s3c24xx_rtc_save_tick_cnt,
821         .restore_tick_cnt       = s3c24xx_rtc_restore_tick_cnt,
822         .enable                 = s3c24xx_rtc_enable,
823         .disable                = s3c24xx_rtc_disable,
824 };
825
826 static struct s3c_rtc_data const s3c2416_rtc_data = {
827         .max_user_freq          = 32768,
828         .irq_handler            = s3c24xx_rtc_irq,
829         .set_freq               = s3c2416_rtc_setfreq,
830         .enable_tick            = s3c24xx_rtc_enable_tick,
831         .select_tick_clk        = s3c2416_rtc_select_tick_clk,
832         .save_tick_cnt          = s3c24xx_rtc_save_tick_cnt,
833         .restore_tick_cnt       = s3c24xx_rtc_restore_tick_cnt,
834         .enable                 = s3c24xx_rtc_enable,
835         .disable                = s3c24xx_rtc_disable,
836 };
837
838 static struct s3c_rtc_data const s3c2443_rtc_data = {
839         .max_user_freq          = 32768,
840         .irq_handler            = s3c24xx_rtc_irq,
841         .set_freq               = s3c2443_rtc_setfreq,
842         .enable_tick            = s3c24xx_rtc_enable_tick,
843         .select_tick_clk        = s3c2416_rtc_select_tick_clk,
844         .save_tick_cnt          = s3c24xx_rtc_save_tick_cnt,
845         .restore_tick_cnt       = s3c24xx_rtc_restore_tick_cnt,
846         .enable                 = s3c24xx_rtc_enable,
847         .disable                = s3c24xx_rtc_disable,
848 };
849
850 static struct s3c_rtc_data const s3c6410_rtc_data = {
851         .max_user_freq          = 32768,
852         .irq_handler            = s3c6410_rtc_irq,
853         .set_freq               = s3c6410_rtc_setfreq,
854         .enable_tick            = s3c6410_rtc_enable_tick,
855         .save_tick_cnt          = s3c6410_rtc_save_tick_cnt,
856         .restore_tick_cnt       = s3c6410_rtc_restore_tick_cnt,
857         .enable                 = s3c24xx_rtc_enable,
858         .disable                = s3c6410_rtc_disable,
859 };
860
861 static struct s3c_rtc_data const exynos3250_rtc_data = {
862         .max_user_freq          = 32768,
863         .needs_src_clk          = true,
864         .irq_handler            = s3c6410_rtc_irq,
865         .set_freq               = s3c6410_rtc_setfreq,
866         .enable_tick            = s3c6410_rtc_enable_tick,
867         .save_tick_cnt          = s3c6410_rtc_save_tick_cnt,
868         .restore_tick_cnt       = s3c6410_rtc_restore_tick_cnt,
869         .enable                 = s3c24xx_rtc_enable,
870         .disable                = s3c6410_rtc_disable,
871 };
872
873 static const struct of_device_id s3c_rtc_dt_match[] = {
874         {
875                 .compatible = "samsung,s3c2410-rtc",
876                 .data = (void *)&s3c2410_rtc_data,
877         }, {
878                 .compatible = "samsung,s3c2416-rtc",
879                 .data = (void *)&s3c2416_rtc_data,
880         }, {
881                 .compatible = "samsung,s3c2443-rtc",
882                 .data = (void *)&s3c2443_rtc_data,
883         }, {
884                 .compatible = "samsung,s3c6410-rtc",
885                 .data = (void *)&s3c6410_rtc_data,
886         }, {
887                 .compatible = "samsung,exynos3250-rtc",
888                 .data = (void *)&exynos3250_rtc_data,
889         },
890         { /* sentinel */ },
891 };
892 MODULE_DEVICE_TABLE(of, s3c_rtc_dt_match);
893
894 static struct platform_driver s3c_rtc_driver = {
895         .probe          = s3c_rtc_probe,
896         .remove         = s3c_rtc_remove,
897         .driver         = {
898                 .name   = "s3c-rtc",
899                 .pm     = &s3c_rtc_pm_ops,
900                 .of_match_table = of_match_ptr(s3c_rtc_dt_match),
901         },
902 };
903 module_platform_driver(s3c_rtc_driver);
904
905 MODULE_DESCRIPTION("Samsung S3C RTC Driver");
906 MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
907 MODULE_LICENSE("GPL");
908 MODULE_ALIAS("platform:s3c2410-rtc");