summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRaj Rajasekaran <b10872@freescale.com>2009-04-29 11:20:58 -0500
committerRaj Rajasekaran <b10872@freescale.com>2009-08-21 13:54:24 -0500
commit12a78a3943ca93ca04f714b6c8cbbaa9b51733b6 (patch)
treeba2adc2d6f9357ea595b7b432fb75dee1f61db0a
parentdabb000f162c2efd6f012f4d1f80d4a1b5f9183d (diff)
ENGR00107366 DryIce: DryIce unit test failed with RTC enabled.rel_imx_2.6.28_4.5.1
Registered Dryice Security and RTC interrupts as shared. Signed-off-by: Raj Rajasekaran <b10872@freescale.com>
-rw-r--r--drivers/mxc/security/dryice.c6
-rw-r--r--drivers/rtc/rtc-imxdi.c50
2 files changed, 35 insertions, 21 deletions
diff --git a/drivers/mxc/security/dryice.c b/drivers/mxc/security/dryice.c
index 96c403585bd2..0f175cd60afc 100644
--- a/drivers/mxc/security/dryice.c
+++ b/drivers/mxc/security/dryice.c
@@ -571,8 +571,10 @@ OS_DEV_INIT(dryice_init)
clk_enable(di->clk);
/* register for interrupts */
- rc = os_register_interrupt("dry_ice", di->irq_norm.irq,
- OS_DEV_ISR_REF(dryice_norm_irq));
+ /* os_register_interrupt() dosen't support an option to make the
+ interrupt as shared. Replaced it with request_irq().*/
+ rc = request_irq(di->irq_norm.irq, dryice_norm_irq, IRQF_SHARED,
+ "dry_ice", di);
if (rc)
goto err_irqs;
else
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;