Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
rtc-snvs.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2011-2012 Freescale Semiconductor, Inc.
3  *
4  * The code contained herein is licensed under the GNU General Public
5  * License. You may obtain a copy of the GNU General Public License
6  * Version 2 or later at the following locations:
7  *
8  * http://www.opensource.org/licenses/gpl-license.html
9  * http://www.gnu.org/copyleft/gpl.html
10  */
11 
12 #include <linux/init.h>
13 #include <linux/io.h>
14 #include <linux/kernel.h>
15 #include <linux/module.h>
16 #include <linux/of.h>
17 #include <linux/of_device.h>
18 #include <linux/platform_device.h>
19 #include <linux/rtc.h>
20 
21 /* These register offsets are relative to LP (Low Power) range */
22 #define SNVS_LPCR 0x04
23 #define SNVS_LPSR 0x18
24 #define SNVS_LPSRTCMR 0x1c
25 #define SNVS_LPSRTCLR 0x20
26 #define SNVS_LPTAR 0x24
27 #define SNVS_LPPGDR 0x30
28 
29 #define SNVS_LPCR_SRTC_ENV (1 << 0)
30 #define SNVS_LPCR_LPTA_EN (1 << 1)
31 #define SNVS_LPCR_LPWUI_EN (1 << 3)
32 #define SNVS_LPSR_LPTA (1 << 0)
33 
34 #define SNVS_LPPGDR_INIT 0x41736166
35 #define CNTR_TO_SECS_SH 15
36 
37 struct snvs_rtc_data {
38  struct rtc_device *rtc;
39  void __iomem *ioaddr;
40  int irq;
42 };
43 
44 static u32 rtc_read_lp_counter(void __iomem *ioaddr)
45 {
46  u64 read1, read2;
47 
48  do {
49  read1 = readl(ioaddr + SNVS_LPSRTCMR);
50  read1 <<= 32;
51  read1 |= readl(ioaddr + SNVS_LPSRTCLR);
52 
53  read2 = readl(ioaddr + SNVS_LPSRTCMR);
54  read2 <<= 32;
55  read2 |= readl(ioaddr + SNVS_LPSRTCLR);
56  } while (read1 != read2);
57 
58  /* Convert 47-bit counter to 32-bit raw second count */
59  return (u32) (read1 >> CNTR_TO_SECS_SH);
60 }
61 
62 static void rtc_write_sync_lp(void __iomem *ioaddr)
63 {
65  int i;
66 
67  /* Wait for 3 CKIL cycles */
68  for (i = 0; i < 3; i++) {
69  do {
70  count1 = readl(ioaddr + SNVS_LPSRTCLR);
71  count2 = readl(ioaddr + SNVS_LPSRTCLR);
72  } while (count1 != count2);
73 
74  /* Now wait until counter value changes */
75  do {
76  do {
77  count2 = readl(ioaddr + SNVS_LPSRTCLR);
78  count3 = readl(ioaddr + SNVS_LPSRTCLR);
79  } while (count2 != count3);
80  } while (count3 == count1);
81  }
82 }
83 
84 static int snvs_rtc_enable(struct snvs_rtc_data *data, bool enable)
85 {
86  unsigned long flags;
87  int timeout = 1000;
88  u32 lpcr;
89 
90  spin_lock_irqsave(&data->lock, flags);
91 
92  lpcr = readl(data->ioaddr + SNVS_LPCR);
93  if (enable)
94  lpcr |= SNVS_LPCR_SRTC_ENV;
95  else
96  lpcr &= ~SNVS_LPCR_SRTC_ENV;
97  writel(lpcr, data->ioaddr + SNVS_LPCR);
98 
99  spin_unlock_irqrestore(&data->lock, flags);
100 
101  while (--timeout) {
102  lpcr = readl(data->ioaddr + SNVS_LPCR);
103 
104  if (enable) {
105  if (lpcr & SNVS_LPCR_SRTC_ENV)
106  break;
107  } else {
108  if (!(lpcr & SNVS_LPCR_SRTC_ENV))
109  break;
110  }
111  }
112 
113  if (!timeout)
114  return -ETIMEDOUT;
115 
116  return 0;
117 }
118 
119 static int snvs_rtc_read_time(struct device *dev, struct rtc_time *tm)
120 {
121  struct snvs_rtc_data *data = dev_get_drvdata(dev);
122  unsigned long time = rtc_read_lp_counter(data->ioaddr);
123 
124  rtc_time_to_tm(time, tm);
125 
126  return 0;
127 }
128 
129 static int snvs_rtc_set_time(struct device *dev, struct rtc_time *tm)
130 {
131  struct snvs_rtc_data *data = dev_get_drvdata(dev);
132  unsigned long time;
133 
134  rtc_tm_to_time(tm, &time);
135 
136  /* Disable RTC first */
137  snvs_rtc_enable(data, false);
138 
139  /* Write 32-bit time to 47-bit timer, leaving 15 LSBs blank */
140  writel(time << CNTR_TO_SECS_SH, data->ioaddr + SNVS_LPSRTCLR);
141  writel(time >> (32 - CNTR_TO_SECS_SH), data->ioaddr + SNVS_LPSRTCMR);
142 
143  /* Enable RTC again */
144  snvs_rtc_enable(data, true);
145 
146  return 0;
147 }
148 
149 static int snvs_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
150 {
151  struct snvs_rtc_data *data = dev_get_drvdata(dev);
152  u32 lptar, lpsr;
153 
154  lptar = readl(data->ioaddr + SNVS_LPTAR);
155  rtc_time_to_tm(lptar, &alrm->time);
156 
157  lpsr = readl(data->ioaddr + SNVS_LPSR);
158  alrm->pending = (lpsr & SNVS_LPSR_LPTA) ? 1 : 0;
159 
160  return 0;
161 }
162 
163 static int snvs_rtc_alarm_irq_enable(struct device *dev, unsigned int enable)
164 {
165  struct snvs_rtc_data *data = dev_get_drvdata(dev);
166  u32 lpcr;
167  unsigned long flags;
168 
169  spin_lock_irqsave(&data->lock, flags);
170 
171  lpcr = readl(data->ioaddr + SNVS_LPCR);
172  if (enable)
174  else
176  writel(lpcr, data->ioaddr + SNVS_LPCR);
177 
178  spin_unlock_irqrestore(&data->lock, flags);
179 
180  rtc_write_sync_lp(data->ioaddr);
181 
182  return 0;
183 }
184 
185 static int snvs_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
186 {
187  struct snvs_rtc_data *data = dev_get_drvdata(dev);
188  struct rtc_time *alrm_tm = &alrm->time;
189  unsigned long time;
190  unsigned long flags;
191  u32 lpcr;
192 
193  rtc_tm_to_time(alrm_tm, &time);
194 
195  spin_lock_irqsave(&data->lock, flags);
196 
197  /* Have to clear LPTA_EN before programming new alarm time in LPTAR */
198  lpcr = readl(data->ioaddr + SNVS_LPCR);
199  lpcr &= ~SNVS_LPCR_LPTA_EN;
200  writel(lpcr, data->ioaddr + SNVS_LPCR);
201 
202  spin_unlock_irqrestore(&data->lock, flags);
203 
204  writel(time, data->ioaddr + SNVS_LPTAR);
205 
206  /* Clear alarm interrupt status bit */
208 
209  return snvs_rtc_alarm_irq_enable(dev, alrm->enabled);
210 }
211 
212 static const struct rtc_class_ops snvs_rtc_ops = {
213  .read_time = snvs_rtc_read_time,
214  .set_time = snvs_rtc_set_time,
215  .read_alarm = snvs_rtc_read_alarm,
216  .set_alarm = snvs_rtc_set_alarm,
217  .alarm_irq_enable = snvs_rtc_alarm_irq_enable,
218 };
219 
220 static irqreturn_t snvs_rtc_irq_handler(int irq, void *dev_id)
221 {
222  struct device *dev = dev_id;
223  struct snvs_rtc_data *data = dev_get_drvdata(dev);
224  u32 lpsr;
225  u32 events = 0;
226 
227  lpsr = readl(data->ioaddr + SNVS_LPSR);
228 
229  if (lpsr & SNVS_LPSR_LPTA) {
230  events |= (RTC_AF | RTC_IRQF);
231 
232  /* RTC alarm should be one-shot */
233  snvs_rtc_alarm_irq_enable(dev, 0);
234 
235  rtc_update_irq(data->rtc, 1, events);
236  }
237 
238  /* clear interrupt status */
239  writel(lpsr, data->ioaddr + SNVS_LPSR);
240 
241  return events ? IRQ_HANDLED : IRQ_NONE;
242 }
243 
244 static int __devinit snvs_rtc_probe(struct platform_device *pdev)
245 {
246  struct snvs_rtc_data *data;
247  struct resource *res;
248  int ret;
249 
250  data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
251  if (!data)
252  return -ENOMEM;
253 
254  res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
255  data->ioaddr = devm_request_and_ioremap(&pdev->dev, res);
256  if (!data->ioaddr)
257  return -EADDRNOTAVAIL;
258 
259  data->irq = platform_get_irq(pdev, 0);
260  if (data->irq < 0)
261  return data->irq;
262 
263  platform_set_drvdata(pdev, data);
264 
265  spin_lock_init(&data->lock);
266 
267  /* Initialize glitch detect */
269 
270  /* Clear interrupt status */
271  writel(0xffffffff, data->ioaddr + SNVS_LPSR);
272 
273  /* Enable RTC */
274  snvs_rtc_enable(data, true);
275 
276  device_init_wakeup(&pdev->dev, true);
277 
278  ret = devm_request_irq(&pdev->dev, data->irq, snvs_rtc_irq_handler,
279  IRQF_SHARED, "rtc alarm", &pdev->dev);
280  if (ret) {
281  dev_err(&pdev->dev, "failed to request irq %d: %d\n",
282  data->irq, ret);
283  return ret;
284  }
285 
286  data->rtc = rtc_device_register(pdev->name, &pdev->dev,
287  &snvs_rtc_ops, THIS_MODULE);
288  if (IS_ERR(data->rtc)) {
289  ret = PTR_ERR(data->rtc);
290  dev_err(&pdev->dev, "failed to register rtc: %d\n", ret);
291  return ret;
292  }
293 
294  return 0;
295 }
296 
297 static int __devexit snvs_rtc_remove(struct platform_device *pdev)
298 {
299  struct snvs_rtc_data *data = platform_get_drvdata(pdev);
300 
301  rtc_device_unregister(data->rtc);
302 
303  return 0;
304 }
305 
306 #ifdef CONFIG_PM_SLEEP
307 static int snvs_rtc_suspend(struct device *dev)
308 {
309  struct snvs_rtc_data *data = dev_get_drvdata(dev);
310 
311  if (device_may_wakeup(dev))
312  enable_irq_wake(data->irq);
313 
314  return 0;
315 }
316 
317 static int snvs_rtc_resume(struct device *dev)
318 {
319  struct snvs_rtc_data *data = dev_get_drvdata(dev);
320 
321  if (device_may_wakeup(dev))
322  disable_irq_wake(data->irq);
323 
324  return 0;
325 }
326 #endif
327 
328 static SIMPLE_DEV_PM_OPS(snvs_rtc_pm_ops, snvs_rtc_suspend, snvs_rtc_resume);
329 
330 static const struct of_device_id __devinitconst snvs_dt_ids[] = {
331  { .compatible = "fsl,sec-v4.0-mon-rtc-lp", },
332  { /* sentinel */ }
333 };
334 MODULE_DEVICE_TABLE(of, snvs_dt_ids);
335 
336 static struct platform_driver snvs_rtc_driver = {
337  .driver = {
338  .name = "snvs_rtc",
339  .owner = THIS_MODULE,
340  .pm = &snvs_rtc_pm_ops,
341  .of_match_table = snvs_dt_ids,
342  },
343  .probe = snvs_rtc_probe,
344  .remove = __devexit_p(snvs_rtc_remove),
345 };
346 module_platform_driver(snvs_rtc_driver);
347 
348 MODULE_AUTHOR("Freescale Semiconductor, Inc.");
349 MODULE_DESCRIPTION("Freescale SNVS RTC Driver");
350 MODULE_LICENSE("GPL");