]> nv-tegra.nvidia Code Review - linux-2.6.git/blob - drivers/rtc/rtc-lpc32xx.c
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/djbw/async_tx
[linux-2.6.git] / drivers / rtc / rtc-lpc32xx.c
1 /*
2  * Copyright (C) 2010 NXP Semiconductors
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  *  You should have received a copy of the GNU General Public License along
10  *  with this program; if not, write to the Free Software Foundation, Inc.,
11  *  675 Mass Ave, Cambridge, MA 02139, USA.
12  */
13
14 #include <linux/kernel.h>
15 #include <linux/module.h>
16 #include <linux/init.h>
17 #include <linux/platform_device.h>
18 #include <linux/spinlock.h>
19 #include <linux/rtc.h>
20 #include <linux/slab.h>
21 #include <linux/io.h>
22
23 /*
24  * Clock and Power control register offsets
25  */
26 #define LPC32XX_RTC_UCOUNT              0x00
27 #define LPC32XX_RTC_DCOUNT              0x04
28 #define LPC32XX_RTC_MATCH0              0x08
29 #define LPC32XX_RTC_MATCH1              0x0C
30 #define LPC32XX_RTC_CTRL                0x10
31 #define LPC32XX_RTC_INTSTAT             0x14
32 #define LPC32XX_RTC_KEY                 0x18
33 #define LPC32XX_RTC_SRAM                0x80
34
35 #define LPC32XX_RTC_CTRL_MATCH0         (1 << 0)
36 #define LPC32XX_RTC_CTRL_MATCH1         (1 << 1)
37 #define LPC32XX_RTC_CTRL_ONSW_MATCH0    (1 << 2)
38 #define LPC32XX_RTC_CTRL_ONSW_MATCH1    (1 << 3)
39 #define LPC32XX_RTC_CTRL_SW_RESET       (1 << 4)
40 #define LPC32XX_RTC_CTRL_CNTR_DIS       (1 << 6)
41 #define LPC32XX_RTC_CTRL_ONSW_FORCE_HI  (1 << 7)
42
43 #define LPC32XX_RTC_INTSTAT_MATCH0      (1 << 0)
44 #define LPC32XX_RTC_INTSTAT_MATCH1      (1 << 1)
45 #define LPC32XX_RTC_INTSTAT_ONSW        (1 << 2)
46
47 #define LPC32XX_RTC_KEY_ONSW_LOADVAL    0xB5C13F27
48
49 #define RTC_NAME "rtc-lpc32xx"
50
51 #define rtc_readl(dev, reg) \
52         __raw_readl((dev)->rtc_base + (reg))
53 #define rtc_writel(dev, reg, val) \
54         __raw_writel((val), (dev)->rtc_base + (reg))
55
56 struct lpc32xx_rtc {
57         void __iomem *rtc_base;
58         int irq;
59         unsigned char alarm_enabled;
60         struct rtc_device *rtc;
61         spinlock_t lock;
62 };
63
64 static int lpc32xx_rtc_read_time(struct device *dev, struct rtc_time *time)
65 {
66         unsigned long elapsed_sec;
67         struct lpc32xx_rtc *rtc = dev_get_drvdata(dev);
68
69         elapsed_sec = rtc_readl(rtc, LPC32XX_RTC_UCOUNT);
70         rtc_time_to_tm(elapsed_sec, time);
71
72         return rtc_valid_tm(time);
73 }
74
75 static int lpc32xx_rtc_set_mmss(struct device *dev, unsigned long secs)
76 {
77         struct lpc32xx_rtc *rtc = dev_get_drvdata(dev);
78         u32 tmp;
79
80         spin_lock_irq(&rtc->lock);
81
82         /* RTC must be disabled during count update */
83         tmp = rtc_readl(rtc, LPC32XX_RTC_CTRL);
84         rtc_writel(rtc, LPC32XX_RTC_CTRL, tmp | LPC32XX_RTC_CTRL_CNTR_DIS);
85         rtc_writel(rtc, LPC32XX_RTC_UCOUNT, secs);
86         rtc_writel(rtc, LPC32XX_RTC_DCOUNT, 0xFFFFFFFF - secs);
87         rtc_writel(rtc, LPC32XX_RTC_CTRL, tmp &= ~LPC32XX_RTC_CTRL_CNTR_DIS);
88
89         spin_unlock_irq(&rtc->lock);
90
91         return 0;
92 }
93
94 static int lpc32xx_rtc_read_alarm(struct device *dev,
95         struct rtc_wkalrm *wkalrm)
96 {
97         struct lpc32xx_rtc *rtc = dev_get_drvdata(dev);
98
99         rtc_time_to_tm(rtc_readl(rtc, LPC32XX_RTC_MATCH0), &wkalrm->time);
100         wkalrm->enabled = rtc->alarm_enabled;
101         wkalrm->pending = !!(rtc_readl(rtc, LPC32XX_RTC_INTSTAT) &
102                 LPC32XX_RTC_INTSTAT_MATCH0);
103
104         return rtc_valid_tm(&wkalrm->time);
105 }
106
107 static int lpc32xx_rtc_set_alarm(struct device *dev,
108         struct rtc_wkalrm *wkalrm)
109 {
110         struct lpc32xx_rtc *rtc = dev_get_drvdata(dev);
111         unsigned long alarmsecs;
112         u32 tmp;
113         int ret;
114
115         ret = rtc_tm_to_time(&wkalrm->time, &alarmsecs);
116         if (ret < 0) {
117                 dev_warn(dev, "Failed to convert time: %d\n", ret);
118                 return ret;
119         }
120
121         spin_lock_irq(&rtc->lock);
122
123         /* Disable alarm during update */
124         tmp = rtc_readl(rtc, LPC32XX_RTC_CTRL);
125         rtc_writel(rtc, LPC32XX_RTC_CTRL, tmp & ~LPC32XX_RTC_CTRL_MATCH0);
126
127         rtc_writel(rtc, LPC32XX_RTC_MATCH0, alarmsecs);
128
129         rtc->alarm_enabled = wkalrm->enabled;
130         if (wkalrm->enabled) {
131                 rtc_writel(rtc, LPC32XX_RTC_INTSTAT,
132                            LPC32XX_RTC_INTSTAT_MATCH0);
133                 rtc_writel(rtc, LPC32XX_RTC_CTRL, tmp |
134                            LPC32XX_RTC_CTRL_MATCH0);
135         }
136
137         spin_unlock_irq(&rtc->lock);
138
139         return 0;
140 }
141
142 static int lpc32xx_rtc_alarm_irq_enable(struct device *dev,
143         unsigned int enabled)
144 {
145         struct lpc32xx_rtc *rtc = dev_get_drvdata(dev);
146         u32 tmp;
147
148         spin_lock_irq(&rtc->lock);
149         tmp = rtc_readl(rtc, LPC32XX_RTC_CTRL);
150
151         if (enabled) {
152                 rtc->alarm_enabled = 1;
153                 tmp |= LPC32XX_RTC_CTRL_MATCH0;
154         } else {
155                 rtc->alarm_enabled = 0;
156                 tmp &= ~LPC32XX_RTC_CTRL_MATCH0;
157         }
158
159         rtc_writel(rtc, LPC32XX_RTC_CTRL, tmp);
160         spin_unlock_irq(&rtc->lock);
161
162         return 0;
163 }
164
165 static irqreturn_t lpc32xx_rtc_alarm_interrupt(int irq, void *dev)
166 {
167         struct lpc32xx_rtc *rtc = dev;
168
169         spin_lock(&rtc->lock);
170
171         /* Disable alarm interrupt */
172         rtc_writel(rtc, LPC32XX_RTC_CTRL,
173                 rtc_readl(rtc, LPC32XX_RTC_CTRL) &
174                           ~LPC32XX_RTC_CTRL_MATCH0);
175         rtc->alarm_enabled = 0;
176
177         /*
178          * Write a large value to the match value so the RTC won't
179          * keep firing the match status
180          */
181         rtc_writel(rtc, LPC32XX_RTC_MATCH0, 0xFFFFFFFF);
182         rtc_writel(rtc, LPC32XX_RTC_INTSTAT, LPC32XX_RTC_INTSTAT_MATCH0);
183
184         spin_unlock(&rtc->lock);
185
186         rtc_update_irq(rtc->rtc, 1, RTC_IRQF | RTC_AF);
187
188         return IRQ_HANDLED;
189 }
190
191 static const struct rtc_class_ops lpc32xx_rtc_ops = {
192         .read_time              = lpc32xx_rtc_read_time,
193         .set_mmss               = lpc32xx_rtc_set_mmss,
194         .read_alarm             = lpc32xx_rtc_read_alarm,
195         .set_alarm              = lpc32xx_rtc_set_alarm,
196         .alarm_irq_enable       = lpc32xx_rtc_alarm_irq_enable,
197 };
198
199 static int __devinit lpc32xx_rtc_probe(struct platform_device *pdev)
200 {
201         struct resource *res;
202         struct lpc32xx_rtc *rtc;
203         resource_size_t size;
204         int rtcirq;
205         u32 tmp;
206
207         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
208         if (!res) {
209                 dev_err(&pdev->dev, "Can't get memory resource\n");
210                 return -ENOENT;
211         }
212
213         rtcirq = platform_get_irq(pdev, 0);
214         if (rtcirq < 0 || rtcirq >= NR_IRQS) {
215                 dev_warn(&pdev->dev, "Can't get interrupt resource\n");
216                 rtcirq = -1;
217         }
218
219         rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL);
220         if (unlikely(!rtc)) {
221                 dev_err(&pdev->dev, "Can't allocate memory\n");
222                 return -ENOMEM;
223         }
224         rtc->irq = rtcirq;
225
226         size = resource_size(res);
227
228         if (!devm_request_mem_region(&pdev->dev, res->start, size,
229                                      pdev->name)) {
230                 dev_err(&pdev->dev, "RTC registers are not free\n");
231                 return -EBUSY;
232         }
233
234         rtc->rtc_base = devm_ioremap(&pdev->dev, res->start, size);
235         if (!rtc->rtc_base) {
236                 dev_err(&pdev->dev, "Can't map memory\n");
237                 return -ENOMEM;
238         }
239
240         spin_lock_init(&rtc->lock);
241
242         /*
243          * The RTC is on a separate power domain and can keep it's state
244          * across a chip power cycle. If the RTC has never been previously
245          * setup, then set it up now for the first time.
246          */
247         tmp = rtc_readl(rtc, LPC32XX_RTC_CTRL);
248         if (rtc_readl(rtc, LPC32XX_RTC_KEY) != LPC32XX_RTC_KEY_ONSW_LOADVAL) {
249                 tmp &= ~(LPC32XX_RTC_CTRL_SW_RESET |
250                         LPC32XX_RTC_CTRL_CNTR_DIS |
251                         LPC32XX_RTC_CTRL_MATCH0 |
252                         LPC32XX_RTC_CTRL_MATCH1 |
253                         LPC32XX_RTC_CTRL_ONSW_MATCH0 |
254                         LPC32XX_RTC_CTRL_ONSW_MATCH1 |
255                         LPC32XX_RTC_CTRL_ONSW_FORCE_HI);
256                 rtc_writel(rtc, LPC32XX_RTC_CTRL, tmp);
257
258                 /* Clear latched interrupt states */
259                 rtc_writel(rtc, LPC32XX_RTC_MATCH0, 0xFFFFFFFF);
260                 rtc_writel(rtc, LPC32XX_RTC_INTSTAT,
261                            LPC32XX_RTC_INTSTAT_MATCH0 |
262                            LPC32XX_RTC_INTSTAT_MATCH1 |
263                            LPC32XX_RTC_INTSTAT_ONSW);
264
265                 /* Write key value to RTC so it won't reload on reset */
266                 rtc_writel(rtc, LPC32XX_RTC_KEY,
267                            LPC32XX_RTC_KEY_ONSW_LOADVAL);
268         } else {
269                 rtc_writel(rtc, LPC32XX_RTC_CTRL,
270                            tmp & ~LPC32XX_RTC_CTRL_MATCH0);
271         }
272
273         platform_set_drvdata(pdev, rtc);
274
275         rtc->rtc = rtc_device_register(RTC_NAME, &pdev->dev, &lpc32xx_rtc_ops,
276                 THIS_MODULE);
277         if (IS_ERR(rtc->rtc)) {
278                 dev_err(&pdev->dev, "Can't get RTC\n");
279                 platform_set_drvdata(pdev, NULL);
280                 return PTR_ERR(rtc->rtc);
281         }
282
283         /*
284          * IRQ is enabled after device registration in case alarm IRQ
285          * is pending upon suspend exit.
286          */
287         if (rtc->irq >= 0) {
288                 if (devm_request_irq(&pdev->dev, rtc->irq,
289                                      lpc32xx_rtc_alarm_interrupt,
290                                      IRQF_DISABLED, pdev->name, rtc) < 0) {
291                         dev_warn(&pdev->dev, "Can't request interrupt.\n");
292                         rtc->irq = -1;
293                 } else {
294                         device_init_wakeup(&pdev->dev, 1);
295                 }
296         }
297
298         return 0;
299 }
300
301 static int __devexit lpc32xx_rtc_remove(struct platform_device *pdev)
302 {
303         struct lpc32xx_rtc *rtc = platform_get_drvdata(pdev);
304
305         if (rtc->irq >= 0)
306                 device_init_wakeup(&pdev->dev, 0);
307
308         platform_set_drvdata(pdev, NULL);
309         rtc_device_unregister(rtc->rtc);
310
311         return 0;
312 }
313
314 #ifdef CONFIG_PM
315 static int lpc32xx_rtc_suspend(struct device *dev)
316 {
317         struct platform_device *pdev = to_platform_device(dev);
318         struct lpc32xx_rtc *rtc = platform_get_drvdata(pdev);
319
320         if (rtc->irq >= 0) {
321                 if (device_may_wakeup(&pdev->dev))
322                         enable_irq_wake(rtc->irq);
323                 else
324                         disable_irq_wake(rtc->irq);
325         }
326
327         return 0;
328 }
329
330 static int lpc32xx_rtc_resume(struct device *dev)
331 {
332         struct platform_device *pdev = to_platform_device(dev);
333         struct lpc32xx_rtc *rtc = platform_get_drvdata(pdev);
334
335         if (rtc->irq >= 0 && device_may_wakeup(&pdev->dev))
336                 disable_irq_wake(rtc->irq);
337
338         return 0;
339 }
340
341 /* Unconditionally disable the alarm */
342 static int lpc32xx_rtc_freeze(struct device *dev)
343 {
344         struct platform_device *pdev = to_platform_device(dev);
345         struct lpc32xx_rtc *rtc = platform_get_drvdata(pdev);
346
347         spin_lock_irq(&rtc->lock);
348
349         rtc_writel(rtc, LPC32XX_RTC_CTRL,
350                 rtc_readl(rtc, LPC32XX_RTC_CTRL) &
351                           ~LPC32XX_RTC_CTRL_MATCH0);
352
353         spin_unlock_irq(&rtc->lock);
354
355         return 0;
356 }
357
358 static int lpc32xx_rtc_thaw(struct device *dev)
359 {
360         struct platform_device *pdev = to_platform_device(dev);
361         struct lpc32xx_rtc *rtc = platform_get_drvdata(pdev);
362
363         if (rtc->alarm_enabled) {
364                 spin_lock_irq(&rtc->lock);
365
366                 rtc_writel(rtc, LPC32XX_RTC_CTRL,
367                            rtc_readl(rtc, LPC32XX_RTC_CTRL) |
368                            LPC32XX_RTC_CTRL_MATCH0);
369
370                 spin_unlock_irq(&rtc->lock);
371         }
372
373         return 0;
374 }
375
376 static const struct dev_pm_ops lpc32xx_rtc_pm_ops = {
377         .suspend = lpc32xx_rtc_suspend,
378         .resume = lpc32xx_rtc_resume,
379         .freeze = lpc32xx_rtc_freeze,
380         .thaw = lpc32xx_rtc_thaw,
381         .restore = lpc32xx_rtc_resume
382 };
383
384 #define LPC32XX_RTC_PM_OPS (&lpc32xx_rtc_pm_ops)
385 #else
386 #define LPC32XX_RTC_PM_OPS NULL
387 #endif
388
389 static struct platform_driver lpc32xx_rtc_driver = {
390         .probe          = lpc32xx_rtc_probe,
391         .remove         = __devexit_p(lpc32xx_rtc_remove),
392         .driver = {
393                 .name   = RTC_NAME,
394                 .owner  = THIS_MODULE,
395                 .pm     = LPC32XX_RTC_PM_OPS
396         },
397 };
398
399 static int __init lpc32xx_rtc_init(void)
400 {
401         return platform_driver_register(&lpc32xx_rtc_driver);
402 }
403 module_init(lpc32xx_rtc_init);
404
405 static void __exit lpc32xx_rtc_exit(void)
406 {
407         platform_driver_unregister(&lpc32xx_rtc_driver);
408 }
409 module_exit(lpc32xx_rtc_exit);
410
411 MODULE_AUTHOR("Kevin Wells <wellsk40@gmail.com");
412 MODULE_DESCRIPTION("RTC driver for the LPC32xx SoC");
413 MODULE_LICENSE("GPL");
414 MODULE_ALIAS("platform:rtc-lpc32xx");