Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
rtc-bfin.c
Go to the documentation of this file.
1 /*
2  * Blackfin On-Chip Real Time Clock Driver
3  * Supports BF51x/BF52x/BF53[123]/BF53[467]/BF54x
4  *
5  * Copyright 2004-2010 Analog Devices Inc.
6  *
7  * Enter bugs at http://blackfin.uclinux.org/
8  *
9  * Licensed under the GPL-2 or later.
10  */
11 
12 /* The biggest issue we deal with in this driver is that register writes are
13  * synced to the RTC frequency of 1Hz. So if you write to a register and
14  * attempt to write again before the first write has completed, the new write
15  * is simply discarded. This can easily be troublesome if userspace disables
16  * one event (say periodic) and then right after enables an event (say alarm).
17  * Since all events are maintained in the same interrupt mask register, if
18  * we wrote to it to disable the first event and then wrote to it again to
19  * enable the second event, that second event would not be enabled as the
20  * write would be discarded and things quickly fall apart.
21  *
22  * To keep this delay from significantly degrading performance (we, in theory,
23  * would have to sleep for up to 1 second every time we wanted to write a
24  * register), we only check the write pending status before we start to issue
25  * a new write. We bank on the idea that it doesn't matter when the sync
26  * happens so long as we don't attempt another write before it does. The only
27  * time userspace would take this penalty is when they try and do multiple
28  * operations right after another ... but in this case, they need to take the
29  * sync penalty, so we should be OK.
30  *
31  * Also note that the RTC_ISTAT register does not suffer this penalty; its
32  * writes to clear status registers complete immediately.
33  */
34 
35 /* It may seem odd that there is no SWCNT code in here (which would be exposed
36  * via the periodic interrupt event, or PIE). Since the Blackfin RTC peripheral
37  * runs in units of seconds (N/HZ) but the Linux framework runs in units of HZ
38  * (2^N HZ), there is no point in keeping code that only provides 1 HZ PIEs.
39  * The same exact behavior can be accomplished by using the update interrupt
40  * event (UIE). Maybe down the line the RTC peripheral will suck less in which
41  * case we can re-introduce PIE support.
42  */
43 
44 #include <linux/bcd.h>
45 #include <linux/completion.h>
46 #include <linux/delay.h>
47 #include <linux/init.h>
48 #include <linux/interrupt.h>
49 #include <linux/kernel.h>
50 #include <linux/module.h>
51 #include <linux/platform_device.h>
52 #include <linux/rtc.h>
53 #include <linux/seq_file.h>
54 #include <linux/slab.h>
55 
56 #include <asm/blackfin.h>
57 
58 #define dev_dbg_stamp(dev) dev_dbg(dev, "%s:%i: here i am\n", __func__, __LINE__)
59 
60 struct bfin_rtc {
64 };
65 
66 /* Bit values for the ISTAT / ICTL registers */
67 #define RTC_ISTAT_WRITE_COMPLETE 0x8000
68 #define RTC_ISTAT_WRITE_PENDING 0x4000
69 #define RTC_ISTAT_ALARM_DAY 0x0040
70 #define RTC_ISTAT_24HR 0x0020
71 #define RTC_ISTAT_HOUR 0x0010
72 #define RTC_ISTAT_MIN 0x0008
73 #define RTC_ISTAT_SEC 0x0004
74 #define RTC_ISTAT_ALARM 0x0002
75 #define RTC_ISTAT_STOPWATCH 0x0001
76 
77 /* Shift values for RTC_STAT register */
78 #define DAY_BITS_OFF 17
79 #define HOUR_BITS_OFF 12
80 #define MIN_BITS_OFF 6
81 #define SEC_BITS_OFF 0
82 
83 /* Some helper functions to convert between the common RTC notion of time
84  * and the internal Blackfin notion that is encoded in 32bits.
85  */
86 static inline u32 rtc_time_to_bfin(unsigned long now)
87 {
88  u32 sec = (now % 60);
89  u32 min = (now % (60 * 60)) / 60;
90  u32 hour = (now % (60 * 60 * 24)) / (60 * 60);
91  u32 days = (now / (60 * 60 * 24));
92  return (sec << SEC_BITS_OFF) +
93  (min << MIN_BITS_OFF) +
94  (hour << HOUR_BITS_OFF) +
95  (days << DAY_BITS_OFF);
96 }
97 static inline unsigned long rtc_bfin_to_time(u32 rtc_bfin)
98 {
99  return (((rtc_bfin >> SEC_BITS_OFF) & 0x003F)) +
100  (((rtc_bfin >> MIN_BITS_OFF) & 0x003F) * 60) +
101  (((rtc_bfin >> HOUR_BITS_OFF) & 0x001F) * 60 * 60) +
102  (((rtc_bfin >> DAY_BITS_OFF) & 0x7FFF) * 60 * 60 * 24);
103 }
104 static inline void rtc_bfin_to_tm(u32 rtc_bfin, struct rtc_time *tm)
105 {
106  rtc_time_to_tm(rtc_bfin_to_time(rtc_bfin), tm);
107 }
108 
133 /*
134 static void bfin_rtc_sync_pending_polled(void)
135 {
136  while (!(bfin_read_RTC_ISTAT() & RTC_ISTAT_WRITE_COMPLETE))
137  if (!(bfin_read_RTC_ISTAT() & RTC_ISTAT_WRITE_PENDING))
138  break;
139  bfin_write_RTC_ISTAT(RTC_ISTAT_WRITE_COMPLETE);
140 }
141 */
142 static DECLARE_COMPLETION(bfin_write_complete);
143 static void bfin_rtc_sync_pending(struct device *dev)
144 {
145  dev_dbg_stamp(dev);
147  wait_for_completion_timeout(&bfin_write_complete, HZ * 5);
148  dev_dbg_stamp(dev);
149 }
150 
157 static void bfin_rtc_reset(struct device *dev, u16 rtc_ictl)
158 {
159  struct bfin_rtc *rtc = dev_get_drvdata(dev);
160  dev_dbg_stamp(dev);
161  bfin_rtc_sync_pending(dev);
162  bfin_write_RTC_PREN(0x1);
163  bfin_write_RTC_ICTL(rtc_ictl);
165  bfin_write_RTC_ISTAT(0xFFFF);
166  rtc->rtc_wrote_regs = 0;
167 }
168 
180 static irqreturn_t bfin_rtc_interrupt(int irq, void *dev_id)
181 {
182  struct device *dev = dev_id;
183  struct bfin_rtc *rtc = dev_get_drvdata(dev);
184  unsigned long events = 0;
185  bool write_complete = false;
186  u16 rtc_istat, rtc_istat_clear, rtc_ictl, bits;
187 
188  dev_dbg_stamp(dev);
189 
190  rtc_istat = bfin_read_RTC_ISTAT();
191  rtc_ictl = bfin_read_RTC_ICTL();
192  rtc_istat_clear = 0;
193 
195  if (rtc_istat & bits) {
196  rtc_istat_clear |= bits;
197  write_complete = true;
198  complete(&bfin_write_complete);
199  }
200 
202  if (rtc_ictl & bits) {
203  if (rtc_istat & bits) {
204  rtc_istat_clear |= bits;
205  events |= RTC_AF | RTC_IRQF;
206  }
207  }
208 
209  bits = RTC_ISTAT_SEC;
210  if (rtc_ictl & bits) {
211  if (rtc_istat & bits) {
212  rtc_istat_clear |= bits;
213  events |= RTC_UF | RTC_IRQF;
214  }
215  }
216 
217  if (events)
218  rtc_update_irq(rtc->rtc_dev, 1, events);
219 
220  if (write_complete || events) {
221  bfin_write_RTC_ISTAT(rtc_istat_clear);
222  return IRQ_HANDLED;
223  } else
224  return IRQ_NONE;
225 }
226 
227 static void bfin_rtc_int_set(u16 rtc_int)
228 {
229  bfin_write_RTC_ISTAT(rtc_int);
231 }
232 static void bfin_rtc_int_clear(u16 rtc_int)
233 {
235 }
236 static void bfin_rtc_int_set_alarm(struct bfin_rtc *rtc)
237 {
238  /* Blackfin has different bits for whether the alarm is
239  * more than 24 hours away.
240  */
241  bfin_rtc_int_set(rtc->rtc_alarm.tm_yday == -1 ? RTC_ISTAT_ALARM : RTC_ISTAT_ALARM_DAY);
242 }
243 
244 static int bfin_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
245 {
246  struct bfin_rtc *rtc = dev_get_drvdata(dev);
247 
248  dev_dbg_stamp(dev);
249  if (enabled)
250  bfin_rtc_int_set_alarm(rtc);
251  else
252  bfin_rtc_int_clear(~(RTC_ISTAT_ALARM | RTC_ISTAT_ALARM_DAY));
253 
254  return 0;
255 }
256 
257 static int bfin_rtc_read_time(struct device *dev, struct rtc_time *tm)
258 {
259  struct bfin_rtc *rtc = dev_get_drvdata(dev);
260 
261  dev_dbg_stamp(dev);
262 
263  if (rtc->rtc_wrote_regs & 0x1)
264  bfin_rtc_sync_pending(dev);
265 
266  rtc_bfin_to_tm(bfin_read_RTC_STAT(), tm);
267 
268  return 0;
269 }
270 
271 static int bfin_rtc_set_time(struct device *dev, struct rtc_time *tm)
272 {
273  struct bfin_rtc *rtc = dev_get_drvdata(dev);
274  int ret;
275  unsigned long now;
276 
277  dev_dbg_stamp(dev);
278 
279  ret = rtc_tm_to_time(tm, &now);
280  if (ret == 0) {
281  if (rtc->rtc_wrote_regs & 0x1)
282  bfin_rtc_sync_pending(dev);
283  bfin_write_RTC_STAT(rtc_time_to_bfin(now));
284  rtc->rtc_wrote_regs = 0x1;
285  }
286 
287  return ret;
288 }
289 
290 static int bfin_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
291 {
292  struct bfin_rtc *rtc = dev_get_drvdata(dev);
293  dev_dbg_stamp(dev);
294  alrm->time = rtc->rtc_alarm;
295  bfin_rtc_sync_pending(dev);
297  return 0;
298 }
299 
300 static int bfin_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
301 {
302  struct bfin_rtc *rtc = dev_get_drvdata(dev);
303  unsigned long rtc_alarm;
304 
305  dev_dbg_stamp(dev);
306 
307  if (rtc_tm_to_time(&alrm->time, &rtc_alarm))
308  return -EINVAL;
309 
310  rtc->rtc_alarm = alrm->time;
311 
312  bfin_rtc_sync_pending(dev);
313  bfin_write_RTC_ALARM(rtc_time_to_bfin(rtc_alarm));
314  if (alrm->enabled)
315  bfin_rtc_int_set_alarm(rtc);
316 
317  return 0;
318 }
319 
320 static int bfin_rtc_proc(struct device *dev, struct seq_file *seq)
321 {
322 #define yesno(x) ((x) ? "yes" : "no")
324  dev_dbg_stamp(dev);
325  seq_printf(seq,
326  "alarm_IRQ\t: %s\n"
327  "wkalarm_IRQ\t: %s\n"
328  "seconds_IRQ\t: %s\n",
329  yesno(ictl & RTC_ISTAT_ALARM),
330  yesno(ictl & RTC_ISTAT_ALARM_DAY),
331  yesno(ictl & RTC_ISTAT_SEC));
332  return 0;
333 #undef yesno
334 }
335 
336 static struct rtc_class_ops bfin_rtc_ops = {
337  .read_time = bfin_rtc_read_time,
338  .set_time = bfin_rtc_set_time,
339  .read_alarm = bfin_rtc_read_alarm,
340  .set_alarm = bfin_rtc_set_alarm,
341  .proc = bfin_rtc_proc,
342  .alarm_irq_enable = bfin_rtc_alarm_irq_enable,
343 };
344 
345 static int __devinit bfin_rtc_probe(struct platform_device *pdev)
346 {
347  struct bfin_rtc *rtc;
348  struct device *dev = &pdev->dev;
349  int ret = 0;
350  unsigned long timeout = jiffies + HZ;
351 
352  dev_dbg_stamp(dev);
353 
354  /* Allocate memory for our RTC struct */
355  rtc = kzalloc(sizeof(*rtc), GFP_KERNEL);
356  if (unlikely(!rtc))
357  return -ENOMEM;
358  platform_set_drvdata(pdev, rtc);
359  device_init_wakeup(dev, 1);
360 
361  /* Register our RTC with the RTC framework */
362  rtc->rtc_dev = rtc_device_register(pdev->name, dev, &bfin_rtc_ops,
363  THIS_MODULE);
364  if (unlikely(IS_ERR(rtc->rtc_dev))) {
365  ret = PTR_ERR(rtc->rtc_dev);
366  goto err;
367  }
368 
369  /* Grab the IRQ and init the hardware */
370  ret = request_irq(IRQ_RTC, bfin_rtc_interrupt, 0, pdev->name, dev);
371  if (unlikely(ret))
372  goto err_reg;
373  /* sometimes the bootloader touched things, but the write complete was not
374  * enabled, so let's just do a quick timeout here since the IRQ will not fire ...
375  */
377  if (time_after(jiffies, timeout))
378  break;
379  bfin_rtc_reset(dev, RTC_ISTAT_WRITE_COMPLETE);
381 
382  return 0;
383 
384 err_reg:
386 err:
387  kfree(rtc);
388  return ret;
389 }
390 
391 static int __devexit bfin_rtc_remove(struct platform_device *pdev)
392 {
393  struct bfin_rtc *rtc = platform_get_drvdata(pdev);
394  struct device *dev = &pdev->dev;
395 
396  bfin_rtc_reset(dev, 0);
397  free_irq(IRQ_RTC, dev);
399  platform_set_drvdata(pdev, NULL);
400  kfree(rtc);
401 
402  return 0;
403 }
404 
405 #ifdef CONFIG_PM
406 static int bfin_rtc_suspend(struct platform_device *pdev, pm_message_t state)
407 {
408  struct device *dev = &pdev->dev;
409 
410  dev_dbg_stamp(dev);
411 
412  if (device_may_wakeup(dev)) {
413  enable_irq_wake(IRQ_RTC);
414  bfin_rtc_sync_pending(dev);
415  } else
416  bfin_rtc_int_clear(0);
417 
418  return 0;
419 }
420 
421 static int bfin_rtc_resume(struct platform_device *pdev)
422 {
423  struct device *dev = &pdev->dev;
424 
425  dev_dbg_stamp(dev);
426 
427  if (device_may_wakeup(dev))
428  disable_irq_wake(IRQ_RTC);
429 
430  /*
431  * Since only some of the RTC bits are maintained externally in the
432  * Vbat domain, we need to wait for the RTC MMRs to be synced into
433  * the core after waking up. This happens every RTC 1HZ. Once that
434  * has happened, we can go ahead and re-enable the important write
435  * complete interrupt event.
436  */
437  while (!(bfin_read_RTC_ISTAT() & RTC_ISTAT_SEC))
438  continue;
439  bfin_rtc_int_set(RTC_ISTAT_WRITE_COMPLETE);
440 
441  return 0;
442 }
443 #else
444 # define bfin_rtc_suspend NULL
445 # define bfin_rtc_resume NULL
446 #endif
447 
448 static struct platform_driver bfin_rtc_driver = {
449  .driver = {
450  .name = "rtc-bfin",
451  .owner = THIS_MODULE,
452  },
453  .probe = bfin_rtc_probe,
454  .remove = __devexit_p(bfin_rtc_remove),
455  .suspend = bfin_rtc_suspend,
456  .resume = bfin_rtc_resume,
457 };
458 
459 module_platform_driver(bfin_rtc_driver);
460 
461 MODULE_DESCRIPTION("Blackfin On-Chip Real Time Clock Driver");
462 MODULE_AUTHOR("Mike Frysinger <[email protected]>");
463 MODULE_LICENSE("GPL");
464 MODULE_ALIAS("platform:rtc-bfin");