summaryrefslogtreecommitdiffstats
path: root/drivers/rtc/rtc-coh901331.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/rtc/rtc-coh901331.c')
-rw-r--r--drivers/rtc/rtc-coh901331.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/drivers/rtc/rtc-coh901331.c b/drivers/rtc/rtc-coh901331.c
index 7fe1fa26c52c..44c4399ee714 100644
--- a/drivers/rtc/rtc-coh901331.c
+++ b/drivers/rtc/rtc-coh901331.c
@@ -58,7 +58,16 @@ static irqreturn_t coh901331_interrupt(int irq, void *data)
clk_enable(rtap->clk);
/* Ack IRQ */
writel(1, rtap->virtbase + COH901331_IRQ_EVENT);
+ /*
+ * Disable the interrupt. This is necessary because
+ * the RTC lives on a lower-clocked line and will
+ * not release the IRQ line until after a few (slower)
+ * clock cycles. The interrupt will be re-enabled when
+ * a new alarm is set anyway.
+ */
+ writel(0, rtap->virtbase + COH901331_IRQ_MASK);
clk_disable(rtap->clk);
+
/* Set alarm flag */
rtc_update_irq(rtap->rtc, 1, RTC_AF);
@@ -128,6 +137,8 @@ static int coh901331_alarm_irq_enable(struct device *dev, unsigned int enabled)
else
writel(0, rtap->virtbase + COH901331_IRQ_MASK);
clk_disable(rtap->clk);
+
+ return 0;
}
static struct rtc_class_ops coh901331_ops = {
@@ -260,12 +271,13 @@ static int coh901331_resume(struct platform_device *pdev)
{
struct coh901331_port *rtap = dev_get_drvdata(&pdev->dev);
- if (device_may_wakeup(&pdev->dev))
+ if (device_may_wakeup(&pdev->dev)) {
disable_irq_wake(rtap->irq);
- else
+ } else {
clk_enable(rtap->clk);
writel(rtap->irqmaskstore, rtap->virtbase + COH901331_IRQ_MASK);
clk_disable(rtap->clk);
+ }
return 0;
}
#else