Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
rtc-lpc32xx.c
Go to the documentation of this file.
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 #include <linux/of.h>
23 
24 /*
25  * Clock and Power control register offsets
26  */
27 #define LPC32XX_RTC_UCOUNT 0x00
28 #define LPC32XX_RTC_DCOUNT 0x04
29 #define LPC32XX_RTC_MATCH0 0x08
30 #define LPC32XX_RTC_MATCH1 0x0C
31 #define LPC32XX_RTC_CTRL 0x10
32 #define LPC32XX_RTC_INTSTAT 0x14
33 #define LPC32XX_RTC_KEY 0x18
34 #define LPC32XX_RTC_SRAM 0x80
35 
36 #define LPC32XX_RTC_CTRL_MATCH0 (1 << 0)
37 #define LPC32XX_RTC_CTRL_MATCH1 (1 << 1)
38 #define LPC32XX_RTC_CTRL_ONSW_MATCH0 (1 << 2)
39 #define LPC32XX_RTC_CTRL_ONSW_MATCH1 (1 << 3)
40 #define LPC32XX_RTC_CTRL_SW_RESET (1 << 4)
41 #define LPC32XX_RTC_CTRL_CNTR_DIS (1 << 6)
42 #define LPC32XX_RTC_CTRL_ONSW_FORCE_HI (1 << 7)
43 
44 #define LPC32XX_RTC_INTSTAT_MATCH0 (1 << 0)
45 #define LPC32XX_RTC_INTSTAT_MATCH1 (1 << 1)
46 #define LPC32XX_RTC_INTSTAT_ONSW (1 << 2)
47 
48 #define LPC32XX_RTC_KEY_ONSW_LOADVAL 0xB5C13F27
49 
50 #define RTC_NAME "rtc-lpc32xx"
51 
52 #define rtc_readl(dev, reg) \
53  __raw_readl((dev)->rtc_base + (reg))
54 #define rtc_writel(dev, reg, val) \
55  __raw_writel((val), (dev)->rtc_base + (reg))
56 
57 struct lpc32xx_rtc {
59  int irq;
60  unsigned char alarm_enabled;
61  struct rtc_device *rtc;
63 };
64 
65 static int lpc32xx_rtc_read_time(struct device *dev, struct rtc_time *time)
66 {
67  unsigned long elapsed_sec;
68  struct lpc32xx_rtc *rtc = dev_get_drvdata(dev);
69 
70  elapsed_sec = rtc_readl(rtc, LPC32XX_RTC_UCOUNT);
71  rtc_time_to_tm(elapsed_sec, time);
72 
73  return rtc_valid_tm(time);
74 }
75 
76 static int lpc32xx_rtc_set_mmss(struct device *dev, unsigned long secs)
77 {
78  struct lpc32xx_rtc *rtc = dev_get_drvdata(dev);
79  u32 tmp;
80 
81  spin_lock_irq(&rtc->lock);
82 
83  /* RTC must be disabled during count update */
84  tmp = rtc_readl(rtc, LPC32XX_RTC_CTRL);
86  rtc_writel(rtc, LPC32XX_RTC_UCOUNT, secs);
87  rtc_writel(rtc, LPC32XX_RTC_DCOUNT, 0xFFFFFFFF - secs);
89 
90  spin_unlock_irq(&rtc->lock);
91 
92  return 0;
93 }
94 
95 static int lpc32xx_rtc_read_alarm(struct device *dev,
96  struct rtc_wkalrm *wkalrm)
97 {
98  struct lpc32xx_rtc *rtc = dev_get_drvdata(dev);
99 
101  wkalrm->enabled = rtc->alarm_enabled;
102  wkalrm->pending = !!(rtc_readl(rtc, LPC32XX_RTC_INTSTAT) &
104 
105  return rtc_valid_tm(&wkalrm->time);
106 }
107 
108 static int lpc32xx_rtc_set_alarm(struct device *dev,
109  struct rtc_wkalrm *wkalrm)
110 {
111  struct lpc32xx_rtc *rtc = dev_get_drvdata(dev);
112  unsigned long alarmsecs;
113  u32 tmp;
114  int ret;
115 
116  ret = rtc_tm_to_time(&wkalrm->time, &alarmsecs);
117  if (ret < 0) {
118  dev_warn(dev, "Failed to convert time: %d\n", ret);
119  return ret;
120  }
121 
122  spin_lock_irq(&rtc->lock);
123 
124  /* Disable alarm during update */
125  tmp = rtc_readl(rtc, LPC32XX_RTC_CTRL);
127 
128  rtc_writel(rtc, LPC32XX_RTC_MATCH0, alarmsecs);
129 
130  rtc->alarm_enabled = wkalrm->enabled;
131  if (wkalrm->enabled) {
134  rtc_writel(rtc, LPC32XX_RTC_CTRL, tmp |
136  }
137 
138  spin_unlock_irq(&rtc->lock);
139 
140  return 0;
141 }
142 
143 static int lpc32xx_rtc_alarm_irq_enable(struct device *dev,
144  unsigned int enabled)
145 {
146  struct lpc32xx_rtc *rtc = dev_get_drvdata(dev);
147  u32 tmp;
148 
149  spin_lock_irq(&rtc->lock);
150  tmp = rtc_readl(rtc, LPC32XX_RTC_CTRL);
151 
152  if (enabled) {
153  rtc->alarm_enabled = 1;
155  } else {
156  rtc->alarm_enabled = 0;
157  tmp &= ~LPC32XX_RTC_CTRL_MATCH0;
158  }
159 
160  rtc_writel(rtc, LPC32XX_RTC_CTRL, tmp);
161  spin_unlock_irq(&rtc->lock);
162 
163  return 0;
164 }
165 
166 static irqreturn_t lpc32xx_rtc_alarm_interrupt(int irq, void *dev)
167 {
168  struct lpc32xx_rtc *rtc = dev;
169 
170  spin_lock(&rtc->lock);
171 
172  /* Disable alarm interrupt */
176  rtc->alarm_enabled = 0;
177 
178  /*
179  * Write a large value to the match value so the RTC won't
180  * keep firing the match status
181  */
182  rtc_writel(rtc, LPC32XX_RTC_MATCH0, 0xFFFFFFFF);
184 
185  spin_unlock(&rtc->lock);
186 
187  rtc_update_irq(rtc->rtc, 1, RTC_IRQF | RTC_AF);
188 
189  return IRQ_HANDLED;
190 }
191 
192 static const struct rtc_class_ops lpc32xx_rtc_ops = {
193  .read_time = lpc32xx_rtc_read_time,
194  .set_mmss = lpc32xx_rtc_set_mmss,
195  .read_alarm = lpc32xx_rtc_read_alarm,
196  .set_alarm = lpc32xx_rtc_set_alarm,
197  .alarm_irq_enable = lpc32xx_rtc_alarm_irq_enable,
198 };
199 
200 static int __devinit lpc32xx_rtc_probe(struct platform_device *pdev)
201 {
202  struct resource *res;
203  struct lpc32xx_rtc *rtc;
205  int rtcirq;
206  u32 tmp;
207 
208  res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
209  if (!res) {
210  dev_err(&pdev->dev, "Can't get memory resource\n");
211  return -ENOENT;
212  }
213 
214  rtcirq = platform_get_irq(pdev, 0);
215  if (rtcirq < 0 || rtcirq >= NR_IRQS) {
216  dev_warn(&pdev->dev, "Can't get interrupt resource\n");
217  rtcirq = -1;
218  }
219 
220  rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL);
221  if (unlikely(!rtc)) {
222  dev_err(&pdev->dev, "Can't allocate memory\n");
223  return -ENOMEM;
224  }
225  rtc->irq = rtcirq;
226 
227  size = resource_size(res);
228 
229  if (!devm_request_mem_region(&pdev->dev, res->start, size,
230  pdev->name)) {
231  dev_err(&pdev->dev, "RTC registers are not free\n");
232  return -EBUSY;
233  }
234 
235  rtc->rtc_base = devm_ioremap(&pdev->dev, res->start, size);
236  if (!rtc->rtc_base) {
237  dev_err(&pdev->dev, "Can't map memory\n");
238  return -ENOMEM;
239  }
240 
241  spin_lock_init(&rtc->lock);
242 
243  /*
244  * The RTC is on a separate power domain and can keep it's state
245  * across a chip power cycle. If the RTC has never been previously
246  * setup, then set it up now for the first time.
247  */
248  tmp = rtc_readl(rtc, LPC32XX_RTC_CTRL);
250  tmp &= ~(LPC32XX_RTC_CTRL_SW_RESET |
257  rtc_writel(rtc, LPC32XX_RTC_CTRL, tmp);
258 
259  /* Clear latched interrupt states */
260  rtc_writel(rtc, LPC32XX_RTC_MATCH0, 0xFFFFFFFF);
265 
266  /* Write key value to RTC so it won't reload on reset */
269  } else {
271  tmp & ~LPC32XX_RTC_CTRL_MATCH0);
272  }
273 
274  platform_set_drvdata(pdev, rtc);
275 
276  rtc->rtc = rtc_device_register(RTC_NAME, &pdev->dev, &lpc32xx_rtc_ops,
277  THIS_MODULE);
278  if (IS_ERR(rtc->rtc)) {
279  dev_err(&pdev->dev, "Can't get RTC\n");
280  platform_set_drvdata(pdev, NULL);
281  return PTR_ERR(rtc->rtc);
282  }
283 
284  /*
285  * IRQ is enabled after device registration in case alarm IRQ
286  * is pending upon suspend exit.
287  */
288  if (rtc->irq >= 0) {
289  if (devm_request_irq(&pdev->dev, rtc->irq,
290  lpc32xx_rtc_alarm_interrupt,
291  0, pdev->name, rtc) < 0) {
292  dev_warn(&pdev->dev, "Can't request interrupt.\n");
293  rtc->irq = -1;
294  } else {
295  device_init_wakeup(&pdev->dev, 1);
296  }
297  }
298 
299  return 0;
300 }
301 
302 static int __devexit lpc32xx_rtc_remove(struct platform_device *pdev)
303 {
304  struct lpc32xx_rtc *rtc = platform_get_drvdata(pdev);
305 
306  if (rtc->irq >= 0)
307  device_init_wakeup(&pdev->dev, 0);
308 
309  platform_set_drvdata(pdev, NULL);
311 
312  return 0;
313 }
314 
315 #ifdef CONFIG_PM
316 static int lpc32xx_rtc_suspend(struct device *dev)
317 {
318  struct platform_device *pdev = to_platform_device(dev);
319  struct lpc32xx_rtc *rtc = platform_get_drvdata(pdev);
320 
321  if (rtc->irq >= 0) {
322  if (device_may_wakeup(&pdev->dev))
323  enable_irq_wake(rtc->irq);
324  else
325  disable_irq_wake(rtc->irq);
326  }
327 
328  return 0;
329 }
330 
331 static int lpc32xx_rtc_resume(struct device *dev)
332 {
333  struct platform_device *pdev = to_platform_device(dev);
334  struct lpc32xx_rtc *rtc = platform_get_drvdata(pdev);
335 
336  if (rtc->irq >= 0 && device_may_wakeup(&pdev->dev))
337  disable_irq_wake(rtc->irq);
338 
339  return 0;
340 }
341 
342 /* Unconditionally disable the alarm */
343 static int lpc32xx_rtc_freeze(struct device *dev)
344 {
345  struct platform_device *pdev = to_platform_device(dev);
346  struct lpc32xx_rtc *rtc = platform_get_drvdata(pdev);
347 
348  spin_lock_irq(&rtc->lock);
349 
353 
354  spin_unlock_irq(&rtc->lock);
355 
356  return 0;
357 }
358 
359 static int lpc32xx_rtc_thaw(struct device *dev)
360 {
361  struct platform_device *pdev = to_platform_device(dev);
362  struct lpc32xx_rtc *rtc = platform_get_drvdata(pdev);
363 
364  if (rtc->alarm_enabled) {
365  spin_lock_irq(&rtc->lock);
366 
370 
371  spin_unlock_irq(&rtc->lock);
372  }
373 
374  return 0;
375 }
376 
377 static const struct dev_pm_ops lpc32xx_rtc_pm_ops = {
378  .suspend = lpc32xx_rtc_suspend,
379  .resume = lpc32xx_rtc_resume,
380  .freeze = lpc32xx_rtc_freeze,
381  .thaw = lpc32xx_rtc_thaw,
382  .restore = lpc32xx_rtc_resume
383 };
384 
385 #define LPC32XX_RTC_PM_OPS (&lpc32xx_rtc_pm_ops)
386 #else
387 #define LPC32XX_RTC_PM_OPS NULL
388 #endif
389 
390 #ifdef CONFIG_OF
391 static const struct of_device_id lpc32xx_rtc_match[] = {
392  { .compatible = "nxp,lpc3220-rtc" },
393  { }
394 };
395 MODULE_DEVICE_TABLE(of, lpc32xx_rtc_match);
396 #endif
397 
398 static struct platform_driver lpc32xx_rtc_driver = {
399  .probe = lpc32xx_rtc_probe,
400  .remove = __devexit_p(lpc32xx_rtc_remove),
401  .driver = {
402  .name = RTC_NAME,
403  .owner = THIS_MODULE,
404  .pm = LPC32XX_RTC_PM_OPS,
405  .of_match_table = of_match_ptr(lpc32xx_rtc_match),
406  },
407 };
408 
409 module_platform_driver(lpc32xx_rtc_driver);
410 
411 MODULE_AUTHOR("Kevin Wells <[email protected]");
412 MODULE_DESCRIPTION("RTC driver for the LPC32xx SoC");
413 MODULE_LICENSE("GPL");
414 MODULE_ALIAS("platform:rtc-lpc32xx");