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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
|
diff -Nur linux-2.6.24.vanilla/drivers/rtc/rtc-sa1100.c linux-2.6.24_rtc/drivers/rtc/rtc-sa1100.c
--- linux-2.6.24.vanilla/drivers/rtc/rtc-sa1100.c 2008-01-24 23:58:37.000000000 +0100
+++ linux-2.6.24_rtc/drivers/rtc/rtc-sa1100.c 2008-03-24 13:49:40.000000000 +0100
@@ -79,7 +79,10 @@
rtsr = RTSR;
/* clear interrupt sources */
- RTSR = 0;
+ RTSR &= ~RTSR_HZE; //RTSR = 0; is not possible and does not work
+ RTSR &= ~RTSR_HZ;
+ RTSR &= ~RTSR_ALE;
+ RTSR &= ~RTSR_AL;
RTSR = (RTSR_AL | RTSR_HZ) & (rtsr >> 2);
/* clear alarm interrupt if it has occurred */
@@ -155,6 +158,20 @@
{
int ret;
+ /*
+ * On some devices RTSR is set to some value but it must be set to 0.
+ * We have to set RTSR to 0 and OIER/OSSR to default. This should not be
+ * necessary here but it is.
+ */
+ spin_lock_irq(&sa1100_rtc_lock);
+ RTSR &= ~RTSR_HZE;
+ RTSR &= ~RTSR_HZ;
+ RTSR &= ~RTSR_ALE;
+ RTSR &= ~RTSR_AL;
+ OIER &= ~OIER_E1;
+ OSSR = OSSR_M1;
+ spin_unlock_irq(&sa1100_rtc_lock);
+
ret = request_irq(IRQ_RTC1Hz, sa1100_rtc_interrupt, IRQF_DISABLED,
"rtc 1Hz", dev);
if (ret) {
@@ -186,7 +203,10 @@
static void sa1100_rtc_release(struct device *dev)
{
spin_lock_irq(&sa1100_rtc_lock);
- RTSR = 0;
+ RTSR &= ~RTSR_HZE; //RTSR = 0; is not possible and does not work
+ RTSR &= ~RTSR_HZ;
+ RTSR &= ~RTSR_ALE;
+ RTSR &= ~RTSR_AL;
OIER &= ~OIER_E1;
OSSR = OSSR_M1;
spin_unlock_irq(&sa1100_rtc_lock);
@@ -339,6 +359,19 @@
platform_set_drvdata(pdev, rtc);
+ /*
+ * On some devices RTSR is set to some value but it must be set to 0.
+ * We have to set RTSR to 0 and OIER/OSSR to default.
+ */
+ spin_lock_irq(&sa1100_rtc_lock);
+ RTSR &= ~RTSR_HZE;
+ RTSR &= ~RTSR_HZ;
+ RTSR &= ~RTSR_ALE;
+ RTSR &= ~RTSR_AL;
+ OIER &= ~OIER_E1;
+ OSSR = OSSR_M1;
+ spin_unlock_irq(&sa1100_rtc_lock);
+
return 0;
}
|