diff options
author | Arnd Bergmann <arnd@arndb.de> | 2018-03-09 12:15:27 -0500 |
---|---|---|
committer | Arnd Bergmann <arnd@arndb.de> | 2018-03-26 09:56:31 -0400 |
commit | 111f750389e0862ad01080fa39e84beb94cbfc8f (patch) | |
tree | 00117788a0ee3786b4e19eb1a64c99160cc5e457 | |
parent | fca94ec61363b0d9839e45ebab14d6e257c4f34b (diff) |
rtc: remove bfin driver
The blackfin architecture is getting removed, so this one is
now obsolete.
Acked-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
Acked-by: Aaron Wu <aaron.wu@analog.com>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
-rw-r--r-- | drivers/rtc/Kconfig | 10 | ||||
-rw-r--r-- | drivers/rtc/Makefile | 1 | ||||
-rw-r--r-- | drivers/rtc/rtc-bfin.c | 448 |
3 files changed, 0 insertions, 459 deletions
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 9664852afc49..319e3c8976d5 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig | |||
@@ -1434,16 +1434,6 @@ config RTC_DRV_AU1XXX | |||
1434 | This driver can also be built as a module. If so, the module | 1434 | This driver can also be built as a module. If so, the module |
1435 | will be called rtc-au1xxx. | 1435 | will be called rtc-au1xxx. |
1436 | 1436 | ||
1437 | config RTC_DRV_BFIN | ||
1438 | tristate "Blackfin On-Chip RTC" | ||
1439 | depends on BLACKFIN && !BF561 | ||
1440 | help | ||
1441 | If you say yes here you will get support for the | ||
1442 | Blackfin On-Chip Real Time Clock. | ||
1443 | |||
1444 | This driver can also be built as a module. If so, the module | ||
1445 | will be called rtc-bfin. | ||
1446 | |||
1447 | config RTC_DRV_RS5C313 | 1437 | config RTC_DRV_RS5C313 |
1448 | tristate "Ricoh RS5C313" | 1438 | tristate "Ricoh RS5C313" |
1449 | depends on SH_LANDISK | 1439 | depends on SH_LANDISK |
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 24f0d4247532..ee0206becd9f 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile | |||
@@ -36,7 +36,6 @@ obj-$(CONFIG_RTC_DRV_ASM9260) += rtc-asm9260.o | |||
36 | obj-$(CONFIG_RTC_DRV_AT91RM9200)+= rtc-at91rm9200.o | 36 | obj-$(CONFIG_RTC_DRV_AT91RM9200)+= rtc-at91rm9200.o |
37 | obj-$(CONFIG_RTC_DRV_AT91SAM9) += rtc-at91sam9.o | 37 | obj-$(CONFIG_RTC_DRV_AT91SAM9) += rtc-at91sam9.o |
38 | obj-$(CONFIG_RTC_DRV_AU1XXX) += rtc-au1xxx.o | 38 | obj-$(CONFIG_RTC_DRV_AU1XXX) += rtc-au1xxx.o |
39 | obj-$(CONFIG_RTC_DRV_BFIN) += rtc-bfin.o | ||
40 | obj-$(CONFIG_RTC_DRV_BRCMSTB) += rtc-brcmstb-waketimer.o | 39 | obj-$(CONFIG_RTC_DRV_BRCMSTB) += rtc-brcmstb-waketimer.o |
41 | obj-$(CONFIG_RTC_DRV_BQ32K) += rtc-bq32k.o | 40 | obj-$(CONFIG_RTC_DRV_BQ32K) += rtc-bq32k.o |
42 | obj-$(CONFIG_RTC_DRV_BQ4802) += rtc-bq4802.o | 41 | obj-$(CONFIG_RTC_DRV_BQ4802) += rtc-bq4802.o |
diff --git a/drivers/rtc/rtc-bfin.c b/drivers/rtc/rtc-bfin.c deleted file mode 100644 index 15344b7c07c5..000000000000 --- a/drivers/rtc/rtc-bfin.c +++ /dev/null | |||
@@ -1,448 +0,0 @@ | |||
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 { | ||
61 | struct rtc_device *rtc_dev; | ||
62 | struct rtc_time rtc_alarm; | ||
63 | u16 rtc_wrote_regs; | ||
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 | |||
109 | /** | ||
110 | * bfin_rtc_sync_pending - make sure pending writes have complete | ||
111 | * | ||
112 | * Wait for the previous write to a RTC register to complete. | ||
113 | * Unfortunately, we can't sleep here as that introduces a race condition when | ||
114 | * turning on interrupt events. Consider this: | ||
115 | * - process sets alarm | ||
116 | * - process enables alarm | ||
117 | * - process sleeps while waiting for rtc write to sync | ||
118 | * - interrupt fires while process is sleeping | ||
119 | * - interrupt acks the event by writing to ISTAT | ||
120 | * - interrupt sets the WRITE PENDING bit | ||
121 | * - interrupt handler finishes | ||
122 | * - process wakes up, sees WRITE PENDING bit set, goes to sleep | ||
123 | * - interrupt fires while process is sleeping | ||
124 | * If anyone can point out the obvious solution here, i'm listening :). This | ||
125 | * shouldn't be an issue on an SMP or preempt system as this function should | ||
126 | * only be called with the rtc lock held. | ||
127 | * | ||
128 | * Other options: | ||
129 | * - disable PREN so the sync happens at 32.768kHZ ... but this changes the | ||
130 | * inc rate for all RTC registers from 1HZ to 32.768kHZ ... | ||
131 | * - use the write complete IRQ | ||
132 | */ | ||
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); | ||
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 | * bfin_rtc_reset - set RTC to sane/known state | ||
153 | * | ||
154 | * Initialize the RTC. Enable pre-scaler to scale RTC clock | ||
155 | * to 1Hz and clear interrupt/status registers. | ||
156 | */ | ||
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); | ||
164 | bfin_write_RTC_ALARM(0); | ||
165 | bfin_write_RTC_ISTAT(0xFFFF); | ||
166 | rtc->rtc_wrote_regs = 0; | ||
167 | } | ||
168 | |||
169 | /** | ||
170 | * bfin_rtc_interrupt - handle interrupt from RTC | ||
171 | * | ||
172 | * Since we handle all RTC events here, we have to make sure the requested | ||
173 | * interrupt is enabled (in RTC_ICTL) as the event status register (RTC_ISTAT) | ||
174 | * always gets updated regardless of the interrupt being enabled. So when one | ||
175 | * even we care about (e.g. stopwatch) goes off, we don't want to turn around | ||
176 | * and say that other events have happened as well (e.g. second). We do not | ||
177 | * have to worry about pending writes to the RTC_ICTL register as interrupts | ||
178 | * only fire if they are enabled in the RTC_ICTL register. | ||
179 | */ | ||
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 | |||
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 | |||
227 | static 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 | } | ||
232 | static void bfin_rtc_int_clear(u16 rtc_int) | ||
233 | { | ||
234 | bfin_write_RTC_ICTL(bfin_read_RTC_ICTL() & rtc_int); | ||
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); | ||
296 | alrm->enabled = !!(bfin_read_RTC_ICTL() & (RTC_ISTAT_ALARM | RTC_ISTAT_ALARM_DAY)); | ||
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") | ||
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 | |||
336 | static const 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 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 | /* Allocate memory for our RTC struct */ | ||
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 | /* Register our RTC with the RTC framework */ | ||
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 | /* Grab the IRQ and init the hardware */ | ||
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 | /* sometimes the bootloader touched things, but the write complete was not | ||
376 | * enabled, so let's just do a quick timeout here since the IRQ will not fire ... | ||
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 | |||
387 | static 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 | ||
397 | static 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 | |||
410 | static 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 | * Since only some of the RTC bits are maintained externally in the | ||
419 | * Vbat domain, we need to wait for the RTC MMRs to be synced into | ||
420 | * the core after waking up. This happens every RTC 1HZ. Once that | ||
421 | * has happened, we can go ahead and re-enable the important write | ||
422 | * complete interrupt event. | ||
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 | |||
432 | static SIMPLE_DEV_PM_OPS(bfin_rtc_pm_ops, bfin_rtc_suspend, bfin_rtc_resume); | ||
433 | |||
434 | static 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 | |||
443 | module_platform_driver(bfin_rtc_driver); | ||
444 | |||
445 | MODULE_DESCRIPTION("Blackfin On-Chip Real Time Clock Driver"); | ||
446 | MODULE_AUTHOR("Mike Frysinger <vapier@gentoo.org>"); | ||
447 | MODULE_LICENSE("GPL"); | ||
448 | MODULE_ALIAS("platform:rtc-bfin"); | ||