diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/mxc/security/dryice.c | 6 | ||||
-rw-r--r-- | drivers/rtc/rtc-imxdi.c | 50 |
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; |