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#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
60struct bfin_rtc {
61 struct rtc_device *rtc_dev;
62 struct rtc_time rtc_alarm;
63 u16 rtc_wrote_regs;
64};
65
66
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
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
84
85
86static 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}
97static 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}
104static 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
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
141
142static DECLARE_COMPLETION(bfin_write_complete);
143static void bfin_rtc_sync_pending(struct device *dev)
144{
145 dev_dbg_stamp(dev);
146 while (bfin_read_RTC_ISTAT() & RTC_ISTAT_WRITE_PENDING)
147 wait_for_completion_timeout(&bfin_write_complete, HZ * 5);
148 dev_dbg_stamp(dev);
149}
150
151
152
153
154
155
156
157static 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);
164 bfin_write_RTC_ALARM(0);
165 bfin_write_RTC_ISTAT(0xFFFF);
166 rtc->rtc_wrote_regs = 0;
167}
168
169
170
171
172
173
174
175
176
177
178
179
180static 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
194 bits = RTC_ISTAT_WRITE_COMPLETE;
195 if (rtc_istat & bits) {
196 rtc_istat_clear |= bits;
197 write_complete = true;
198 complete(&bfin_write_complete);
199 }
200
201 bits = (RTC_ISTAT_ALARM | RTC_ISTAT_ALARM_DAY);
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
227static void bfin_rtc_int_set(u16 rtc_int)
228{
229 bfin_write_RTC_ISTAT(rtc_int);
230 bfin_write_RTC_ICTL(bfin_read_RTC_ICTL() | rtc_int);
231}
232static void bfin_rtc_int_clear(u16 rtc_int)
233{
234 bfin_write_RTC_ICTL(bfin_read_RTC_ICTL() & rtc_int);
235}
236static void bfin_rtc_int_set_alarm(struct bfin_rtc *rtc)
237{
238
239
240
241 bfin_rtc_int_set(rtc->rtc_alarm.tm_yday == -1 ? RTC_ISTAT_ALARM : RTC_ISTAT_ALARM_DAY);
242}
243
244static 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
257static 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
271static 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
290static 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);
296 alrm->enabled = !!(bfin_read_RTC_ICTL() & (RTC_ISTAT_ALARM | RTC_ISTAT_ALARM_DAY));
297 return 0;
298}
299
300static 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
320static int bfin_rtc_proc(struct device *dev, struct seq_file *seq)
321{
322#define yesno(x) ((x) ? "yes" : "no")
323 u16 ictl = bfin_read_RTC_ICTL();
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
336static 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
345static int bfin_rtc_probe(struct platform_device *pdev)
346{
347 struct bfin_rtc *rtc;
348 struct device *dev = &pdev->dev;
349 int ret;
350 unsigned long timeout = jiffies + HZ;
351
352 dev_dbg_stamp(dev);
353
354
355 rtc = devm_kzalloc(dev, 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
362 rtc->rtc_dev = devm_rtc_device_register(dev, pdev->name, &bfin_rtc_ops,
363 THIS_MODULE);
364 if (IS_ERR(rtc->rtc_dev))
365 return PTR_ERR(rtc->rtc_dev);
366
367
368 ret = devm_request_irq(dev, IRQ_RTC, bfin_rtc_interrupt, 0,
369 pdev->name, dev);
370 if (unlikely(ret))
371 dev_err(&pdev->dev,
372 "unable to request IRQ; alarm won't work, "
373 "and writes will be delayed\n");
374
375
376
377
378 while (bfin_read_RTC_ISTAT() & RTC_ISTAT_WRITE_PENDING)
379 if (time_after(jiffies, timeout))
380 break;
381 bfin_rtc_reset(dev, RTC_ISTAT_WRITE_COMPLETE);
382 bfin_write_RTC_SWCNT(0);
383
384 return 0;
385}
386
387static int bfin_rtc_remove(struct platform_device *pdev)
388{
389 struct device *dev = &pdev->dev;
390
391 bfin_rtc_reset(dev, 0);
392
393 return 0;
394}
395
396#ifdef CONFIG_PM_SLEEP
397static int bfin_rtc_suspend(struct device *dev)
398{
399 dev_dbg_stamp(dev);
400
401 if (device_may_wakeup(dev)) {
402 enable_irq_wake(IRQ_RTC);
403 bfin_rtc_sync_pending(dev);
404 } else
405 bfin_rtc_int_clear(0);
406
407 return 0;
408}
409
410static int bfin_rtc_resume(struct device *dev)
411{
412 dev_dbg_stamp(dev);
413
414 if (device_may_wakeup(dev))
415 disable_irq_wake(IRQ_RTC);
416
417
418
419
420
421
422
423
424 while (!(bfin_read_RTC_ISTAT() & RTC_ISTAT_SEC))
425 continue;
426 bfin_rtc_int_set(RTC_ISTAT_WRITE_COMPLETE);
427
428 return 0;
429}
430#endif
431
432static SIMPLE_DEV_PM_OPS(bfin_rtc_pm_ops, bfin_rtc_suspend, bfin_rtc_resume);
433
434static struct platform_driver bfin_rtc_driver = {
435 .driver = {
436 .name = "rtc-bfin",
437 .pm = &bfin_rtc_pm_ops,
438 },
439 .probe = bfin_rtc_probe,
440 .remove = bfin_rtc_remove,
441};
442
443module_platform_driver(bfin_rtc_driver);
444
445MODULE_DESCRIPTION("Blackfin On-Chip Real Time Clock Driver");
446MODULE_AUTHOR("Mike Frysinger <vapier@gentoo.org>");
447MODULE_LICENSE("GPL");
448MODULE_ALIAS("platform:rtc-bfin");
449