summaryrefslogtreecommitdiff
path: root/drivers/rtc/rtc-imxdi.c
diff options
context:
space:
mode:
authorRaj Rajasekaran <b10872@freescale.com>2009-04-29 11:20:58 -0500
committerJustin Waters <justin.waters@timesys.com>2009-10-13 11:05:25 -0400
commitdd06362ddd4d9340f63e62eb557888ad88b0c269 (patch)
treeba2adc2d6f9357ea595b7b432fb75dee1f61db0a /drivers/rtc/rtc-imxdi.c
parent4bbaa26015adef4fb41d89e2aceaf1e6a60513d7 (diff)
ENGR00107366 DryIce: DryIce unit test failed with RTC enabled.2.6.28-mx-200904291620
Registered Dryice Security and RTC interrupts as shared. Signed-off-by: Raj Rajasekaran <b10872@freescale.com>
Diffstat (limited to 'drivers/rtc/rtc-imxdi.c')
-rw-r--r--drivers/rtc/rtc-imxdi.c50
1 files changed, 31 insertions, 19 deletions
diff --git a/drivers/rtc/rtc-imxdi.c b/drivers/rtc/rtc-imxdi.c
index 063963736790..b54fb638c840 100644
--- a/drivers/rtc/rtc-imxdi.c
+++ b/drivers/rtc/rtc-imxdi.c
@@ -342,30 +342,42 @@ static irqreturn_t dryice_norm_irq(int irq, void *dev_id)
u32 dsr, dier;
irqreturn_t rc = IRQ_NONE;
- /* DSR_WCF clears itself on DSR read */
- dsr = di_read(pdata, DSR);
dier = di_read(pdata, DIER);
/* handle write complete and write error cases */
- if ((dier & DIER_WCIE) && (dsr & (DSR_WCF | DSR_WEF))) {
- /* mask the interrupt */
- di_int_disable(pdata, DIER_WCIE);
-
- /* save the dsr value for the wait queue */
- pdata->dsr |= dsr;
-
- wake_up_interruptible(&pdata->write_wait);
- rc = IRQ_HANDLED;
+ if ((dier & DIER_WCIE)) {
+ /*If the write wait queue is empty then there is no pending
+ operations. It means the interrupt is for DryIce -Security.
+ IRQ must be returned as none.*/
+ if (list_empty_careful(&pdata->write_wait.task_list))
+ return rc;
+
+ /* DSR_WCF clears itself on DSR read */
+ dsr = di_read(pdata, DSR);
+ if ((dsr & (DSR_WCF | DSR_WEF))) {
+ /* mask the interrupt */
+ di_int_disable(pdata, DIER_WCIE);
+
+ /* save the dsr value for the wait queue */
+ pdata->dsr |= dsr;
+
+ wake_up_interruptible(&pdata->write_wait);
+ rc = IRQ_HANDLED;
+ }
}
/* handle the alarm case */
- if ((dier & DIER_CAIE) && (dsr & DSR_CAF)) {
- /* mask the interrupt */
- di_int_disable(pdata, DIER_CAIE);
-
- /* finish alarm in user context */
- schedule_work(&pdata->work);
- rc = IRQ_HANDLED;
+ if ((dier & DIER_CAIE)) {
+ /* DSR_WCF clears itself on DSR read */
+ dsr = di_read(pdata, DSR);
+ if (dsr & DSR_CAF) {
+ /* mask the interrupt */
+ di_int_disable(pdata, DIER_CAIE);
+
+ /* finish alarm in user context */
+ schedule_work(&pdata->work);
+ rc = IRQ_HANDLED;
+ }
}
return rc;
}
@@ -440,7 +452,7 @@ static int dryice_rtc_probe(struct platform_device *pdev)
clk_enable(pdata->clk);
if (pdata->irq >= 0) {
- if (request_irq(pdata->irq, dryice_norm_irq, IRQF_DISABLED,
+ if (request_irq(pdata->irq, dryice_norm_irq, IRQF_SHARED,
pdev->name, pdata) < 0) {
dev_warn(&pdev->dev, "interrupt not available.\n");
pdata->irq = -1;