diff options
author | Justin Waters <justin.waters@timesys.com> | 2008-05-21 11:04:59 -0400 |
---|---|---|
committer | Justin Waters <justin.waters@timesys.com> | 2008-05-21 11:04:59 -0400 |
commit | 969c26a51d236659812b97209f1f1f6cd5f64c32 (patch) | |
tree | 0897ba38506a0323913e8564d7186d98bfc7fb98 /drivers | |
parent | 4c2a2437ea37c42778c318cb6626668518001193 (diff) |
RTC_MXC: Handle shared interrupts properly
The MXC RTC driver interrupt handler never checked to make sure it was handling
the correct IRQ. This was causing it to oops whenever CONFIG_DEBUG_SHIRQ was
enabled in the kernel. This fixes that problem by checking the IRQ status
registers on the RTC module whenever the IRQ occurs.
Signed-off-by: Justin Waters <justin.waters@timesys.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/rtc/rtc-mxc.c | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/drivers/rtc/rtc-mxc.c b/drivers/rtc/rtc-mxc.c index da96395d7f8f..4c186934042f 100644 --- a/drivers/rtc/rtc-mxc.c +++ b/drivers/rtc/rtc-mxc.c @@ -317,13 +317,25 @@ static int rtc_update_alarm(struct device *dev, struct rtc_time *alrm) */ static irqreturn_t mxc_rtc_interrupt(int irq, void *dev_id) { - struct platform_device *pdev = dev_id; - struct rtc_plat_data *pdata = platform_get_drvdata(pdev); - void __iomem *ioaddr = pdata->ioaddr; + struct platform_device *pdev; + struct rtc_plat_data *pdata; + void __iomem *ioaddr; u32 status; u32 events = 0; spin_lock(&rtc_lock); - status = readw(ioaddr + RTC_RTCISR) & readw(ioaddr + RTC_RTCIENR); + status = readw(IO_ADDRESS(RTC_BASE_ADDR + RTC_RTCISR)) & + readw(IO_ADDRESS(RTC_BASE_ADDR + RTC_RTCIENR)); + + /* This IRQ is shared, so make sure an interrupt really occurred */ + if (unlikely(!status)) { + spin_unlock(&rtc_lock); + return IRQ_NONE; + } + + pdev = dev_id; + pdata = platform_get_drvdata(pdev); + ioaddr = pdata->ioaddr; + /* clear interrupt sources */ writew(status, ioaddr + RTC_RTCISR); |