x86/nmi: Fix use of unallocated cpumask_var_t
[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         info->rtc_src_clk = devm_clk_get(&pdev->dev, "rtc_src");
539         if (IS_ERR(info->rtc_src_clk)) {
540                 dev_err(&pdev->dev, "failed to find rtc source clock\n");
541                 return PTR_ERR(info->rtc_src_clk);
542         }
543         clk_prepare_enable(info->rtc_src_clk);
544
545
546         /* check to see if everything is setup correctly */
547         if (info->data->enable)
548                 info->data->enable(info);
549
550         dev_dbg(&pdev->dev, "s3c2410_rtc: RTCCON=%02x\n",
551                  readw(info->base + S3C2410_RTCCON));
552
553         device_init_wakeup(&pdev->dev, 1);
554
555         /* register RTC and exit */
556         info->rtc = devm_rtc_device_register(&pdev->dev, "s3c", &s3c_rtcops,
557                                   THIS_MODULE);
558         if (IS_ERR(info->rtc)) {
559                 dev_err(&pdev->dev, "cannot attach rtc\n");
560                 ret = PTR_ERR(info->rtc);
561                 goto err_nortc;
562         }
563
564         ret = devm_request_irq(&pdev->dev, info->irq_alarm, s3c_rtc_alarmirq,
565                           0,  "s3c2410-rtc alarm", info);
566         if (ret) {
567                 dev_err(&pdev->dev, "IRQ%d error %d\n", info->irq_alarm, ret);
568                 goto err_nortc;
569         }
570
571         ret = devm_request_irq(&pdev->dev, info->irq_tick, s3c_rtc_tickirq,
572                           0,  "s3c2410-rtc tick", info);
573         if (ret) {
574                 dev_err(&pdev->dev, "IRQ%d error %d\n", info->irq_tick, ret);
575                 goto err_nortc;
576         }
577
578         /* Check RTC Time */
579         s3c_rtc_gettime(&pdev->dev, &rtc_tm);
580
581         if (rtc_valid_tm(&rtc_tm)) {
582                 rtc_tm.tm_year  = 100;
583                 rtc_tm.tm_mon   = 0;
584                 rtc_tm.tm_mday  = 1;
585                 rtc_tm.tm_hour  = 0;
586                 rtc_tm.tm_min   = 0;
587                 rtc_tm.tm_sec   = 0;
588
589                 s3c_rtc_settime(&pdev->dev, &rtc_tm);
590
591                 dev_warn(&pdev->dev, "warning: invalid RTC value so initializing it\n");
592         }
593
594         if (info->data->select_tick_clk)
595                 info->data->select_tick_clk(info);
596
597         s3c_rtc_setfreq(info, 1);
598
599         if (info->data->needs_src_clk)
600                 clk_disable(info->rtc_src_clk);
601         clk_disable(info->rtc_clk);
602
603         return 0;
604
605  err_nortc:
606         if (info->data->disable)
607                 info->data->disable(info);
608         clk_disable_unprepare(info->rtc_clk);
609
610         return ret;
611 }
612
613 #ifdef CONFIG_PM_SLEEP
614
615 static int s3c_rtc_suspend(struct device *dev)
616 {
617         struct s3c_rtc *info = dev_get_drvdata(dev);
618
619         clk_enable(info->rtc_clk);
620         if (info->data->needs_src_clk)
621                 clk_enable(info->rtc_src_clk);
622
623         /* save TICNT for anyone using periodic interrupts */
624         if (info->data->save_tick_cnt)
625                 info->data->save_tick_cnt(info);
626
627         if (info->data->disable)
628                 info->data->disable(info);
629
630         if (device_may_wakeup(dev) && !info->wake_en) {
631                 if (enable_irq_wake(info->irq_alarm) == 0)
632                         info->wake_en = true;
633                 else
634                         dev_err(dev, "enable_irq_wake failed\n");
635         }
636
637         if (info->data->needs_src_clk)
638                 clk_disable(info->rtc_src_clk);
639         clk_disable(info->rtc_clk);
640
641         return 0;
642 }
643
644 static int s3c_rtc_resume(struct device *dev)
645 {
646         struct s3c_rtc *info = dev_get_drvdata(dev);
647
648         clk_enable(info->rtc_clk);
649         if (info->data->needs_src_clk)
650                 clk_enable(info->rtc_src_clk);
651
652         if (info->data->enable)
653                 info->data->enable(info);
654
655         if (info->data->restore_tick_cnt)
656                 info->data->restore_tick_cnt(info);
657
658         if (device_may_wakeup(dev) && info->wake_en) {
659                 disable_irq_wake(info->irq_alarm);
660                 info->wake_en = false;
661         }
662
663         if (info->data->needs_src_clk)
664                 clk_disable(info->rtc_src_clk);
665         clk_disable(info->rtc_clk);
666
667         return 0;
668 }
669 #endif
670 static SIMPLE_DEV_PM_OPS(s3c_rtc_pm_ops, s3c_rtc_suspend, s3c_rtc_resume);
671
672 static void s3c24xx_rtc_irq(struct s3c_rtc *info, int mask)
673 {
674         clk_enable(info->rtc_clk);
675         if (info->data->needs_src_clk)
676                 clk_enable(info->rtc_src_clk);
677         rtc_update_irq(info->rtc, 1, RTC_AF | RTC_IRQF);
678         if (info->data->needs_src_clk)
679                 clk_disable(info->rtc_src_clk);
680         clk_disable(info->rtc_clk);
681
682         s3c_rtc_alarm_clk_enable(info, false);
683 }
684
685 static void s3c6410_rtc_irq(struct s3c_rtc *info, int mask)
686 {
687         clk_enable(info->rtc_clk);
688         if (info->data->needs_src_clk)
689                 clk_enable(info->rtc_src_clk);
690         rtc_update_irq(info->rtc, 1, RTC_AF | RTC_IRQF);
691         writeb(mask, info->base + S3C2410_INTP);
692         if (info->data->needs_src_clk)
693                 clk_disable(info->rtc_src_clk);
694         clk_disable(info->rtc_clk);
695
696         s3c_rtc_alarm_clk_enable(info, false);
697 }
698
699 static void s3c2410_rtc_setfreq(struct s3c_rtc *info, int freq)
700 {
701         unsigned int tmp = 0;
702         int val;
703
704         tmp = readb(info->base + S3C2410_TICNT);
705         tmp &= S3C2410_TICNT_ENABLE;
706
707         val = (info->rtc->max_user_freq / freq) - 1;
708         tmp |= val;
709
710         writel(tmp, info->base + S3C2410_TICNT);
711 }
712
713 static void s3c2416_rtc_setfreq(struct s3c_rtc *info, int freq)
714 {
715         unsigned int tmp = 0;
716         int val;
717
718         tmp = readb(info->base + S3C2410_TICNT);
719         tmp &= S3C2410_TICNT_ENABLE;
720
721         val = (info->rtc->max_user_freq / freq) - 1;
722
723         tmp |= S3C2443_TICNT_PART(val);
724         writel(S3C2443_TICNT1_PART(val), info->base + S3C2443_TICNT1);
725
726         writel(S3C2416_TICNT2_PART(val), info->base + S3C2416_TICNT2);
727
728         writel(tmp, info->base + S3C2410_TICNT);
729 }
730
731 static void s3c2443_rtc_setfreq(struct s3c_rtc *info, int freq)
732 {
733         unsigned int tmp = 0;
734         int val;
735
736         tmp = readb(info->base + S3C2410_TICNT);
737         tmp &= S3C2410_TICNT_ENABLE;
738
739         val = (info->rtc->max_user_freq / freq) - 1;
740
741         tmp |= S3C2443_TICNT_PART(val);
742         writel(S3C2443_TICNT1_PART(val), info->base + S3C2443_TICNT1);
743
744         writel(tmp, info->base + S3C2410_TICNT);
745 }
746
747 static void s3c6410_rtc_setfreq(struct s3c_rtc *info, int freq)
748 {
749         int val;
750
751         val = (info->rtc->max_user_freq / freq) - 1;
752         writel(val, info->base + S3C2410_TICNT);
753 }
754
755 static void s3c24xx_rtc_enable_tick(struct s3c_rtc *info, struct seq_file *seq)
756 {
757         unsigned int ticnt;
758
759         ticnt = readb(info->base + S3C2410_TICNT);
760         ticnt &= S3C2410_TICNT_ENABLE;
761
762         seq_printf(seq, "periodic_IRQ\t: %s\n", ticnt  ? "yes" : "no");
763 }
764
765 static void s3c2416_rtc_select_tick_clk(struct s3c_rtc *info)
766 {
767         unsigned int con;
768
769         con = readw(info->base + S3C2410_RTCCON);
770         con |= S3C2443_RTCCON_TICSEL;
771         writew(con, info->base + S3C2410_RTCCON);
772 }
773
774 static void s3c6410_rtc_enable_tick(struct s3c_rtc *info, struct seq_file *seq)
775 {
776         unsigned int ticnt;
777
778         ticnt = readw(info->base + S3C2410_RTCCON);
779         ticnt &= S3C64XX_RTCCON_TICEN;
780
781         seq_printf(seq, "periodic_IRQ\t: %s\n", ticnt  ? "yes" : "no");
782 }
783
784 static void s3c24xx_rtc_save_tick_cnt(struct s3c_rtc *info)
785 {
786         info->ticnt_save = readb(info->base + S3C2410_TICNT);
787 }
788
789 static void s3c24xx_rtc_restore_tick_cnt(struct s3c_rtc *info)
790 {
791         writeb(info->ticnt_save, info->base + S3C2410_TICNT);
792 }
793
794 static void s3c6410_rtc_save_tick_cnt(struct s3c_rtc *info)
795 {
796         info->ticnt_en_save = readw(info->base + S3C2410_RTCCON);
797         info->ticnt_en_save &= S3C64XX_RTCCON_TICEN;
798         info->ticnt_save = readl(info->base + S3C2410_TICNT);
799 }
800
801 static void s3c6410_rtc_restore_tick_cnt(struct s3c_rtc *info)
802 {
803         unsigned int con;
804
805         writel(info->ticnt_save, info->base + S3C2410_TICNT);
806         if (info->ticnt_en_save) {
807                 con = readw(info->base + S3C2410_RTCCON);
808                 writew(con | info->ticnt_en_save,
809                                 info->base + S3C2410_RTCCON);
810         }
811 }
812
813 static struct s3c_rtc_data const s3c2410_rtc_data = {
814         .max_user_freq          = 128,
815         .irq_handler            = s3c24xx_rtc_irq,
816         .set_freq               = s3c2410_rtc_setfreq,
817         .enable_tick            = s3c24xx_rtc_enable_tick,
818         .save_tick_cnt          = s3c24xx_rtc_save_tick_cnt,
819         .restore_tick_cnt       = s3c24xx_rtc_restore_tick_cnt,
820         .enable                 = s3c24xx_rtc_enable,
821         .disable                = s3c24xx_rtc_disable,
822 };
823
824 static struct s3c_rtc_data const s3c2416_rtc_data = {
825         .max_user_freq          = 32768,
826         .irq_handler            = s3c24xx_rtc_irq,
827         .set_freq               = s3c2416_rtc_setfreq,
828         .enable_tick            = s3c24xx_rtc_enable_tick,
829         .select_tick_clk        = s3c2416_rtc_select_tick_clk,
830         .save_tick_cnt          = s3c24xx_rtc_save_tick_cnt,
831         .restore_tick_cnt       = s3c24xx_rtc_restore_tick_cnt,
832         .enable                 = s3c24xx_rtc_enable,
833         .disable                = s3c24xx_rtc_disable,
834 };
835
836 static struct s3c_rtc_data const s3c2443_rtc_data = {
837         .max_user_freq          = 32768,
838         .irq_handler            = s3c24xx_rtc_irq,
839         .set_freq               = s3c2443_rtc_setfreq,
840         .enable_tick            = s3c24xx_rtc_enable_tick,
841         .select_tick_clk        = s3c2416_rtc_select_tick_clk,
842         .save_tick_cnt          = s3c24xx_rtc_save_tick_cnt,
843         .restore_tick_cnt       = s3c24xx_rtc_restore_tick_cnt,
844         .enable                 = s3c24xx_rtc_enable,
845         .disable                = s3c24xx_rtc_disable,
846 };
847
848 static struct s3c_rtc_data const s3c6410_rtc_data = {
849         .max_user_freq          = 32768,
850         .irq_handler            = s3c6410_rtc_irq,
851         .set_freq               = s3c6410_rtc_setfreq,
852         .enable_tick            = s3c6410_rtc_enable_tick,
853         .save_tick_cnt          = s3c6410_rtc_save_tick_cnt,
854         .restore_tick_cnt       = s3c6410_rtc_restore_tick_cnt,
855         .enable                 = s3c24xx_rtc_enable,
856         .disable                = s3c6410_rtc_disable,
857 };
858
859 static struct s3c_rtc_data const exynos3250_rtc_data = {
860         .max_user_freq          = 32768,
861         .needs_src_clk          = true,
862         .irq_handler            = s3c6410_rtc_irq,
863         .set_freq               = s3c6410_rtc_setfreq,
864         .enable_tick            = s3c6410_rtc_enable_tick,
865         .save_tick_cnt          = s3c6410_rtc_save_tick_cnt,
866         .restore_tick_cnt       = s3c6410_rtc_restore_tick_cnt,
867         .enable                 = s3c24xx_rtc_enable,
868         .disable                = s3c6410_rtc_disable,
869 };
870
871 static const struct of_device_id s3c_rtc_dt_match[] = {
872         {
873                 .compatible = "samsung,s3c2410-rtc",
874                 .data = (void *)&s3c2410_rtc_data,
875         }, {
876                 .compatible = "samsung,s3c2416-rtc",
877                 .data = (void *)&s3c2416_rtc_data,
878         }, {
879                 .compatible = "samsung,s3c2443-rtc",
880                 .data = (void *)&s3c2443_rtc_data,
881         }, {
882                 .compatible = "samsung,s3c6410-rtc",
883                 .data = (void *)&s3c6410_rtc_data,
884         }, {
885                 .compatible = "samsung,exynos3250-rtc",
886                 .data = (void *)&exynos3250_rtc_data,
887         },
888         { /* sentinel */ },
889 };
890 MODULE_DEVICE_TABLE(of, s3c_rtc_dt_match);
891
892 static struct platform_driver s3c_rtc_driver = {
893         .probe          = s3c_rtc_probe,
894         .remove         = s3c_rtc_remove,
895         .driver         = {
896                 .name   = "s3c-rtc",
897                 .owner  = THIS_MODULE,
898                 .pm     = &s3c_rtc_pm_ops,
899                 .of_match_table = of_match_ptr(s3c_rtc_dt_match),
900         },
901 };
902 module_platform_driver(s3c_rtc_driver);
903
904 MODULE_DESCRIPTION("Samsung S3C RTC Driver");
905 MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
906 MODULE_LICENSE("GPL");
907 MODULE_ALIAS("platform:s3c2410-rtc");