diff options
author | David Brownell <david-b@pacbell.net> | 2007-12-18 01:19:50 +0100 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-12-18 04:28:15 +0100 |
commit | 8d431dbef4e63d54f1965c3ed6ca5f91ee4512de (patch) | |
tree | 47683f614c6d3c8d07d55bc4b03169e189ffe8fa /drivers | |
parent | alpha: strncpy/strncat fixes (diff) | |
download | linux-8d431dbef4e63d54f1965c3ed6ca5f91ee4512de.tar.xz linux-8d431dbef4e63d54f1965c3ed6ca5f91ee4512de.zip |
rtc-at32ap700x: fix irq init oops
Reorder at32_rtc_probe() so that it's safe (no oopsing) to fire the
IRQ handler the instant that it's registered. (Bug noted via "Debug
shared IRQ handlers" kernel debug option.)
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Cc: Alessandro Zummo <a.zummo@towertech.it>
Cc: <hcegtvedt@atmel.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/rtc/rtc-at32ap700x.c | 20 |
1 files changed, 10 insertions, 10 deletions
diff --git a/drivers/rtc/rtc-at32ap700x.c b/drivers/rtc/rtc-at32ap700x.c index 2999214ca534..d3b9b14267ab 100644 --- a/drivers/rtc/rtc-at32ap700x.c +++ b/drivers/rtc/rtc-at32ap700x.c @@ -225,18 +225,12 @@ static int __init at32_rtc_probe(struct platform_device *pdev) goto out; } - ret = request_irq(irq, at32_rtc_interrupt, IRQF_SHARED, "rtc", rtc); - if (ret) { - dev_dbg(&pdev->dev, "could not request irq %d\n", irq); - goto out; - } - rtc->irq = irq; rtc->regs = ioremap(regs->start, regs->end - regs->start + 1); if (!rtc->regs) { ret = -ENOMEM; dev_dbg(&pdev->dev, "could not map I/O memory\n"); - goto out_free_irq; + goto out; } spin_lock_init(&rtc->lock); @@ -253,12 +247,18 @@ static int __init at32_rtc_probe(struct platform_device *pdev) | RTC_BIT(CTRL_EN)); } + ret = request_irq(irq, at32_rtc_interrupt, IRQF_SHARED, "rtc", rtc); + if (ret) { + dev_dbg(&pdev->dev, "could not request irq %d\n", irq); + goto out_iounmap; + } + rtc->rtc = rtc_device_register(pdev->name, &pdev->dev, &at32_rtc_ops, THIS_MODULE); if (IS_ERR(rtc->rtc)) { dev_dbg(&pdev->dev, "could not register rtc device\n"); ret = PTR_ERR(rtc->rtc); - goto out_iounmap; + goto out_free_irq; } platform_set_drvdata(pdev, rtc); @@ -268,10 +268,10 @@ static int __init at32_rtc_probe(struct platform_device *pdev) return 0; -out_iounmap: - iounmap(rtc->regs); out_free_irq: free_irq(irq, rtc); +out_iounmap: + iounmap(rtc->regs); out: kfree(rtc); return ret; |