1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
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
55#include <asm/blackfin.h>
56
57#define dev_dbg_stamp(dev) dev_dbg(dev, "%s:%i: here i am\n", __func__, __LINE__)
58
59struct bfin_rtc {
60 struct rtc_device *rtc_dev;
61 struct rtc_time rtc_alarm;
62 u16 rtc_wrote_regs;
63};
64
65
66#define RTC_ISTAT_WRITE_COMPLETE 0x8000
67#define RTC_ISTAT_WRITE_PENDING 0x4000
68#define RTC_ISTAT_ALARM_DAY 0x0040
69#define RTC_ISTAT_24HR 0x0020
70#define RTC_ISTAT_HOUR 0x0010
71#define RTC_ISTAT_MIN 0x0008
72#define RTC_ISTAT_SEC 0x0004
73#define RTC_ISTAT_ALARM 0x0002
74#define RTC_ISTAT_STOPWATCH 0x0001
75
76
77#define DAY_BITS_OFF 17
78#define HOUR_BITS_OFF 12
79#define MIN_BITS_OFF 6
80#define SEC_BITS_OFF 0
81
82
83
84
85static inline u32 rtc_time_to_bfin(unsigned long now)
86{
87 u32 sec = (now % 60);
88 u32 min = (now % (60 * 60)) / 60;
89 u32 hour = (now % (60 * 60 * 24)) / (60 * 60);
90 u32 days = (now / (60 * 60 * 24));
91 return (sec << SEC_BITS_OFF) +
92 (min << MIN_BITS_OFF) +
93 (hour << HOUR_BITS_OFF) +
94 (days << DAY_BITS_OFF);
95}
96static inline unsigned long rtc_bfin_to_time(u32 rtc_bfin)
97{
98 return (((rtc_bfin >> SEC_BITS_OFF) & 0x003F)) +
99 (((rtc_bfin >> MIN_BITS_OFF) & 0x003F) * 60) +
100 (((rtc_bfin >> HOUR_BITS_OFF) & 0x001F) * 60 * 60) +
101 (((rtc_bfin >> DAY_BITS_OFF) & 0x7FFF) * 60 * 60 * 24);
102}
103static inline void rtc_bfin_to_tm(u32 rtc_bfin, struct rtc_time *tm)
104{
105 rtc_time_to_tm(rtc_bfin_to_time(rtc_bfin), tm);
106}
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141static DECLARE_COMPLETION(bfin_write_complete);
142static void bfin_rtc_sync_pending(struct device *dev)
143{
144 dev_dbg_stamp(dev);
145 while (bfin_read_RTC_ISTAT() & RTC_ISTAT_WRITE_PENDING)
146 wait_for_completion_timeout(&bfin_write_complete, HZ * 5);
147 dev_dbg_stamp(dev);
148}
149
150
151
152
153
154
155
156static void bfin_rtc_reset(struct device *dev, u16 rtc_ictl)
157{
158 struct bfin_rtc *rtc = dev_get_drvdata(dev);
159 dev_dbg_stamp(dev);
160 bfin_rtc_sync_pending(dev);
161 bfin_write_RTC_PREN(0x1);
162 bfin_write_RTC_ICTL(rtc_ictl);
163 bfin_write_RTC_ALARM(0);
164 bfin_write_RTC_ISTAT(0xFFFF);
165 rtc->rtc_wrote_regs = 0;
166}
167
168
169
170
171
172
173
174
175
176
177
178
179static irqreturn_t bfin_rtc_interrupt(int irq, void *dev_id)
180{
181 struct device *dev = dev_id;
182 struct bfin_rtc *rtc = dev_get_drvdata(dev);
183 unsigned long events = 0;
184 bool write_complete = false;
185 u16 rtc_istat, rtc_ictl;
186
187 dev_dbg_stamp(dev);
188
189 rtc_istat = bfin_read_RTC_ISTAT();
190 rtc_ictl = bfin_read_RTC_ICTL();
191
192 if (rtc_istat & RTC_ISTAT_WRITE_COMPLETE) {
193 bfin_write_RTC_ISTAT(RTC_ISTAT_WRITE_COMPLETE);
194 write_complete = true;
195 complete(&bfin_write_complete);
196 }
197
198 if (rtc_ictl & (RTC_ISTAT_ALARM | RTC_ISTAT_ALARM_DAY)) {
199 if (rtc_istat & (RTC_ISTAT_ALARM | RTC_ISTAT_ALARM_DAY)) {
200 bfin_write_RTC_ISTAT(RTC_ISTAT_ALARM | RTC_ISTAT_ALARM_DAY);
201 events |= RTC_AF | RTC_IRQF;
202 }
203 }
204
205 if (rtc_ictl & RTC_ISTAT_SEC) {
206 if (rtc_istat & RTC_ISTAT_SEC) {
207 bfin_write_RTC_ISTAT(RTC_ISTAT_SEC);
208 events |= RTC_UF | RTC_IRQF;
209 }
210 }
211
212 if (events)
213 rtc_update_irq(rtc->rtc_dev, 1, events);
214
215 if (write_complete || events)
216 return IRQ_HANDLED;
217 else
218 return IRQ_NONE;
219}
220
221static void bfin_rtc_int_set(u16 rtc_int)
222{
223 bfin_write_RTC_ISTAT(rtc_int);
224 bfin_write_RTC_ICTL(bfin_read_RTC_ICTL() | rtc_int);
225}
226static void bfin_rtc_int_clear(u16 rtc_int)
227{
228 bfin_write_RTC_ICTL(bfin_read_RTC_ICTL() & rtc_int);
229}
230static void bfin_rtc_int_set_alarm(struct bfin_rtc *rtc)
231{
232
233
234
235 bfin_rtc_int_set(rtc->rtc_alarm.tm_yday == -1 ? RTC_ISTAT_ALARM : RTC_ISTAT_ALARM_DAY);
236}
237static int bfin_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
238{
239 struct bfin_rtc *rtc = dev_get_drvdata(dev);
240 int ret = 0;
241
242 dev_dbg_stamp(dev);
243
244 bfin_rtc_sync_pending(dev);
245
246 switch (cmd) {
247 case RTC_UIE_ON:
248 dev_dbg_stamp(dev);
249 bfin_rtc_int_set(RTC_ISTAT_SEC);
250 break;
251 case RTC_UIE_OFF:
252 dev_dbg_stamp(dev);
253 bfin_rtc_int_clear(~RTC_ISTAT_SEC);
254 break;
255
256 case RTC_AIE_ON:
257 dev_dbg_stamp(dev);
258 bfin_rtc_int_set_alarm(rtc);
259 break;
260 case RTC_AIE_OFF:
261 dev_dbg_stamp(dev);
262 bfin_rtc_int_clear(~(RTC_ISTAT_ALARM | RTC_ISTAT_ALARM_DAY));
263 break;
264
265 default:
266 dev_dbg_stamp(dev);
267 ret = -ENOIOCTLCMD;
268 }
269
270 return ret;
271}
272
273static int bfin_rtc_read_time(struct device *dev, struct rtc_time *tm)
274{
275 struct bfin_rtc *rtc = dev_get_drvdata(dev);
276
277 dev_dbg_stamp(dev);
278
279 if (rtc->rtc_wrote_regs & 0x1)
280 bfin_rtc_sync_pending(dev);
281
282 rtc_bfin_to_tm(bfin_read_RTC_STAT(), tm);
283
284 return 0;
285}
286
287static int bfin_rtc_set_time(struct device *dev, struct rtc_time *tm)
288{
289 struct bfin_rtc *rtc = dev_get_drvdata(dev);
290 int ret;
291 unsigned long now;
292
293 dev_dbg_stamp(dev);
294
295 ret = rtc_tm_to_time(tm, &now);
296 if (ret == 0) {
297 if (rtc->rtc_wrote_regs & 0x1)
298 bfin_rtc_sync_pending(dev);
299 bfin_write_RTC_STAT(rtc_time_to_bfin(now));
300 rtc->rtc_wrote_regs = 0x1;
301 }
302
303 return ret;
304}
305
306static int bfin_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
307{
308 struct bfin_rtc *rtc = dev_get_drvdata(dev);
309 dev_dbg_stamp(dev);
310 alrm->time = rtc->rtc_alarm;
311 bfin_rtc_sync_pending(dev);
312 alrm->enabled = !!(bfin_read_RTC_ICTL() & (RTC_ISTAT_ALARM | RTC_ISTAT_ALARM_DAY));
313 return 0;
314}
315
316static int bfin_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
317{
318 struct bfin_rtc *rtc = dev_get_drvdata(dev);
319 unsigned long rtc_alarm;
320
321 dev_dbg_stamp(dev);
322
323 if (rtc_tm_to_time(&alrm->time, &rtc_alarm))
324 return -EINVAL;
325
326 rtc->rtc_alarm = alrm->time;
327
328 bfin_rtc_sync_pending(dev);
329 bfin_write_RTC_ALARM(rtc_time_to_bfin(rtc_alarm));
330 if (alrm->enabled)
331 bfin_rtc_int_set_alarm(rtc);
332
333 return 0;
334}
335
336static int bfin_rtc_proc(struct device *dev, struct seq_file *seq)
337{
338#define yesno(x) ((x) ? "yes" : "no")
339 u16 ictl = bfin_read_RTC_ICTL();
340 dev_dbg_stamp(dev);
341 seq_printf(seq,
342 "alarm_IRQ\t: %s\n"
343 "wkalarm_IRQ\t: %s\n"
344 "seconds_IRQ\t: %s\n",
345 yesno(ictl & RTC_ISTAT_ALARM),
346 yesno(ictl & RTC_ISTAT_ALARM_DAY),
347 yesno(ictl & RTC_ISTAT_SEC));
348 return 0;
349#undef yesno
350}
351
352static struct rtc_class_ops bfin_rtc_ops = {
353 .ioctl = bfin_rtc_ioctl,
354 .read_time = bfin_rtc_read_time,
355 .set_time = bfin_rtc_set_time,
356 .read_alarm = bfin_rtc_read_alarm,
357 .set_alarm = bfin_rtc_set_alarm,
358 .proc = bfin_rtc_proc,
359};
360
361static int __devinit bfin_rtc_probe(struct platform_device *pdev)
362{
363 struct bfin_rtc *rtc;
364 struct device *dev = &pdev->dev;
365 int ret = 0;
366 unsigned long timeout;
367
368 dev_dbg_stamp(dev);
369
370
371 rtc = kzalloc(sizeof(*rtc), GFP_KERNEL);
372 if (unlikely(!rtc))
373 return -ENOMEM;
374 platform_set_drvdata(pdev, rtc);
375 device_init_wakeup(dev, 1);
376
377
378 ret = request_irq(IRQ_RTC, bfin_rtc_interrupt, IRQF_SHARED, pdev->name, dev);
379 if (unlikely(ret))
380 goto err;
381
382
383
384 timeout = jiffies + HZ;
385 while (bfin_read_RTC_ISTAT() & RTC_ISTAT_WRITE_PENDING)
386 if (time_after(jiffies, timeout))
387 break;
388 bfin_rtc_reset(dev, RTC_ISTAT_WRITE_COMPLETE);
389 bfin_write_RTC_SWCNT(0);
390
391
392 rtc->rtc_dev = rtc_device_register(pdev->name, dev, &bfin_rtc_ops, THIS_MODULE);
393 if (unlikely(IS_ERR(rtc->rtc_dev))) {
394 ret = PTR_ERR(rtc->rtc_dev);
395 goto err_irq;
396 }
397
398 return 0;
399
400 err_irq:
401 free_irq(IRQ_RTC, dev);
402 err:
403 kfree(rtc);
404 return ret;
405}
406
407static int __devexit bfin_rtc_remove(struct platform_device *pdev)
408{
409 struct bfin_rtc *rtc = platform_get_drvdata(pdev);
410 struct device *dev = &pdev->dev;
411
412 bfin_rtc_reset(dev, 0);
413 free_irq(IRQ_RTC, dev);
414 rtc_device_unregister(rtc->rtc_dev);
415 platform_set_drvdata(pdev, NULL);
416 kfree(rtc);
417
418 return 0;
419}
420
421#ifdef CONFIG_PM
422static int bfin_rtc_suspend(struct platform_device *pdev, pm_message_t state)
423{
424 if (device_may_wakeup(&pdev->dev)) {
425 enable_irq_wake(IRQ_RTC);
426 bfin_rtc_sync_pending(&pdev->dev);
427 } else
428 bfin_rtc_int_clear(-1);
429
430 return 0;
431}
432
433static int bfin_rtc_resume(struct platform_device *pdev)
434{
435 if (device_may_wakeup(&pdev->dev))
436 disable_irq_wake(IRQ_RTC);
437 else
438 bfin_write_RTC_ISTAT(-1);
439
440 return 0;
441}
442#else
443# define bfin_rtc_suspend NULL
444# define bfin_rtc_resume NULL
445#endif
446
447static struct platform_driver bfin_rtc_driver = {
448 .driver = {
449 .name = "rtc-bfin",
450 .owner = THIS_MODULE,
451 },
452 .probe = bfin_rtc_probe,
453 .remove = __devexit_p(bfin_rtc_remove),
454 .suspend = bfin_rtc_suspend,
455 .resume = bfin_rtc_resume,
456};
457
458static int __init bfin_rtc_init(void)
459{
460 return platform_driver_register(&bfin_rtc_driver);
461}
462
463static void __exit bfin_rtc_exit(void)
464{
465 platform_driver_unregister(&bfin_rtc_driver);
466}
467
468module_init(bfin_rtc_init);
469module_exit(bfin_rtc_exit);
470
471MODULE_DESCRIPTION("Blackfin On-Chip Real Time Clock Driver");
472MODULE_AUTHOR("Mike Frysinger <vapier@gentoo.org>");
473MODULE_LICENSE("GPL");
474MODULE_ALIAS("platform:rtc-bfin");
475