Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

David Brownell and committed by
Linus Torvalds
8d431dbe fe4304ba

+10 -10
+10 -10
drivers/rtc/rtc-at32ap700x.c
··· 225 225 goto out; 226 226 } 227 227 228 - ret = request_irq(irq, at32_rtc_interrupt, IRQF_SHARED, "rtc", rtc); 229 - if (ret) { 230 - dev_dbg(&pdev->dev, "could not request irq %d\n", irq); 231 - goto out; 232 - } 233 - 234 228 rtc->irq = irq; 235 229 rtc->regs = ioremap(regs->start, regs->end - regs->start + 1); 236 230 if (!rtc->regs) { 237 231 ret = -ENOMEM; 238 232 dev_dbg(&pdev->dev, "could not map I/O memory\n"); 239 - goto out_free_irq; 233 + goto out; 240 234 } 241 235 spin_lock_init(&rtc->lock); 242 236 ··· 247 253 | RTC_BIT(CTRL_EN)); 248 254 } 249 255 256 + ret = request_irq(irq, at32_rtc_interrupt, IRQF_SHARED, "rtc", rtc); 257 + if (ret) { 258 + dev_dbg(&pdev->dev, "could not request irq %d\n", irq); 259 + goto out_iounmap; 260 + } 261 + 250 262 rtc->rtc = rtc_device_register(pdev->name, &pdev->dev, 251 263 &at32_rtc_ops, THIS_MODULE); 252 264 if (IS_ERR(rtc->rtc)) { 253 265 dev_dbg(&pdev->dev, "could not register rtc device\n"); 254 266 ret = PTR_ERR(rtc->rtc); 255 - goto out_iounmap; 267 + goto out_free_irq; 256 268 } 257 269 258 270 platform_set_drvdata(pdev, rtc); ··· 268 268 269 269 return 0; 270 270 271 - out_iounmap: 272 - iounmap(rtc->regs); 273 271 out_free_irq: 274 272 free_irq(irq, rtc); 273 + out_iounmap: 274 + iounmap(rtc->regs); 275 275 out: 276 276 kfree(rtc); 277 277 return ret;