diff options
author | Raj Rajasekaran <b10872@freescale.com> | 2009-04-29 11:20:58 -0500 |
---|---|---|
committer | Justin Waters <justin.waters@timesys.com> | 2009-10-13 11:05:25 -0400 |
commit | dd06362ddd4d9340f63e62eb557888ad88b0c269 (patch) | |
tree | ba2adc2d6f9357ea595b7b432fb75dee1f61db0a /drivers/rtc/rtc-imxdi.c | |
parent | 4bbaa26015adef4fb41d89e2aceaf1e6a60513d7 (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.c | 50 |
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; |