Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 225763
b: refs/heads/master
c: 7decaa5
h: refs/heads/master
i:
  225761: 33aaf44
  225759: 1b8c3d6
v: v3
  • Loading branch information
Marcelo Roberto Jimenez authored and Russell King committed Nov 10, 2010
1 parent 907ba09 commit 2023523
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 2 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: fd3ee6d3421bc05ce42ee7f48071aee72051af28
refs/heads/master: 7decaa557a20f48aabef35f817ec16ef563567b0
42 changes: 41 additions & 1 deletion trunk/drivers/rtc/rtc-sa1100.c
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,23 @@ static irqreturn_t sa1100_rtc_interrupt(int irq, void *dev_id)
rtsr = RTSR;
/* clear interrupt sources */
RTSR = 0;
RTSR = (RTSR_AL | RTSR_HZ) & (rtsr >> 2);
/* Fix for a nasty initialization problem the in SA11xx RTSR register.
* See also the comments in sa1100_rtc_probe(). */
if (rtsr & (RTSR_ALE | RTSR_HZE)) {
/* This is the original code, before there was the if test
* above. This code does not clear interrupts that were not
* enabled. */
RTSR = (RTSR_AL | RTSR_HZ) & (rtsr >> 2);
} else {
/* For some reason, it is possible to enter this routine
* without interruptions enabled, it has been tested with
* several units (Bug in SA11xx chip?).
*
* This situation leads to an infinite "loop" of interrupt
* routine calling and as a result the processor seems to
* lock on its first call to open(). */
RTSR = RTSR_AL | RTSR_HZ;
}

/* clear alarm interrupt if it has occurred */
if (rtsr & RTSR_AL)
Expand Down Expand Up @@ -382,6 +398,30 @@ static int sa1100_rtc_probe(struct platform_device *pdev)

platform_set_drvdata(pdev, rtc);

/* Fix for a nasty initialization problem the in SA11xx RTSR register.
* See also the comments in sa1100_rtc_interrupt().
*
* Sometimes bit 1 of the RTSR (RTSR_HZ) will wake up 1, which means an
* interrupt pending, even though interrupts were never enabled.
* In this case, this bit it must be reset before enabling
* interruptions to avoid a nonexistent interrupt to occur.
*
* In principle, the same problem would apply to bit 0, although it has
* never been observed to happen.
*
* This issue is addressed both here and in sa1100_rtc_interrupt().
* If the issue is not addressed here, in the times when the processor
* wakes up with the bit set there will be one spurious interrupt.
*
* The issue is also dealt with in sa1100_rtc_interrupt() to be on the
* safe side, once the condition that lead to this strange
* initialization is unknown and could in principle happen during
* normal processing.
*
* Notice that clearing bit 1 and 0 is accomplished by writting ONES to
* the corresponding bits in RTSR. */
RTSR = RTSR_AL | RTSR_HZ;

return 0;
}

Expand Down

0 comments on commit 2023523

Please sign in to comment.